docs: add regmap directive
Automate table generation for register maps. Based on tfcollins' vger python scripts. There are docs/adi_regmap_*.txt with more than one regmap per file, so the logic changed to allow that. Using title tool as the unique identifier now. It has a global option to set the default state (hidden or visible) for the collpasible tables. Also remove CSVs. Signed-off-by: Jorge Marques <jorge.marques@analog.com>main
parent
83d2bf9603
commit
cf056cf81c
|
@ -31,6 +31,8 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|||
|
||||
# -- Custom extensions configuration -------------------------------------------
|
||||
|
||||
hide_collapsible_content = False
|
||||
|
||||
# -- todo configuration -------------------------------------------------------
|
||||
|
||||
todo_include_todos = True
|
||||
|
@ -41,10 +43,6 @@ todo_emit_warnings = True
|
|||
symbolator_cmd = '~/.local/bin/symbolator' # Update with your installed location
|
||||
symbolator_cmd_args = ['-t', '--scale=0.75']
|
||||
|
||||
# -- BibTeX configuration -----------------------------------------------------
|
||||
|
||||
bibtex_bibfiles = ['appendix/references.bib']
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
html_theme = 'furo'
|
||||
|
|
|
@ -15,6 +15,7 @@ Templates are available:
|
|||
|
||||
* :git-hdl:`docs/library/template_ip` (:ref:`rendered <template_ip>`).
|
||||
* :git-hdl:`docs/library/template_framework` (:ref:`rendered <template_framework>`).
|
||||
* :git-hdl:`docs/projects/template` (:ref:`rendered <template_project>`).
|
||||
|
||||
Remove the ``:orphan:`` in the first line, it is to hide the templates from the
|
||||
`TOC tree <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-toctree>`_.
|
||||
|
@ -282,7 +283,7 @@ Renders as:
|
|||
* - NUM_OF_SDI
|
||||
- Number of SDI lines on the physical SPI interface.
|
||||
|
||||
Descriptions in the directive have higher precedece tha in the *component.xml*
|
||||
Descriptions in the directive have higher precedence than in the *component.xml*
|
||||
file.
|
||||
|
||||
The ``:path:`` option is optional, and should **not** be included if the
|
||||
|
@ -316,24 +317,57 @@ For example:
|
|||
.. hdl-interfaces::
|
||||
:path: library/spi_engine/spi_engine_interconnect
|
||||
|
||||
|
||||
Renders as:
|
||||
|
||||
::
|
||||
|
||||
.. hdl-interfaces::
|
||||
:path: library/spi_engine/spi_engine_interconnect
|
||||
|
||||
|
||||
Descriptions in the directive have higher precedece than in the *component.xml*
|
||||
Descriptions in the directive have higher precedence than in the *component.xml*
|
||||
file.
|
||||
You can provide description to a port or a bus, but not for a bus port.
|
||||
|
||||
The ``:path:`` option is optional, and should **not** be included if the
|
||||
documentation file path matches the *component.xml* hierarchically.
|
||||
|
||||
HDL regmap directive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The HDL regmap directive gets information from *docs/regmap/adi_regmap_\*.txt* files
|
||||
and generates tables with the register maps.
|
||||
|
||||
The directive syntax is:
|
||||
|
||||
.. code:: rst
|
||||
|
||||
.. hdl-regmap::
|
||||
:name: <regmap_name>
|
||||
:no-type-info:
|
||||
|
||||
For example:
|
||||
|
||||
.. code:: rst
|
||||
|
||||
.. hdl-regmap::
|
||||
:name: DMAC
|
||||
|
||||
.. note::
|
||||
|
||||
The register map name is the title-tool, the value above ``ENDTITLE`` in the
|
||||
source file.
|
||||
|
||||
This directive does not support content for descriptions, since the source file
|
||||
already have proper descriptions.
|
||||
|
||||
The ``:name:`` option is **required**, because the title tool does not match
|
||||
the IP name and one single *docs/regmap/adi_regmap_\*.txt* file can have more than
|
||||
one register map.
|
||||
The ``:no-type-info:`` option is optional, and should **not** be included if it is
|
||||
in the main IP documentation page. It appends an auxiliary table explaining the
|
||||
register access types.
|
||||
|
||||
.. _installing_pandoc:
|
||||
|
||||
Global options for HDL directives
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Use the `hide_collapsible_content` to set the default state of the collapsibles,
|
||||
if you set to False, they be expanded by default.
|
||||
|
||||
Installing pandoc
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -5,11 +5,58 @@ from docutils.parsers.rst import Directive, directives
|
|||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
from sphinx.util import logging
|
||||
from lxml import etree
|
||||
from adi_hdl_static import hdl_strings
|
||||
from uuid import uuid4
|
||||
import contextlib
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class node_parameters(nodes.Structural, nodes.Element):
|
||||
pass
|
||||
dft_hide_collapsible_content = True
|
||||
|
||||
class node_base(nodes.Element, nodes.General):
|
||||
"""
|
||||
Adapted from
|
||||
https://github.com/pradyunsg/sphinx-inline-tabs
|
||||
https://github.com/dgarcia360/sphinx-collapse
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def visit(translator, node):
|
||||
attributes = node.attributes.copy()
|
||||
|
||||
attributes.pop("ids")
|
||||
attributes.pop("classes")
|
||||
attributes.pop("names")
|
||||
attributes.pop("dupnames")
|
||||
attributes.pop("backrefs")
|
||||
|
||||
text = translator.starttag(node, node.tagname, **attributes)
|
||||
translator.body.append(text.strip())
|
||||
|
||||
@staticmethod
|
||||
def depart(translator, node):
|
||||
if node.endtag:
|
||||
translator.body.append(f"</{node.tagname}>")
|
||||
|
||||
@staticmethod
|
||||
def default(translator, node):
|
||||
pass
|
||||
|
||||
class node_div(node_base):
|
||||
tagname = 'div'
|
||||
endtag = 'true'
|
||||
|
||||
class node_input(node_base):
|
||||
tagname = 'input'
|
||||
endtag = 'false'
|
||||
|
||||
class node_label(node_base):
|
||||
tagname = 'label'
|
||||
endtag = 'true'
|
||||
|
||||
class node_icon(node_base):
|
||||
tagname = 'div'
|
||||
endtag = 'false'
|
||||
|
||||
def dot_fix(string):
|
||||
if (string.rfind('.') != len(string)-1):
|
||||
|
@ -22,19 +69,24 @@ def pretty_dep(string):
|
|||
return ''
|
||||
return string.replace("'MODELPARAM_VALUE.",'').replace("'",'')
|
||||
|
||||
def sanitized_bool(string):
|
||||
string_ = string.strip().lower()
|
||||
if string_ in ['1', 'true', 'yes', 'y']:
|
||||
return True
|
||||
elif string_ in ['0', 'false', 'no', 'n']:
|
||||
return False
|
||||
else:
|
||||
logger.warning(f"Got malformed bool value {string}.")
|
||||
return False
|
||||
|
||||
class directive_base(Directive):
|
||||
option_spec = {'path': directives.unchanged}
|
||||
has_content = True
|
||||
add_index = True
|
||||
current_doc = ''
|
||||
final_argument_whitespace = True
|
||||
|
||||
def warning(self, msg):
|
||||
logger.warning(msg + f" Current file: {self.current_doc}")
|
||||
def info(self, msg):
|
||||
logger.info(msg + f" Current file: {self.current_doc}")
|
||||
|
||||
def get_descriptions(self, content):
|
||||
@staticmethod
|
||||
def get_descriptions(content):
|
||||
items = {}
|
||||
key = ''
|
||||
for line in content:
|
||||
|
@ -47,6 +99,32 @@ class directive_base(Directive):
|
|||
items[key] = ' '.join(items[key]).strip().replace('- ', '', 1)
|
||||
return items
|
||||
|
||||
def column_entry(self, row, text, node_type, classes=[]):
|
||||
entry = nodes.entry(classes=classes)
|
||||
if node_type == 'literal':
|
||||
entry += nodes.literal(text=text)
|
||||
elif node_type == 'paragraph':
|
||||
entry += nodes.paragraph(text=text)
|
||||
elif node_type == 'reST':
|
||||
rst = ViewList()
|
||||
rst.append(text, f"virtual_{str(uuid4())}", 0)
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, rst, node)
|
||||
entry += node
|
||||
else:
|
||||
return
|
||||
row += entry
|
||||
|
||||
def column_entries(self, rows, items):
|
||||
row = nodes.row()
|
||||
for item in items:
|
||||
if len(item) == 3:
|
||||
self.column_entry(row, item[0], item[1], classes=item[2])
|
||||
else:
|
||||
self.column_entry(row, item[0], item[1])
|
||||
rows.append(row)
|
||||
|
||||
def generic_table(self, description):
|
||||
tgroup = nodes.tgroup(cols=2)
|
||||
for _ in range(2):
|
||||
|
@ -65,7 +143,7 @@ class directive_base(Directive):
|
|||
row += entry
|
||||
entry = nodes.entry()
|
||||
rst = ViewList()
|
||||
rst.append(description[key], "virtual_"+self.current_doc, 0)
|
||||
rst.append(description[key], f"virtual_{str(uuid4())}", 0)
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, rst, node)
|
||||
|
@ -79,7 +157,8 @@ class directive_base(Directive):
|
|||
|
||||
return table
|
||||
|
||||
def table_header(self, tgroup, columns):
|
||||
@staticmethod
|
||||
def table_header(tgroup, columns):
|
||||
thead = nodes.thead()
|
||||
tgroup += thead
|
||||
row = nodes.row()
|
||||
|
@ -91,40 +170,83 @@ class directive_base(Directive):
|
|||
|
||||
thead.append(row)
|
||||
|
||||
def collapsible(self, section, text=""):
|
||||
env = self.state.document.settings.env
|
||||
|
||||
_id = str(uuid4())
|
||||
container = nodes.container(
|
||||
"",
|
||||
is_div=True,
|
||||
classes=['collapsible']
|
||||
)
|
||||
checked = {"checked": ''} if not env.config.hide_collapsible_content else {}
|
||||
input_ = node_input(
|
||||
type="checkbox",
|
||||
**checked,
|
||||
ids=[_id],
|
||||
name=_id,
|
||||
classes=['collapsible_input']
|
||||
)
|
||||
label = node_label(
|
||||
**{"for": _id}
|
||||
)
|
||||
icon = node_icon(
|
||||
classes=['icon']
|
||||
)
|
||||
content = nodes.container(
|
||||
"",
|
||||
is_div=True,
|
||||
classes=['collapsible_content']
|
||||
)
|
||||
label += icon
|
||||
label += nodes.paragraph(text=text)
|
||||
|
||||
container += input_
|
||||
container += label
|
||||
container += content
|
||||
|
||||
section += container
|
||||
|
||||
return (content, label)
|
||||
|
||||
|
||||
class directive_interfaces(directive_base):
|
||||
option_spec = {'path': directives.unchanged}
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
|
||||
def tables(self, content, component):
|
||||
def tables(self, subnode, content, component):
|
||||
description = self.get_descriptions(content)
|
||||
|
||||
if component is None:
|
||||
return self.generic_table(description)
|
||||
|
||||
node_tables = nodes.section()
|
||||
|
||||
bs = component['bus_interface']
|
||||
for tag in bs:
|
||||
section = nodes.section(ids=[f"virtual_{self.current_doc}_bus_interface_{tag}"])
|
||||
section = nodes.section(
|
||||
ids=[f"bus-interface-{tag}"]
|
||||
)
|
||||
title = nodes.title(text=tag)
|
||||
section += title
|
||||
|
||||
if bs[tag]['dependency'] is not None:
|
||||
dependency = nodes.paragraph(text=f"Depends on {pretty_dep(bs[tag]['dependency'])}.")
|
||||
section += dependency
|
||||
if tag in description:
|
||||
rst = ViewList()
|
||||
rst.append(description[tag], "virtual_"+self.current_doc, 0)
|
||||
rst.append(description[tag], f"virtual_{str(uuid4())}", 0)
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, rst, node)
|
||||
section += node
|
||||
|
||||
content, _ = self.collapsible(section, f"Ports of {tag} bus.")
|
||||
|
||||
tgroup = nodes.tgroup(cols=3)
|
||||
for _ in range(3):
|
||||
colspec = nodes.colspec(colwidth=1)
|
||||
tgroup.append(colspec)
|
||||
table = nodes.table()
|
||||
table += section
|
||||
table += tgroup
|
||||
|
||||
self.table_header(tgroup, ["Physical Port", "Logical Port", "Direction"])
|
||||
|
@ -132,91 +254,187 @@ class directive_interfaces(directive_base):
|
|||
rows = []
|
||||
pm = bs[tag]['port_map']
|
||||
for key in pm:
|
||||
row = nodes.row()
|
||||
entry = nodes.entry()
|
||||
entry += nodes.literal(text=key)
|
||||
row += entry
|
||||
entry = nodes.entry()
|
||||
entry += nodes.literal(text=pm[key]['logical_port'])
|
||||
row += entry
|
||||
entry = nodes.entry()
|
||||
entry += nodes.paragraph(text=pm[key]['direction'])
|
||||
row += entry
|
||||
rows.append(row)
|
||||
self.column_entries(rows, [
|
||||
[key, 'literal'],
|
||||
[pm[key]['logical_port'], 'literal'],
|
||||
[pm[key]['direction'], 'paragraph'],
|
||||
])
|
||||
|
||||
tbody = nodes.tbody()
|
||||
tbody.extend(rows)
|
||||
tgroup += tbody
|
||||
node_tables += table
|
||||
content += table
|
||||
|
||||
section = nodes.section(ids=[f"virtual_{self.current_doc}_ports"])
|
||||
subnode += section
|
||||
|
||||
section = nodes.section(ids=[f"ports"])
|
||||
title = nodes.title(text="Ports")
|
||||
section += title
|
||||
content, _ = self.collapsible(section, f"Ports table.")
|
||||
|
||||
tgroup = nodes.tgroup(cols=4)
|
||||
for _ in range(4):
|
||||
colspec = nodes.colspec(colwidth=1)
|
||||
tgroup.append(colspec)
|
||||
table = nodes.table()
|
||||
table += section
|
||||
table += tgroup
|
||||
|
||||
self.table_header(tgroup, ["Physical Port", "Description", "Direction", "Dependency"])
|
||||
self.table_header(tgroup, ["Physical Port", "Direction", "Dependency", "Description"])
|
||||
|
||||
rows = []
|
||||
pr = component['ports']
|
||||
for key in pr:
|
||||
row = nodes.row()
|
||||
entry = nodes.entry()
|
||||
entry += nodes.literal(text=key)
|
||||
row += entry
|
||||
entry = nodes.entry()
|
||||
self.column_entry(row, key, 'literal')
|
||||
self.column_entry(row, pr[key]['direction'], 'paragraph')
|
||||
self.column_entry(row, pretty_dep(pr[key]['dependency']), 'paragraph')
|
||||
if key in description:
|
||||
rst = ViewList()
|
||||
rst.append(description[key], "virtual_"+self.current_doc, 0)
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, rst, node)
|
||||
entry += node
|
||||
self.column_entry(row, description[key], 'reST', classes=['description'])
|
||||
else:
|
||||
entry += nodes.paragraph(text='')
|
||||
row += entry
|
||||
entry = nodes.entry()
|
||||
entry += nodes.paragraph(text=pr[key]['direction'])
|
||||
row += entry
|
||||
entry = nodes.entry()
|
||||
entry += nodes.paragraph(text=pretty_dep(pr[key]['dependency']))
|
||||
row += entry
|
||||
self.column_entry(row, '', 'paragraph')
|
||||
rows.append(row)
|
||||
|
||||
tbody = nodes.tbody()
|
||||
tbody.extend(rows)
|
||||
tgroup += tbody
|
||||
node_tables += table
|
||||
content += table
|
||||
|
||||
return node_tables
|
||||
subnode += section
|
||||
|
||||
return subnode
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
self.current_doc = env.doc2path(env.docname)
|
||||
|
||||
node = node_parameters()
|
||||
node = node_div()
|
||||
|
||||
if 'path' in self.options:
|
||||
lib_name = self.options['path']
|
||||
else:
|
||||
lib_name = env.docname.replace('/index', '')
|
||||
|
||||
subnode = nodes.section(ids=["hdl-interfaces"])
|
||||
if lib_name in env.component:
|
||||
subnode += self.tables(self.content, env.component[lib_name])
|
||||
self.tables(node, self.content, env.component[lib_name])
|
||||
else:
|
||||
subnode += self.tables(self.content, None)
|
||||
|
||||
node += subnode
|
||||
self.tables(node, self.content, None)
|
||||
|
||||
return [ node ]
|
||||
|
||||
class directive_regmap(directive_base):
|
||||
option_spec = {'name': directives.unchanged, 'no-type-info': directives.unchanged}
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
|
||||
def tables(self, subnode, obj):
|
||||
section = nodes.section(ids=[f"register-map-{obj['title']}"])
|
||||
title = nodes.title(text=f"{obj['title']} ({obj['title']})")
|
||||
|
||||
section += title
|
||||
content, _ = self.collapsible(section, f"Register map table.")
|
||||
tgroup = nodes.tgroup(cols=7)
|
||||
for _ in range(7):
|
||||
colspec = nodes.colspec(colwidth=1)
|
||||
tgroup.append(colspec)
|
||||
table = nodes.table(classes=['regmap'])
|
||||
table += tgroup
|
||||
|
||||
self.table_header(tgroup, ["DWORD", "BYTE", "BITS", "Name", "Type", "Default", "Description"])
|
||||
|
||||
rows = []
|
||||
for reg in obj['regmap']:
|
||||
self.column_entries(rows, [
|
||||
[reg['address'][0], 'literal'],
|
||||
[reg['address'][1], 'literal'],
|
||||
['', 'literal'],
|
||||
[reg['name'], 'literal'],
|
||||
['', 'literal'],
|
||||
['', 'literal'],
|
||||
[reg['description'], 'reST', ['description']],
|
||||
])
|
||||
|
||||
for field in reg['fields']:
|
||||
self.column_entries(rows, [
|
||||
['', 'literal'],
|
||||
['', 'literal'],
|
||||
[f"[{field['bits']}]", 'literal'],
|
||||
[field['name'], 'literal'],
|
||||
[field['rw'], 'paragraph'],
|
||||
[field['default'], 'paragraph', ['default']],
|
||||
[field['description'], 'reST', ['description']],
|
||||
])
|
||||
|
||||
tbody = nodes.tbody()
|
||||
tbody.extend(rows)
|
||||
tgroup += tbody
|
||||
content += table
|
||||
|
||||
subnode += section
|
||||
|
||||
if 'no-type-info' in self.options:
|
||||
return subnode
|
||||
|
||||
tgroup = nodes.tgroup(cols=3)
|
||||
for _ in range(3):
|
||||
colspec = nodes.colspec(colwidth=1)
|
||||
tgroup.append(colspec)
|
||||
table = nodes.table()
|
||||
table += tgroup
|
||||
|
||||
self.table_header(tgroup, ["Access Type", "Name", "Description"])
|
||||
|
||||
rows = []
|
||||
for at in obj['access_type']:
|
||||
self.column_entries(rows, [
|
||||
[at, 'paragraph'],
|
||||
[hdl_strings.access_type[at]['name'], 'paragraph'],
|
||||
[hdl_strings.access_type[at]['description'], 'paragraph']
|
||||
])
|
||||
|
||||
tbody = nodes.tbody()
|
||||
tbody.extend(rows)
|
||||
tgroup += tbody
|
||||
section += table
|
||||
|
||||
return subnode
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
self.current_doc = env.doc2path(env.docname)
|
||||
if os.getcwd() not in self.current_doc:
|
||||
raise Exception(f"Inconsistent paths, {os.getcwd()} not in {self.current_doc}")
|
||||
owner = self.current_doc[len(os.getcwd())+1:-4]
|
||||
|
||||
node = node_div()
|
||||
|
||||
if 'name' in self.options:
|
||||
lib_name = self.options['name']
|
||||
else:
|
||||
logger.warning("hdl-regmap directive without name option, skipped!")
|
||||
return [ node ]
|
||||
|
||||
subnode = nodes.section(ids=["hdl-regmap"])
|
||||
|
||||
# Have to search all because it is allowed to have more than one regmap per file...
|
||||
file = None
|
||||
for f in env.regmaps:
|
||||
if lib_name in env.regmaps[f]['subregmap']:
|
||||
file = f
|
||||
break
|
||||
|
||||
if file is None:
|
||||
logger.warning(f"Title tool {lib_name} not-found in any regmap file, skipped!")
|
||||
return [ node ]
|
||||
|
||||
if owner not in env.regmaps[f]['owners']:
|
||||
env.regmaps[f]['owners'].append(owner)
|
||||
self.tables(subnode, env.regmaps[f]['subregmap'][lib_name])
|
||||
|
||||
node += subnode
|
||||
return [ node ]
|
||||
|
||||
class directive_parameters(directive_base):
|
||||
option_spec = {'path': directives.unchanged}
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
|
||||
|
@ -238,33 +456,20 @@ class directive_parameters(directive_base):
|
|||
rows = []
|
||||
for key in parameter:
|
||||
row = nodes.row()
|
||||
entry = nodes.entry()
|
||||
entry += nodes.literal(text="{:s}".format(key))
|
||||
row += entry
|
||||
entry = nodes.entry()
|
||||
self.column_entry(row, "{:s}".format(key), 'literal')
|
||||
if key in description:
|
||||
rst = ViewList()
|
||||
rst.append(description[key], "virtual_"+self.current_doc, 0)
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, rst, node)
|
||||
entry += node
|
||||
self.column_entry(row, description[key], 'reST', classes=['description'])
|
||||
else:
|
||||
entry += nodes.paragraph(text=dot_fix(parameter[key]['description']))
|
||||
row += entry
|
||||
self.column_entry(row, dot_fix(parameter[key]['description']), 'paragraph', classes=['description'])
|
||||
for tag in ['type', 'default']:
|
||||
entry = nodes.entry()
|
||||
entry += nodes.paragraph(text=parameter[key][tag].title())
|
||||
row += entry
|
||||
self.column_entry(row, parameter[key][tag].title(), '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'])
|
||||
crange = '. '.join(crange)
|
||||
entry = nodes.entry()
|
||||
entry += nodes.paragraph(text=crange)
|
||||
row += entry
|
||||
self.column_entry(row, crange, 'paragraph')
|
||||
|
||||
rows.append(row)
|
||||
|
||||
|
@ -274,7 +479,7 @@ class directive_parameters(directive_base):
|
|||
|
||||
for tag in description:
|
||||
if tag not in parameter:
|
||||
self.warning(f"{tag} does not exist in {file_2}!")
|
||||
logger.warning(f"{tag} does not exist in {file_2}!")
|
||||
|
||||
return table
|
||||
|
||||
|
@ -282,7 +487,7 @@ class directive_parameters(directive_base):
|
|||
env = self.state.document.settings.env
|
||||
self.current_doc = env.doc2path(env.docname)
|
||||
|
||||
node = node_parameters()
|
||||
node = node_div()
|
||||
|
||||
if 'path' in self.options:
|
||||
lib_name = self.options['path']
|
||||
|
@ -299,12 +504,6 @@ class directive_parameters(directive_base):
|
|||
|
||||
return [ node ]
|
||||
|
||||
def visit_node_parameters(self, node):
|
||||
pass
|
||||
|
||||
def depart_node_parameters(self, node):
|
||||
pass
|
||||
|
||||
def parse_hdl_component(path, ctime):
|
||||
component = {
|
||||
'bus_interface':{},
|
||||
|
@ -313,7 +512,7 @@ def parse_hdl_component(path, ctime):
|
|||
'ctime': ctime
|
||||
}
|
||||
|
||||
def get_namespaces( item):
|
||||
def get_namespaces(item):
|
||||
nsmap = item.nsmap
|
||||
for i in ['spirit', 'xilinx', 'xsi']:
|
||||
if i not in nsmap:
|
||||
|
@ -321,40 +520,40 @@ def parse_hdl_component(path, ctime):
|
|||
|
||||
return (nsmap['spirit'], nsmap['xilinx'], nsmap['xsi'])
|
||||
|
||||
def get( item, local_name):
|
||||
def get(item, local_name):
|
||||
items = get_all(item, local_name)
|
||||
if len(items) == 0:
|
||||
return None
|
||||
else:
|
||||
return items[0]
|
||||
|
||||
def get_all( item, local_name):
|
||||
def get_all(item, local_name):
|
||||
template = "/*[local-name()='%s']"
|
||||
if not isinstance(local_name, str):
|
||||
raise Exception("Got wrong type, only Strings are allowed")
|
||||
local_name = local_name.split('/')
|
||||
return item.xpath('.' + ''.join([template % ln for ln in local_name]))
|
||||
|
||||
def sattrib( item, attr):
|
||||
def sattrib(item, attr):
|
||||
nonlocal spirit
|
||||
return item.get(f"{{{spirit}}}{attr}")
|
||||
|
||||
def xattrib( item, attr):
|
||||
def xattrib(item, attr):
|
||||
nonlocal xilinx
|
||||
return item.get(f"{{{xilinx}}}{attr}")
|
||||
|
||||
def stag( item):
|
||||
def stag(item):
|
||||
nonlocal spirit
|
||||
return item.tag.replace(f"{{{spirit}}}",'')
|
||||
|
||||
def xtag( item):
|
||||
def xtag(item):
|
||||
nonlocal xilinx
|
||||
return item.tag.replace(f"{{{xilinx}}}",'')
|
||||
|
||||
def clean_dependency( string):
|
||||
def clean_dependency(string):
|
||||
return string[string.find("'"): string.rfind(')')].replace(')','')
|
||||
|
||||
def get_dependency( item, type_=None):
|
||||
def get_dependency(item, type_=None):
|
||||
if type_ is None:
|
||||
type_ = stag(item)
|
||||
|
||||
|
@ -364,7 +563,7 @@ def parse_hdl_component(path, ctime):
|
|||
else:
|
||||
return clean_dependency(xattrib(dependency, 'dependency'))
|
||||
|
||||
def get_range( item):
|
||||
def get_range(item):
|
||||
min_ = sattrib(item, 'minimum')
|
||||
max_ = sattrib(item, 'maximum')
|
||||
if max_ == None or min_ == None:
|
||||
|
@ -372,7 +571,7 @@ def parse_hdl_component(path, ctime):
|
|||
else:
|
||||
return f"From {min_} to {max_}."
|
||||
|
||||
def get_choice_type( name):
|
||||
def get_choice_type(name):
|
||||
return name[name.find('_')+1:name.rfind('_')]
|
||||
|
||||
root = etree.parse(path).getroot()
|
||||
|
@ -393,7 +592,7 @@ def parse_hdl_component(path, ctime):
|
|||
for port_map in get_all(bus_interface, 'portMaps/portMap'):
|
||||
pm[get(port_map, 'physicalPort/name').text] = {
|
||||
'logical_port': get(port_map, 'logicalPort/name').text,
|
||||
'direction': None
|
||||
'direction': ''
|
||||
}
|
||||
|
||||
lport = component['ports']
|
||||
|
@ -448,9 +647,7 @@ def parse_hdl_component(path, ctime):
|
|||
|
||||
return component
|
||||
|
||||
def manage_hdl_components(app, env, docnames):
|
||||
libraries = [[k.replace('/index',''), k] for k in env.found_docs if k.find('library/') == 0]
|
||||
|
||||
def manage_hdl_components(env, docnames, libraries):
|
||||
if not hasattr(env, 'component'):
|
||||
env.component = {}
|
||||
cp = env.component
|
||||
|
@ -470,15 +667,182 @@ def manage_hdl_components(app, env, docnames):
|
|||
cp[lib] = parse_hdl_component(f, ctime)
|
||||
docnames.append(doc)
|
||||
|
||||
# From https://github.com/tfcollins/vger/blob/main/vger/hdl_reg_map.py
|
||||
def parse_hdl_regmap(reg, ctime):
|
||||
regmap = {
|
||||
'subregmap': {},
|
||||
'owners':[],
|
||||
'ctime': ctime
|
||||
}
|
||||
|
||||
with open(f"regmap/adi_regmap_{reg}.txt", "r") as f:
|
||||
data = f.readlines()
|
||||
data = [d.replace("\n", "") for d in data]
|
||||
|
||||
while "TITLE" in data:
|
||||
# Get title
|
||||
tit = data.index("TITLE")
|
||||
|
||||
title = str(data[tit + 1].strip())
|
||||
title_tool = str(data[tit + 2].strip())
|
||||
data = data[tit + 2 :]
|
||||
|
||||
if 'ENDTITLE' in [title_tool, title]:
|
||||
logger.warning(f"Malformed title fields at file regmap/adi_regmap_{reg}.txt, skipped!")
|
||||
continue
|
||||
|
||||
regmap['subregmap'][title_tool] = {
|
||||
'title': title,
|
||||
'regmap': [],
|
||||
'access_type': []
|
||||
}
|
||||
|
||||
# Get registers
|
||||
access_type = []
|
||||
while "REG" in data:
|
||||
regi = data.index("REG")
|
||||
rfi = data.index("ENDREG")
|
||||
|
||||
if not regi:
|
||||
break
|
||||
|
||||
reg_addr = data[regi + 1].strip()
|
||||
reg_name = data[regi + 2].strip()
|
||||
reg_desc = [data[fi].strip() for fi in range(regi + 3, rfi)]
|
||||
reg_desc = " ".join(reg_desc)
|
||||
|
||||
with contextlib.suppress(ValueError):
|
||||
if tet := data.index("TITLE"):
|
||||
if regi > tet:
|
||||
# into next regmap
|
||||
break
|
||||
data = data[regi + 1 :]
|
||||
|
||||
# Get fields
|
||||
fields = []
|
||||
while "FIELD" in data:
|
||||
fi = data.index("FIELD")
|
||||
efi = data.index("ENDFIELD")
|
||||
|
||||
if not fi:
|
||||
break
|
||||
|
||||
with contextlib.suppress(ValueError):
|
||||
if rege := data.index("REG"):
|
||||
if fi > rege:
|
||||
# into next register
|
||||
break
|
||||
|
||||
field_loc = data[fi + 1].strip()
|
||||
field_loc = field_loc.split(" ")
|
||||
field_bits = field_loc[0].replace("[", "").replace("]", "")
|
||||
field_default = field_loc[1] if len(field_loc) > 1 else "NA"
|
||||
|
||||
field_name = data[fi + 2].strip()
|
||||
field_rw = data[fi + 3].strip()
|
||||
|
||||
if field_rw == 'R':
|
||||
field_rw = 'RO'
|
||||
elif field_rw == 'W':
|
||||
field_rw = 'WO'
|
||||
if '-V' in field_rw:
|
||||
if 'V' not in access_type:
|
||||
access_type.append('V')
|
||||
field_rw_ = field_rw.replace('-V','')
|
||||
if field_rw_ not in access_type:
|
||||
if field_rw_ not in hdl_strings.access_type:
|
||||
logger.warning(f"Malformed access type {field_rw} for register {field_name}, file regmap/adi_regmap_{reg}.txt.")
|
||||
else:
|
||||
access_type.append(field_rw)
|
||||
|
||||
field_desc = [data[fi].strip() for fi in range(fi + 4, efi)]
|
||||
field_desc = " ".join(field_desc)
|
||||
|
||||
fields.append(
|
||||
{
|
||||
"name": field_name,
|
||||
"bits": field_bits,
|
||||
"default": field_default,
|
||||
"rw": field_rw,
|
||||
"description": field_desc,
|
||||
}
|
||||
)
|
||||
|
||||
data = data[fi + 1 :]
|
||||
|
||||
try:
|
||||
if '+' in reg_addr:
|
||||
reg_addr_ = reg_addr.split('+')
|
||||
reg_addr_[0] = int(reg_addr_[0], 16)
|
||||
reg_addr_[1] = int(reg_addr_[1].replace('*n',''), 16)
|
||||
reg_addr_dword = f"{hex(reg_addr_[0])} + {hex(reg_addr_[1])}*n"
|
||||
reg_addr_byte = f"{hex(reg_addr_[0]<<2)} + {hex(reg_addr_[1]<<2)}*n"
|
||||
else:
|
||||
reg_addr_ = int(reg_addr, 16)
|
||||
reg_addr_dword = f"{hex(reg_addr_)}"
|
||||
reg_addr_byte = f"{hex(reg_addr_<<2)}"
|
||||
except:
|
||||
logger.warning(f"Got malformed register address {reg_addr} for register {reg_name}, file regmap/adi_regmap_{reg}.txt.")
|
||||
reg_addr_dword = ""
|
||||
reg_addr_byte = ""
|
||||
|
||||
regmap['subregmap'][title_tool]['regmap'].append(
|
||||
{
|
||||
'name': reg_name,
|
||||
'address': [reg_addr_dword, reg_addr_byte],
|
||||
'description': reg_desc,
|
||||
'fields': fields
|
||||
}
|
||||
)
|
||||
regmap['subregmap'][title_tool]['access_type'] = access_type
|
||||
return regmap
|
||||
|
||||
def manage_hdl_regmaps(env, docnames):
|
||||
if not hasattr(env, 'regmaps'):
|
||||
env.regmaps = {}
|
||||
|
||||
rm = env.regmaps
|
||||
for lib in list(rm):
|
||||
f = f"regmap/adi_regmap_{lib}.txt"
|
||||
if not os.path.isfile(f):
|
||||
del rm[lib]
|
||||
# Inconsistent naming convention, need to parse all in directory.
|
||||
files = []
|
||||
for (dirpath, dirnames, filenames) in os.walk("regmap"):
|
||||
files.extend(filenames)
|
||||
break
|
||||
regmaps = [f.replace('adi_regmap_','').replace('.txt','') for f in files]
|
||||
for reg_name in regmaps:
|
||||
ctime = os.path.getctime(f"regmap/adi_regmap_{reg_name}.txt")
|
||||
if reg_name in rm and rm[reg_name]['ctime'] < ctime:
|
||||
for o in rm[reg_name]['owners']:
|
||||
if o not in docnames:
|
||||
docnames.append(o)
|
||||
if reg_name in rm and rm[reg_name]['ctime'] >= ctime:
|
||||
pass
|
||||
else:
|
||||
rm[reg_name] = parse_hdl_regmap(reg_name, ctime)
|
||||
|
||||
def manage_hdl_artifacts(app, env, docnames):
|
||||
libraries = [[k.replace('/index',''), k] for k in env.found_docs if k.find('library/') == 0]
|
||||
|
||||
manage_hdl_components(env, docnames, libraries)
|
||||
manage_hdl_regmaps(env, docnames)
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('hdl-parameters', directive_parameters)
|
||||
app.add_directive('hdl-interfaces', directive_interfaces)
|
||||
app.add_node(node_parameters,
|
||||
html=(visit_node_parameters, depart_node_parameters),
|
||||
latex=(visit_node_parameters, depart_node_parameters),
|
||||
text=(visit_node_parameters, depart_node_parameters))
|
||||
app.add_directive('hdl-regmap', directive_regmap)
|
||||
|
||||
app.connect('env-before-read-docs', manage_hdl_components)
|
||||
for node in [node_div, node_input, node_label, node_icon]:
|
||||
app.add_node(node,
|
||||
html =(node.visit, node.depart),
|
||||
latex=(node.visit, node.depart),
|
||||
text =(node.visit, node.depart))
|
||||
|
||||
app.connect('env-before-read-docs', manage_hdl_artifacts)
|
||||
|
||||
app.add_config_value('hide_collapsible_content', dft_hide_collapsible_content, 'env')
|
||||
|
||||
return {
|
||||
'version': '0.1',
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
class hdl_strings ():
|
||||
access_type = {
|
||||
'RO':{
|
||||
'name': 'Read-only',
|
||||
'description': 'Reads will return the current register value. Writes have no effect.'
|
||||
},
|
||||
'WO':{
|
||||
'name': 'Write-only',
|
||||
'description': 'Writes will change the current register value. Reads have no effect.'
|
||||
},
|
||||
'RW':{
|
||||
'name': 'Read-write',
|
||||
'description': 'Reads will return the current register value. Writes will change the current register value.'
|
||||
},
|
||||
'RW1C':{
|
||||
'name': 'Read,write-1-to-clear',
|
||||
'description': 'Reads will return the current register value. Writing the register will clear those bits of the register which were set to 1 in the value written. Bits are set by hardware.'
|
||||
},
|
||||
'RW1S':{
|
||||
'name': 'Read,write-1-to-set',
|
||||
'description': 'Reads will return the current register value. Writing the register will set those bits of the register which were set to 1 in the value written. Bits are cleared by hardware.'
|
||||
},
|
||||
'W1S':{
|
||||
'name': 'Write-1-to-set',
|
||||
'description': 'Writing the register will set those bits of the register which were set to 1 in the value written. Bits are cleared by hardware. Reads have no effect.'
|
||||
},
|
||||
'V':{
|
||||
'name': 'Volatile',
|
||||
'description': 'The V suffix indicates that the register is volatile and its content might change without software interaction. The value of registers without the volatile designation will not change without an explicit write done by software.'
|
||||
},
|
||||
'NA':{
|
||||
'name': 'No access',
|
||||
'description': 'Do not read or write the register.'
|
||||
}
|
||||
}
|
|
@ -186,42 +186,8 @@ Interface
|
|||
Register Map
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. csv-table::
|
||||
:file: regmap.csv
|
||||
:class: regmap
|
||||
:header-rows: 2
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 20 70
|
||||
:header-rows: 1
|
||||
|
||||
* - Access Type
|
||||
- Name
|
||||
- Description
|
||||
* - RO
|
||||
- Read-only
|
||||
- Reads will return the current register value. Writes have no effect.
|
||||
* - RW
|
||||
- Read-write
|
||||
- Reads will return the current register value. Writes will change the
|
||||
current register value.
|
||||
* - RW1C
|
||||
- Write-1-to-clear
|
||||
- Reads will return the current register value. Writing the register will
|
||||
clear those bits of the register which were set to 1 in the value written.
|
||||
Bits are set by hardware.
|
||||
* - RW1S
|
||||
- Write-1-to-set
|
||||
- Reads will return the current register value. Writing the register will
|
||||
set those bits of the register which were set to 1 in the value written.
|
||||
Bits are cleared by hardware.
|
||||
* - V
|
||||
- Volatile
|
||||
- The V suffix indicates that the register is volatile and its content
|
||||
might change without software interaction. The value of registers without
|
||||
the volatile designation will not change without an explicit write done
|
||||
by software.
|
||||
|
||||
.. hdl-regmap::
|
||||
:name: DMAC
|
||||
|
||||
Theory of Operation
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
Address ,,,,,,
|
||||
DWORD ,BYTE ,Bits ,Name ,Type ,Default ,Description
|
||||
0x000 ,0x0000 ,,VERSION ,,,Version of the peripheral. Follows semantic versioning. Current version 4.04.61.
|
||||
,,[31:16] ,VERSION_MAJOR ,RO ,0x04 ,
|
||||
,,[15:8] ,VERSION_MINOR ,RO ,0x03 ,
|
||||
,,[7:0] ,VERSION_PATCH ,RO ,0x61 ,
|
||||
0x001 ,0x0004 ,,PERIPHERAL_ID ,,,
|
||||
,,[31:0] ,PERIPHERAL_ID ,RO ,ID ,Value of the ID configuration parameter.
|
||||
0x002 ,0x0008 ,,SCRATCH ,,,
|
||||
,,[31:0] ,SCRATCH ,RW ,0x00000000 ,Scratch register useful for debug.
|
||||
0x003 ,0x000c ,,IDENTIFICATION ,,,
|
||||
,,[31:0] ,IDENTIFICATION ,RO ,0x444D4143 ,"Peripheral identification ('D', 'M', 'A', 'C'). "
|
||||
0x004 ,0x0010 ,,INTERFACE_DESCRIPTION ,,,
|
||||
,,[3:0] ,BYTES_PER_BEAT_DEST_LOG2 ,R ,log2(DMA_DATA_WIDTH_DEST/8) ,Width of data bus on destination interface. Log2 of interface data widths in bytes.
|
||||
,,[5:4] ,DMA_TYPE_DEST ,R ,DMA_TYPE_DEST ,"Value of DMA_TYPE_DEST parameter.(0 - AXI MemoryMap, 1 - AXI Stream, 2 - FIFO "
|
||||
,,[11:8] ,BYTES_PER_BEAT_SRC_LOG2 ,R ,log2(DMA_DATA_WIDTH_SRC/8) ,Width of data bus on source interface. Log2 of interface data widths in bytes.
|
||||
,,[13:12] ,DMA_TYPE_SRC ,R ,DMA_TYPE_SRC ,"Value of DMA_TYPE_SRC parameter.(0 - AXI MemoryMap, 1 - AXI Stream, 2 - FIFO "
|
||||
,,[19:16] ,BYTES_PER_BURST_WIDTH ,R ,BYTES_PER_BURST_WIDTH ,Value of BYTES_PER_BURST_WIDTH interface parameter. Log2 of the real MAX_BYTES_PER_BURST. The starting address of the transfer must be aligned with MAX_BYTES_PER_BURST to avoid crossing the 4kB address boundary.
|
||||
0x020 ,0x0080 ,,IRQ_MASK ,,,
|
||||
,,[1] ,TRANSFER_COMPLETED ,RW ,0x1 ,Masks the TRANSFER_COMPLETED IRQ.
|
||||
,,[0] ,TRANSFER_QUEUED ,RW ,0x1 ,Masks the TRANSFER_QUEUED IRQ.
|
||||
0x021 ,0x0084 ,,IRQ_PENDING ,,,
|
||||
,,[1] ,TRANSFER_COMPLETED ,RW1C ,0x0 ,This bit will be asserted if a transfer has been completed and the TRANSFER_COMPLETED bit in the IRQ_MASK register is not set. Either if all bytes have been transferred or an error occurred during the transfer.
|
||||
,,[0] ,TRANSFER_QUEUED ,RW1C ,0x0 ,This bit will be asserted if a transfer has been queued and it is possible to queue the next transfer. It can be masked out by setting the TRANSFER_QUEUED bit in the IRQ_MASK register.
|
||||
0x022 ,0x0088 ,,IRQ_SOURCE ,,,
|
||||
,,[1] ,TRANSFER_COMPLETED ,RO ,0x0 ,This bit will be asserted if a transfer has been completed. Either if all bytes have been transferred or an error occurred during the transfer. Cleared together with the corresponding IRQ_PENDING bit.
|
||||
,,[0] ,TRANSFER_QUEUED ,RO ,0x0 ,This bit will be asserted if a transfer has been queued and it is possible to queue the next transfer. Cleared together with the corresponding IRQ_PENDING bit.
|
||||
0x100 ,0x0400 ,,CONTROL ,,,
|
||||
,,[1] ,PAUSE ,RW ,0x0 ,When set to 1 the currently active transfer is paused. It will be resumed once the bit is cleared again.
|
||||
,,[0] ,ENABLE ,RW ,0x0 ,When set to 1 the DMA channel is enabled.
|
||||
0x101 ,0x0404 ,,TRANSFER_ID ,,,
|
||||
,,[1:0] ,TRANSFER_ID ,RO ,0x00 ,This register contains the ID of the next transfer. The ID is generated by the DMAC and after the transfer has been started can be used to check if the transfer has finished by checking the corresponding bit in the TRANSFER_DONE register. The contents of this register is only valid if TRANSFER_SUBMIT is 0.
|
||||
0x102 ,0x0408 ,,TRANSFER_SUBMIT ,,,
|
||||
,,[0] ,TRANSFER_SUBMIT ,RW ,0x00 ,Writing a 1 to this register queues a new transfer. The bit transitions back to 0 once the transfer has been queued or the DMA channel is disabled. Writing a 0 to this register has no effect.
|
||||
0x103 ,0x040c ,FLAGS ,,,,
|
||||
,,[0] ,CYCLIC ,RW ,CYCLIC ,Setting this field to 1 puts the DMA transfer into cyclic mode. In cyclic mode the controller will re-start a transfer again once it has finished. In cyclic mode no end-of-transfer interrupts will be generated.
|
||||
,,[1] ,TLAST ,RW ,0x1 ,When setting this bit for a MM to AXIS transfer the TLAST signal will be asserted during the last beat of the transfer. For AXIS to MM transfers the TLAST signal from the AXIS interface is monitored. After its occurrence all descriptors are ignored until this bit is set.
|
||||
,,[2] ,PARTIAL_REPORTING_EN ,RW ,0x0 ,When setting this bit the length of partial transfers caused eventually by TLAST will be recorded.
|
||||
0x104 ,0x0410 ,,DEST_ADDRESS ,,,
|
||||
,,[31:0] ,DEST_ADDRESS ,RW ,0x00000000 ,This register contains the destination address of the transfer. The address needs to be aligned to the bus width. This register is only valid if the DMA channel has been configured for write to memory support.
|
||||
0x105 ,0x0414 ,,SRC_ADDRESS ,,,
|
||||
,,[31:0] ,SRC_ADDRESS ,RW ,0x00000000 ,This register contains the source address of the transfer. The address needs to be aligned to the bus width. This register is only valid if the DMA channel has been configured for read from memory support.
|
||||
0x106 ,0x0418 ,,X_LENGTH ,,,
|
||||
,,[23:0] ,X_LENGTH ,RW ,"{log2(max(
|
||||
DMA_DATA_WIDTH_SRC,
|
||||
DMA_DATA_WIDTH_DEST
|
||||
)/8){1'b1}} ",Number of bytes to transfer - 1.
|
||||
0x107 ,0x041c ,,Y_LENGTH ,,,
|
||||
,,[23:0] ,Y_LENGTH ,RW ,0x000000 ,"Number of rows to transfer - 1. Note, this field is only valid if the DMA channel has been configured with 2D transfer support. "
|
||||
0x108 ,0x0420 ,,DEST_STRIDE ,,,
|
||||
,,[23:0] ,DEST_STRIDE ,RW ,0x000000 ,"The number of bytes between the start of one row and the next row for the destination address. Needs to be aligned to the bus width. Note, this field is only valid if the DMA channel has been configured with 2D transfer support and write to memory support. "
|
||||
0x109 ,0x0424 ,,SRC_STRIDE ,,,
|
||||
,,[23:0] ,SRC_STRIDE ,RW ,0x000000 ,"The number of bytes between the start of one row and the next row for the source address. Needs to be aligned to the bus width. Note, this field is only valid if the DMA channel has been configured with 2D transfer and read from memory support. "
|
||||
0x10a ,0x0428 ,,TRANSFER_DONE ,,,If bit x is set in this register the transfer with ID x has been completed. The bit will automatically be cleared when a new transfer with this ID is queued and will be set when the transfer has been completed.
|
||||
,,[0] ,TRANSFER_0_DONE ,RO ,0x0 ,If this bit is set the transfer with ID 0 has been completed.
|
||||
,,[1] ,TRANSFER_1_DONE ,RO ,0x0 ,If this bit is set the transfer with ID 1 has been completed.
|
||||
,,[2] ,TRANSFER_2_DONE ,RO ,0x0 ,If this bit is set the transfer with ID 2 has been completed.
|
||||
,,[3] ,TRANSFER_3_DONE ,RO ,0x0 ,If this bit is set the transfer with ID 3 has been completed.
|
||||
,,[31] ,PARTIAL_TRANSFER_DONE ,RO ,0x0 ,If this bit is set at least one partial transfer was transferred. This field will reset when the ENABLE control bit is reset or when all information on partial transfers was read through PARTIAL_TRANSFER_LENGTH and PARTIAL_TRANSFER_ID registers.
|
||||
0x10b ,0x042c ,,ACTIVE_TRANSFER_ID ,,,
|
||||
,,[4:0] ,ACTIVE_TRANSFER_ID ,RO ,0x00 ,ID of the currently active transfer. When no transfer is active this register will be equal to the TRANSFER_ID register.
|
||||
0x10c ,0x0430 ,,STATUS ,,,
|
||||
,,[31:0] ,RESERVED ,RO ,0x00 ,This register is reserved for future usage. Reading it will always return 0.
|
||||
0x10d ,0x0434 ,,CURRENT_DEST_ADDRESS ,,,
|
||||
,,[31:0] ,CURRENT_DEST_ADDRESS ,RO ,0x00 ,Address to which the next data sample is written to. This register is only valid if the DMA channel has been configured for write to memory support.
|
||||
0x10e ,0x0438 ,,CURRENT_SRC_ADDRESS ,,,
|
||||
,,[31:0] ,CURRENT_SRC_ADDRESS ,RO ,0x00 ,Address form which the next data sample is read. This register is only valid if the DMA channel has been configured for read from memory support.
|
||||
0x112 ,0x0448 ,,TRANSFER_PROGRESS ,,,
|
||||
,,[23:0] ,TRANSFER_PROGRESS ,RO ,0x000000 ,This field presents the number of bytes transferred to the destination for the current transfer. This register will be cleared once the transfer completes. This should be used for debugging purposes only.
|
||||
0x113 ,0x044c ,,PARTIAL_TRANSFER_LENGTH ,,,
|
||||
,,[31:0] ,PARTIAL_LENGTH ,RO ,0x000000 ,Length of the partial transfer in bytes. Represents the number of bytes received until the moment of TLAST assertion. This will be smaller than the programmed length from the X_LENGTH and Y_LENGTH registers.
|
||||
0x114 ,0x0450 ,,PARTIAL_TRANSFER_ID ,,,Must be read after the PARTIAL_TRANSFER_LENGTH registers.
|
||||
,,[1:0] ,PARTIAL_TRANSFER_ID ,RO ,0x0 ,ID of the transfer that was partial.
|
||||
0x124 ,0x0490 ,,DEST_ADDRESS_HIGH ,,,
|
||||
,,[31:0] ,DEST_ADDRESS_HIGH ,RW ,0x00000000 ,This register contains the HIGH segment of the destination address of the transfer. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if DMA channel has been configured for write to memory support.
|
||||
0x125 ,0x0494 ,,SRC_ADDRESS_HIGH ,,,
|
||||
,,[31:0] ,SRC_ADDRESS_HIGH ,RW ,0x00000000 ,This register contains the HIGH segment of the source address of the transfer. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured for read from memory support.
|
||||
0x126 ,0x0498 ,,CURRENT_DEST_ADDRESS_HIGH ,,,
|
||||
,,[31:0] ,CURRENT_DEST_ADDRESS_HIGH ,RO ,0x00 ,HIGH segment of the address to which the next data sample is written to. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured for write to memory support.
|
||||
0x127 ,0x049c ,,CURRENT_SRC_ADDRESS_HIGH ,,,
|
||||
,,[31:0] ,CURRENT_SRC_ADDRESS_HIGH ,RO ,0x00 ,HIGH segment of the address from which the next data sample is read. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured for read from memory support.
|
||||
,,,,,,Tue Mar 14 10:17:59 2023
|
|
|
@ -1,53 +0,0 @@
|
|||
Address ,,,,,,
|
||||
DWORD ,BYTE ,Bits ,Name ,Type ,Default ,Description
|
||||
0x0100 ,0x0400 ,,REG_CHAN_CNTRL ,,,ADC Interface Control & Status
|
||||
,,[11] ,ADC_LB_OWR ,RW ,0x0 ,"If set, forces ADC_DATA_SEL to 1, enabling data loopback "
|
||||
,,[10] ,ADC_PN_SEL_OWR ,RW ,0x0 ,"If set, forces ADC_PN_SEL to 0x9, device specific pn (e.g. ad9361) If both ADC_PN_TYPE_OWR and ADC_PN_SEL_OWR are set, they are ignored "
|
||||
,,[9] ,IQCOR_ENB ,RW ,0x0 ,"if set, enables IQ correction or scale correction. NOT-APPLICABLE if IQCORRECTION_DISABLE is set (0x1). "
|
||||
,,[8] ,DCFILT_ENB ,RW ,0x0 ,"if set, enables DC filter (to disable DC offset, set offset value to 0x0). NOT-APPLICABLE if DCFILTER_DISABLE is set (0x1). "
|
||||
,,[6] ,FORMAT_SIGNEXT ,RW ,0x0 ,"if set, enables sign extension (applicable only in 2's complement mode). The data is always sign extended to the nearest byte boundary. NOT-APPLICABLE if DATAFORMAT_DISABLE is set (0x1). "
|
||||
,,[5] ,FORMAT_TYPE ,RW ,0x0 ,Select offset binary (0x1) or 2's complement (0x0) data type. This sets the incoming data type and is required by the post processing modules for any data conversion. NOT-APPLICABLE if DATAFORMAT_DISABLE is set (0x1).
|
||||
,,[4] ,FORMAT_ENABLE ,RW ,0x0 ,Enable data format conversion (see register bits above). NOT-APPLICABLE if DATAFORMAT_DISABLE is set (0x1).
|
||||
,,[3] ,RESERVED ,RO ,0x0 ,Reserved for backward compatibility.
|
||||
,,[2] ,RESERVED ,RO ,0x0 ,Reserved for backward compatibility.
|
||||
,,[1] ,ADC_PN_TYPE_OWR ,RW ,0x0 ,"If set, forces ADC_PN_SEL to 0x1, modified pn23 If both ADC_PN_TYPE_OWR and ADC_PN_SEL_OWR are set, they are ignored "
|
||||
,,[0] ,ENABLE ,RW ,0x0 ,"If set, enables channel. A 0x0 to 0x1 transition transfers all the control signals to the respective channel processing module. If a channel is part of a complex signal (I/Q), even channel is the master and the odd channel is the slave. Though a single control is used, both must be individually selected. "
|
||||
0x0101 ,0x0404 ,,REG_CHAN_STATUS ,,,ADC Interface Control & Status
|
||||
,,[12] ,CRC_ERR ,RW1C ,0x0 ,"CRC errors. If set, indicates CRC error. Software must first clear this bit before initiating a transfer and monitor afterwards. "
|
||||
,,[11:4] ,STATUS_HEADER ,RO ,0x00 ,The status header sent by the ADC.(compatible with AD7768/AD7768-4/AD777x).
|
||||
,,[2] ,PN_ERR ,RW1C ,0x0 ,"PN errors. If set, indicates spurious mismatches in sync state. This bit is cleared if OOS is set and is only indicates errors when OOS is cleared. "
|
||||
,,[1] ,PN_OOS ,RW1C ,0x0 ,"PN Out Of Sync. If set, indicates an OOS status. OOS is set, if 64 consecutive patterns mismatch from the expected pattern. It is cleared, when 16 consecutive patterns match the expected pattern. "
|
||||
,,[0] ,OVER_RANGE ,RW1C ,0x0 ,"If set, indicates over range. Note that over range is independent of the data path, it indicates an over range over a data transfer period. Software must first clear this bit before initiating a transfer and monitor afterwards. "
|
||||
0x0102 ,0x0408 ,,REG_CHAN_RAW_DATA ,,,ADC Raw Data Reading
|
||||
,,[31:0] ,ADC_READ_DATA[31:0] ,RO ,0x0000 ,Raw data read from the ADC.
|
||||
0x0104 ,0x0410 ,,REG_CHAN_CNTRL_1 ,,,ADC Interface Control & Status
|
||||
,,[31:16] ,DCFILT_OFFSET[15:0] ,RW ,0x0000 ,DC removal (if equipped) offset. This is a 2's complement number added to the incoming data to remove a known DC offset. NOT-APPLICABLE if DCFILTER_DISABLE is set (0x1).
|
||||
,,[15:0] ,DCFILT_COEFF[15:0] ,RW ,0x0000 ,"DC removal filter (if equipped) coefficient. The format is 1.1.14 (sign, integer and fractional bits). NOT-APPLICABLE if DCFILTER_DISABLE is set (0x1). "
|
||||
0x0105 ,0x0414 ,,REG_CHAN_CNTRL_2 ,,,ADC Interface Control & Status
|
||||
,,[31:16] ,IQCOR_COEFF_1[15:0] ,RW ,0x0000 ,"IQ correction (if equipped) coefficient. If scale & offset is implemented, this is the scale value and the format is 1.1.14 (sign, integer and fractional bits). If matrix multiplication is used, this is the channel I coefficient and the format is 1.1.14 (sign, integer and fractional bits). If SCALECORRECTION_ONLY is set, this implements the scale value correction for the current channel with the format 1.1.14 (sign, integer and fractional bits). NOT-APPLICABLE if IQCORRECTION_DISABLE is set (0x1). "
|
||||
,,[15:0] ,IQCOR_COEFF_2[15:0] ,RW ,0x0000 ,"IQ correction (if equipped) coefficient. If scale & offset is implemented, this is the offset value and the format is 2's complement. If matrix multiplication is used, this is the channel Q coefficient and the format is 1.1.14 (sign, integer and fractional bits). NOT-APPLICABLE if IQCORRECTION_DISABLE is set (0x1). "
|
||||
0x0106 ,0x0418 ,,REG_CHAN_CNTRL_3 ,,,ADC Interface Control & Status
|
||||
,,[19:16] ,ADC_PN_SEL[3:0] ,RW ,0x0 ,"Selects the PN monitor sequence type (available only if ADC supports it).
|
||||
- 0x0: pn9a (device specific, modified pn9)
|
||||
- 0x1: pn23a (device specific, modified pn23)
|
||||
- 0x4: pn7 (standard O.150)
|
||||
- 0x5: pn15 (standard O.150)
|
||||
- 0x6: pn23 (standard O.150)
|
||||
- 0x7: pn31 (standard O.150)
|
||||
- 0x9: pnX (device specific, e.g. ad9361)
|
||||
- 0x0A: Nibble ramp (Device specific e.g. adrv9001)
|
||||
- 0x0B: 16 bit ramp (Device specific e.g. adrv9001) "
|
||||
,,[3:0] ,ADC_DATA_SEL[3:0] ,RW ,0x0 ,Selects the data source to DMA. 0x0: input data (ADC) 0x1: loopback data (DAC)
|
||||
0x0108 ,0x0420 ,,REG_CHAN_USR_CNTRL_1 ,,,ADC Interface Control & Status
|
||||
,,[25] ,USR_DATATYPE_BE ,RO ,0x0 ,"The user data type format- if set, indicates big endian (default is little endian). NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1). "
|
||||
,,[24] ,USR_DATATYPE_SIGNED ,RO ,0x0 ,"The user data type format- if set, indicates signed (2's complement) data (default is unsigned). NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1). "
|
||||
,,[23:16] ,USR_DATATYPE_SHIFT[7:0] ,RO ,0x00 ,The user data type format- the amount of right shift for actual samples within the total number of bits. NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1).
|
||||
,,[15:8] ,USR_DATATYPE_TOTAL_BITS[7:0] ,RO ,0x00 ,The user data type format- number of total bits used for a sample. The total number of bits must be an integer multiple of 8 (byte aligned). NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1).
|
||||
,,[7:0] ,USR_DATATYPE_BITS[7:0] ,RO ,0x00 ,The user data type format- number of bits in a sample. This indicates the actual sample data bits. NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1).
|
||||
0x0109 ,0x0424 ,,REG_CHAN_USR_CNTRL_2 ,,,ADC Interface Control & Status
|
||||
,,[31:16] ,USR_DECIMATION_M[15:0] ,RW ,0x0000 ,This holds the user decimation M value of the channel that is currently being selected on the multiplexer above. The total decimation factor is of the form M/N. NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1).
|
||||
,,[15:0] ,USR_DECIMATION_N[15:0] ,RW ,0x0000 ,This holds the user decimation N value of the channel that is currently being selected on the multiplexer above. The total decimation factor is of the form M/N. NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1).
|
||||
0x0110 ,0x0440 ,,REG_* ,,,"Channel 1, similar to register 0x100 to 0x10f. "
|
||||
0x0120 ,0x0480 ,,REG_* ,,,"Channel 2, similar to register 0x100 to 0x10f. "
|
||||
0x01F0 ,0x07c0 ,,REG_* ,,,"Channel 15, similar to register 0x100 to 0x10f. "
|
||||
,,,,,,Tue Mar 14 10:17:59 2023
|
|
|
@ -1,78 +0,0 @@
|
|||
Address ,,,,,,
|
||||
DWORD ,BYTE ,Bits ,Name ,Type ,Default ,Description
|
||||
0x0010 ,0x0040 ,,REG_RSTN ,,,ADC Interface Control & Status
|
||||
,,[2] ,CE_N ,RW ,0x0 ,"Clock enable, default is enabled(0x0). An inverse version of the signal is exported out of the module to control clock enables "
|
||||
,,[1] ,MMCM_RSTN ,RW ,0x0 ,"MMCM reset only (required for DRP access). Reset, default is IN-RESET (0x0), software must write 0x1 to bring up the core. "
|
||||
,,[0] ,RSTN ,RW ,0x0 ,"Reset, default is IN-RESET (0x0), software must write 0x1 to bring up the core. "
|
||||
0x0011 ,0x0044 ,,REG_CNTRL ,,,ADC Interface Control & Status
|
||||
,,[16] ,SDR_DDR_N ,RW ,0x0 ,"Interface type (1 represents SDR, 0 represents DDR) "
|
||||
,,[15] ,SYMB_OP ,RW ,0x0 ,Select symbol data format mode (0x1)
|
||||
,,[14] ,SYMB_8_16B ,RW ,0x0 ,"Select number of bits for symbol format mode (1 represents 8b, 0 represents 16b) "
|
||||
,,[12:8] ,NUM_LANES[4:0] ,RW ,0x0 ,"Number of active lanes (1 : CSSI 1-lane, LSSI 1-lane, 2 : LSSI 2-lane, 4 : CSSI 4-lane). For AD7768, AD7768-4 and AD777x number of active lanes : 1/2/4/8 where supported. "
|
||||
,,[3] ,SYNC ,RW ,0x0 ,Initialize synchronization between multiple ADCs
|
||||
,,[2] ,R1_MODE ,RW ,0x0 ,Select number of RF channels 1 (0x1) or 2 (0x0).
|
||||
,,[1] ,DDR_EDGESEL ,RW ,0x0 ,Select rising edge (0x0) or falling edge (0x1) for the first part of a sample (if applicable) followed by the successive edges for the remaining parts. This only controls how the sample is delineated from the incoming data post DDR registers.
|
||||
,,[0] ,PIN_MODE ,RW ,0x0 ,"Select interface pin mode to be clock multiplexed (0x1) or pin multiplexed (0x0). In clock multiplexed mode, samples are received on alternative clock edges. In pin multiplexed mode, samples are interleaved or grouped on the pins at the same clock edge. "
|
||||
0x0012 ,0x0048 ,,REG_CNTRL_2 ,,,ADC Interface Control & Status
|
||||
,,[1] ,EXT_SYNC_ARM ,RW ,0x0 ,"Setting this bit will arm the trigger mechanism sensitive to an external sync signal. Once the external sync signal goes high it synchronizes channels within a ADC, and across multiple instances. This bit has an effect only the EXT_SYNC synthesis parameter is set. This bit self clears. "
|
||||
,,[2] ,EXT_SYNC_DISARM ,RW ,0x0 ,Setting this bit will disarm the trigger mechanism sensitive to an external sync signal. This bit has an effect only the EXT_SYNC synthesis parameter is set. This bit self clears.
|
||||
,,[8] ,MANUAL_SYNC_REQUEST ,RW ,0x0 ,Setting this bit will issue an external sync event if it is hooked up inside the fabric. This bit has an effect only the EXT_SYNC synthesis parameter is set. This bit self clears.
|
||||
0x0013 ,0x004c ,,REG_CNTRL_3 ,,,ADC Interface Control & Status
|
||||
,,[8] ,CRC_EN ,RW ,0x0 ,Setting this bit will enable the CRC generation.
|
||||
,,[7:0] ,CUSTOM_CONTROL ,RW ,0x00 ,"Select output format decode mode.(for ADAQ8092: bit 0 - enables digital output randomizer decode , bit 1 - enables alternate bit polarity decode). "
|
||||
0x0015 ,0x0054 ,,REG_CLK_FREQ ,,,ADC Interface Control & Status
|
||||
,,[31:0] ,CLK_FREQ[31:0] ,RO ,0x0000 ,Interface clock frequency. This is relative to the processor clock and in many cases is 100MHz. The number is represented as unsigned 16.16 format. Assuming a 100MHz processor clock the minimum is 1.523kHz and maximum is 6.554THz. The actual interface clock is CLK_FREQ * CLK_RATIO (see below). Note that the actual sampling clock may not be the same as the interface clock- software must consider device specific implementation parameters to calculate the final sampling clock.
|
||||
0x0016 ,0x0058 ,,REG_CLK_RATIO ,,,ADC Interface Control & Status
|
||||
,,[31:0] ,CLK_RATIO[31:0] ,RO ,0x0000 ,Interface clock ratio - as a factor actual received clock. This is implementation specific and depends on any serial to parallel conversion and interface type (ddr/sdr/qdr).
|
||||
0x0017 ,0x005c ,,REG_STATUS ,,,ADC Interface Control & Status
|
||||
,,[4] ,ADC_CTRL_STATUS ,RO ,0x0 ,"If set, indicates that the device's register data is available on the data bus. "
|
||||
,,[3] ,PN_ERR ,RO ,0x0 ,"If set, indicates pn error in one or more channels. "
|
||||
,,[2] ,PN_OOS ,RO ,0x0 ,"If set, indicates pn oos in one or more channels. "
|
||||
,,[1] ,OVER_RANGE ,RO ,0x0 ,"If set, indicates over range in one or more channels. "
|
||||
,,[0] ,STATUS ,RO ,0x0 ,"Interface status, if set indicates no errors. If not set, there are errors, software may try resetting the cores. "
|
||||
0x0018 ,0x0060 ,,REG_DELAY_CNTRL ,,,ADC Interface Control & Status(Deprecated from version 9)
|
||||
,,[17] ,DELAY_SEL ,RW ,0x0 ,"Delay select, a 0x0 to 0x1 transition in this register initiates a delay access controlled by the registers below. "
|
||||
,,[16] ,DELAY_RWN ,RW ,0x0 ,"Delay read (0x1) or write (0x0), the delay is accessed directly (no increment or decrement) with an address corresponding to each pin, and data corresponding to the total delay. "
|
||||
,,[15:8] ,DELAY_ADDRESS[7:0] ,RW ,0x00 ,"Delay address, the range depends on the interface pins, data pins are usually at the lower range. "
|
||||
,,[4:0] ,DELAY_WDATA[4:0] ,RW ,0x0 ,"Delay write data, a value of 1 corresponds to (1/200)ns for most devices. "
|
||||
0x0019 ,0x0064 ,,REG_DELAY_STATUS ,,,ADC Interface Control & Status(Deprecated from version 9)
|
||||
,,[9] ,DELAY_LOCKED ,RO ,0x0 ,"Indicates delay locked (0x1) state. If this bit is read 0x0, delay control has failed to calibrate the elements. "
|
||||
,,[8] ,DELAY_STATUS ,RO ,0x0 ,"If set, indicates busy status (access pending). The read data may not be valid if this bit is set. "
|
||||
,,[4:0] ,DELAY_RDATA[4:0] ,RO ,0x0 ,"Delay read data, current delay value in the elements "
|
||||
0x001A ,0x0068 ,,REG_SYNC_STATUS ,,,ADC Synchronization Status register
|
||||
,,[0] ,ADC_SYNC ,RO ,0x0 ,ADC synchronization status. Will be set to 1 after the synchronization has been completed or while waiting for the synchronization signal in JESD204 systems.
|
||||
0x001C ,0x0070 ,,REG_DRP_CNTRL ,,,ADC Interface Control & Status
|
||||
,,[28] ,DRP_RWN ,RW ,0x0 ,DRP read (0x1) or write (0x0) select (does not include GTX lanes). NOT-APPLICABLE if DRP_DISABLE is set (0x1).
|
||||
,,[27:16] ,DRP_ADDRESS[11:0] ,RW ,0x00 ,"DRP address, designs that contain more than one DRP accessible primitives have selects based on the most significant bits (does not include GTX lanes). NOT-APPLICABLE if DRP_DISABLE is set (0x1). "
|
||||
,,[15:0] ,RESERVED[15:0] ,RO ,0x0000 ,Reserved for backward compatibility.
|
||||
0x001D ,0x0074 ,,REG_DRP_STATUS ,,,ADC Interface Control & Status
|
||||
,,[17] ,DRP_LOCKED ,RO ,0x0 ,If set indicates that the DRP has been locked.
|
||||
,,[16] ,DRP_STATUS ,RO ,0x0 ,If set indicates busy (access pending). The read data may not be valid if this bit is set (does not include GTX lanes). NOT-APPLICABLE if DRP_DISABLE is set (0x1).
|
||||
,,[15:0] ,RESERVED[15:0] ,RO ,0x00 ,Reserved for backward compatibility.
|
||||
0x001E ,0x0078 ,,REG_DRP_WDATA ,,,ADC DRP Write Data
|
||||
,,[15:0] ,DRP_WDATA[15:0] ,RW ,0x00 ,DRP write data (does not include GTX lanes). NOT-APPLICABLE if DRP_DISABLE is set (0x1).
|
||||
0x001F ,0x007c ,,REG_DRP_RDATA ,,,ADC DRP Read Data
|
||||
,,[15:0] ,DRP_RDATA[15:0] ,RO ,0x00 ,DRP read data (does not include GTX lanes).
|
||||
0x0020 ,0x0080 ,,REG_ADC_CONFIG_WR ,,,ADC Write Configuration Data
|
||||
,,[31:0] ,ADC_CONFIG_WR[31:0] ,RW ,0x0000 ,Custom Write to the available registers.
|
||||
0x0021 ,0x0084 ,,REG_ADC_CONFIG_RD ,,,ADC Read Configuration Data
|
||||
,,[31:0] ,ADC_CONFIG_RD[31:0] ,RO ,0x0000 ,Custom read of the available registers.
|
||||
0x0022 ,0x0088 ,,REG_UI_STATUS ,,,User Interface Status
|
||||
,,[2] ,UI_OVF ,RW1C ,0x0 ,"User Interface overflow. If set, indicates an overflow occurred during data transfer at the user interface (FIFO interface). Software must write a 0x1 to clear this register bit. "
|
||||
,,[1] ,UI_UNF ,RW1C ,0x0 ,"User Interface underflow. If set, indicates an underflow occurred during data transfer at the user interface (FIFO interface). Software must write a 0x1 to clear this register bit. "
|
||||
,,[0] ,UI_RESERVED ,RW1C ,0x0 ,Reserved for backward compatibility.
|
||||
0x0023 ,0x008c ,,REG_ADC_CONFIG_CTRL ,,,ADC RD/WR configuration
|
||||
,,[31:0] ,ADC_CONFIG_CTRL[31:0] ,RW ,0x0000 ,"Control RD/WR requests to the device's register map: bit 1 - RD ('b1) , WR ('b0), bit 0 - enable WR/RD operation. "
|
||||
0x0028 ,0x00a0 ,,REG_USR_CNTRL_1 ,,,ADC Interface Control & Status
|
||||
,,[7:0] ,USR_CHANMAX[7:0] ,RW ,0x00 ,This indicates the maximum number of inputs for the channel data multiplexers. User may add different processing modules post data capture as another input to this common multiplexer. NOT-APPLICABLE if USERPORTS_DISABLE is set (0x1).
|
||||
0x0029 ,0x00a4 ,,REG_ADC_START_CODE ,,,ADC Synchronization start word
|
||||
,,[31:0] ,ADC_START_CODE[31:0] ,RW ,0x00000000 ,This sets the startcode that is used by the ADCs for synchronization NOT-APPLICABLE if START_CODE_DISABLE is set (0x1).
|
||||
0x002E ,0x00b8 ,,REG_ADC_GPIO_IN ,,,ADC GPIO inputs
|
||||
,,[31:0] ,ADC_GPIO_IN[31:0] ,RO ,0x00000000 ,This reads auxiliary GPI pins of the ADC core
|
||||
0x002F ,0x00bc ,,REG_ADC_GPIO_OUT ,,,ADC GPIO outputs
|
||||
,,[31:0] ,ADC_GPIO_OUT[31:0] ,RW ,0x00000000 ,This controls auxiliary GPO pins of the ADC core NOT-APPLICABLE if GPIO_DISABLE is set (0x1).
|
||||
0x0030 ,0x00c0 ,,REG_PPS_COUNTER ,,,PPS Counter register
|
||||
,,[31:0] ,PPS_COUNTER[31:0] ,RO ,0x00000000 ,Counts the core clock cycles (can be a device clock or interface clock) between two 1PPS pulse.
|
||||
0x0031 ,0x00c4 ,,REG_PPS_STATUS ,,,PPS Status register
|
||||
,,[0] ,PPS_STATUS ,RO ,0x0 ,If this bit is asserted there is no incomming 1PPS signal. Maybe the source is out of sync or it's not active.
|
||||
,,,,,,Tue Mar 14 10:17:59 2023
|
|
|
@ -1,29 +0,0 @@
|
|||
Address ,,,,,,
|
||||
DWORD ,BYTE ,Bits ,Name ,Type ,Default ,Description
|
||||
0x0000 ,0x0000 ,,REG_VERSION ,,,Version and Scratch Registers
|
||||
,,[31:0] ,VERSION[31:0] ,RO ,0x00000000 ,Version number. Unique to all cores.
|
||||
0x0001 ,0x0004 ,,REG_ID ,,,Version and Scratch Registers
|
||||
,,[31:0] ,ID[31:0] ,RO ,0x00000000 ,Instance identifier number.
|
||||
0x0002 ,0x0008 ,,REG_SCRATCH ,,,Version and Scratch Registers
|
||||
,,[31:0] ,SCRATCH[31:0] ,RW ,0x00000000 ,Scratch register.
|
||||
0x0003 ,0x000c ,,REG_CONFIG ,,,Version and Scratch Registers
|
||||
,,[0] ,IQCORRECTION_DISABLE ,RO ,0x0 ,"If set, indicates that the IQ Correction module was not implemented. (as a result of a configuration of the IP instance) "
|
||||
,,[1] ,DCFILTER_DISABLE ,RO ,0x0 ,"If set, indicates that the DC Filter module was not implemented. (as a result of a configuration of the IP instance) "
|
||||
,,[2] ,DATAFORMAT_DISABLE ,RO ,0x0 ,"If set, indicates that the Data Format module was not implemented. (as a result of a configuration of the IP instance) "
|
||||
,,[3] ,USERPORTS_DISABLE ,RO ,0x0 ,"If set, indicates that the logic related to the User Data Format (e.g. decimation) was not implemented. (as a result of a configuration of the IP instance) "
|
||||
,,[4] ,MODE_1R1T ,RO ,0x0 ,"If set, indicates that the core was implemented in 1 channel mode. (e.g. refer to AD9361 data sheet) "
|
||||
,,[5] ,DELAY_CONTROL_DISABLE ,RO ,0x0 ,"If set, indicates that the delay control is disabled for this IP. (as a result of a configuration of the IP instance) "
|
||||
,,[6] ,DDS_DISABLE ,RO ,0x0 ,"If set, indicates that the DDS is disabled for this IP. (as a result of a configuration of the IP instance) "
|
||||
,,[7] ,CMOS_OR_LVDS_N ,RO ,0x0 ,CMOS or LVDS mode is used for the interface. (as a result of a configuration of the IP instance)
|
||||
,,[8] ,PPS_RECEIVER_ENABLE ,RO ,0x0 ,"If set, indicates the PPS receiver is enabled. (as a result of a configuration of the IP instance) "
|
||||
,,[9] ,SCALECORRECTION_ONLY ,RO ,0x0 ,"If set, indicates that the IQ Correction module implements only scale correction. IQ correction must be enabled. (as a result of a configuration of the IP instance) "
|
||||
,,[12] ,EXT_SYNC ,RO ,0x0 ,If set the transport layer cores (ADC/DAC) have implemented the support for external synchronization signal.
|
||||
,,[13] ,RD_RAW_DATA ,RO ,0x0 ,"If set, the ADC has the capability to read raw data in register REG_CHAN_RAW_DATA from adc_channel. "
|
||||
0x0004 ,0x0010 ,,REG_PPS_IRQ_MASK ,,,PPS Interrupt mask
|
||||
,,[0] ,PPS_IRQ_MASK ,RW ,0x1 ,Mask bit for the 1PPS receiver interrupt
|
||||
0x0007 ,0x001c ,,REG_FPGA_INFO ,,,FPGA device information Intel encoded values Xilinx encoded values
|
||||
,,[31:24] ,FPGA_TECHNOLOGY ,RO ,0x0 ,Encoded value describing the technology/generation of the FPGA device (arria 10/7series)
|
||||
,,[23:16] ,FPGA_FAMILY ,RO ,0x0 ,"Encoded value describing the family variant of the FPGA device(e.g., SX, GX, GT or zynq, kintex, virtex) "
|
||||
,,[15:8] ,SPEED_GRADE ,RO ,0x0 ,Encoded value describing the FPGA's speed-grade
|
||||
,,[7:0] ,DEV_PACKAGE ,RO ,0x0 ,Encoded value describing the device package. The package might affect high-speed interfaces
|
||||
,,,,,,Tue Mar 14 10:17:59 2023
|
|
|
@ -77,33 +77,8 @@ Signal and Interface Pins
|
|||
Register Map
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. csv-table::
|
||||
:file: regmap.csv
|
||||
:class: regmap
|
||||
:header-rows: 2
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 20 70
|
||||
:header-rows: 1
|
||||
|
||||
* - Access Type
|
||||
- Name
|
||||
- Description
|
||||
* - RO
|
||||
- Read-only
|
||||
- Reads will return the current register value. Writes have no effect.
|
||||
* - RW
|
||||
- Read-write
|
||||
- Reads will return the current register value. Writes will change the
|
||||
current register value.
|
||||
* - WO
|
||||
- Write-only
|
||||
- Writes will change the current register value. Reads have no effect.
|
||||
* - RW1C
|
||||
- Write-1-to-clear
|
||||
- Reads will return the current register value. Writing the register will
|
||||
clear those bits of the register which were set to 1 in the value written.
|
||||
Bits are set by hardware.
|
||||
.. hdl-regmap::
|
||||
:name: axi_spi_engine
|
||||
|
||||
Theory of Operation
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
Address ,,,,,,
|
||||
DWORD ,BYTE ,Bits ,Name ,Type ,Default ,Description
|
||||
0x00 ,0x0000 ,,VERSION ,,,Version of the peripheral. Follows semantic versioning. Current version 1.00.71.
|
||||
,,[31:16] ,VERSION_MAJOR ,RO ,0x01 ,
|
||||
,,[15:8] ,VERSION_MINOR ,RO ,0x00 ,
|
||||
,,[7:0] ,VERSION_PATCH ,RO ,0x71 ,
|
||||
0x01 ,0x0004 ,,PERIPHERAL_ID ,,,
|
||||
,,[31:0] ,PERIPHERAL_ID ,RO ,ID ,"Value of the ID configuration parameter. In case of multiple instances, each instance will have a unique ID. "
|
||||
0x02 ,0x0008 ,,SCRATCH ,,,
|
||||
,,[31:0] ,SCRATCH ,RW ,0x00000000 ,Scratch register useful for debug.
|
||||
0x03 ,0x000c ,,DATA_WIDTH ,,,
|
||||
,,[31:0] ,DATA_WIDTH ,RO ,0x00000008 ,Data width of the SDI/SDO parallel interface. It is equal with the maximum supported transfer length in bits.
|
||||
0x10 ,0x0040 ,,ENABLE ,,,
|
||||
,,[31:0] ,ENABLE ,RW ,0x00000001 ,"Enable register. If the enable bit is set to 1 the internal state of the peripheral is reset. For proper operation, the bit needs to be set to 0. "
|
||||
0x20 ,0x0080 ,,IRQ_MASK ,,,
|
||||
,,[0] ,CMD_ALMOST_EMPTY ,RW ,0x00 ,If set to 0 the CMD_ALMOST_EMPTY interrupt is masked.
|
||||
,,[1] ,SDO_ALMOST_EMPTY ,RW ,0x00 ,If set to 0 the SDO_ALMOST_EMPTY interrupt is masked.
|
||||
,,[2] ,SDI_ALMOST_FULL ,RW ,0x00 ,If set to 0 the SDI_ALMOST_FULL interrupt is masked.
|
||||
,,[3] ,SYNC_EVENT ,RW ,0x00 ,If set to 0 the SYNC_EVENT interrupt is masked.
|
||||
0x21 ,0x0084 ,,IRQ_PENDING ,,,
|
||||
,,[31:0] ,IRQ_PENDING ,RW1C ,0x00000000 ,Pending IRQs with mask.
|
||||
0x22 ,0x0088 ,,IRQ_SOURCE ,,,
|
||||
,,[31:0] ,IRQ_SOURCE ,RO ,0x00000000 ,Pending IRQs without mask.
|
||||
0x30 ,0x00c0 ,,SYNC_ID ,,,
|
||||
,,[31:0] ,SYNC_ID ,RO ,0x00000000 ,Last synchronization event ID received from the SPI engine control interface.
|
||||
0x34 ,0x00d0 ,,CMD_FIFO_ROOM ,,,
|
||||
,,[31:0] ,CMD_FIFO_ROOM ,RO ,0x???????? ,Number of free entries in the command FIFO. The reset value of the CMD_FIFO_ROOM register depends on the setting of the CMD_FIFO_ADDRESS_WIDTH parameter.
|
||||
0x35 ,0x00d4 ,,SDO_FIFO_ROOM ,,,
|
||||
,,[31:0] ,SDO_FIFO_ROOM ,RO ,0x???????? ,Number of free entries in the serial-data-out FIFO. The reset value of the SDO_FIFO_ROOM register depends on the setting of the SDO_FIFO_ADDRESS_WIDTH parameter.
|
||||
0x36 ,0x00d8 ,,SDI_FIFO_LEVEL ,,,
|
||||
,,[31:0] ,SDI_FIFO_LEVEL ,RO ,0x00000000 ,Number of valid entries in the serial-data-in FIFO.
|
||||
0x38 ,0x00e0 ,,CMD_FIFO ,,,
|
||||
,,[31:0] ,CMD_FIFO ,WO ,0x????????? ,Command FIFO register. Writing to this register inserts an entry into the command FIFO. Writing to this register when the command FIFO is full has no effect and the written entry is discarded. Reading from this register always returns 0x00000000.
|
||||
0x39 ,0x00e4 ,,SDO_FIFO ,,,
|
||||
,,[31:0] ,SDO_FIFO ,WO ,0x????????? ,SDO FIFO register. Writing to this register inserts an entry into the SDO FIFO. Writing to this register when the SDO FIFO is full has no effect and the written entry is discarded. Reading from this register always returns 0x00000000.
|
||||
0x3a ,0x00e8 ,,SDI_FIFO ,,,
|
||||
,,[31:0] ,SDI_FIFO ,RO ,0x????????? ,SDI FIFO register. Reading from this register removes the first entry from the SDI FIFO. Reading this register when the SDI FIFO is empty will return undefined data. Writing to it has no effect.
|
||||
0x3c ,0x00f0 ,,SDI_FIFO_PEEK ,,,
|
||||
,,[31:0] ,SDI_FIFO_PEEK ,RO ,0x????????? ,"SDI FIFO peek register. Reading from this register returns the first entry from the SDI FIFO, but without removing it from the FIFO. Reading this register when the SDI FIFO is empty will return undefined data. Writing to it has no effect. "
|
||||
0x40 ,0x0100 ,,OFFLOAD0_EN ,,,
|
||||
,,[31:0] ,OFFLOAD0_EN ,RW ,0x00000000 ,Set this bit to enable the offload module.
|
||||
0x41 ,0x0104 ,,OFFLOAD0_STATUS ,,,
|
||||
,,[31:0] ,OFFLOAD0_STATUS ,RO ,0x00000000 ,Offload status register.
|
||||
0x42 ,0x0108 ,,OFFLOAD0_MEM_RESET ,,,
|
||||
,,[31:0] ,OFFLOAD0_MEM_RESET ,WO ,0x00000000 ,Reset the memory of the offload module.
|
||||
0x44 ,0x0110 ,,OFFLOAD0_CDM_FIFO ,,,
|
||||
,,[31:0] ,OFFLOAD0_CDM_FIFO ,WO ,0x???????? ,Offload command FIFO register. Writing to this register inserts an entry into the command FIFO of the offload module. Writing to this register when the command FIFO is full has no effect and the written entry is discarded. Reading from this register always returns 0x00000000.
|
||||
0x45 ,0x0114 ,,OFFLOAD0_SDO_FIFO ,,,
|
||||
,,[31:0] ,OFFLOAD0_SDO_FIFO ,WO ,0x???????? ,Offload SDO FIFO register. Writing to this register inserts an entry into the offload SDO FIFO. Writing to this register when the SDO FIFO is full has no effect and the written entry is discarded. Reading from this register always returns 0x00000000.
|
||||
,,,,,,Wed Oct 12 14:15:25 2022
|
|
|
@ -34,22 +34,8 @@ Configuration Parameters
|
|||
Signal and Interface Pins
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 25 65
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``clk``
|
||||
- Clock
|
||||
- All other signals are synchronous to this clock.
|
||||
* - ``resetn``
|
||||
- Synchronous active-low reset
|
||||
- Resets the internal state machine of the core.
|
||||
* - ``ctrl``
|
||||
- :ref:`template_framework interface` master
|
||||
- {brief description}.
|
||||
.. hdl-interfaces::
|
||||
:path: library/spi_engine/spi_engine_interconnect
|
||||
|
||||
Theory of Operation
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
|
@ -47,41 +47,8 @@ Configuration Parameters
|
|||
Interface
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. list-table:: Clock and reset
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``clk``
|
||||
- input
|
||||
- All signals are synchronous to this clock.
|
||||
* - ``resetn``
|
||||
- input
|
||||
- Synchronous active low resey.
|
||||
|
||||
.. list-table:: DMA_TX interface
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``dac_enable_*``
|
||||
- output
|
||||
- If set, the channel is enabled (one for each channel).
|
||||
* - ``dac_valid``
|
||||
- output
|
||||
- Indicates valid data request for all channels
|
||||
|
||||
.. list-table:: AXI_S_MM interface
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``s_axi_*``
|
||||
-
|
||||
- Standard AXI Slave Memory Map interface .
|
||||
.. hdl-interfaces::
|
||||
:path: library/axi_ad9783
|
||||
|
||||
Detailed Architecture
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -110,20 +77,17 @@ basic monitoring and control of the ADC's channel.
|
|||
Register Map
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
.. csv-table:: Base (common to all cores)
|
||||
:file: ../common/regmap_base.csv
|
||||
:class: regmap
|
||||
:header-rows: 2
|
||||
.. hdl-regmap::
|
||||
:name: COMMON
|
||||
:no-type-info:
|
||||
|
||||
.. csv-table:: ADC Common (axi_ad*)
|
||||
:file: ../common/regmap_adc_common.csv
|
||||
:class: regmap
|
||||
:header-rows: 2
|
||||
.. hdl-regmap::
|
||||
:name: ADC_COMMON
|
||||
:no-type-info:
|
||||
|
||||
.. csv-table:: ADC Channel (axi_ad*)
|
||||
:file: ../common/regmap_adc_channel.csv
|
||||
:class: regmap
|
||||
:header-rows: 2
|
||||
.. hdl-regmap::
|
||||
:name: ADC_CHANNEL
|
||||
:no-type-info:
|
||||
|
||||
Design Guidelines
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
:orphan:
|
||||
|
||||
.. _template_project:
|
||||
|
||||
Project template
|
||||
================================================================================
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
TITLE
|
||||
Clock Monitor (axi_clock_monitor)
|
||||
axi_clock_monitor
|
||||
ENDTITLE
|
||||
|
||||
############################################################################################
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
TITLE
|
||||
Base (common to all cores)
|
||||
COMMON
|
||||
ENDTITLE
|
||||
|
||||
############################################################################################
|
||||
|
@ -167,8 +168,9 @@ ENDFIELD
|
|||
REG
|
||||
0x0007
|
||||
REG_FPGA_INFO
|
||||
FPGA device information [[https://github.com/analogdevicesinc/hdl/blob/master/library/scripts/adi_intel_device_info_enc.tcl |Intel encoded values]]
|
||||
[[https://github.com/analogdevicesinc/hdl/blob/master/library/scripts/adi_xilinx_device_info_enc.tcl |Xilinx encoded values]]
|
||||
FPGA device information
|
||||
:git-hdl:`master:library/scripts/adi_intel_device_info_enc.tcl` (Intel encoded values)
|
||||
:git-hdl:`master:library/scripts/adi_xilinx_device_info_enc.tcl` (Xilinx encoded values)
|
||||
ENDREG
|
||||
|
||||
FIELD
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
TITLE
|
||||
PWM Generator (axi_pwm_gen)
|
||||
axi_pwm_gen
|
||||
ENDTITLE
|
||||
|
||||
############################################################################################
|
||||
|
|
|
@ -54,8 +54,62 @@ iframe {
|
|||
padding: .5em 0;
|
||||
}
|
||||
table.regmap {
|
||||
font-size: .75em;
|
||||
font-size: .9em;
|
||||
}
|
||||
table.regmap .caption-text{
|
||||
font-size: 1rem;
|
||||
}
|
||||
td.description{
|
||||
width: 45%;
|
||||
font-size:.8em;
|
||||
}
|
||||
.collapsible {
|
||||
border: 1px solid var(--color-table-border);
|
||||
border-radius: .25em;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.collapsible_input {
|
||||
display: none;
|
||||
}
|
||||
.collapsible_content {
|
||||
border-top: 1px solid var(--color-table-border);
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
transition: ease opacity .25s;
|
||||
opacity: 0;
|
||||
}
|
||||
.collapsible label {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding-left: .75em;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.collapsible label .icon {
|
||||
display: inline-block;
|
||||
padding-right: .25em;
|
||||
}
|
||||
.collapsible label p {
|
||||
display: inline-block;
|
||||
margin: .75em 0;
|
||||
}
|
||||
.collapsible label .icon:before {
|
||||
content: '⮞';
|
||||
color: #666;
|
||||
transition: transform ease .125s, padding ease .125s;
|
||||
display: block;
|
||||
line-height: 1em;
|
||||
padding-right: .25em;
|
||||
}
|
||||
.collapsible_input:checked ~ label .icon:before {
|
||||
transform: rotate(90deg);
|
||||
padding-left: 4px;
|
||||
}
|
||||
.collapsible_input:checked ~ .collapsible_content {
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
.default {
|
||||
min-width: 7em;
|
||||
line-break: anywhere;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue