From 4d676ca25a3e6cc4caf10db3e307488c346dc427 Mon Sep 17 00:00:00 2001 From: Jorge Marques <2892061+gastmaier@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:23:50 -0300 Subject: [PATCH] docs: Update README, misspelings, and improvements Update docs instructions in the README.md to recommend building the libraries before generating the documentation. Fix misspellings in the SPI Engines. Use hashlib to gen the reproducible ids, so these elements won't be committed at every build in the gh-pages branch. Get username from environment variable, to use in the symbolator local installation path, dismissing user interaction for this. Use modelParameter to extract the type from ip-xact parameters without the format field, and improve formatting. Signed-off-by: Jorge Marques --- README.md | 16 ++++--- docs/conf.py | 3 +- docs/extensions/adi_hdl_parser.py | 46 +++++++++++++++---- .../library/spi_engine/instruction-format.rst | 4 +- docs/library/spi_engine/tutorial.rst | 23 +++++----- docs/sources/custom.css | 5 +- 6 files changed, 65 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 9c078aa2b..30a55256f 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ The HDL is provided "AS IS", support is only provided on [EngineerZone](https:// If you feel you can not, or do not want to ask questions on [EngineerZone](https://ez.analog.com/community/fpga), you should not use or look at the HDL found in this repository. Just like you have the freedom and rights to use this software in your products (with the obligations found in individual licenses) and get support on [EngineerZone](https://ez.analog.com/community/fpga), you have the freedom and rights not to use this software and get datasheet level support from traditional ADI contacts that you may have. -There is no free replacement for consulting services. If you have questions that are best handed one-on-one engagement, and are time sensitive, consider hiring a consultant. If you want to find a consultant who is familar with the HDL found in this repository - ask on [EngineerZone](https://ez.analog.com/community/fpga). +There is no free replacement for consulting services. If you have questions that are best handed one-on-one engagement, and are time sensitive, consider hiring a consultant. If you want to find a consultant who is familiar with the HDL found in this repository - ask on [EngineerZone](https://ez.analog.com/community/fpga). ## Getting started @@ -47,15 +47,19 @@ This repository supports reference designs for different [Analog Devices boards] ### Building documentation -Install necessary tools +Install the documentation tools. ``` -cd docs -pip install -r requirements.txt +(cd docs ; pip install -r requirements.txt) ``` -Then build the documentation with sphinx +Build the libraries (recommended). ``` -make html +(cd library ; make) ``` +Build the documentation with Sphinx. +``` +(cd docs ; make html) +``` +The generated documentation will be available at `docs/_build/html`. ### Prerequisites diff --git a/docs/conf.py b/docs/conf.py index 581ca9f8c..532b4068d 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,6 +13,7 @@ release = 'v0.1' import os, sys +user = os.environ.get("USER") sys.path.append(os.path.abspath("./extensions")) extensions = [ @@ -40,7 +41,7 @@ todo_emit_warnings = True # -- Symbolator configuration ------------------------------------------------- -symbolator_cmd = '~/.local/bin/symbolator' # Update with your installed location +symbolator_cmd = f"/home/{user}/.local/bin/symbolator" symbolator_cmd_args = ['-t', '--scale=0.75'] # -- Options for HTML output -------------------------------------------------- diff --git a/docs/extensions/adi_hdl_parser.py b/docs/extensions/adi_hdl_parser.py index fd8d7d895..f87cf4434 100644 --- a/docs/extensions/adi_hdl_parser.py +++ b/docs/extensions/adi_hdl_parser.py @@ -12,6 +12,7 @@ from sphinx.util import logging from lxml import etree from adi_hdl_static import hdl_strings from uuid import uuid4 +from hashlib import sha1 import contextlib logger = logging.getLogger(__name__) @@ -178,7 +179,7 @@ class directive_base(Directive): def collapsible(self, section, text=""): env = self.state.document.settings.env - _id = str(uuid4()) + _id = sha1(text.encode('utf-8')).hexdigest() container = nodes.container( "", is_div=True, @@ -491,7 +492,7 @@ class directive_parameters(directive_base): table = nodes.table() table += tgroup - self.table_header(tgroup, ["Name", "Description", "Type", "Default Value", "Choices/Range"]) + self.table_header(tgroup, ["Name", "Description", "Data Type", "Default Value", "Choices/Range"]) rows = [] for key in parameter: @@ -501,13 +502,16 @@ class directive_parameters(directive_base): self.column_entry(row, description[key], 'reST', classes=['description']) else: self.column_entry(row, dot_fix(parameter[key]['description']), 'paragraph', classes=['description']) - for tag in ['type', 'default']: - self.column_entry(row, parameter[key][tag].title(), 'paragraph') + for tag, ty in zip(['type', 'default'], ['paragraph', 'literal']): + if parameter[key][tag] is not None: + self.column_entry(row, parameter[key][tag], ty, classes=[tag]) + else: + logger.warning(f"Got empty {tag} at parameter {key}!") + self.column_entry(row, "", 'paragraph') crange = [] - if parameter[key]['choices'] is not None: - crange.append(parameter[key]['choices']) - if parameter[key]['range'] is not None: - crange.append(parameter[key]['range']) + for tag in ['choices', 'range']: + if parameter[key][tag] is not None: + crange.append(parameter[key][tag]) crange = '. '.join(crange) self.column_entry(row, crange, 'paragraph') @@ -615,6 +619,15 @@ def parse_hdl_component(path, ctime): def get_choice_type(name): return name[name.find('_')+1:name.rfind('_')] + def format_default_value(value, fmt): + if fmt == "bitString" and value[0:2].lower() == "0x": + return f"'h{value[2:].upper()}" + if fmt == "bitString" and value[0] == '"' and value[-1] == '"': + return f"'b{value[1:-1]}" + if fmt == "bool": + return value.title() + return value + root = etree.parse(path).getroot() spirit, xilinx, _ = get_namespaces(root) vendor = get(root, 'vendor').text @@ -673,15 +686,28 @@ def parse_hdl_component(path, ctime): if param_description is not None: param_name = get(parameter, 'name').text param_value = get(parameter, 'value') + param_format = sattrib(param_value, 'format') pr[param_name] = { 'description': param_description.text, - 'default': param_value.text, - 'type': sattrib(param_value, 'format'), + 'default': format_default_value(param_value.text, param_format), + 'type': param_format, '_choice_ref': sattrib(param_value, 'choiceRef'), 'choices': None, 'range': get_range(param_value) } + for parameter in get_all(root, 'model/modelParameters/modelParameter'): + param_name = get(parameter, 'name').text + param_type = sattrib(parameter, 'dataType') + if param_type == "std_logic_vector": + param_type = "logic vector" + if param_type is not None and param_name in pr: + if pr[param_name]['type'] is None: + pr[param_name]['type'] = param_type.capitalize() + else: + param_format = pr[param_name]['type'] + pr[param_name]['type'] = param_format[0].upper()+param_format[1:] + for choice in get_all(root, 'choices/choice'): name = get(choice, 'name').text for key in pr: diff --git a/docs/library/spi_engine/instruction-format.rst b/docs/library/spi_engine/instruction-format.rst index 22bd56d10..152e6f955 100644 --- a/docs/library/spi_engine/instruction-format.rst +++ b/docs/library/spi_engine/instruction-format.rst @@ -7,10 +7,10 @@ The SPI Engine instruction set is a simple 16-bit instruction set of which 12-bit is currently allocated (bits 15,14,11,10 are always 0). Instructions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------------------------------------------------------- Transfer Instruction --------------------------------------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ == == == == == == = = = = = = = = = = 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/docs/library/spi_engine/tutorial.rst b/docs/library/spi_engine/tutorial.rst index 1771fc011..a12abc711 100644 --- a/docs/library/spi_engine/tutorial.rst +++ b/docs/library/spi_engine/tutorial.rst @@ -6,7 +6,7 @@ SPI Engine Tutorial - PulSAR-ADC The goal of this tutorial is to present the process of adding :ref:`spi_engine` support for an ADI precision converter or family of converters using a few simple steps. -The target carrier is the Digilent Cora-z7s board using a Pmod connector. +The target carrier is the Digilent Cora-z7s board using a PMOD connector. Evaluating the target device -------------------------------------------------------------------------------- @@ -73,7 +73,7 @@ each IP individually or by using the function provided by the Using the script ensures that the correct connections are being made and that the IP cores will receive the correct parameter configuration since certain parameters need to be set to the same value. The function takes the following -argumets +arguments: .. code:: tcl @@ -88,7 +88,7 @@ and some of them require 18bit transfers, this value will be rounded to 32bit. **async_spi_clk** will chose the reference clock for the SPI Engine. Setting this parameter to 0 will configure the hierarchy to use the axi clock (100MHz) -as the reference clock. Setting it to 1 will allow for an external referece +as the reference clock. Setting it to 1 will allow for an external reference clock (spi_clk). Because some devices need 80MHz SCLK, a 160MHz reference clock is required which implies an external reference. @@ -171,7 +171,7 @@ Sample rate control ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The T_CYC parameter is the what sets the maximum sample rate (1/750 => 1333 -KSPS). To achieve precise control over the the sample rate we will use a PWM +KSPS). To achieve precise control over the sample rate we will use a PWM generator (AXI PWM GEN) using the spi_clk as reference. The spi_clock is used to avoid clock domain crossing mechanisms which will introduce latency, decreasing the overall performance of the system. @@ -199,13 +199,13 @@ wide range of options. The PWM output will be used as a trigger signal for the offload IP core. The CS signal will be used to drive CNV and will have the same frequency as the -PWM-trgger signal. +PWM-trigger signal. DMA setup -------------------------------------------------------------------------------- DMA destination bus (connection to Zynq – DDR memory) shall always be 64 bit -wide AXI4 MM and source bus shall be data_wdth \* num_sdi = 32 bit, AXI4 Stream. +wide AXI4 MM and source bus shall be data_width \* num_sdi = 32 bit, AXI4 Stream. .. code:: tcl @@ -233,7 +233,7 @@ System Top This is a layer on top of the system_wrapper generated by Vivado used to instantiate IO buffers, I/ODDRs or to create some custom connections which would -be harder to do in the block design. It also alows for more consistency across +be harder to do in the block design. It also allows for more consistency across projects. In this particular case we use it to place an IO buffer for the ADC power down signal (pulsar_adc_spi_pd). @@ -247,10 +247,9 @@ design for the carrier board which has a separate constraints file (i.e. DDR pins, Ethernet, UART etc). It also contains some timing constraints specific to the SPI Engine. -create_generated_clock -name spi_clk -source [get_pins -filter name=~*CLKIN1 -of -[get_cells -hier -filter name=~*spi_clkgen*i_mmcm]] -master_clock clk_fpga_0 -[get_pins -filter name=~*CLKOUT0 -of [get_cells -hier -filter -name=~*spi_clkgen*i_mmcm]] +.. code:: + + create_generated_clock -name spi_clk -source [get_pins -filter name=~*CLKIN1 -of [get_cells -hier -filter name=~*spi_clkgen*i_mmcm]] -master_clock clk_fpga_0 [get_pins -filter name=~*CLKOUT0 -of [get_cells -hier -filter name=~*spi_clkgen*i_mmcm]] .. code:: @@ -292,7 +291,7 @@ Holding CS high for 500ns ensures that we always meet T_CONV minimum. .. image:: tutorial/pulsar_hdl_timing_3.png :width: 100% -The 250ns minimum T_ACQ is alse met with a slightly higher value of 256.25ns. +The 250ns minimum T_ACQ is also met with a slightly higher value of 256.25ns. .. image:: tutorial/pulsar_hdl_timing_4.png :width: 100% diff --git a/docs/sources/custom.css b/docs/sources/custom.css index 73db5d68f..74c28ce31 100755 --- a/docs/sources/custom.css +++ b/docs/sources/custom.css @@ -60,7 +60,10 @@ table.regmap { table.regmap .caption-text{ font-size: 1rem; } -td.description{ +th, td.type, td.default { + white-space: nowrap; +} +td.description { width: 45%; font-size:.8em; }