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 <jorge.marques@analog.com>
main
Jorge Marques 2023-10-06 09:23:50 -03:00 committed by GitHub
parent 455bfbcafb
commit 4d676ca25a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 32 deletions

View File

@ -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. 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 ## Getting started
@ -47,15 +47,19 @@ This repository supports reference designs for different [Analog Devices boards]
### Building documentation ### Building documentation
Install necessary tools Install the documentation tools.
``` ```
cd docs (cd docs ; pip install -r requirements.txt)
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 ### Prerequisites

View File

@ -13,6 +13,7 @@ release = 'v0.1'
import os, sys import os, sys
user = os.environ.get("USER")
sys.path.append(os.path.abspath("./extensions")) sys.path.append(os.path.abspath("./extensions"))
extensions = [ extensions = [
@ -40,7 +41,7 @@ todo_emit_warnings = True
# -- Symbolator configuration ------------------------------------------------- # -- 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'] symbolator_cmd_args = ['-t', '--scale=0.75']
# -- Options for HTML output -------------------------------------------------- # -- Options for HTML output --------------------------------------------------

View File

@ -12,6 +12,7 @@ from sphinx.util import logging
from lxml import etree from lxml import etree
from adi_hdl_static import hdl_strings from adi_hdl_static import hdl_strings
from uuid import uuid4 from uuid import uuid4
from hashlib import sha1
import contextlib import contextlib
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -178,7 +179,7 @@ class directive_base(Directive):
def collapsible(self, section, text=""): def collapsible(self, section, text=""):
env = self.state.document.settings.env env = self.state.document.settings.env
_id = str(uuid4()) _id = sha1(text.encode('utf-8')).hexdigest()
container = nodes.container( container = nodes.container(
"", "",
is_div=True, is_div=True,
@ -491,7 +492,7 @@ class directive_parameters(directive_base):
table = nodes.table() table = nodes.table()
table += tgroup 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 = [] rows = []
for key in parameter: for key in parameter:
@ -501,13 +502,16 @@ class directive_parameters(directive_base):
self.column_entry(row, description[key], 'reST', classes=['description']) self.column_entry(row, description[key], 'reST', classes=['description'])
else: else:
self.column_entry(row, dot_fix(parameter[key]['description']), 'paragraph', classes=['description']) self.column_entry(row, dot_fix(parameter[key]['description']), 'paragraph', classes=['description'])
for tag in ['type', 'default']: for tag, ty in zip(['type', 'default'], ['paragraph', 'literal']):
self.column_entry(row, parameter[key][tag].title(), 'paragraph') 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 = [] crange = []
if parameter[key]['choices'] is not None: for tag in ['choices', 'range']:
crange.append(parameter[key]['choices']) if parameter[key][tag] is not None:
if parameter[key]['range'] is not None: crange.append(parameter[key][tag])
crange.append(parameter[key]['range'])
crange = '. '.join(crange) crange = '. '.join(crange)
self.column_entry(row, crange, 'paragraph') self.column_entry(row, crange, 'paragraph')
@ -615,6 +619,15 @@ def parse_hdl_component(path, ctime):
def get_choice_type(name): def get_choice_type(name):
return name[name.find('_')+1:name.rfind('_')] 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() root = etree.parse(path).getroot()
spirit, xilinx, _ = get_namespaces(root) spirit, xilinx, _ = get_namespaces(root)
vendor = get(root, 'vendor').text vendor = get(root, 'vendor').text
@ -673,15 +686,28 @@ def parse_hdl_component(path, ctime):
if param_description is not None: if param_description is not None:
param_name = get(parameter, 'name').text param_name = get(parameter, 'name').text
param_value = get(parameter, 'value') param_value = get(parameter, 'value')
param_format = sattrib(param_value, 'format')
pr[param_name] = { pr[param_name] = {
'description': param_description.text, 'description': param_description.text,
'default': param_value.text, 'default': format_default_value(param_value.text, param_format),
'type': sattrib(param_value, 'format'), 'type': param_format,
'_choice_ref': sattrib(param_value, 'choiceRef'), '_choice_ref': sattrib(param_value, 'choiceRef'),
'choices': None, 'choices': None,
'range': get_range(param_value) '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'): for choice in get_all(root, 'choices/choice'):
name = get(choice, 'name').text name = get(choice, 'name').text
for key in pr: for key in pr:

View File

@ -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). 12-bit is currently allocated (bits 15,14,11,10 are always 0).
Instructions Instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --------------------------------------------------------------------------------
Transfer Instruction Transfer Instruction
-------------------------------------------------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
== == == == == == = = = = = = = = = = == == == == == == = = = = = = = = = =
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

View File

@ -6,7 +6,7 @@ SPI Engine Tutorial - PulSAR-ADC
The goal of this tutorial is to present the process of adding 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 :ref:`spi_engine` support for an ADI precision converter or family of converters
using a few simple steps. 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 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 Using the script ensures that the correct connections are being made and that
the IP cores will receive the correct parameter configuration since certain 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 parameters need to be set to the same value. The function takes the following
argumets arguments:
.. code:: tcl .. 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 **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) 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 clock (spi_clk). Because some devices need 80MHz SCLK, a 160MHz reference clock
is required which implies an external reference. 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 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 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 avoid clock domain crossing mechanisms which will introduce latency, decreasing
the overall performance of the system. 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 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 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 setup
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
DMA destination bus (connection to Zynq DDR memory) shall always be 64 bit 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 .. code:: tcl
@ -233,7 +233,7 @@ System Top
This is a layer on top of the system_wrapper generated by Vivado used to 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 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 projects. In this particular case we use it to place an IO buffer for the ADC
power down signal (pulsar_adc_spi_pd). 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 pins, Ethernet, UART etc). It also contains some timing constraints specific to
the SPI Engine. the SPI Engine.
create_generated_clock -name spi_clk -source [get_pins -filter name=~*CLKIN1 -of .. code::
[get_cells -hier -filter name=~*spi_clkgen*i_mmcm]] -master_clock clk_fpga_0
[get_pins -filter name=~*CLKOUT0 -of [get_cells -hier -filter 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]]
name=~*spi_clkgen*i_mmcm]]
.. code:: .. 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 .. image:: tutorial/pulsar_hdl_timing_3.png
:width: 100% :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 .. image:: tutorial/pulsar_hdl_timing_4.png
:width: 100% :width: 100%

View File

@ -60,6 +60,9 @@ table.regmap {
table.regmap .caption-text{ table.regmap .caption-text{
font-size: 1rem; font-size: 1rem;
} }
th, td.type, td.default {
white-space: nowrap;
}
td.description { td.description {
width: 45%; width: 45%;
font-size:.8em; font-size:.8em;