From 8dc9252db195733db133112835c2cf9d4367353c Mon Sep 17 00:00:00 2001 From: "Travis F. Collins" Date: Mon, 12 Dec 2022 20:07:35 -0700 Subject: [PATCH 1/8] Initial work for linting jobs Signed-off-by: Travis F. Collins --- .github/workflows/lint.yml | 44 ++++++++++++++++++++++++++++++++++++++ requirements_dev.txt | 1 + 2 files changed, 45 insertions(+) create mode 100644 .github/workflows/lint.yml create mode 100644 requirements_dev.txt diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..6d485921 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,44 @@ +name: Lint + +on: [push, pull_request] + +jobs: + LintCode: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.7 + uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: Install dependencies + run: | + pip install -r requirements_dev.txt + - name: Check code styling + run: | + mh_style +adi + + RunMetrics: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.7 + uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: Install dependencies + run: | + pip install -r requirements_dev.txt + - name: Check code styling + run: | + mh_metrics +adi --html=metrics.html + + - name: Archive report + uses: actions/upload-artifact@v2 + with: + name: Metrics + path: metrics.html \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 00000000..09793806 --- /dev/null +++ b/requirements_dev.txt @@ -0,0 +1 @@ +miss_hit \ No newline at end of file From 9d0d107663fa8e14b798d382b20a286d90392fe8 Mon Sep 17 00:00:00 2001 From: Travis Collins Date: Thu, 21 May 2026 21:54:17 -0400 Subject: [PATCH 2/8] Add doc linting, formatting, and Sphinx config improvements - Wire up Vale prose linting and mdformat Markdown formatting via a new docs-lint CI workflow (push & PR), plus make lint/format/format-check targets - Format authored Markdown sources (table alignment, whitespace normalization) - Add Kuiper and buildroot to the Vale accept vocabulary - Modernize conf.py: derive release from +adi/Version.m, dynamic copyright, enable sphinx_copybutton, drop dead config - Add .editorconfig and .mdformat.toml --- .editorconfig | 24 ++++++++++ .../config/vocabularies/Sphinx/accept.txt | 2 + .github/workflows/docs-lint.yml | 41 +++++++++++++++++ .mdformat.toml | 5 ++ CI/doc/Makefile | 20 +++++++- CI/doc/README_doc.md | 22 +++++++++ CI/doc/requirements_doc.txt | 3 +- CI/doc/requirements_lint.txt | 2 + CI/doc/source/conf.py | 33 +++++++++---- CI/doc/source/dev_hdl_workflow.md | 14 ++---- CI/doc/source/examples.md | 7 ++- CI/doc/source/index.md | 46 +++++++++---------- CI/doc/source/install.md | 23 ++++------ CI/doc/source/streaming.md | 10 ++-- CI/doc/source/targeting.md | 1 - 15 files changed, 186 insertions(+), 67 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/docs-lint.yml create mode 100644 .mdformat.toml create mode 100644 CI/doc/requirements_lint.txt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..0aefff30 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +# EditorConfig — https://editorconfig.org +# Top-most EditorConfig file +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[*.{md,yml,yaml,json,toml}] +indent_size = 2 + +[*.py] +indent_size = 4 + +# Makefiles require literal tabs +[Makefile] +indent_style = tab + +[**/Makefile] +indent_style = tab diff --git a/.github/doc/styles/config/vocabularies/Sphinx/accept.txt b/.github/doc/styles/config/vocabularies/Sphinx/accept.txt index c0856077..16e0168e 100644 --- a/.github/doc/styles/config/vocabularies/Sphinx/accept.txt +++ b/.github/doc/styles/config/vocabularies/Sphinx/accept.txt @@ -88,3 +88,5 @@ spi [nN]arrowband [Ww]ideband rf_enabled +[kK]uiper +[bB]uildroot diff --git a/.github/workflows/docs-lint.yml b/.github/workflows/docs-lint.yml new file mode 100644 index 00000000..f6fb743b --- /dev/null +++ b/.github/workflows/docs-lint.yml @@ -0,0 +1,41 @@ +name: Documentation Lint + +on: [push, pull_request] + +jobs: + vale: + name: Vale prose lint + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install Vale + run: | + VALE_VERSION=3.9.1 + curl -sfL "https://github.com/errata-ai/vale/releases/download/v${VALE_VERSION}/vale_${VALE_VERSION}_Linux_64-bit.tar.gz" \ + | sudo tar -xz -C /usr/local/bin vale + vale --version + + # Styles are committed under .github/doc/styles; .vale.ini drives the rules. + # Vale exits non-zero only on error-level alerts, so warnings do not fail CI. + - name: Run Vale + run: vale CI/doc/source + + mdformat: + name: Markdown format check + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install mdformat + run: pip install -r CI/doc/requirements_lint.txt + + - name: Check Markdown formatting + run: make -C CI/doc format-check diff --git a/.mdformat.toml b/.mdformat.toml new file mode 100644 index 00000000..40f6236b --- /dev/null +++ b/.mdformat.toml @@ -0,0 +1,5 @@ +# mdformat configuration — https://mdformat.readthedocs.io +# Do not reflow prose; only normalize structure (lists, spacing, tables). +wrap = "keep" +number = false +end_of_line = "lf" diff --git a/CI/doc/Makefile b/CI/doc/Makefile index d3392f87..d44316e7 100644 --- a/CI/doc/Makefile +++ b/CI/doc/Makefile @@ -9,12 +9,18 @@ SOURCEDIR = source BUILDDIR = build PYTHON = python +VALE ?= vale +MDFORMAT ?= mdformat + +# Authored Markdown sources to lint/format. The index pages objects.md and +# allrefdesigns.md are regenerated by gen_autodocs, so they are excluded. +DOCSRC := $(filter-out $(SOURCEDIR)/objects.md $(SOURCEDIR)/allrefdesigns.md, $(wildcard $(SOURCEDIR)/*.md)) # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -.PHONY: help Makefile +.PHONY: help Makefile lint format format-check # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). @@ -26,3 +32,15 @@ gen_autodocs: $(PYTHON) gen_sysobj_pages.py ; \ $(PYTHON) gen_rd_svg.py ; \ $(PYTHON) gen_hdl_refdesigns.py + +# Prose linting with Vale (styles live in .github/doc/styles, config in .vale.ini) +lint: + $(VALE) $(SOURCEDIR) + +# Auto-format the authored Markdown sources in place +format: + $(MDFORMAT) $(DOCSRC) + +# Verify the authored Markdown sources are formatted (used by CI) +format-check: + $(MDFORMAT) --check $(DOCSRC) diff --git a/CI/doc/README_doc.md b/CI/doc/README_doc.md index b13505de..ac8b4a1a 100644 --- a/CI/doc/README_doc.md +++ b/CI/doc/README_doc.md @@ -22,3 +22,25 @@ The system object documentation is generated from the MATLAB code and comments, cd CI/doc/gen_pages gen_sysobj_doc ``` + +## Linting and Formatting + +The documentation is prose-linted with [Vale](https://vale.sh) and the Markdown is +formatted with [mdformat](https://mdformat.readthedocs.io). Both run automatically on push +and pull request through the *Documentation Lint* workflow, and can be run locally: + +```bash +# Prose linting (requires the Vale binary on PATH). +# Styles are committed under .github/doc/styles and configured by the root .vale.ini. +# Only error-level alerts fail; warnings are advisory. +make -C CI/doc lint + +# Markdown formatting of the authored source files. +pip install -r CI/doc/requirements_lint.txt +make -C CI/doc format # rewrite files in place +make -C CI/doc format-check # verify only (used by CI) +``` + +The generated index pages `objects.md` and `allrefdesigns.md` are produced by `gen_autodocs` +and are intentionally excluded from formatting. To refresh the bundled Google style rules, run +`.github/doc/scripts/get_styles.sh`. diff --git a/CI/doc/requirements_doc.txt b/CI/doc/requirements_doc.txt index a00cef0f..e23ac323 100644 --- a/CI/doc/requirements_doc.txt +++ b/CI/doc/requirements_doc.txt @@ -7,4 +7,5 @@ sphinx-simplepdf pillow numpy jinja2 -sphinx_design \ No newline at end of file +sphinx_design +sphinx-copybutton \ No newline at end of file diff --git a/CI/doc/requirements_lint.txt b/CI/doc/requirements_lint.txt new file mode 100644 index 00000000..7d1ebd0a --- /dev/null +++ b/CI/doc/requirements_lint.txt @@ -0,0 +1,2 @@ +mdformat +mdformat-gfm diff --git a/CI/doc/source/conf.py b/CI/doc/source/conf.py index d1dc5603..e1818de8 100644 --- a/CI/doc/source/conf.py +++ b/CI/doc/source/conf.py @@ -12,8 +12,10 @@ # import contextlib import os +import re import shutil import sys +from datetime import datetime from typing import List sys.path.insert(0, os.path.abspath("../..")) @@ -43,11 +45,30 @@ # -- Project information ----------------------------------------------------- project = "Analog Devices, Inc. Transceiver Toolbox" -copyright = "2019-2022, Analog Devices, Inc" +copyright = f"2019-{datetime.now().year}, Analog Devices, Inc" author = "Analog Devices, Inc." + +def _toolbox_release() -> str: + """Return the toolbox release, read from the source of truth +adi/Version.m. + + Falls back to a literal so the docs always build even if the file moves. + """ + version_file = os.path.join( + os.path.dirname(__file__), "..", "..", "..", "+adi", "Version.m" + ) + try: + with open(version_file, encoding="utf-8") as fh: + match = re.search(r"Release\s*=\s*'([^']+)'", fh.read()) + if match: + return f"v{match.group(1)}" + except OSError: + pass + return "v23.2.2" + + # The full version, including alpha/beta/rc tags -release = "v22.2.1" +release = _toolbox_release() # -- General configuration --------------------------------------------------- @@ -59,14 +80,12 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - # "sphinx.ext.autodoc", "sphinx.ext.coverage", "sphinx.ext.githubpages", "myst_parser", "sphinx_favicon", "sphinxcontrib.mermaid", - # "sphinx_copybutton", - # "sphinx_togglebutton", # Using this? + "sphinx_copybutton", "sphinx_design", ] @@ -82,9 +101,6 @@ # This pattern also affects html_static_path and html_extra_path. exclude_patterns: List[str] = [] -# Configuration of sphinx.ext.coverage -#coverage_show_missing_items = True - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -93,7 +109,6 @@ html_theme = "furo" html_title = f"{project} {release}" -#favicons = ["favicon.png"] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/CI/doc/source/dev_hdl_workflow.md b/CI/doc/source/dev_hdl_workflow.md index 6fda924f..541c21d5 100644 --- a/CI/doc/source/dev_hdl_workflow.md +++ b/CI/doc/source/dev_hdl_workflow.md @@ -6,17 +6,18 @@ This content is meant for developers or advanced users and is not meant for gene This page discusses the HDL targeting support from the perspective of the HDL source repository and HDL-Coder itself. It is not necessary for users to understand these details but for those managing the toolbox or developers extending support to new platforms this information is valuable. -This page assumes a basic understanding of MathWork's [HDL Workflow Advisor (HWA)](https://www.mathworks.com/help/hdlcoder/ug/overview-of-workflows-in-hdl-workflow-advisor.html) and its different steps for creating IP, creating a HDL project, and generating a bitstream. +This page assumes a basic understanding of MathWork's [HDL Workflow Advisor (HWA)](https://www.mathworks.com/help/hdlcoder/ug/overview-of-workflows-in-hdl-workflow-advisor.html) and its different steps for creating IP, creating a HDL project, and generating a bitstream. ## HDL Repository Preparation -When the toolbox is built it will clone a specific branch of the [ADI HDL repository](https://github.com/analogdevicesinc/hdl) and apply certain changes to support the [IP-Core Generation HDL-Coder](https://www.mathworks.com/discovery/ip-core-generation.html) workflow. However, with the current flow there are minimal changes required which makes moving between release simpler. This is currently done by simply replacing certain TCL scripts within the HDL repository. +When the toolbox is built it will clone a specific branch of the [ADI HDL repository](https://github.com/analogdevicesinc/hdl) and apply certain changes to support the [IP-Core Generation HDL-Coder](https://www.mathworks.com/discovery/ip-core-generation.html) workflow. However, with the current flow there are minimal changes required which makes moving between release simpler. This is currently done by simply replacing certain TCL scripts within the HDL repository. Creation of the toolbox, cloning of the HDL source, and applying the necessary update is driven through a Makefile in the **CI/scripts** folder. The toolbox is built in source form with the **build** as follows: ```bash make -C CI/scripts build ``` + After the above command completes the HDL source will be in place with necessary changes. The changes primarily required of the HDL source are interceptions of the build functions (procs) to skip synthesis when building a project. This is done by inserting environmental variable checks into the [adi_project_xilinx.tcl](https://github.com/analogdevicesinc/TransceiverToolbox/blob/master/CI/scripts/adi_project_xilinx.tcl#L138) script. At build time these environmental variables are set and will prevent synthesis. This way an HDL project can be built, then handed off to HDL-Coder for IP insertion and eventual synthesis. @@ -44,6 +45,7 @@ style E fill:#f9f,stroke:#333,stroke-width:4px style C fill:#FF0,stroke:#333,stroke-width:4px,stroke-dasharray: 5 5 style D fill:#FF0,stroke:#333,stroke-width:4px,stroke-dasharray: 5 5 ``` +
Figure 1: Details IP-Core Generation flow with Toolbox
At a high-level there are six main steps, two of which are optional. From the far left stage "Generate Verilog From Simulink IP" occurs in Stage 3 "HDL Code Generation" within HWA as outlined in red below. This will create Verilog within the defined project folder and then be copied into the full HDL project later on. @@ -55,27 +57,22 @@ HDL Workflow Advisor IP verilog generation. Within the largest central block of the flowchart labeled **vivado_create_prj.tcl** are all the core steps related the HWA Step 4.1, where the reference HDL project folder is built and necessary cores and nets removed to make room for IP from Simulink generated in HWA Step 3. This stage is highlighted in the figure below. The purple boxes are optional stages that are used in certain customized examples when additional work is required to prepare a reference design. The [Frequency Hopping example](https://github.com/analogdevicesinc/TransceiverToolbox/tree/master/trx_examples/targeting/frequency-hopping) leverages these stages. Once the project is prepared the IP is inserted and bitstream generated, which occurs through HWA Step 4.3. - ```{figure} /_static/assets/HWA_project_gen.png HDL Workflow Advisor project generation step. ``` - ### Vivado Project Perspective Based on the flow in Figure 1, there are a three main states the HDL reference design enters from a high level. These states will be discussed more from the Vivado project perspective, specifically the data path of an FMComms2 project. Other HDL projects will be similar. The first state is just the initial creation of the standard unmodified block design. Looking at Figure 4, the three IPs show the dataflow from the interface core (axi_ad9361), through the ADC FIFO, and finally into the pack core. In orange are the data buses and valid signal highlighted. These are important since the generated IP needs to be inserted where these nets are connected. Therefore, in the second state of the design these nets are removed to make room from the new IP. - ```{figure} /_static/assets/stock_reference_design.png RX path in unmodified standard reference design. ``` - - Once the IP is inserted into the project by HDL-Coder it is connected to the FIFO and pack cores where the nets in Figure 4 were highlighted. The new inserted and connected IP can be see in Figure 5. ```{figure} /_static/assets/reference_design_with_IP.png @@ -87,9 +84,8 @@ The connecting of the IPs and insertion are entirely managed by HDL-Coder and th ### Generated TCL Scripts - The following scripts outlined in the figure above have certain purposes: - **vivado_create_prj.tcl**: This is the first TCL scripted called in Stage 4 of HWA and is responsible for setting up a standard reference design and trimming nets and IPs to make room for IP from Simulink - **vivado_custom_block_design.tcl**: This is a carbon copy of the **system_project_rxtx.tcl** script and is called by **vivado_create_prj.tcl**. This script will call [adi_make.tcl](https://wiki.analog.com/resources/fpga/docs/build#xilinx_auto_tcl_build), the correct system_project.tcl file, and finally matlab_processor.tcl. It will optionally call the pre/post processor TCL scripts. -- **vivado_insert_ip.tcl**: This script is fully generated by MATLAB based on the [add_io](https://github.com/analogdevicesinc/TransceiverToolbox/blob/master/hdl/vendor/AnalogDevices/+AnalogDevices/add_io.m) definitions in MATLAB to insert the custom IP into the prepared reference design. \ No newline at end of file +- **vivado_insert_ip.tcl**: This script is fully generated by MATLAB based on the [add_io](https://github.com/analogdevicesinc/TransceiverToolbox/blob/master/hdl/vendor/AnalogDevices/+AnalogDevices/add_io.m) definitions in MATLAB to insert the custom IP into the prepared reference design. diff --git a/CI/doc/source/examples.md b/CI/doc/source/examples.md index 9dee6e37..0110a2f9 100644 --- a/CI/doc/source/examples.md +++ b/CI/doc/source/examples.md @@ -1,4 +1,3 @@ - # Examples Examples for streaming data and targeting FPGAs are listed within the Toolbox documentation itself. To view run the following with MATLAB: @@ -9,8 +8,8 @@ doc adi They can also be viewed on GitHub: - - [Targeting examples](https://github.com/analogdevicesinc/TransceiverToolbox/tree/master/trx_examples/targeting) - - [Streaming examples](https://github.com/analogdevicesinc/TransceiverToolbox/tree/master/trx_examples/streaming) +- [Targeting examples](https://github.com/analogdevicesinc/TransceiverToolbox/tree/master/trx_examples/targeting) +- [Streaming examples](https://github.com/analogdevicesinc/TransceiverToolbox/tree/master/trx_examples/streaming) ## Highlighted Demos @@ -19,4 +18,4 @@ Certain examples have full articles that discuss different applications - [Frequency hopping](https://wiki.analog.com/resources/eval/user-guides/adrv936x_rfsom/tutorials/frequency_hopping) - [Loopback delay estimation](https://wiki.analog.com/resources/eval/user-guides/adrv936x_rfsom/tutorials/loopback_delay_estimation) - [AGC Optimization](https://wiki.analog.com/resources/eval/user-guides/ad9361_agc_tuning) -- [Pluto LTE App](https://wiki.analog.com/resources/tools-software/transceiver-toolbox/examples/pluto_lte_app) \ No newline at end of file +- [Pluto LTE App](https://wiki.analog.com/resources/tools-software/transceiver-toolbox/examples/pluto_lte_app) diff --git a/CI/doc/source/index.md b/CI/doc/source/index.md index c8c68e01..35317527 100644 --- a/CI/doc/source/index.md +++ b/CI/doc/source/index.md @@ -1,4 +1,5 @@ +