README.md: header, docs info; docs: license, fixes

Add documentation info to the README.md
At adi_hdl_parser.py, filter "_signal_clock" and "_signal_reset"
pseudo buses from component.xml files, append them as description
in the ports table, in the format
"{Bus} [...] is synchronous to this {domain}".
Also, adds collapsible directive

Signed-off-by: Jorge Marques <jorge.marques@analog.com>
main
Jorge Marques 2023-08-21 15:55:11 -03:00 committed by Jorge Marques
parent 58df312e8b
commit 55d4215f45
7 changed files with 181 additions and 31 deletions

View File

@ -1,4 +1,32 @@
<p align="center">
<img src="docs/sources/HDL_logo.png" width="500" alt="ADI HDL Logo"> </br>
</p>
<p align="center">
<a href="https://github.com/analogdevicesinc/hdl/actions">
<img src="https://github.com/analogdevicesinc/hdl/actions/workflows/check_for_guideline_rules.yml/badge.svg" alt="Build Status">
</a>
<a href="https://github.com/analogdevicesinc/hdl/actions">
<img src="https://github.com/analogdevicesinc/hdl/actions/workflows/test_n_lint.yml/badge.svg" alt="Build Status">
</a>
</p>
<p align="center">
<a href="http://analogdevicesinc.github.io/hdl/">
<img alt="GitHub Pages" src="https://img.shields.io/badge/docs-GitHub%20Pages-blue.svg">
</a>
<a href="https://ez.analog.com/fpga/f/q-a">
<img alt="EngineerZone" src="https://img.shields.io/badge/Support-on%20EngineerZone-blue.svg">
</a>
<a href="https://wiki.analog.com/resources/fpga/docs/hdl">
<img alt="Analog Wiki" src="https://img.shields.io/badge/Wiki-on%20wiki.analog.com-blue.svg">
</a>
</p>
---
# HDL Reference Designs # HDL Reference Designs
[Analog Devices Inc.](http://www.analog.com/en/index.html) HDL libraries and projects for various reference design and prototyping systems. [Analog Devices Inc.](http://www.analog.com/en/index.html) HDL libraries and projects for various reference design and prototyping systems.
@ -17,6 +45,18 @@ There is no free replacement for consulting services. If you have questions that
This repository supports reference designs for different [Analog Devices boards](../master/projects) based on [Intel and Xilinx FPGA development boards](../master/projects/common) or standalone. This repository supports reference designs for different [Analog Devices boards](../master/projects) based on [Intel and Xilinx FPGA development boards](../master/projects/common) or standalone.
### Building documentation
Install necessary tools
```
cd docs
pip install -r requirements.txt
```
Then build the documentation with sphinx
```
make html
```
### Prerequisites ### Prerequisites
* [Vivado Design Suite](https://www.xilinx.com/support/download.html) * [Vivado Design Suite](https://www.xilinx.com/support/download.html)
@ -35,8 +75,8 @@ Windows user please checkout [this page](https://wiki.analog.com/resources/fpga/
To build a project, checkout the [latest release](https://github.com/analogdevicesinc/hdl/releases), after that just **cd** to the To build a project, checkout the [latest release](https://github.com/analogdevicesinc/hdl/releases), after that just **cd** to the
project that you want to build and run make: project that you want to build and run make:
``` ```
[~]cd projects/fmcomms2/zc706 cd projects/fmcomms2/zc706
[~]make make
``` ```
A more comprehensive build guide can be found under the following link: A more comprehensive build guide can be found under the following link:

View File

@ -1,3 +1,8 @@
###############################################################################
## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIBSD
###############################################################################
import os.path import os.path
from docutils import nodes from docutils import nodes
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
@ -96,7 +101,7 @@ class directive_base(Directive):
else: else:
items[key].append(line) items[key].append(line)
for key in items: for key in items:
items[key] = ' '.join(items[key]).strip().replace('- ', '', 1) items[key] = ' '.join(items[key]).replace('-', '', 1).strip()
return items return items
def column_entry(self, row, text, node_type, classes=[]): def column_entry(self, row, text, node_type, classes=[]):
@ -198,8 +203,8 @@ class directive_base(Directive):
is_div=True, is_div=True,
classes=['collapsible_content'] classes=['collapsible_content']
) )
label += icon
label += nodes.paragraph(text=text) label += nodes.paragraph(text=text)
label += icon
container += input_ container += input_
container += label container += label
@ -209,6 +214,23 @@ class directive_base(Directive):
return (content, label) return (content, label)
class directive_collapsible(directive_base):
option_spec = {'path': directives.unchanged}
required_arguments = 1
optional_arguments = 0
def run(self):
self.assert_has_content()
env = self.state.document.settings.env
self.current_doc = env.doc2path(env.docname)
node = node_div()
content, _ = self.collapsible(node, self.arguments[0].strip())
self.state.nested_parse(self.content, self.content_offset, content)
return [ node ]
class directive_interfaces(directive_base): class directive_interfaces(directive_base):
option_spec = {'path': directives.unchanged} option_spec = {'path': directives.unchanged}
@ -230,8 +252,9 @@ class directive_interfaces(directive_base):
section += title section += title
if bs[tag]['dependency'] is not None: if bs[tag]['dependency'] is not None:
dependency = nodes.paragraph(text=f"Depends on {pretty_dep(bs[tag]['dependency'])}.") section += [nodes.inline(text="Enabled if "),
section += dependency nodes.literal(text=pretty_dep(bs[tag]['dependency'])),
nodes.inline(text=".")]
if tag in description: if tag in description:
rst = ViewList() rst = ViewList()
rst.append(description[tag], f"virtual_{str(uuid4())}", 0) rst.append(description[tag], f"virtual_{str(uuid4())}", 0)
@ -283,15 +306,28 @@ class directive_interfaces(directive_base):
rows = [] rows = []
pr = component['ports'] pr = component['ports']
dm = component['bus_domain']
for key in pr: for key in pr:
row = nodes.row() row = nodes.row()
self.column_entry(row, key, 'literal') self.column_entry(row, key, 'literal')
self.column_entry(row, pr[key]['direction'], 'paragraph') self.column_entry(row, pr[key]['direction'], 'paragraph')
self.column_entry(row, pretty_dep(pr[key]['dependency']), 'paragraph') self.column_entry(row, pretty_dep(pr[key]['dependency']), 'paragraph')
if key in description: if 'clk' in key or 'clock' in key:
self.column_entry(row, description[key], 'reST', classes=['description']) domain = 'clock domain'
elif 'reset':
domain = 'reset signal'
else: else:
self.column_entry(row, '', 'paragraph') domain = 'domain'
if key in dm:
bus = 'Buses' if len(dm[key]) > 1 else 'Bus'
plr = 'are' if len(dm[key]) > 1 else 'is'
in_domain = f"{bus} ``{'``, ``'.join(dm[key])}`` {plr} synchronous to this {domain}."
else:
in_domain = ""
if key in description:
self.column_entry(row, " ".join([description[key], in_domain]), 'reST', classes=['description'])
else:
self.column_entry(row, in_domain, 'reST', classes=['description'])
rows.append(row) rows.append(row)
tbody = nodes.tbody() tbody = nodes.tbody()
@ -507,6 +543,7 @@ class directive_parameters(directive_base):
def parse_hdl_component(path, ctime): def parse_hdl_component(path, ctime):
component = { component = {
'bus_interface':{}, 'bus_interface':{},
'bus_domain':{},
'ports': {}, 'ports': {},
'parameters': {}, 'parameters': {},
'ctime': ctime 'ctime': ctime
@ -580,8 +617,22 @@ def parse_hdl_component(path, ctime):
name = get(root, 'name').text name = get(root, 'name').text
bs = component['bus_interface'] bs = component['bus_interface']
dm = component['bus_domain']
for bus_interface in get_all(root, 'busInterfaces/busInterface'): for bus_interface in get_all(root, 'busInterfaces/busInterface'):
bus_name = get(bus_interface, 'name').text bus_name = get(bus_interface, 'name').text
if '_signal_clock' in bus_name:
signal_name = get(get(bus_interface, 'portMaps/portMap'), 'physicalPort/name').text
if signal_name not in dm:
dm[signal_name] = []
dm[signal_name].append(bus_name[0:bus_name.find('_signal_clock')])
continue
if '_signal_reset' in bus_name:
signal_name = get(get(bus_interface, 'portMaps/portMap'), 'physicalPort/name').text
if signal_name not in dm:
dm[signal_name] = []
dm[signal_name].append(bus_name[0:bus_name.find('_signal_reset')])
continue
bs[bus_name] = { bs[bus_name] = {
'name': sattrib(get(bus_interface, 'busType'), 'name'), 'name': sattrib(get(bus_interface, 'busType'), 'name'),
'dependency': get_dependency(bus_interface, 'busInterface'), 'dependency': get_dependency(bus_interface, 'busInterface'),
@ -830,6 +881,7 @@ def manage_hdl_artifacts(app, env, docnames):
manage_hdl_regmaps(env, docnames) manage_hdl_regmaps(env, docnames)
def setup(app): def setup(app):
app.add_directive('collapsible', directive_collapsible)
app.add_directive('hdl-parameters', directive_parameters) app.add_directive('hdl-parameters', directive_parameters)
app.add_directive('hdl-interfaces', directive_interfaces) app.add_directive('hdl-interfaces', directive_interfaces)
app.add_directive('hdl-regmap', directive_regmap) app.add_directive('hdl-regmap', directive_regmap)

View File

@ -1,3 +1,8 @@
###############################################################################
## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIBSD
###############################################################################
class hdl_strings (): class hdl_strings ():
access_type = { access_type = {
'RO':{ 'RO':{

View File

@ -1,3 +1,8 @@
###############################################################################
## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIBSD
###############################################################################
from docutils import nodes from docutils import nodes
import subprocess import subprocess

View File

@ -63,8 +63,7 @@ Signal and Interface Pins
Interrupt output of the module. Is asserted when at least one of the Interrupt output of the module. Is asserted when at least one of the
modules interrupt is pending and unmasked. modules interrupt is pending and unmasked.
* - spi_clk * - spi_clk
- All ``spi_engine_ctrl`` signals and ``spi_resetn`` are - ``spi_resetn`` is synchronous to this clock.
synchronous to this clock.
* - spi_engine_ctrl * - spi_engine_ctrl
- :ref:`spi_engine control-interface` slave. - :ref:`spi_engine control-interface` slave.
SPI Engine Control stream that contains commands and data for the SPI Engine Control stream that contains commands and data for the

View File

@ -6,15 +6,16 @@
0 0
calc(var(--sidebar-item-spacing-horizontal)/2); calc(var(--sidebar-item-spacing-horizontal)/2);
padding: 0; padding: 0;
width: 11em;
margin-left: 2.25em;
} }
.sidebar-brand::before { .sidebar-brand::before {
content: ""; content: "";
display: inline-block; display: block;
width: 100%; height: 4.5em;
height: 4rem; background-size: auto 5.625em;
background-image: url(HDL_logo.svg); background-image: url(HDL_logo.svg);
background-size: auto 4rem; background-position: -10em -.5em;
background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.sidebar-brand-text { .sidebar-brand-text {
@ -63,6 +64,12 @@ td.description{
width: 45%; width: 45%;
font-size:.8em; font-size:.8em;
} }
#signal-and-interface-pins h3 {
font-weight: normal;
}
.table-wrapper {
overflow: visible;
}
.collapsible { .collapsible {
border: 1px solid var(--color-table-border); border: 1px solid var(--color-table-border);
border-radius: .25em; border-radius: .25em;
@ -75,35 +82,44 @@ td.description{
border-top: 1px solid var(--color-table-border); border-top: 1px solid var(--color-table-border);
overflow: hidden; overflow: hidden;
height: 0; height: 0;
padding: 0 .75em !important;
transition: ease opacity .25s; transition: ease opacity .25s;
opacity: 0; opacity: 0;
} }
.collapsible label { .collapsible label {
width: 100%; width: 100%;
display: block; padding: 0.75em 1em 0.75em .75em;
padding-left: .75em;
user-select: none; user-select: none;
box-sizing: border-box;
cursor: pointer; cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
font-weight: bold;
color: var(--color-toc-item-text);
} }
.collapsible label .icon { .collapsible label .icon {
display: inline-block; border: solid var(--color-toc-item-text);
padding-right: .25em; border-width: 0 2px 2px 0;
display: block;
transition: transform ease .125s, margin-top ease .125s;
width: .6em;
height: .6em;
transform: rotate(-45deg);
} }
.collapsible label p { .collapsible label p {
display: inline-block; display: inline-block;
margin: .75em 0; margin: 0;
} }
.collapsible label .icon:before { .collapsible label, .collapsible div {
content: '⮞'; transition: box-shadow ease .25s;
color: #666;
transition: transform ease .125s, padding ease .125s;
display: block;
line-height: 1em;
padding-right: .25em;
} }
.collapsible_input:checked ~ label .icon:before { .collapsible label:hover ~ div, .collapsible label:hover {
transform: rotate(90deg); box-shadow: 0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);
padding-left: 4px; }
.collapsible_input:checked ~ label .icon {
transform: rotate(45deg);
margin-top: -.5em;
} }
.collapsible_input:checked ~ .collapsible_content { .collapsible_input:checked ~ .collapsible_content {
height: 100%; height: 100%;

View File

@ -385,6 +385,39 @@ The ``:no-type-info:`` option is optional, and should **not** be included if it
in the main IP documentation page. It appends an auxiliary table explaining the in the main IP documentation page. It appends an auxiliary table explaining the
register access types. register access types.
Collapsible directive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The collapsible directive creates a collapsible/dropdown/"HTML details".
The directive syntax is:
.. code:: rst
.. collapsible:: <label>
<content>
For example:
.. code:: rst
.. collapsible:: Python code example.
.. code:: python
print("Hello World!")
Renders as:
.. collapsible:: Python code example.
.. code:: python
print("Hello World!")
Notice how you can use any Sphinx syntax, even nest other directives.
.. _installing_pandoc: .. _installing_pandoc:
Global options for HDL directives Global options for HDL directives