diff --git a/docs/Containerfile b/docs/Containerfile new file mode 100644 index 000000000..082847e7e --- /dev/null +++ b/docs/Containerfile @@ -0,0 +1,36 @@ +FROM registry.gitlab.com/islandoftex/images/texlive:TL2022-2022-12-25-full + +SHELL ["/bin/bash", "-c"] + +ENV HOME /root + +ARG DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe/Bucharest + +ENV PROJ hdl-docs + +RUN apt-get update + +RUN apt-get -y --no-install-recommends install \ + python3 python3-venv python3-pip + +# To convert svg to pdf, used in sphinx->LaTeX->pdf pipeline +RUN apt-get -y --no-install-recommends install \ + librsvg2-bin + +RUN python3 -m venv /opt/venv + +COPY requirements.txt . + +RUN source /opt/venv/bin/activate ; \ + pip3 install -U pip + +RUN source /opt/venv/bin/activate ; \ + pip3 install wheel vext vext.gi + +RUN source /opt/venv/bin/activate ; \ + pip3 install -r requirements.txt ; \ + deactivate + +RUN mkdir -p /usr/local/bin ; \ + ln -s /opt/venv/bin/symbolator /usr/local/bin/symbolator diff --git a/docs/Makefile b/docs/Makefile new file mode 100755 index 000000000..58c2f28b8 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,76 @@ +SHELL = /bin/bash +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +help: + @echo "For help about the container instance, do \`make container-help\`" + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +#------------------------------------------------------------------------------ +# Container commands +#------------------------------------------------------------------------------ + +CONTAINER_IMG ?=hdl-docs +CONTAINER_ENGINE =podman +CONTAINER_REPO =${CONTAINER_IMG} +CONTAINER_IMAGE =${CONTAINER_IMG}_build +CONTAINER_VERSION ?=0.1 +CONTAINER_SHELL ?=bash -l +CONTAINER_RUN_EXTRA ?= +CONTAINER_FORMAT =$(if $(filter podman,${CONTAINER_ENGINE}),--format docker,) + +IF_CONTAINER_RUNS=$(shell ${CONTAINER_ENFINE} container inspect -f '{{.State.Running}}' ${CONTAINER_IMAGE} 2>/dev/null) + +CONTAINER_RUN_PARAMS = -it --rm --name=${CONTAINER_IMG} \ + --name=${CONTAINER_IMAGE} \ + --workdir=/${CONTAINER_IMG} \ + --mount type=bind,source=${CURDIR}/../,target=/${CONTAINER_IMG} \ + ${CONTAINER_RUN_EXTRA} \ + ${CONTAINER_REPO}/${CONTAINER_IMAGE}:${CONTAINER_VERSION} + +container-login: + @if [ "${IF_CONTAINER_RUNS}" != "true" ]; then \ + ${CONTAINER_ENGINE} run ${CONTAINER_RUN_PARAMS} \ + ${CONTAINER_SHELL}; \ + else \ + ${CONTAINER_ENGINE} exec -it ${CONTAINER_IMAGE} \ + ${CONTAINER_SHELL}; \ + fi + +container-build: + @printf "Building container image\n" + @${CONTAINER_ENGINE} build --no-cache=true ${CONTAINER_FORMAT} -t ${CONTAINER_REPO}/${CONTAINER_IMAGE}:${CONTAINER_VERSION} -f ./Containerfile . + + +container-html: + @${CONTAINER_ENGINE} run ${CONTAINER_RUN_PARAMS} ${CONTAINER_SHELL} -c \ + "source /.venv/bin/activate ; cd docs ; make html" + +container-pdf: + @${CONTAINER_ENGINE} run ${CONTAINER_RUN_PARAMS} ${CONTAINER_SHELL} -c \ + "source /.venv/bin/activate ; cd docs ; make latexpdf" + +container-clean: + @${CONTAINER_ENGINE} run ${CONTAINER_RUN_PARAMS} ${CONTAINER_SHELL} -c \ + "source /.venv/bin/activate ; cd docs ; make clean" + +.PHONY: container-build container-login container-html container-pdf container-clean + +container-help: + @printf "The container commands allow to use a container to build the documentation.\n" + @printf "Both podman and docker are supported, change the CONTAINER_ENGINE variable to select which to use.\n\n" + @printf "Usage: make [options]\n" + @printf "\ +Options:\n\ + container-build Build the container image with dependencies (do once).\n\ + container-login Access the container shell.\n\ + container-html Build html documentation.\n\ + container-latexpdf Build pdf documentation.\n\ +\n" diff --git a/docs/appendix/bibliography.rst b/docs/appendix/bibliography.rst new file mode 100755 index 000000000..7aa7a7a8f --- /dev/null +++ b/docs/appendix/bibliography.rst @@ -0,0 +1,6 @@ +Bibliography +====================================================== + +.. bibliography:: + :all: + diff --git a/docs/appendix/glossary.rst b/docs/appendix/glossary.rst new file mode 100644 index 000000000..9623d9fda --- /dev/null +++ b/docs/appendix/glossary.rst @@ -0,0 +1,97 @@ +Glossary +====================================================== + +.. glossary:: + + SVG + Scalable Vector Graphics + + reST + reStructuredText Primer + + HDL + hardware description language + + S + Start + + PS + Processing System + + Sr + Repeated Start + + P + Stop + + ACK + Acknowledge + + IBI + In-band Interrupt + + DAA + Dynamic Address Assignment + + ADC + analog-digital converter + + SoC + system-on-a-chip + + SAR + succesive-approximation-register + + IP + intellectual-property + + PMOD + peripheral module interface + + SOM + system on module + + SDR + standard data rate + + DDR + double data rate + + HDR + high data rate + + ID + identification + + PID + Provisioned ID + + MIPI + Manufacturer ID + + MDB + Mandatory data byte + + I/O + input/output + + PUR + Pull-Up Resistor + + CCC + Common Command Codes + + T-bit + Transaction bit + + SCL + Serial Clock + + SDA + Serial Data + + SPI + Serial Peripheral Interface + + GPIO + General Purpose Input/Output diff --git a/docs/appendix/references.bib b/docs/appendix/references.bib new file mode 100755 index 000000000..d3753068d --- /dev/null +++ b/docs/appendix/references.bib @@ -0,0 +1,13 @@ +@misc{adi:hdl, + organization = {Analog Devices Inc}, + title = {HDL Reference Designs}, + howpublished = {\url{https://github.com/analogdevicesinc/hdl}}, + year = {2023} +} +@misc{adi:i2c-quick-guide, + organization = {Analog Devices Inc}, + title = {I²C Quick Guide}, + howpublished = {\url{https://www.analog.com/media/en/technical-documentation/product-selector-card/i2Cb.pdf}}, + year = {2017}, + month = {April} +} diff --git a/docs/conf.py b/docs/conf.py new file mode 100755 index 000000000..2e4fac49f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,56 @@ +# Configuration file for the Sphinx documentation builder. +# +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- + +project = 'HDL, Analog Devices' +copyright = '2023, Analog Devices Inc' +author = 'Analog Devices Inc' +release = 'v0.1' + +# -- General configuration --------------------------------------------------- + +import os, sys + +sys.path.append(os.path.abspath("./extensions")) + +extensions = [ + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "sphinxcontrib.bibtex", + "sphinxcontrib.mermaid", + "sphinxcontrib.wavedrom", + "symbolator_sphinx", + "adi_links", + "adi_hdl_parser" +] + +templates_path = ['sources/template'] + +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# -- Custom extensions configuration ------------------------------------------- + + +# -- todo configuration ------------------------------------------------------- + +todo_include_todos = True +todo_emit_warnings = True + +# -- Symbolator configuration ------------------------------------------------- + +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' +html_static_path = ['sources'] +source_suffix = '.rst' +html_css_files = ["custom.css"] +html_favicon = "sources/icon.svg" diff --git a/docs/contributing/guidelines.rst b/docs/contributing/guidelines.rst new file mode 100644 index 000000000..1100a4fc4 --- /dev/null +++ b/docs/contributing/guidelines.rst @@ -0,0 +1,316 @@ +Guidelines +================================================================================ + +A brief set-of-rules for the documentation. + +.. note:: + The old wiki uses `dokuwiki `_. When + importing text from there, consider the automated options that are provided + in this page to convert it to :term:`reST`. + +Templates +-------------------------------------------------------------------------------- + +Templates are available: + +* :git-hdl:`docs/library/template_ip` (:ref:`rendered `). +* :git-hdl:`docs/library/template_framework` (:ref:`rendered `). + +Remove the ``:orphan:`` in the first line, it is to hide the templates from the +`TOC tree `_. + +Indentation +-------------------------------------------------------------------------------- + +Directives are indented with 3 space, which is Sphinx's default. +At code directives, the code keeps its original indentation (e.g. 2 spaces for +verilog code), but is offset by 3 spaces at the beginning of every line, to +instruct Sphinx the beginning and end of the code directive. + +References +-------------------------------------------------------------------------------- + +References have the format ``library/project context``, e.g. +:code:`:ref:\`spi_engine execution\`` renders as :ref:`spi_engine execution`. +Notice how neither *library* nor *project* are present in the label, since there is no +naming collision between libraries or projects (no project will ever be named +*axi_dmac*). + +Also, for project, libraries and :term:`IP`\s, the names should be exactly the +name of its folders, e.g. ``axi_pwm_gen`` and not ``axi-pwm-gen`` or ``AXI_PWM_GEN``, +this helps avoid broken references. + +For resources without a particular source code file/folder, prefer hyphen ``-`` +separation, for example, ``spi_engine control-interface`` instead of +``spi_engine control_interface``. + +Text width +-------------------------------------------------------------------------------- + +Each line must be less than 80 columns wide. +You can use the :code:`fold` command to break the lines of the imported text +while respecting word-breaks: + +.. code:: bash + + cat imported.txt | fold -sw 80 > imported.rst + +Or use the pandoc command provided in the next topic, since it will also fold +at column 80. + +Tables +-------------------------------------------------------------------------------- + +Prefer +`list-tables `_ +and imported +`csv-tables `_ +(using the file option), because they are faster to create, easier to maintain +and the 80 column-width rule can be respected with list-tables. + +Converting dokuwiki tables to list-table would be very time consuming, however +there is a pandoc `list-table filter `_, +see :ref:`installing_pandoc` for install instructions. + +You can use the following command: + +.. code:: bash + + pandoc -f dokuwiki -t rst --columns=80 -s -o --list-tables + +The :code:`list-tables` parameter requires *pandoc-types* >= 1.23, if it is not +an option, you shall remove it and export in the *grid* table format. + +Now you only have to adjust the widths and give the final touches, like using +the correct directives and roles. + +Code +-------------------------------------------------------------------------------- + +Prefer +`code-blocks `_ +to +`code `_ +directives, because code-blocks have more options, such as showing line numbers +and emphasizing lines. + +For example, + +.. code:: rst + + .. code-block:: python + :linenos: + :emphasize-lines: 2 + + def hello_world(): + string = "Hello world" + print(string) + +renders as + +.. code-block:: python + :linenos: + :emphasize-lines: 2 + + def hello_world(): + string = "Hello world" + print(string) + + +Images +-------------------------------------------------------------------------------- + +Prefer the :term:`SVG` format for images, and save it as *Optimized SVG* in +`inkscape `_ to use less space. + +Vivado block-diagrams +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Vivado block-diadrams can be exported as PDF and then converted to SVG with +inkscape. See :ref:`spi_engine tutorial` for a "final result" example. + +Vivado waveform data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There is no way to export Vivado waveform data as vectors. +Therefore, the recommended method is to take a PNG screenshot and use +`GIMP `_ to export as **8bpc RGB** with all metadata options +disabled. + +.. note:: + + Always use the *Export As..* ``Ctrl+Shift+E`` option. + +To reduce even further the size, you can use *Color > Dither..* to reduce the +number of colors in the png. +Saving as greyscale also reduces the PNG size, but might reduce readability and +it is not recommended. + +Third-party directives and roles +-------------------------------------------------------------------------------- + +Third-party tools are used to expand Sphinx functionality, for example, to +generate component diagrams. + +.. tip:: + + Check :git-hdl:`docs/Containterfile` for a recipe to install these + tools, either in the host or in a container. + +Symbolator directive +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`Symbolator `_ is a tool to generate +component diagrams. + +Custom directives and roles +-------------------------------------------------------------------------------- + +To expand Sphinx functionality beyond existing tools, custom directives and roles +have been written, which are located in the *docs/extensions* folder. +Extensions are straight forward to create, if some functionality is missing, +consider requesting or creating one. + +Git role +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Git role allows to create links to the Git repository with a shorter syntax. +The role syntax is :code:`:git-:\`:\``, for example, +:code:`:git-hdl:\`master:contributing/guidelines.rst\`` +is rendered as :git-hdl:`master:contributing/guidelines.rst`. +You can leave the branch blank to autofill the link with the current branch. + +You can also do :code:`:git-:\`/\`` for a link to the root of the +repository with pretty naming, for example, :code:`:git-hdl:\`/\`` is rendered +as :git-hdl:`/`. + +Part role +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The part role creates links for a part to the Analog Devices website. + +The role syntax is :code:`:part:\`:\``, for example, +:code:`:part:\`ad7175-2:AD7175-2\``. +Since links are case insensitive, you can also reduce it to +:code:`:part:\`AD7175-2\``, when *part_id* is the same as *part_name*. +It is rendered as :part:`AD7175-2`. + +Datasheet role +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The datasheet role creates links for a datasheet in the Analog Devices website. + +The role syntax is :code:`:datasheet:\`:\``, for example, +:code:`:datasheet:\`AD7984:[{"num"%3A51%2C"gen"%3A0}%2C{"name"%3A"XYZ"}%2C52%2C713%2C0]\`` +is rendered as +:datasheet:`AD7984:[{"num"%3A51%2C"gen"%3A0}%2C{"name"%3A"XYZ"}%2C52%2C713%2C0]`. +The anchor is optional and is a link to a section of the PDF, and can be obtained +by just copying the link in the table of contents. + +.. caution:: + + Since not all PDF readers support anchors, always provide the page and/or + figure number! + +Dokuwiki role +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The dokuwiki role creates links to the Analog Devices wiki website. +The role syntax is :code:`:dokuwiki:\`:\``, for example, +:code:`:dokuwiki:\`pulsar-adc-pmods:resources/eval/user-guides/circuits-from-the-lab/pulsar-adc-pmods\`` +gets rendered as +:dokuwiki:`pulsar-adc-pmods:resources/eval/user-guides/circuits-from-the-lab/pulsar-adc-pmods`. + +EngineerZone role +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ez role creates links to the Analog Devices EngineerZone support website. +The role syntax is :code:`:ez:\`\``, for example, :code:`:ez:\`fpga\`` +gets rendered as :ez:`fpga`. + +Xilinx role +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The xilinx role creates links to the Xilinx website. +The role syntax is :code:`:xilinx:\`:\``, for example, +:code:`:xilinx:\`Zynq-7000 SoC Overview:support/documentation/data_sheets/ds190-Zynq-7000-Overview.pdf\`` +gets rendered +:xilinx:`Zynq-7000 SoC Overview:support/documentation/data_sheets/ds190-Zynq-7000-Overview.pdf`. + +The name parameter is optional, if absent, the file name will be used as the name. + +HDL parameters directive +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The HDL parameters directive parses the *\*_hw.tcl* library files to generate a +table with the IP parameters. + +.. attention:: + + This directive does not support parameters generated in a foreach loop yet + (e.g. :git-hdl:`library/axi_dmac/axi_dmac_hw.tcl#L90`). + Manually create the parameters table in these cases. + +The directive syntax is: + +.. code:: rst + + .. hdl-parameters:: + :path: + + * - + - + +For example: + +.. code:: rst + + .. hdl-parameters:: + :path: library/spi_engine/spi_engine_interconnect + + * - DATA_WIDTH + - Data width of the parallel SDI/SDO data interfaces. + * - NUM_OF_SDI + - Number of SDI lines on the physical SPI interface. + +renders as: + +.. hdl-parameters:: + :path: library/spi_engine/spi_engine_interconnect + + * - DATA_WIDTH + - Data width of the parallel SDI/SDO data interfaces. + * - NUM_OF_SDI + - Number of SDI lines on the physical SPI interface. + +Notice how the *Type* and *Default* values are obtained from the *\*_hw.tcl*. +Parameters not listed in the directive are also added to the table, but +will have an empty description, unless a comment follows the ``ad_ip_parameter`` +method in the source file. + +If you are felling adventurous, the ``:path:`` option is optional, and the +extension will guess the path to the library. + +.. _installing_pandoc: + +Installing pandoc +-------------------------------------------------------------------------------- + +The recommended way to import dokuwiki to reST is to use +`pandoc `_. + +To ensure a up-to date version, considering installing from source: + +.. code:: + + curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh + cabal v2-update + cabal v2-install pandoc-cli + +If custom pandoc haskell filters are needed, also install as a library: + +.. code:: + + cabal v2-install --lib pandoc-types --package-env . + +The tested *pandoc* version is 3.1.5, with *pandoc-types* version 2.13. diff --git a/docs/extensions/adi_hdl_parser.py b/docs/extensions/adi_hdl_parser.py new file mode 100644 index 000000000..78fea1ae3 --- /dev/null +++ b/docs/extensions/adi_hdl_parser.py @@ -0,0 +1,162 @@ +from docutils import nodes +from docutils.statemachine import ViewList +from docutils.parsers.rst import Directive, directives +from sphinx.util.nodes import nested_parse_with_titles +from sphinx.util import logging +import os.path + +logger = logging.getLogger(__name__) + +class node_parameters(nodes.Structural, nodes.Element): + pass + +class directive_parameters(Directive): + required_arguments = 0 + optional_arguments = 0 + final_argument_whitespace = True + option_spec = {'path': directives.unchanged} + has_content = True + add_index = True + current_doc = '' + + def warning(self, msg): + logger.warning(msg + f" Current file: {self.current_doc}") + + + def table_parameters(self, path, content): + description = {} + tag = '' + for line in content: + if line.startswith('* -'): + tag = line[line.find('* -')+3:].split()[0] + description[tag] = [] + else: + description[tag].append(line) + for tag in description: + description[tag] = ' '.join(description[tag]).strip().replace('- ', '', 1) + + table = nodes.table() + + parameters = {} + full_path = path+'/'+path[path.rfind('/')+1:]+'_hw.tcl' + if not os.path.isfile('../'+full_path): + self.warning(f"{full_path} does not exist!") + return table + with open('../'+full_path, 'r') as file: + for line in file: + line = line.strip() + if line.startswith('ad_ip_parameter'): + line_ = line.split(' ', 4) + if len(line_) == 4: + line_.append('') + _, name, type_, default, comment = line_ + comment = comment.replace('#','',1).strip() + if comment != '' and comment[-1] != '.': + comment += '.' + parameters[name] = {'type':type_, 'default':default, 'comment':comment} + + for tag in description: + if tag not in parameters: + self.warning(f"{tag} does not exist in {full_path}!") + elif parameters[tag]['comment'] != '': + description[tag] = ' '.join([parameters[tag]['comment'], description[tag]]) + + tgroup = nodes.tgroup(cols=4) + for _ in range(4): + colspec = nodes.colspec(colwidth=1) + tgroup.append(colspec) + table += tgroup + + thead = nodes.thead() + tgroup += thead + row = nodes.row() + + for header_name in ["Name", "Description", "Type", "Default Value"]: + entry = nodes.entry() + entry += nodes.paragraph(text=header_name) + row += entry + + thead.append(row) + + rows = [] + for key in parameters: + row = nodes.row() + entry = nodes.entry() + entry += nodes.literal(text="{:s}".format(key)) + row += entry + entry = nodes.entry() + if key in description: + rst = ViewList() + rst.append(description[key], "virtual_"+path, 0) + node = nodes.section() + node.document = self.state.document + nested_parse_with_titles(self.state, rst, node) + entry += node + else: + entry += '' + row += entry + for tag in ['type', 'default']: + entry = nodes.entry() + entry += nodes.paragraph(text=parameters[key][tag].title()) + row += entry + + rows.append(row) + + tbody = nodes.tbody() + tbody.extend(rows) + tgroup += tbody + + return table + + def guess_path(self): + path = self.current_doc + for key in ['library', 'projects']: + start_index = path.find(key) + if start_index != -1: + break + + end_index = path.rfind('.') + return path[start_index:end_index] + + def run(self): + env = self.state.document.settings.env + self.current_doc = env.doc2path(env.docname) + + node = node_parameters() + + if 'path' not in self.options: + path = self.guess_path() + if not os.path.isdir('../'+path): + self.warning(f"Guessed path {path}, but it does not exist, set the path option explicitely!") + return [ node ] + else: + path = self.options['path'] + if not os.path.isdir('../'+path): + self.warning(f"Path {path} does not exist!") + return [ node ] + + node_table = nodes.section(ids=["hdl-parameters"]) + + node_table += self.table_parameters(path, self.content) + node += node_table + + return [ node ] + +def visit_node_parameters(self, node): + pass + +def depart_node_parameters(self, node): + pass + +def setup(app): + app.add_directive('hdl-parameters', directive_parameters) + 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)) + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/docs/extensions/adi_links.py b/docs/extensions/adi_links.py new file mode 100644 index 000000000..6485f70be --- /dev/null +++ b/docs/extensions/adi_links.py @@ -0,0 +1,107 @@ +from docutils import nodes +import subprocess + +# Default values +dft_url_datasheet = 'https://www.analog.com/media/en/technical-documentation/data-sheets/' +dft_url_dokuwiki = 'https://wiki.analog.com' +dft_url_ez = 'https://ez.analog.com' +dft_url_git = 'https://github.com/analogdevicesinc' +dft_url_part = 'https://www.analog.com/products' +dft_url_xilinx = 'https://www.xilinx.com' + +def get_url_config(name, inliner): + app = inliner.document.settings.env.app + try: + if not eval("app.config.url_"+name): + raise AttributeError + except AttributeError as err: + raise ValueError(str(err)) + return eval("app.config.url_"+name) + +def datasheet(): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + if text.find(':') in [0, -1]: + url = get_url_config('datasheet', inliner) + '/' + part_id + '.pdf' + else: + anchor = text[text.find(':')+1:] + part_id = text[0:text.find(':')] + url = get_url_config('datasheet', inliner) + '/' + part_id + '.pdf#' + anchor + node = nodes.reference(rawtext, part_id + " datasheet", refuri=url, **options) + return [node], [] + return role + +def dokuwiki(): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + path = text[text.find(':')+1:] + name = path[path.rfind('/')+1:] if text.find(':') in [0, -1] else text[0:text.find(':')] + url = get_url_config('dokuwiki', inliner) + '/' + path + node = nodes.reference(rawtext, name, refuri=url, **options) + return [node], [] + return role + +def ez(): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + url = get_url_config('ez', inliner) + '/' + text + node = nodes.reference(rawtext, "EngineerZone", refuri=url, **options) + return [node], [] + return role + + +def get_active_branch_name(): + branch = subprocess.run(['git', 'branch', '--show-current'], capture_output=True) + return branch.stdout.decode('utf-8').replace('\n','') + +def git(repo, alt_name): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + url = get_url_config('git', inliner) + '/' + repo + if text == '/': + name = "ADI " + alt_name + " repository" + node = nodes.reference(rawtext, name, refuri=url, **options) + else: + branch = get_active_branch_name() if text.find(':') in [0, -1] else text[0:text.find(':')] + path = text[text.find(':')+1:] + url = url + '/blob/' + branch + '/' + path + node = nodes.reference(rawtext, path[path.rfind('/')+1:], refuri=url, **options) + return [node], [] + return role + +def part(): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + part_name = text[text.find(':')+1:] + part_id = part_name if text.find(':') in [0, -1] else text[0:text.find(':')] + url = get_url_config('part', inliner) + '/' + part_id + '.html' + node = nodes.reference(rawtext, part_name, refuri=url, **options) + return [node], [] + return role + +def xilinx(): + def role(name, rawtext, text, lineno, inliner, options={}, content=[]): + name = text[text.rfind('/')+1:] if text.find(':') in [0, -1] else text[0:text.find(':')] + path = text[text.find(':')+1:] + url = get_url_config('xilinx', inliner) + '/' + path + node = nodes.reference(rawtext, name, refuri=url, **options) + return [node], [] + return role + +def setup(app): + app.add_role("datasheet", datasheet()) + app.add_role("dokuwiki", dokuwiki()) + app.add_role("ez", ez()) + app.add_role("git-hdl", git('hdl', "HDL")) + app.add_role("git-testbenches", git('testbenches', "Testbenches")) + app.add_role("git-linux", git('linux', "Linux")) + app.add_role("part", part()) + app.add_role("xilinx", xilinx()) + + app.add_config_value('url_datasheet', dft_url_datasheet, 'env') + app.add_config_value('url_dokuwiki', dft_url_dokuwiki, 'env') + app.add_config_value('url_ez', dft_url_ez, 'env') + app.add_config_value('url_git', dft_url_git, 'env') + app.add_config_value('url_part', dft_url_part, 'env') + app.add_config_value('url_xilinx', dft_url_xilinx, 'env') + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/docs/index.rst b/docs/index.rst new file mode 100755 index 000000000..4cdcfcc47 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,40 @@ +:hide-toc: + +HDL Reference Designs +=============================================================================== + +.. toctree:: + :caption: Libraries + :hidden: + + library/spi_engine/index + library/axi_dmac/index + +.. toctree:: + :caption: Contributing + :hidden: + + contributing/guidelines + +.. toctree:: + :caption: Appendix + :hidden: + + appendix/glossary + appendix/bibliography + +.. attention:: + + Work-in-progress, not all content available at the + `wiki `_ + have been imported yet. + +.. image:: sources/HDL_logo.svg + :align: center + :scale: 100% + +`Analog Devices Inc. `_ +HDL libraries and projects for various reference design and prototyping systems. +This repository contains HDL code (Verilog or VHDL) and the required Tcl scripts +to create and build a specific FPGA example design using Xilinx and/or Intel tool +chain. diff --git a/docs/library/axi_dmac/block_diagram.svg b/docs/library/axi_dmac/block_diagram.svg new file mode 100644 index 000000000..5b024bd05 --- /dev/null +++ b/docs/library/axi_dmac/block_diagram.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Store-and-forwardData Buffer + + + Register Map + S_AXI + s_axi_aclk + irq + + + + Transfer queue + + + + SourceDataInterface + + + + DestinationDataInterface + + + + + + + + + + + + + + + + AXI-MM /AXI-Streaming /FIFO + AXI-MM /AXI-Streaming /FIFO + + + + Transfermanagement + + Control + + Status + + + Transfer request + Transfer request + + Transfer response + + Transfer response + + + src_clk + + dest_clk + + diff --git a/docs/library/axi_dmac/index.rst b/docs/library/axi_dmac/index.rst new file mode 100644 index 000000000..a9e4e3bd3 --- /dev/null +++ b/docs/library/axi_dmac/index.rst @@ -0,0 +1,742 @@ +High-Speed DMA Controller +================================================================================ + +The AXI DMAC is a high-speed, high-throughput, general purpose DMA controller +intended to be used to transfer data between system memory and other peripherals +like high-speed converters. + +Features +-------------------------------------------------------------------------------- + +- Supports multiple interface types + + - AXI3/4 memory mapped + - AXI4 Streaming + - ADI FIFO interface + +- Zero-latency transfer switch-over architecture + + - Allows **continuous** high-speed streaming + +- Cyclic transfers +- 2D transfers + +Utilization +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Device Family + - LUTs + - FFs + * - Intel Arria 10 + - TBD + - TBD + * - Xilinx Artix 7 + - TBD + - TBD + * - Xilinx Kintex 7 + - TBD + - TBD + * - Xilinx Virtex 7 + - TBD + - TBD + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/axi_dmac/axi_dmac.v` + - Verilog source for the peripheral. + +Block Diagram +-------------------------------------------------------------------------------- + +.. image:: block_diagram.svg + :alt: AXI DMAC block diagram + :align: center + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + - Default + * - ``ID`` + - Instance identification number. + - 0 + * - ``DMA_DATA_WIDTH_SRC`` + - Data path width of the source interface in bits. + - 64 + * - ``DMA_DATA_WIDTH_DEST`` + - Data path width of the destination interface in bits. + - 64 + * - ``DMA_LENGTH_WIDTH`` + - Width of transfer length control register in bits. + Limits length of the transfers to 2*\*\ ``DMA_LENGTH_WIDTH``. + - 24 + * - ``DMA_2D_TRANSFER`` + - Enable support for 2D transfers. + - 1 + * - ``ASYNC_CLK_REQ_SRC`` + - Whether the request and source clock domains are asynchronous. + - 1 + * - ``ASYNC_CLK_SRC_DEST`` + - Whether the source and destination clock domains are asynchronous. + - 1 + * - ``ASYNC_CLK_DEST_REQ`` + - Whether the destination and request clock domains are asynchronous. + - 1 + * - ``AXI_SLICE_DEST`` + - Whether to insert a extra register slice on the source data path. + - 0 + * - ``AXI_SLICE_SRC`` + - Whether to insert a extra register slice on the destination data path. + - 0 + * - ``SYNC_TRANSFER_START`` + - Enable the transfer start synchronization feature. + - 0 + * - ``CYCLIC`` + - Enable support for Cyclic transfers. + - 1 + * - ``DMA_AXI_PROTOCOL_SRC`` + - AXI protocol version of the source interface (0 = AXI4, 1 = AXI3). + - 0 + * - ``DMA_AXI_PROTOCOL_DEST`` + - AXI protocol version of the destionation interface (0 = AXI4, 1 = AXI3). + - 0 + * - ``DMA_TYPE_SRC`` + - Interface type for the source interface + (0 = AXI-MM, 1 = AXI-Streaming, 2 = ADI-FIFO). + - 2 + * - ``DMA_TYPE_DEST`` + - Interface type for the destination interface + (0 = AXI-MM, 1 = AXI-Streaming, 2 = ADI-FIFO). + - 0 + * - ``DMA_AXI_ADDR_WIDTH`` + - Maximum address width for AXI interfaces. + - 32 + * - ``MAX_BYTES_PER_BURST`` + - Maximum size of bursts in bytes. Must be power of 2 in a range of 2 + beats to 4096 bytes + The size of the burst is limited by the largest burst that both source + and destination supports. This depends on the selected protocol. + For AXI3 the maximum beats per burst is 16, while for AXI4 is 256. For + non AXI interfaces the maximum beats per burst is in theory unlimited + but it is set to 1024 to provide a reasonable upper threshold. + This limitation is done internally in the core. + - 128 + * - ``FIFO_SIZE`` + - Size of the store-and-forward memory in bursts. Size of a burst is + defined by the ``MAX_BYTES_PER_BURST`` parameter. Must be power of 2 in + the range of 2 to 32. + - 4 + * - ``DISABLE_DEBUG_REGISTERS`` + - Disable debug registers. + - 0 + * - ``ENABLE_DIAGNOSTICS_IF`` + - Add insight into internal operation of the core, for debug purposes + only. + - 0 + +Interface +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Type + - Description + * - ``s_axi_aclk`` + - Clock + - All ``s_axi`` signals and ``irq`` are synchronous to this clock. + * - ``s_axi_aresetn`` + - Synchronous active low reset + - Resets the internal state of the peripheral. + * - ``s_axi`` + - AXI4-Lite bus slave + - Memory mapped AXI-lite bus that provides access to modules register map. + * - ``irq`` + - Level-High Interrupt + - Interrupt output of the module. Is asserted when at least one of the + modules interrupt is pending and enabled. + * - ``m_src_axi_aclk`` + - Clock + - The ``m_src_axi`` interface is synchronous to this clock. + Only present when ``DMA_TYPE_SRC`` parameter is set to AXI-MM (0). + * - ``m_src_axi_aresetn`` + - Synchronous active low reset + - Reset for the ``m_src_axi`` interface. + Only present when ``DMA_TYPE_SRC`` parameter is set to AXI-MM (0). + * - ``m_src_axi`` + - AXI3/AXI4 bus master + - + * - ``m_dest_axi_aclk`` + - Clock + - The ``m_src_axi`` interface is synchronous to this clock. + Only present when ``DMA_TYPE_DEST`` parameter is set to AXI-MM (0). + * - ``m_dest_axi_aresetn`` + - Synchronous active low reset + - Reset for the ``m_dest_axi`` interface. + Only present when ``DMA_TYPE_DEST`` parameter is set to AXI-MM (0). + * - ``m_dest_axi`` + - AXI3/AXI4 bus master + - + * - ``s_axis_aclk`` + - Clock + - The ``s_axis`` interface is synchronous to this clock. + Only present when ``DMA_TYPE_SRC`` parameter is set to AXI-Streaming + (1). + * - ``s_axis`` + - AXI-streaming bus slave + - + Only present when ``DMA_TYPE_SRC`` parameter is set to AXI-Streaming + (1). + * - ``m_axis_aclk`` + - Clock + - The ``m_axis`` interface is synchronous to this clock. + Only present when ``DMA_TYPE_DEST`` parameter is set to AXI-Streaming + (1). + * - ``m_axis`` + - AXI-streaming bus master + - Only present when ``DMA_TYPE_DEST`` parameter is set to AXI-Streaming + (1). + * - ``fifo_wr_clk`` + - Clock + - The ``fifo_wr`` interface is synchronous to this clock. + Only present when ``DMA_TYPE_SRC`` parameter is set to FIFO (2). + * - ``fifo_wr`` + - FIFO write interface + - + Only present when ``DMA_TYPE_SRC`` parameter is set to FIFO (2). + * - ``fifo_rd_clk`` + - Clock + - The ``fifo_rd`` interface is synchronous to this clock. + Only present when ``DMA_TYPE_DEST`` parameter is set to FIFO (2). + * - ``fifo_rd`` + - FIFO read interface + - Only present when ``DMA_TYPE_DEST`` parameter is set to FIFO (2). + * - ``dest_diag_level_bursts`` + - Diagnostics interface + - Only present when ``ENABLE_DIAGNOSTICS_IF`` parameter is set. + +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. + + +Theory of Operation +-------------------------------------------------------------------------------- + +HDL Synthesis Settings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sizing of the internal store-and-forward data buffer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +An internal buffer is used to store data from the source interface before it is +forwarded to the destination once that can accept it. The purpose of the buffer +is to even out the rate mismatches between the source and destination. e.g if +the destination is a FIFO interface with a fixed data rate and the source is a +MM interface, the intent is to keep the buffer as full as possible so in case of +the MM interface is not ready data can be still provided to the destination +without risking an underflow. Similarly in case the destination is a MM +interface and the source a FIFO interface with a fixed data rate, the intent is +to keep the buffer as empty as possible so in case the MM interface is not ready +data can be still accepted from the source without risking an overflow. + +The size of the buffer in bytes is determined by the synthesis parameters of the +module and it is equal to ``FIFO_SIZE`` \* ``MAX_BYTES_PER_BURST`` + +The width of the buffer is sized to be the largest width from the source and +destination interfaces. + +- BUFFER_WIDTH_IN_BYTES = + MAX(``DMA_DATA_WIDTH_SRC``,\ ``DMA_DATA_WIDTH_DEST``)/8 +- BUFFER_DEPTH = ``FIFO_SIZE``\ \*\ ``MAX_BYTES_PER_BURST`` / + BUFFER_WIDTH_IN_BYTES + +Interfaces and Signals +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Register Map Configuration Interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The register map configuration interface can be accessed through the AXI4-Lite +``S_AXI`` interface. The interface is synchronous to the ``s_axi_aclk``. The +``s_axi_aresetn`` signal is used to reset the peripheral and should be asserted +during system startup until the ``s_axi_aclk`` is active and stable. +De-assertion of the reset signal should by synchronous to ``s_axi_aclk``. + +Data Interfaces +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +AXI-Streaming slave +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +The interface back-pressures through the ``s_axis_ready`` signal. If the core is +in the idle state the ``s_axis_ready`` signal will stay low until a descriptor +is submitted. The ``s_axis_ready`` will go low once the internal buffer of the +core is full. It will go high only after enough space is available to store at +least a burst (``MAX_BYTES_PER_BURST`` bytes); Once the current transfer is +finished and a new descriptor was not submitted the ``s_axis_ready`` will go +low. The ``s_axis_ready`` will go low also when the TLAST is used that asserts +unexpectedly. Unexpectedly means that the transfer length defined by TLAST is +shorter than the transfer length programmed in the descriptor (``X_LENGTH`` +register). If the next descriptor was already submitted the ``s_axis_ready`` +will assert within few cycles, in other hand will stay low until a new +descriptor is submitted. + +The ``xfer_req`` is asserted once a transfer is submitted to the descriptor +queue and stays high until all data from the current transfer is received/send +through the AXI Stream/FIFO interface. If during the current transfer another +descriptor is queued (submitted) it will stay high and so on. + +Configuration Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The peripheral features a register map configuration interface that can be +accessed through the AXI4-Lite ``S_AXI`` port. The register map can be used to +configure the peripherals operational parameters, query the current status of +the device and query the features supported by the device. + +Peripheral Identification +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The peripheral contains multiple registers that allow the identification of the +peripheral as well as discovery of features that were configured at HDL +synthesis time. Apart from the ``SCRATCH`` register all registers in this +section are read only and writes to them will be ignored. + +The ``VERSION`` (``0x000``) register contains the version of the peripheral. The +version determines the register map layout and general features supported by the +peripheral. The version number follows `semantic versioning `_. +Increments in the major number indicate backwards incompatible changes, increments +in the minor number indicate backwards compatible changes, patch letter increments +indicate fixed incorrect behavior. + +The ``PERIPHERAL_ID`` (``0x004``) register contains the value of the ``ID`` HDL +configuration parameter that was set during synthesis. Its primary function is +to allow to distinguish between multiple instances of the peripheral in the same +design. + +The ``SCRATCH`` (``0x008``) register is a general purpose 32-bit register that +can be set to an arbitrary values. Reading the register will yield the value +previously written (The value will be cleared when the peripheral is reset). +It's content does not affect the operation of the peripheral. It can be used by +software to test whether the register map is accessible or store custom +peripheral associated data. + +The ``IDENTIFICATION`` (``0x00c``) register contains the value of ``"DMAC"``. +This value is unique to this type of peripheral and can be used to ensure that +the peripheral exists at the expected location in the memory mapped IO register +space. + +Interrupt Handling +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Interrupt processing is handled by three closely related registers. All three +registers follow the same layout, each bit in the register corresponds to one +particular interrupt. + +When an interrupt event occurs it is recorded in the ``IRQ_SOURCE`` (``0x088``) +register. For a recorded interrupt event the corresponding bit is set to 1. If +an interrupt event occurs while the bit is already set to 1 it will stay set to +1. + +The ``IRQ_MASK`` (``0x080``) register controls how recorded interrupt events +propagate. An interrupt is considered to be enabled if the corresponding bit in +the ``IRQ_MASK`` register is set to 0, it is considered to be disabled if the +bit is set to 1. + +Disabling an interrupt will not prevent it from being recorded, but only its +propagation. This means if an interrupt event was previously recorded while the +interrupt was disabled and the interrupt is being enabled the interrupt event +will then propagate. + +An interrupt event that has been recorded and is enabled propagates to the +``IRQ_PENDING`` (``0x084``) register. The corresponding bit for such an +interrupt will read as 1. Disabled or interrupts for which no events have been +recorded will read as 0. Also if at least one interrupt has been recorded and is +enabled the external ``irq`` signal will be asserted to signal the IRQ event to +the upstream IRQ controller. + +A recorded interrupt event can be cleared (or acknowledged) by writing a 1 to +the corresponding bit to either the ``IRQ_SOURCE`` or ``IRQ_PENDING`` register. +It is possible to clear multiple interrupt events at the same time by setting +multiple bits in a single write operation. + +For more details regarding interrupt operation see the :ref:`axi_dmac interrupts`. + +Transfer Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``DEST_ADDRESS`` (``0x410``) register contains the destination address of +the transfer. The address must be aligned to the destination bus width. +Non-aligned addresses will be automatically aligned internally by setting the +LSBs to 0. This register is only valid if the DMA channel has been configured +for write to memory support. + +The ``SRC_ADDRESS`` (``0x414``) register contains the source address of the +transfer. The address must be aligned to the source bus width. Non-aligned +addresses will be automatically aligned internally by setting the LSBs to 0. +This register is only valid if the DMA channel has been configured for write +from memory support. + +The ``X_LENGTH`` (``0x418``) register contains the number of bytes to transfer +per row. The number of bytes is equal to the value of the register + 1 (E.g. a +value of 0x3ff means 0x400 bytes). + +The ``Y_LENGTH`` (``0x41C``) register contains the number of rows to transfer. +The number of rows is equal to the value of the register + 1 (E.g. a value of +1079 means 1080 rows). This register is only valid if the DMA channel has been +configured with 2D transfer support. If 2D transfer support is disabled the +number of rows is always 1 per transfer. + +The ``SRC_STRIDE`` (``0x424``) and ``DEST_STRIDE`` (``0x420``) registers contain +the number of bytes between the start of one row and the next row. Needs to be +aligned to the bus width. This field is only valid if the DMA channel has been +configured with 2D transfer support. + +The total number of bytes transferred is equal to (``X_LENGTH`` + ``1``) \* +(``Y_LENGTH`` + ``1``). + +The ``FLAGS`` (``0x40C``) register controls the behavior of the transfer. + +- If the ``CYCLIC`` (``[0]``) bit is set the transfer will run in + :ref:`axi_dmac cyclic-transfers`. +- If the ``TLAST`` (``[1]``) bit is set the TLAST signal will be asserted + during the last beat of the AXI Stream transfer. + +Transfer Submission +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Writing a 1 to the ``TRANSFER_SUBMIT`` (``0x408``) register queues a new +transfer. If the internal transfer queue is full the ``TRANSFER_SUBMIT`` bit +will stay asserted until room becomes available, the bit transitions back to 0 +once the transfer has been queued. Writing a 0 to this register has no effect. +Writing a 1 to the register while it is already 1 will also have no effect. When +submitting a new transfer software should always check that the +``TRANSFER_SUBMIT`` [0] bit is 0 before setting it, otherwise the transfer will +not be queued. + +If the DMA channel is disabled (``ENABLE`` control bit is set to 0) while a +queuing operation is in progress it will be aborted and the ``TRANSFER_SUBMIT`` +bit will de-assert. + +The ``TRANSFER_ID`` (``0x404``) register contains the ID of the next transfer. +The ID is generated by the DMA controller and can be used to check if a transfer +has been completed by checking the corresponding bit in the ``TRANSFER_DONE`` +(``0x428``) register. The contents of this register is only valid if +``TRANSFER_SUBMIT`` is 0. Software should read this register before asserting +the ``TRANSFER_SUBMIT`` bit. + +Transfer Status +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``TRANSFER_DONE`` (``0x428``) register indicates whether a submitted +transfer has been completed. Each bit in the register corresponds to transfer +ID. When a new transfer is submitted the corresponding bit in the register is +cleared, once the the transfer has been completed the corresponding bit will be +set. + +The ``ACTIVE_TRANSFER_ID`` (``0x42C``) register holds the ID of the currently +active transfer. When no transfer is active the value of register will be equal +to the value of the ``TRANSFER_ID`` (``0x404``) register. + +Transfer length reporting +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When using MM or FIFO source interfaces the amount of data which the core will +transfer is defined by ``X_LENGTH`` and ``Y_LENGTH`` registers in the moment of +the transfer submission. Once the corresponding bit from the ``TRANSFER_DONE`` +is set the programmed amount of data is transferred. + +When using streaming interface (AXIS) as source, the length of transfers will be +defined by the assertion of ``TLAST`` signal which is unknown at the moment of +transfer submission. In this case ``X_LENGTH`` and ``Y_LENGTH`` specified during +the transfer submission will act as upper limits for the transfer. Transfers +where the TLAST occurs ahead of programmed length will be noted as partial +transfers. If ``PARTIAL_REPORTING_EN`` bit from the ``FLAGS`` register is set, +the length of partial transfers will be recorded and exposed through the +``PARTIAL_TRANSFER_LENGTH`` and ``PARTIAL_TRANSFER_ID`` registers. The +availability of information regarding partial transfers is done through the +``PARTIAL_TRANSFER_DONE`` field of ``TRANSFER_DONE`` register. + +During operation the ``TRANSFER_PROGRESS`` register can be consulted to check +the progress of the current transfer. The register presents the number of bytes +the destination accepted during the in progress transfer. This register will be +cleared once the transfer completes. This register should be used for debugging +purposes only. + +Transfer Tear-down +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Non-cyclic transfers stop once the programmed amount of data is transferred to +the destination. Cyclic transfers needs to be stopped with software intervention +by setting the ``ENABLE`` control bit to 0. In case if required, non cyclic +transfers can be interrupted in the same way. The transfer tear down is done +gracefully and is done at a burst resolution on MM interfaces and beat +resolution on non-MM interfaces. DMAC shuts down gracefully as fast as possible +while completing all in-progress MM transactions. + +Source side: For MM interface once the ``ENABLE`` bit de-asserts the DMAC won't +issue new requests towards the source interface but will wait until all pending +requests are fulfilled by the source. For non-MM interfaces, once the ``ENABLE`` +bit de-asserts the DMAC will stop to accept new data. This will lead to partial +bursts in the internal buffer but this data will be cleared/lost once the +destination side completes all pending bursts. + +Destination side: For MM interface the DMAC will complete all pending requests +that have been started by issuing the address. For non-MM interfaces once the +``ENABLE`` bit de-asserts the DMAC will stop to drive new data. All the data +from the internal buffer will be cleared/lost. In case of AXIS the DMAC will +wait for data to be accepted if valid is high since it can't just de-assert +valid without breaking the interface semantics + +.. _axi_dmac interrupts: + +Interrupts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The DMA controller supports interrupts to allow asynchronous notification of +certain events to the CPU. This can be used as an alternative to busy-polling +the status registers. Two types of interrupt events are implemented by the DMA +controller. + +The ``TRANSFER_QUEUED`` interrupt is asserted when a transfer is moved from the +register map to the internal transfer queue. This is equivalent to the +``TRANSFER_SUBMIT`` register transitioning from 1 to 0. Software can use this +interrupt as an indication that the next transfer can be submitted. + +Note that a transfer being queued does not mean that it has been started yet. If +other transfers are already queued those will be processed first. + +The ``TRANSFER_COMPLETED`` interrupt is asserted when a previously submitted +transfer has been completed. To find out which transfer has been completed the +``TRANSFER_DONE`` register should be checked. + +Note that depending on the transfer size and interrupt latency it is possible +for multiple transfers to complete before the interrupt handler runs. In that +case the interrupt handler will only run once. Software should always check all +submitted transfers for completion. + +2D Transfers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the ``DMA_2D_TRANSFER`` HDL synthesis configuration parameter is set the DMA +controller has support for 2D transfers. + +A 2D transfer is composed of a number of rows with each row containing a certain +number of bytes. Between each row there might be a certain amount of padding +bytes that are skipped by the DMA. + +For 2D transfers the ``X_LENGTH`` register configures the number of bytes per +row and the ``Y_LENGTH`` register configures the number of rows. The +``SRC_STRIDE`` and ``DEST_STRIDE`` registers configure the number of bytes in +between start of two rows. + +E.g. the first row will start at the configured source or destination address, +the second row will start at the configured source or destination address plus +the stride and so on. + +.. math:: + + ROW\_SRC\_ADDRESS = SRC\_ADDRESS + SRC\_STRIDE * N + +.. math:: + + ROW\_DEST\_ADDRESS = DEST\_ADDRESS + DEST\_STRIDE * N + +If support for 2D transfers is disabled only the X_LENGTH register is +considered and the number of rows per transfer is fixed to 1. + +.. _axi_dmac cyclic-transfers: + +Cyclic Transfers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the ``CYCLIC`` HDL synthesis configuration parameter is set the DMA +controller has support for cyclic transfers. + +A cyclic transfer once completed will restart automatically with the same +configuration. The behavior of cyclic transfer is equivalent to submitting the +same transfer over and over again, but generates less software management +overhead. + +A transfer is cyclic if the ``CYCLIC`` (``[0]``) bit of the ``FLAGS`` +(``0x40C``) is set to 1 during transfer submission. + +For cyclic transfers no end-of-transfer interrupts will be generated. To stop a +cyclic transfer the DMA channel must be disabled. + +Any additional transfers that are submitted after the submission of a cyclic +transfer (and before stopping the cyclic transfer) will never be executed. + +Transfer Start Synchronization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the transfer start synchronization feature of the DMA controller is enabled +the start of a transfer is synchronized to a flag in the data stream. This is +primarily useful if the data stream does not have any back-pressure and one unit +of data spans multiple beats (e.g. packetized data). This ensures that the data +is properly aligned to the beginning of the memory buffer. + +Data that is received before the synchronization flag is asserted will be +ignored by the DMA controller. + +For the FIFO write interface the ``fifo_wr_sync`` signal is the synchronization +flag signal. For the AXI-Streaming interface the synchronization flag is carried +in ``s_axis_user[0]``. In both cases the synchronization flag is qualified by +the same control signal as the data. + +Diagnostics interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For debug purposes a diagnostics interface is added to the core. +The ``dest_diag_level_bursts`` signal adds insight into the fullness of the +internal memory buffer during operation. The information is exposed in number +of bursts where the size of a burst is defined by the ``MAX_BYTES_PER_BURST`` +parameter. The value of ``dest_diag_level_bursts`` increments for each burst +accumulated in the DMACs internal buffer. It decrements once the burst leaves +the DMAC on its destination port. The signal is synchronous to the destination +clock domain (``m_dest_axi_aclk`` or ``m_axis_aclk`` depending on ``DMA_TYPE_DEST``). + +Limitations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +AXI 4kByte Address Boundary +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Software must program the ``SRC_ADDRESS`` and ``DEST_ADDRESS`` registers in such +way that AXI burst won't cross the 4kB address boundary. The following condition +must hold: + +* ``MAX_BYTES_PER_BURST`` ≤ 4096; +* ``MAX_BYTES_PER_BURST`` is power of 2; +* ``​SRC/​DEST_ADDRESS`` ​mod ``​MAX_BYTES_PER_BURST`` ​== 0 +* ``SRC/DEST_ADDRESS[11:0]`` + MIN(``X_LENGTH``\ +1,\ ``MAX_BYTES_PER_BURST``) ≤ 4096 + +Address Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Software must program the ``SRC_ADDRESS`` and ``DEST_ADDRESS``\ registers to be +multiple of the corresponding MM data bus. The following conditions must hold: + +* ``SRC_ADDRESS`` MOD (``DMA_DATA_WIDTH_SRC``/8) == 0 +* ``DEST_ADDRESS`` MOD (``DMA_DATA_WIDTH_DEST``/8) == 0 + +Transfer Length Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Software must program the ``X_LENGTH`` register to be multiple of the widest +data bus. The following condition must hold: + +- (``X_LENGTH``\ +1) MOD MAX(``DMA_DATA_WIDTH_SRC``, ``DMA_DATA_WIDTH_DEST``)/8 + == 0 + +This restriction can be relaxed for the memory mapped interfaces. This is done +by partially ignoring data of a beat from/to the MM interface: + +- For write access the strobe bits are used to mask out bytes that do not + contain valid data. +- For read access a full beat is read but part of the data is discarded. This + works fine as long as the read access is side effect free. I.e. this method + should not be used to access data from memory mapped peripherals like a FIFO. + +E.g. the length alignment requirement of a DMA configured for a 64-bit memory +mapped interface and a 16-bit streaming interface is only 2 bytes instead of 8 +bytes. + +Note that the address alignment requirement is not affected by this. The address +still needs to be aligned to the width of the MM interface that it belongs to. + +Software Support +-------------------------------------------------------------------------------- + +Analog Devices recommends to use the provided software drivers. + +- :dokuwiki:`Analog Device AXI-DMAC DMA Controller Linux Driver: + resources/tools-software/linux-drivers/axi-dmac` + +Known Issues +-------------------------------------------------------------------------------- + +1. When max bytes per burst matches the data width of destination interface an +erroneous extra beat is inserted after every valid beat on the destination side. +Example configuration: + +* axi mm -> axi stream +* max bytes per burst = 128 +* destination width = 1024 bits + +Workaround: increase the max bytes per burst to larger than 128 + +Technical Support +-------------------------------------------------------------------------------- + +Analog Devices will provide limited online support for anyone using the core +with Analog Devices components (ADC, DAC, Video, Audio, etc) via the :ez:`fpga`. + +Glossary +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Term + - Description + * - beat + - Represents the amount of data that is transferred in one clock cycle. + * - burst + - Represents the amount of data that is transferred in a group of + consecutive beats. + * - partial transfer + - Represents a transfer which is shorter than the programmed length that + is based on the X_LENGTH and Y_LENGTH registers. This can occur on AXIS + source interfaces when TLAST asserts earlier than the programmed + length. diff --git a/docs/library/axi_dmac/regmap.csv b/docs/library/axi_dmac/regmap.csv new file mode 100644 index 000000000..392cab7a0 --- /dev/null +++ b/docs/library/axi_dmac/regmap.csv @@ -0,0 +1,82 @@ +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 diff --git a/docs/library/common/regmap_adc_channel.csv b/docs/library/common/regmap_adc_channel.csv new file mode 100644 index 000000000..466789606 --- /dev/null +++ b/docs/library/common/regmap_adc_channel.csv @@ -0,0 +1,53 @@ +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 diff --git a/docs/library/common/regmap_adc_common.csv b/docs/library/common/regmap_adc_common.csv new file mode 100644 index 000000000..7043ab433 --- /dev/null +++ b/docs/library/common/regmap_adc_common.csv @@ -0,0 +1,78 @@ +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 diff --git a/docs/library/common/regmap_base.csv b/docs/library/common/regmap_base.csv new file mode 100644 index 000000000..c10ca10ae --- /dev/null +++ b/docs/library/common/regmap_base.csv @@ -0,0 +1,29 @@ +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 diff --git a/docs/library/spi_engine/axi_spi_engine.rst b/docs/library/spi_engine/axi_spi_engine.rst new file mode 100644 index 000000000..e558d890e --- /dev/null +++ b/docs/library/spi_engine/axi_spi_engine.rst @@ -0,0 +1,236 @@ +.. _spi_engine axi: + +AXI SPI Engine Module +================================================================================ + +.. symbolator:: ../../../library/spi_engine/axi_spi_engine/axi_spi_engine.v + :caption: axi_spi_engine + +The AXI SPI Engine peripheral allows asynchronous interrupt-driven memory-mapped +access to a SPI Engine Control Interface. +This is typically used in combination with a software program to dynamically +generate SPI transactions. + +The peripheral has also support for providing memory-mapped access to one or more +:ref:`spi_engine offload` cores and change its content dynamically at runtime. + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/axi_spi_engine/axi_spi_engine.v` + - Verilog source for the peripheral. + * - :git-hdl:`master:library/spi_engine/axi_spi_engine/axi_spi_engine_ip.tcl` + - TCL script to generate the Vivado IP-integrator project for the peripheral. + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. hdl-parameters:: + :path: library/spi_engine/axi_spi_engine + + * - ASYNC_SPI_CLK + - If set to 1 the ``s_axi_aclk`` and ``spi_clk`` clocks are assumed + to be asynchronous. + * - CMD_FIFO_ADDRESS_WIDTH + - Configures the size of the command FIFO. + * - SDO_FIFO_ADDRESS_WIDTH + - Configures the size of the serial-data out FIFO. + * - SDI_FIFO_ADDRESS_WIDTH + - Configures the size of the serial-data in FIFO. + * - NUM_OFFLOAD + - The number of offload control interfaces. + +Signal and Interface Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 25 65 + :header-rows: 1 + + * - Name + - Type + - Description + * - ``s_axi_aclk`` + - Clock + - All ``s_axi`` signals and ``irq`` are synchronous to this clock. + * - ``s_axi_aresetn`` + - Synchronous active-low reset + - Resets the internal state of the peripheral. + * - ``s_axi`` + - AXI-Lite bus slave + - Memory-mapped AXI-lite bus that provides access to modules register map. + * - ``irq`` + - Level-High Interrupt + - Interrupt output of the module. Is asserted when at least one of the + modules interrupt is pending and unmasked. + * - ``spi_clk`` + - Clock + - All ``spi_engine_ctrl`` signals and ``spi_resetn`` are + synchronous to this clock. + * - ``spi_engine_ctrl`` + - :ref:`spi_engine control-interface` slave + - SPI Engine Control stream that contains commands and data for the + execution module. + * - ``spi_resetn`` + - Output + - This signal is asserted when the module is disabled through the ENABLE + register. Typically used as the reset for the SPI Engine modules + connected to these modules. + +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. + +Theory of Operation +-------------------------------------------------------------------------------- + +Typically a software application running on a CPU will be able to execute much +faster than the SPI engine command will be processed. +In order to allow the software to execute other tasks while the SPI engine is +busy processing commands the AXI SPI Engine peripheral offers interrupt-driven +notification which can be used to notify the software when a SPI command has +been executed. +In order to reduce the necessary context switches the AXI SPI Engine peripheral +incorporates FIFOs to buffer the command as well as the data streams. + +FIFOs +-------------------------------------------------------------------------------- + +The AXI SPI Engine peripheral has three FIFOs, one for each of the command, SDO +and SDI streams. +The size of the FIFOs can be configured by setting the CMD_FIFO_ADDRESS_WIDTH, +SDO_FIFO_ADDRESS_WIDTH and SDI_FIFO_ADDRESS_WIDTH parameters. + +One end of the FIFOs are connected to a memory-mapped register and can be +accessed via the AXI-Lite interface. +The other end is directly connected to the matching stream of the +:ref:`spi_engine control-interface`. + +Data can be inserted into the command FIFO by writing to the CMD_FIFO register +and new data can be inserted into the SDO_FIFO register. +If an application attempts to write to a FIFO while the FIFO is already full the +data is discarded and the state of the FIFO remains unmodified. +The number of empty entries in the command and SDO FIFO can be queried by +reading the CMD_FIFO_ROOM or SDO_FIFO_ROOM register. + +Data can be removed from the SDI FIFO by reading from the SDI_FIFO register. +If an application attempts to read data while the FIFO is empty undefined data +is returned and the state of the FIFO remains unmodified. +It is possible to read the first entry in the SDI FIFO without removing it by +reading from the SDI_FIFO_PEEK register. +The number of valid entries in the SDI FIFO register can be queried by reading +the SDI_FIFO_LEVEL register. + +If the peripheral is disabled by setting the ENABLE register to 0 any data +stored in the FIFOs is discarded and the state of the FIFO is reset. + +Synchronization Events +-------------------------------------------------------------------------------- + +Synchronization events can be used to notify the software application about the +progress of the command stream. +An application can insert a SYNC instruction at any point in the command stream. +If the execution module reaches the SYNC instruction it will generate an event +on the SYNC stream. +When this event is received by the AXI SPI Engine peripheral it will update the +SYNC_ID register with the received event ID and will assert the SYNC_EVENT +interrupt. + +Typically the SYNC instruction should be inserted after the last instruction in +a SPI transaction. +This will allow the application to be notified about the completion of the +transaction and allows it to do further processing based on the result of the +transaction. + +It is recommended that synchronization IDs are generated in a monotonic +incrementing or decrementing manner. +This makes it possible to easily check if an event has completed by checking if +it is less or equal (incrementing IDs) or more or equal (decrementing IDs) to +the ID of the last completed event. + +Interrupts +-------------------------------------------------------------------------------- + +The SPI Engine AXI peripheral has 4 internal interrupts. One for each of the +FIFOs which are asserted when the FIFO level falls bellow the almost empty level +(for the command or SDO FIFO) or rises above the almost full level (for the SDI +FIFO). +And one interrupt which is asserted when a new synchronization event arrives. +The peripheral has 1 external interrupt which is supposed to be connected to the +upstream interrupt controller. +The external interrupt is a logical OR-operation over the internal interrupts, +meaning if at least one of the internal interrupts is asserted the external +interrupt is asserted and only if all internal interrupts are de-asserted the +external interrupt is de-asserted. In addition, each interrupt has a mask bit +which can be used to stop the propagation of the internal interrupt to the +external interrupt. If an interrupt is masked it will count towards the external +interrupt state as if it were not asserted. +The mask bits can be modified by writing to the IRQ_MASK register. +The raw interrupt status can be read from the IRQ_SOURCE register and the +combined state of the IRQ_MASK and raw interrupt state can be read from the +IRQ_PENDING register. + +.. code:: + + IRQ_PENDING = IRQ_SOURCE & IRQ_MASK; + IRQ = |IRQ_PENDING; + +FIFO Threshold Interrupts +-------------------------------------------------------------------------------- + +The FIFO threshold interrupts can be used by software for flow control of the +command, SDI and SDO streams. +If an application wants to send more data than what fits into the FIFO can write +samples into the FIFO until it is full then suspend operation wait for the almost +empty interrupt and continue writing data to the FIFO. +Similarly, when the application wants to read more data than what fits into FIFO +it should listen for the almost full interrupt and read data from the FIFO when +it occurs. + +The FIFO threshold interrupt is asserted when then FIFO level rises above the +watermark and is automatically de-asserted when the level drops below the +watermark. + +SYNC_EVENT Interrupt +-------------------------------------------------------------------------------- + +The SYNC_EVENT interrupt is asserted when a new sync event is received from the +sync stream. +An application that generated a SYNC instruction on the command stream can use +this interrupt to be notified when the sync instruction has been completed. +To de-assert, the SYNC_EVENT interrupt the reception of the interrupt needs to +be acknowledged by the application by writing a 1 to the SYNC_EVENT bit in the +IRQ_PENDING register. diff --git a/docs/library/spi_engine/control-interface.rst b/docs/library/spi_engine/control-interface.rst new file mode 100644 index 000000000..925add1d1 --- /dev/null +++ b/docs/library/spi_engine/control-interface.rst @@ -0,0 +1,94 @@ +.. _spi_engine control-interface: + +SPI Engine Control Interface +================================================================================ + +The SPI Engine Control Interface is used to exchange data between different +cores within the SPI Engine framework. It is used to exchange the commands and +synchronization points as well as the SPI bus transmit and receive data. + +The interface consists of four streams: + +* The CMD stream which carries the SPI Engine commands. (Master to Slave) +* The SDO stream which carries the to be transmitted data for the SPI bus. + (Master to Slave) +* The SDI stream which carries the received data from the SPI bus. (Slave to + Master) +* The SYNC stream which carries the synchronization events. (Slave to Master) + +Each of the streams has a valid, ready and data signal. They follow the +handshaking protocol as defined by the AXI standard. Meaning the master asserts +valid when the data on the data signal is valid and the slave asserts ready when +it is able to accept new data. If both valid and ready are asserted at the same +time the data has been transmitted from the master to the slave. + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/interfaces/spi_engine_ctrl_rtl.xml` + - Interface definition file + +Signal Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 10 10 70 + :header-rows: 1 + + * - Width + - Name + - Direction (Master) + - Description + * - + - ``cmd_ready`` + - Input + - Ready signal of the CMD stream + * - + - ``cmd_valid`` + - Output + - Valid signal of the CMD stream + * - [15:0] + - ``cmd_data`` + - Output + - Data signal of the CMD stream + * - + - ``sdo_ready`` + - Input + - Ready signal of the SDO stream + * - + - ``sdo_valid`` + - Output + - Valid signal of the SDO stream + * - [DATA_WIDTH-1:0] + - ``sdo_data`` + - Output + - Data signal of the SDO stream + * - + - ``sdi_ready`` + - Output + - Ready signal of the SDI stream + * - + - ``sdi_valid`` + - Input + - Valid signal of the SDI stream + * - [(NUM_OF_SDI*DATA_WIDTH-1):0] + - ``sdi_data`` + - Input + - Data signal of the SDI stream + * - + - ``sync_ready`` + - Output + - Ready signal of the SYNC stream + * - + - ``sync_valid`` + - Input + - Valid signal of the SYNC stream + * - [7:0] + - ``sync_data`` + - Input + - Data signal of the sync stream diff --git a/docs/library/spi_engine/index.rst b/docs/library/spi_engine/index.rst new file mode 100644 index 000000000..2d9a89b39 --- /dev/null +++ b/docs/library/spi_engine/index.rst @@ -0,0 +1,96 @@ +.. _spi_engine: + +SPI Engine +================================================================================ + +.. toctree:: + :hidden: + + Execution Module + AXI Module + Offload Module + Interconnect Module + Control Interface + Offload Control Interface + SPI Bus Interface + Instruction Set Specification + Tutorial - PulSAR ADC + +SPI Engine is a highly flexible and powerful SPI controller framework. +It consist out of multiple sub-modules which communicate over well defined +interfaces. +This allows a high degree of flexibility and re-usability while at the same time +staying highly customizable and easily extensible. + +The core component of the SPI Engine framework is a lean but powerful fully +programmable execution module, which implements the SPI bus control logic. +The SPI Engine execution module is controlled by a command stream which is +generated by a separate module. Different command stream master modules are +available and can be used depending on the system requirements. +For example a software controlled memory mapped command stream offers high +flexibility, while a offload core which executes a pre-programmed command stream +when triggered by an external event allows for very low latency response times. +By using a SPI Engine interconnect it is possible to connect multiple command +stream master modules to a SPI Engine execution module. + +Sub-modules +-------------------------------------------------------------------------------- + +* :ref:`spi_engine execution`: Main module which processes a SPI engine command + stream and implements the SPI bus interface logic. +* :ref:`spi_engine axi`: Memory mapped software accessible interface to a + SPI Engine command stream and/or offload cores. +* :ref:`spi_engine offload`: Stores a SPI Engine command stream, execution is + triggered by an external event. +* :ref:`spi_engine interconnect`: Connects multiple SPI Engine command streams + to a SPI Engine execution module. + +Interfaces +-------------------------------------------------------------------------------- + +* :ref:`spi_engine control-interface`: SPI Engine command stream. +* :ref:`spi_engine offload-control-interface`: Program the command stream stored + in a offload module. +* :ref:`spi_engine spi-bus-interface`: Low-level SPI bus interface. + +Software +-------------------------------------------------------------------------------- + +* :dokuwiki:`Linux Driver:resources/tools-software/linux-drivers/spi/spi_engine`: + Linux driver for the SPI Engine framework. +* :ref:`spi_engine instruction-format`: Overview of the SPI Engine Instruction + format. + +Related IP Cores +-------------------------------------------------------------------------------- + +This list contains cores that are not part of the core SPI engine framework but +make use of its interfaces and are intend to be used together with the SPI engine +framework. + +* :dokuwiki:`util-sigma-delta-spi:resources/fpga/peripherals/util_sigma_delta_spi`: + Helper module for interfacing ADCs from the Analog Devices Sigma-Delta family. + +Examples +-------------------------------------------------------------------------------- + +* :dokuwiki:`CN0363:resources/eval/user-guides/eval-cn0363-pmdz`: + Colorimeter application using the :part:`AD7175-2` Sigma-Delta ADC. +* :dokuwiki:`resources/eval/user-guides/adaq7980-sdz`: + A 16-bit ADC subsystem with four common signal processing and conditioning blocks. +* :dokuwiki:`resources/tools-software/uc-drivers/ad5766`: + 16-channel, 16-/12-bit, voltage output Digital-to-Analog Converters (DAC). +* :dokuwiki:`CN0363:resources/eval/user-guides/eval-cn0363-pmdz`: + The AD7768-1 is a low power, high performance, Σ-Δ analog-to-digital converter (ADC). +* :git-hdl:`master:projects/ad40xx_fmc` + Evaluation Board for the AD4000 Series 16-/18-/20-Bit Precision SAR ADCs. +* :dokuwiki:`AD469x:resources/eval/user-guides/ad469x`: + 16-Bit, 16-Channel, 500 kSPS/1 MSPS, Easy Drive Multiplexed SAR ADC. +* :dokuwiki:`AD4630-24 / AD4030-24 / AD4630-16:resources/eval/user-guides/ad463x/hdl`: + 16/24-Bit, 2 MSPS Single or Dual Channel SAR ADC. + +Additional Resources +-------------------------------------------------------------------------------- + +* :download:`Presentation: SPI Engine Design Philosophy `. +* :ref:`spi_engine tutorial`. diff --git a/docs/library/spi_engine/instruction-format.rst b/docs/library/spi_engine/instruction-format.rst new file mode 100644 index 000000000..22bd56d10 --- /dev/null +++ b/docs/library/spi_engine/instruction-format.rst @@ -0,0 +1,252 @@ +.. _spi_engine instruction-format: + +SPI Engine Instruction Set Specification +================================================================================ + +The SPI Engine instruction set is a simple 16-bit instruction set of which +12-bit is currently allocated (bits 15,14,11,10 are always 0). + +Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Transfer Instruction +-------------------------------------------------------------------------------- + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 0 0 0 0 r w n n n n n n n n +== == == == == == = = = = = = = = = = + +The transfer instructions perform a low-level SPI transfer. It will generate +SCLK transitions for the specified amount of cycles according to the SPI +configuration register. If the r bit is set the SDI pin will be sampled and +stored in the shift register at the end of each word the data is output on the +SDI_DATA stream. If the w bit is set the SDO pin will be updated with the data +received from the SDO_DATA stream. If the w bit is set the sdo_t signal will +also be set to 0 for the duration of the transfer. If the SDI_DATA stream is not +able to accept data or the SDO_DATA stream is not able to provide data the +execution is stalled at the end/start of the transfer until data is +accepted/becomes available. + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - r + - Read + - If set to 1 data will be read from the SDI pin during and the read words + will be available on the SDI_DATA interface. + * - w + - Write + - If set to 1 data will be taken from the SDO_DATA interface and output on + the SDO pin. + * - n + - Length + - n + 1 number of words that will be transferred. + +Chip-select Instruction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 0 1 0 0 t t s s s s s s s s +== == == == == == = = = = = = = = = = + +The chip-select instruction updates the value chip-select output signal of the +SPI Engine execution module. + +Before and after the update is performed the execution module is paused for the +specified delay. The length of the delay depends on the module clock frequency, +the setting of the prescaler register and the t parameter of the instruction. +This delay is inserted before and after the update of the chip-select signal, +so the total execution time of the chip-select +instruction is twice the delay. + +.. math:: + + delay = t * \frac{div + 1}{f_{clk}} + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - t + - Delay + - Delay before and after setting the new configuration. + * - s + - Chip-select + - The new chip-select configuration. + +Configuration Write Instruction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 1 0 0 0 r r v v v v v v v v +== == == == == == = = = = = = = = = = + +The configuration writes instruction updates a +:ref:`spi_engine configutarion-registers` +of the SPI Engine execution module with a new value. + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - r + - Register + - Configuration register address. + 2'b00 = :ref:`spi_engine prescaler-configuration-register` + 2'b01 = :ref:`spi_engine spi-configuration-register` + 2'b10 = :ref:`spi_engine dynamic-transfer-length-register`. + * - v + - Value + - New value for the configuration register. + +Synchronize Instruction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 1 1 0 0 0 0 n n n n n n n n +== == == == == == = = = = = = = = = = + +The synchronize instruction generates a synchronization event on the SYNC output +stream. This can be used to monitor the progress of the command stream. The +synchronize instruction is also used by the :ref:`spi_engine interconnect` +module to identify the end of a transaction and re-start the arbitration process. + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - n + - id + - Value of the generated synchronization event. + +Sleep Instruction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 1 1 0 0 0 1 t t t t t t t t +== == == == == == = = = = = = = = = = + +The sleep instruction stops the execution of the command stream for the +specified amount of time. The time is based on the external clock frequency the +configuration value of the prescaler register and the time parameter of the +instruction. + +.. math:: + + sleep\_time = \frac{(t + 1) * ((div + 1) * 2)}{f_{clk}} + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - t + - Time + - The amount of time to wait. + +.. _spi_engine configutarion-registers: + +Configuration Registers +-------------------------------------------------------------------------------- + +The SPI Engine execution module has a set of 8-bit configuration registers which +can be used to dynamically modify the behavior of the module at runtime. + +.. _spi_engine spi-configuration-register: + +SPI Configuration Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The SPI configuration register configures various aspects of the low-level SPI +bus behavior. + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - [7:3] + - reserved + - Must always be 0. + * - [2] + - three_wire + - Configures the output of the three_wire pin. + * - [1] + - CPOL + - Configures the polarity of the SCLK signal. When 0, the idle state of + the SCLK signal is low. When 1, the idle state of the SCLK signal is + high. + * - [0] + - CPHA + - Configures the phase of the SCLK signal. When 0, data is updated on the + leading edge and sampled on the trailing edge. When 1, data is is + sampled on the leading edge and updated on the trailing edge. + +.. _spi_engine prescaler-configuration-register: + +Prescaler Configuration Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The prescaler configuration register configures the divider that is applied to +the module clock when generating the SCLK signal and other internal control +signals used by the sleep and chip-select commands. + +===== ==== ======================= +Bits Name Description +===== ==== ======================= +[7:0] div Prescaler clock divider +===== ==== ======================= + +The frequency of the SCLK signal is derived from the module clock frequency +using the following formula: + +.. math:: + + f_{sclk} = \frac{f_{clk}}{((div + 1) * 2)} + + +If no prescaler block is present div is 0. + +.. _spi_engine dynamic-transfer-length-register: + +Dynamic Transfer Length Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The dynamic transfer length register sets the length (in bits) of a transfer. By +default, the transfer length is equal to the DATA_WIDTH of the execution module. +If required the user can reduce this length by setting this register. A general +rule of thumb is to set the DATA_WIDTH parameter to the largest transfer length +supported by the target device. + +===== ==== ======================= +Bits Name Description +===== ==== ======================= +[7:0] div Dynamic transfer length +===== ==== ======================= diff --git a/docs/library/spi_engine/offload-control-interface.rst b/docs/library/spi_engine/offload-control-interface.rst new file mode 100644 index 000000000..7002d2813 --- /dev/null +++ b/docs/library/spi_engine/offload-control-interface.rst @@ -0,0 +1,78 @@ +.. _spi_engine offload-control-interface: + +SPI Engine Offload Control Interface +================================================================================ + +The SPI-Engine offload control interface is used to configure and control a +:ref:`spi_engine offload`. +It is used to activate/deactivate the core as well re-program the command and +SDO data RAM. + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/interfaces/spi_engine_offload_ctrl_rtl.xml` + - Interface definition file + +Signal Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 10 70 + :header-rows: 1 + + * - Name + - Direction (Master) + - Description + * - ``cmd_wr_en`` + - Output + - If asserted cmd_wr_data is written to the command memory. + * - ``cmd_wr_data`` + - Output + - Data to write to the command memory. + * - ``sdo_wr_en`` + - Output + - If asserted sdo_wr_data is written to the SDO data memory. + * - ``sdo_wr_data`` + - Output + - Data to write to the SDO data memory. + * - ``mem_reset`` + - Output + - Reset the contents of both the command and SDO data memory. + * - ``enable`` + - Output + - If asserted the connected offload core will get enabled. + * - ``enabled`` + - Input + - If asserted the connected offload core is enabled. + +Theory of Operation +-------------------------------------------------------------------------------- + +The SPI-Engine offload core typically implements to RAMs, one for the command +stream and one for the SDO data stream. If the ``mem_reset`` signal is asserted +the content of both memories is cleared. Asserting ``cmd_wr_en`` will write the +value of ``cmd_wr_data`` to the command memory and increase the write address by +one. The next time ``cmd_wr_en`` is asserted the next entry in the memory will +be written and so on. If ``cmd_wr_en`` is asserted more times than the size of +the command memory (without a reset in between) undefined behavior will occur. +``sdo_wr_en`` and ``sdo_wr_data`` behave analogously for the SDO data memory. + +If the ``enable`` signal the is asserted the SPI-Engine offload core will be +active, this means it will listen to external trigger events and execute the +stored SPI transfer when the external trigger is asserted. If ``enable`` is not +asserted the core will no longer listen to trigger events and will not start new +transfers. But it might still be busy executing a SPI transfer that was started +previously. The ``enabled`` signal is used to indicate this and it will stay +asserted even after ``enable`` as been deasserted until the currently active SPI +transfer has been completed. + +If either ``enable`` or ``enabled`` is asserted ``cmd_wr_en``, ``sdo_wr_en``, or +``memt_reset`` must not be asserted, otherwise undefined behavior can occur. In +other words as long as the SPI-Engine offload core is active the content of both +the command and SDO data memory must remain stable and be consistent. diff --git a/docs/library/spi_engine/regmap.csv b/docs/library/spi_engine/regmap.csv new file mode 100644 index 000000000..3720a45c1 --- /dev/null +++ b/docs/library/spi_engine/regmap.csv @@ -0,0 +1,50 @@ +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 diff --git a/docs/library/spi_engine/spi-bus-interface.rst b/docs/library/spi_engine/spi-bus-interface.rst new file mode 100644 index 000000000..e90256a84 --- /dev/null +++ b/docs/library/spi_engine/spi-bus-interface.rst @@ -0,0 +1,73 @@ +.. _spi_engine spi-bus-interface: + +SPI Bus Interface +================================================================================ + +The SPI bus interface carries logical low-level SPI bus signals. + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/interfaces/spi_master_rtl.xml` + - Interface definition file + +Signal Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 15 65 + :header-rows: 1 + + * - Name + - Direction (Master) + - Description + * - ``sclk`` + - Output + - SPI Clock. + * - ``sdo`` + - Output + - SPI SDO (MOSI) signal. + * - ``sdo_t`` + - Output + - ``sdo`` tri-state enable. If 1 the MOSI signal should be tristated and + not be connected to ``sdo`` + * - ``sdi`` + - Input + - SPI SDI (MISO) signal. Execution module supports max 8 individual + ``sdi`` lines. + * - ``cs`` + - Output + - SPI chip-select signal. + * - ``three_wire`` + - Output + - If set to 1 the bus should operate in three-wire mode. In three-wire + mode ``sdi`` is connected to MOSI instead of MISO. + +IO configuration +-------------------------------------------------------------------------------- + +.. image:: spi_bus.svg + :width: 30% + :align: right + +The SPI bus interface only carries a logical representation of the low-level SPI +bus signals. The top-level module in the FPGA design project is responsible for +translating the signal to physical SPI bus signals by instantiating and +connecting it to appropriate IO primitives. + +The ``sclk`` and ``cs`` signals can typically be directly connected to a output +buffer. ``sdi`` should be connected to a mux, that depending on the setting of +the ``three_wire`` signal connects to a input buffer connected to the ``miso`` +signal or to a input buffer connected to the ``mosi`` signal. The ``sdo`` signal +should be connected to a output tri-state buffer with the ``sdo_t`` signal +controlling the tri-state setting. + +In some configurations three-wire support may not be required and ``sdi`` can +directly be connected to the input buffer for the ``miso`` signal. Similarly +when ``mosi`` tri-stating is not required the ``sdo`` signal can be directly +connected to the ``mosi`` signal leaving the ``sdo_t`` signal unconnected. diff --git a/docs/library/spi_engine/spi_bus.svg b/docs/library/spi_engine/spi_bus.svg new file mode 100644 index 000000000..03610d56d --- /dev/null +++ b/docs/library/spi_engine/spi_bus.svg @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PhysicalBys + FPGABus + + miso + sclk + sclk + cs + mosi + cs + three_wire + sdi + sdo + sdo_t + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/library/spi_engine/spi_engine.svg b/docs/library/spi_engine/spi_engine.svg new file mode 100644 index 000000000..0dc20a28b --- /dev/null +++ b/docs/library/spi_engine/spi_engine.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + sdi + sdo + + + Data Shift Register + + + SDI + + + + + + + + SDO + + + + + + + + + + + MultifunctionCounter and CompareUnit + + + + Prescaler + + + + clk + + trigger + + sclk + + Instruction Decoder + + + + + + + CMD + + + + chip-select + + + cs + + CE + + D + Q + + + SYNC + + + + + + + + + + + + + + + Clock Gen + + + + CE + three_wire + + Config + + + + + + + + + + + + + cphacpol + sleep_compare + + active + + diff --git a/docs/library/spi_engine/spi_engine_execution.rst b/docs/library/spi_engine/spi_engine_execution.rst new file mode 100644 index 000000000..bd5177a17 --- /dev/null +++ b/docs/library/spi_engine/spi_engine_execution.rst @@ -0,0 +1,95 @@ +.. _spi_engine execution: + +SPI Engine Execution Module +================================================================================ + +.. symbolator:: ../../../library/spi_engine/spi_engine_execution/spi_engine_execution.v + :caption: spi_engine_execution + +The SPI Engine Execution peripheral forms the heart of the SPI Engine framework. +It is responsible for handling a SPI Engine control stream and translates it +into low-level SPI bus transactions. + +Files +------------------------------------------------------------------------------- + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/spi_engine_execution/spi_engine_execution.v` + - Verilog source for the peripheral. + * - :git-hdl:`master:library/spi_engine/spi_engine_execution/spi_engine_execution_ip.tcl` + - TCL script to generate the Vivado IP-integrator project for the peripheral. + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. hdl-parameters:: + :path: library/spi_engine/spi_engine_execution + + * - NUM_OF_CS + - Number of chip-select signals for the SPI bus (min: 1, max: 8). + * - DEFAULT_SPI_CFG + - Reset configuration value for the + :ref:`spi_engine spi-configuration-register` + * - DEFAULT_CLK_DIV + - Reset configuration value for the + :ref:`spi_engine prescaler-configuration-register` + * - DATA_WIDTH + - Data width of the parallel data stream. Will define the transaction's + granularity. Supported values: 8/16/24/32 + * - NUM_OF_SDI + - Number of multiple SDI lines, (min: 1, max: 8) + +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. + * - ``active`` + - Output + - Indicates whether the peripheral is currently active and processing + commands. + * - ``ctrl`` + - :ref:`spi_engine control-interface` slave + - SPI Engine Control stream that contains commands and data for the + execution module. + * - ``spi`` + - :ref:`spi_engine spi-bus-interface` master + - Low-level SPI bus interface that is controlled by peripheral. + +Theory of Operation +-------------------------------------------------------------------------------- + +The SPI Engine Execution module implements the physical access to the SPI bus. +It implements a small but powerful programmable state machine that translates a +SPI Engine command stream into low-level SPI bus access. + +Communication with a command stream generator happens via the ``ctrl`` +interface and the low-level SPI access is handled on the ``spi`` interface. +The ``active`` signal is asserted as long as the peripheral is busy executing +incoming commands. + +Internally the SPI Engine execution module consists of an instruction encoder +that translates the incoming commands into an internal control signal, a +multi-function counter and compares unit that is responsible for handling the +timing and a shift register which holds the received and transmitted SPI data. + +The module has an optional programmable pre-scaler register that can be used to +divide the external clock to the counter and compare unit. + +.. image:: spi_engine.svg diff --git a/docs/library/spi_engine/spi_engine_interconnect.rst b/docs/library/spi_engine/spi_engine_interconnect.rst new file mode 100644 index 000000000..5c615fd34 --- /dev/null +++ b/docs/library/spi_engine/spi_engine_interconnect.rst @@ -0,0 +1,90 @@ +.. _spi_engine interconnect: + +SPI Engine Interconnect Module +================================================================================ + +.. symbolator:: ../../../library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v + :caption: axi_spi_engine + +The SPI Engine Interconnect module allows connecting multiple +:ref:`spi_engine control-interface` masters to a single +:ref:`spi_engine control-interface` slave. +This enables multiple command stream generators to connect to a single +:ref:`spi_engine execution` and consequential give them access to the same SPI bus. +The interconnect modules take care of properly arbitrating between the different +command streams. + +Combining multiple command stream generators in a design and connecting them to +a single execution module allows for the creation of flexible and efficient +designs using standard components. + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v` + - Verilog source for the peripheral. + * - :git-hdl:`master:library/spi_engine/spi_engine_interconnect/spi_engine_interconnect_ip.tcl` + - TCL script to generate the Vivado IP-integrator project for the + peripheral. + + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. hdl-parameters:: + :path: library/spi_engine/spi_engine_interconnect + + * - DATA_WIDTH + - Data width of the parallel SDI/SDO data interfaces. + * - NUM_OF_SDI + - Number of SDI lines on the physical SPI interface. + + +Signal and Interface Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 25 65 + :header-rows: 1 + + * - Name + - Type + - Description + * - ``clk`` + - Clock + - A signals of the module are synchronous to this clock. + * - ``resetn`` + - Synchronous active-low reset + - Resets the internal state of the module. + * - ``s0_ctrl`` + - :ref:`spi_engine control-interface` slave + - Connects to the first control interface master + * - ``s1_ctrl`` + - :ref:`spi_engine control-interface` slave + - Connects to the second control interface master + * - ``m_ctrl`` + - :ref:`spi_engine control-interface` master + - Connects to the control interface slave + +Theory of Operation +-------------------------------------------------------------------------------- + +The SPI Engine Interconnect module has multiple +:ref:`spi_engine control-interface` slave ports and a single +:ref:`spi_engine control-interface` master port. +It can be used to connect multiple command stream generators to a single command +execution engine. Arbitration between the streams is done on a priority +basis, streams with a lower index have higher priority. This means if commands +are present on two streams arbitration will be granted to the one with the lower +index. Once arbitration has been granted the port it was granted to stays in +control until it sends a SYNC command. When the interconnect module sees a SYNC +command arbitration will be re-evaluated after the SYNC command has been +completed. This makes sure that once a SPI transaction consisting of multiple +commands has been started it is able to complete without being interrupted by a +higher priority stream. diff --git a/docs/library/spi_engine/spi_engine_offload.rst b/docs/library/spi_engine/spi_engine_offload.rst new file mode 100644 index 000000000..4a754930f --- /dev/null +++ b/docs/library/spi_engine/spi_engine_offload.rst @@ -0,0 +1,77 @@ +.. _spi_engine offload: + +SPI Engine Offload +================================================================================ + +.. symbolator:: ../../../library/spi_engine/spi_engine_offload/spi_engine_offload.v + +The SPI Engine Offload peripheral allows to store a SPI Engine command and SDO +data stream in a RAM or ROM module. The command stream is executed when the +``trigger`` signal is asserted. This allows the execution of SPI transactions +with a very short delay in reaction to a event. + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/spi_engine_offload/spi_engine_offload.v` + - Verilog source for the peripheral. + * - :git-hdl:`master:library/spi_engine/spi_engine_offload/spi_engine_offload_ip.tcl` + - TCL script to generate the Vivado IP-integrator project for the + peripheral. + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. hdl-parameters:: + :path: library/spi_engine/spi_engine_offload + + * - ASYNC_SPI_CLK + - If set to 1 the ``ctrl_clk`` and ``spi_clk`` are assumed to be + asynchronous. + * - CMD_MEM_ADDRESS_WIDTH + - Configures the size of the command stream storage. The size is + ``2**CMD_MEM_ADDR_WIDTH`` entries. + * - SDO_MEM_ADDRESS_WIDTH + - Configures the size of the SDO data stream storage. The size is + ``2**SDO_MEM_ADDR_WIDTH`` entries. + +Signal and Interface Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 25 65 + :header-rows: 1 + + * - Name + - Type + - Description + * - ``ctrl_clk`` + - Clock + - The ``spi_engine_offload_ctrl`` signals are synchronous to this clock. + * - ``spi_clk`` + - Clock + - The ``spi_engine_ctrl`` signals, ``offload_sdi`` signals and + trigger are synchronous to this clock. + * - ``spi_resetn`` + - Synchronous active low reset + - Resets the internal state machine of the core. + * - ``trigger`` + - Input + - When asserted the stored command and data stream is send out on the + ``spi_engine_ctrl`` interface. + * - ``spi_engine_offload_ctrl`` + - :ref:`spi_engine offload-control-interface` slave + - Control interface which allows to re-program the stored command and SDO + data stream. + * - ``spi_engine_ctrl`` + - :ref:`spi_engine control-interface` master + - SPI Engine Control stream that contains commands and data. + * - ``offload_sdi`` + - Streaming AXI master + - Output stream of the received SPI data. diff --git a/docs/library/spi_engine/tutorial.rst b/docs/library/spi_engine/tutorial.rst new file mode 100644 index 000000000..c66cc37d0 --- /dev/null +++ b/docs/library/spi_engine/tutorial.rst @@ -0,0 +1,308 @@ +.. _spi_engine tutorial: + +SPI Engine Tutorial - PulSAR-ADC +================================================================================ + +The goal of this tutorial is to present the process of adding +:ref:`spi_engine` support for an ADI precision converter or family of converters +using a few simple steps. +The target carrier is the Digilent Cora-z7s board using a Pmod connector. + +Evaluating the target device +-------------------------------------------------------------------------------- + +The aim of this project is to provide support for a family of ADCs which come in +the form of +:dokuwiki:`pulsar-adc-pmods:resources/eval/user-guides/circuits-from-the-lab/pulsar-adc-pmods`. +They all share the same interface and the same PCB, the differences being found +in their performance. The table below offers a comparison between the timing +parameters of the SPI interface for these devices. Using this table we can see +how much they have in common and where the key differences are. All the values +are for 3.3V VIO since the Cora-z7s is only 3.3V capable. + ++----------+----------+------+----------+----------+----------+----------+ +| Device | Re | KSPS | T\_ | T_CONV | T_CYC | T_ACQ | +| | solution | | SPI_SCLK | max [ns] | min [ns] | min [ns] | +| | | | min [ns] | | | | ++==========+==========+======+==========+==========+==========+==========+ +| AD7942 | 14 | 250 | 18 | 2200 | 4000 | 1800 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7946 | 14 | 500 | 15 | 1600 | 2000 | 400 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7988-1 | 16 | 100 | 12 | 9500 | 1000 | 500 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7685 | 16 | 250 | 15 | 2200 | 4000 | 1800 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7687 | 16 | 250 | 10 | 2200 | 4000 | 1800 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7691 | 16 | 250 | 15 | 2200 | 4000 | 1800 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7686 | 16 | 500 | 15 | 1600 | 2000 | 400 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7693 | 16 | 500 | 15 | 1600 | 2000 | 400 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7 | 16 | 500 | 12 | 1600 | 2000 | 400 | +| 988-5(B) | | | | | | | ++----------+----------+------+----------+----------+----------+----------+ +| AD7 | 16 | 500 | 12 | 1200 | 2000 | 800 | +| 988-5(C) | | | | | | | ++----------+----------+------+----------+----------+----------+----------+ +| AD7980 | 16 | 1000 | 10 | 710 | 1000 | 290 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7983 | 16 | 1333 | 12 | 500 | 750 | 250 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7690 | 18 | 400 | 15 | 2100 | 2500 | 400 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7982 | 18 | 1000 | 12 | 710 | 1000 | 290 | ++----------+----------+------+----------+----------+----------+----------+ +| AD7984 | 18 | 1333 | 12 | 500 | 750 | 250 | ++----------+----------+------+----------+----------+----------+----------+ + +The device with the most demanding timing specifications is the AD7984. It +requires the highest amount of data (18 bit) to be read in the least amount of +time (T_ACQ 250ns). The other devices will work with the same HDL by just using +different “downgraded” configurations. + +SPI Engine hierarchy instantiation +-------------------------------------------------------------------------------- + +The SPI Engine can be implemented in two ways, either by placing and connecting +each IP individually or by using the function provided by the spi_engine.tcl +script :git-hdl:`master:library/spi_engine/scripts/spi_engine.tcl` + +Using the script ensures that the correct connections are being made and that +the IP cores will receive the correct parameter configuration since certain +parameters need to be set to the same value. The function takes the following +argumets + +.. code:: tcl + + proc spi_engine_create {{name "spi_engine"} {data_width 32} {async_spi_clk 1} {num_cs 1} {num_sdi 1} {sdi_delay 0} {echo_sclk 0}} + +**data_width** will set the width of the data bus / data line used by the SPI +engine to connect to the DMA and which serves the purpose of sending ADC sample +data to the DDR memory. The data_width value will also set the maximum word +length for the SPI transfer. Valid values are are 8/16/24/32. The DMA valid +values are 16/32/64/128[…]. Since the Pulsar_ADC devices are all single SDI/SDO +and some of them require 18bit transfers, this value will be rounded to 32bit. + +**async_spi_clk** will chose the reference clock for the SPI Engine. Setting +this parameter to 0 will configure the hierarchy to use the axi clock (100MHz) +as the reference clock. Setting it to 1 will allow for an external referece +clock (spi_clk). Because some devices need 80MHz SCLK, a 160MHz reference clock +is required which implies an external reference. + +**num_cs** selects the number of CS lines. + +**num_sdi** selects the number of SDI lines. + +**sdi_delay** The latch of the SDI line can be delayed with 1, 2 or 3 SPI core +clock cycle. Needed for designs with high SCLK rate (>50MHz). + +Configuration tcl code and result below: + +.. code:: tcl + + source $ad_hdl_dir/library/spi_engine/scripts/spi_engine.tcl + + set data_width 32 + set async_spi_clk 1 + set num_cs 1 + set num_sdi 1 + set sdi_delay 1 + set hier_spi_engine spi_pulsar_adc + + spi_engine_create $hier_spi_engine $data_width $async_spi_clk $num_cs $num_sdi $sdi_delay + +.. image:: tutorial/pulsar_hdl_1.svg + :align: center + +SPI Engine reference clock +-------------------------------------------------------------------------------- + +There are 3 categories of devices depending on the SPI interface clock (SCLK): +80 MHz, 50MHz (one device) and 40MHz. SCLK will be derived from the spi_clk +reference signal using an internal prescaler with this formula: + +.. math:: + + f_{sclk} = \frac{f_{clk}}{((div + 1) * 2)} + +Therefore a 160MHz reference clock will be needed for the 40 and 80MHz variants +and 100MHz for the 50MHz SCLK. The axi_clkgen IP core will be used to obtain the +160MHz which will be the default value to ensure that the design bitstream meets +timing. This IP can also be configured from software to output 100MHz. + +.. code:: tcl + + ad_ip_instance axi_clkgen spi_clkgen + ad_ip_parameter spi_clkgen CONFIG.CLK0_DIV 5 + ad_ip_parameter spi_clkgen CONFIG.VCO_DIV 1 + ad_ip_parameter spi_clkgen CONFIG.VCO_MUL 8 + +Clock source for IP and spi_clk connection + +.. code:: tcl + + ad_connect $sys_cpu_clk spi_clkgen/clk + ad_connect spi_clk spi_clkgen/clk_0 + ad_connect spi_clk spi_pulsar_adc/spi_clk + ad_connect spi_clk axi_pulsar_adc_dma/s_axis_aclk + +AD7984 Timing diagram +-------------------------------------------------------------------------------- + +The operation mode that will be implemented using the SPI Engine in offload mode +is the :math:`\overline{CS}` Mode, 3-Wire with Busy Indicator Serial Interface Timing (SDI High), +as shown in :datasheet:`AD7984:[{"num"%3A51%2C"gen"%3A0}%2C{"name"%3A"XYZ"}%2C52%2C713%2C0]`, +page 18, figure 30. + +Key timing characteristics: + +.. code:: tcl + + 18 bit transfers + 750 ns T_CYC + 500 ns T_CONV + 250 ns T_ACQ + 12 ns T_SCLK @ >3V VIO (cora pmod is 3V3) + +Sample rate control +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The T_CYC parameter is the what sets the maximum sample rate (1/750 => 1333 +KSPS). To achieve precise control over the the sample rate we will use a PWM +generator (AXI PWM GEN) using the spi_clk as reference. The spi_clock is used to +avoid clock domain crossing mechanisms which will introduce latency, decreasing +the overall performance of the system. + +.. code:: tcl + + ad_ip_instance axi_pwm_gen pulsar_adc_trigger_gen + ad_ip_parameter pulsar_adc_trigger_gen CONFIG.PULSE_0_PERIOD 120 + ad_ip_parameter pulsar_adc_trigger_gen CONFIG.PULSE_0_WIDTH 1 + + ad_connect spi_clk pulsar_adc_trigger_gen/ext_clk + ad_connect $sys_cpu_clk pulsar_adc_trigger_gen/s_axi_aclk + ad_connect sys_cpu_resetn pulsar_adc_trigger_gen/s_axi_aresetn + ad_connect pulsar_adc_trigger_gen/pwm_0 $hier_spi_engine/offload/trigger + +.. image:: tutorial/pwm_trigger_1.svg + :align: right + :width: 50% + +Since the AXI PWM IP core is connected to the system with AXI4 Lite, the +software will be able to change the frequency of its output at any time. The +resolution of the PWM period is the reference clock period (spi_clk) providing a +wide range of options. + +The PWM output will be used as a trigger signal for the offload IP core. + +The CS signal will be used to drive CNV and will have the same frequency as the +PWM-trgger signal. + +DMA setup +-------------------------------------------------------------------------------- + +DMA destination bus (connection to Zynq – DDR memory) shall always be 64 bit +wide AXI4 MM and source bus shall be data_wdth \* num_sdi = 32 bit, AXI4 Stream. + +.. code:: tcl + + ad_ip_instance axi_dmac axi_pulsar_adc_dma + ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_TYPE_SRC 1 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_TYPE_DEST 0 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.CYCLIC 0 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.SYNC_TRANSFER_START 0 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.AXI_SLICE_SRC 0 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.AXI_SLICE_DEST 1 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_2D_TRANSFER 0 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_DATA_WIDTH_SRC $data_width //32 + ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_DATA_WIDTH_DEST 64 + +The system clock is used as destination clock and the spi_clk is used as source +clock + +.. code:: tcl + + ad_connect spi_clk axi_pulsar_adc_dma/s_axis_aclk + ad_mem_hp1_interconnect $sys_cpu_clk axi_pulsar_adc_dma/m_dest_axi + +System Top +-------------------------------------------------------------------------------- + +This is a layer on top of the system_wrapper generated by Vivado used to +instantiate IO buffers, I/ODDRs or to create some custom connections which would +be harder to do in the block design. It also alows for more consistency across +projects. In this particular case we use it to place an IO buffer for the ADC +power down signal (pulsar_adc_spi_pd). + +System Constraints +-------------------------------------------------------------------------------- + +The system_constr.xdc file inside the carrier folder +(/coraz7s/system_constr.xdc) is used for defining the physical FPGA pins used by +this particular project (in this case the AD7984 ADC), excluding the "common" +design for the carrier board which has a separate constraints file (i.e. DDR +pins, Ethernet, UART etc). It also contains some timing constraints specific to +the SPI Engine. + +create_generated_clock -name spi_clk -source [get_pins -filter name=~*CLKIN1 -of +[get_cells -hier -filter name=~*spi_clkgen*i_mmcm]] -master_clock clk_fpga_0 +[get_pins -filter name=~*CLKOUT0 -of [get_cells -hier -filter +name=~*spi_clkgen*i_mmcm]] + +.. code:: + + # relax the SDO path to help closing timing at high frequencies + set_multicycle_path -setup 8 -to [get_cells -hierarchical -filter {NAME=~*/data_sdo_shift_reg[*]}] -from [get_clocks spi_clk] + set_multicycle_path -hold 7 -to [get_cells -hierarchical -filter {NAME=~*/data_sdo_shift_reg[*]}] -from [get_clocks spi_clk] + set_multicycle_path -setup 8 -to [get_cells -hierarchical -filter {NAME=~*/execution/inst/left_aligned_reg*}] -from [get_clocks spi_clk] + set_multicycle_path -hold 7 -to [get_cells -hierarchical -filter {NAME=~*/execution/inst/left_aligned_reg*}] -from [get_clocks spi_clk] + +Testbench +-------------------------------------------------------------------------------- + +To check the overall performance of the design and also to expose any major +bugs, the system can be tested using a testbench (:git-testbenches:`main:`). + +The testbench framework is designed to use the same bd.tcl as the actual project +:git-testbenches:`main:pulsar_adc_pmdz/system_bd.tcl#L50` + +The setup assumes the testbenches repo is cloned inside the hdl repo. To build +the testbench project simply run :code:`make cfg1` from the +*hdl/testbenches/pulsar_adc_pmdz/* folder. Besides exposing possible bugs, +using the testbench will provide the user with an early way of evaluating the +timing of the design. The testbench can also be a very useful tool for IP +development. + +Evaluating the result +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to the limits of the SPI Engine cores, T_CYC needs to be increased slightly +over the minimum value, to ensure that the design meets the T_CONV minimum. This +will slightly lower the maximum sample rate of the design from 1.333 MSPS to +1.322 MSPS. + +.. image:: tutorial/pulsar_hdl_timing_2.png + :width: 100% + +Holding CS high for 500ns ensures that we always meet T_CONV minimum. + +.. image:: tutorial/pulsar_hdl_timing_3.png + :width: 100% + +The 250ns minimum T_ACQ is alse met with a slightly higher value of 256.25ns. + +.. image:: tutorial/pulsar_hdl_timing_4.png + :width: 100% + +Overall the project appears to be functional and ready for the next step in +development, using software. + +Software section +-------------------------------------------------------------------------------- + +.. important:: + + This section is still under development. diff --git a/docs/library/spi_engine/tutorial/pulsar_hdl_1.svg b/docs/library/spi_engine/tutorial/pulsar_hdl_1.svg new file mode 100644 index 000000000..19a04da3b --- /dev/null +++ b/docs/library/spi_engine/tutorial/pulsar_hdl_1.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + trigger + + + + + s_axi + + + + + clk + + + + + resetn + + + + + spi_clk + + + + spi_pulsar_adc_axi_regmap + + + axi_spi_engine_v1_0 + + + + + + + + + + s_axi + + + + + + + + + + spi_engine_ctrl + + + + + + + + + + spi_engine_offload_ctrl0 + + + + s_axi_aclk + + + + + s_axi_aresetn + + + + irq + + + + spi_clk + + + + + spi_resetn + + + + + + + + + + + + + + spi_pulsar_adc_interconnect + + + spi_engine_interconnect_v1_0 + + + + + + + + + + m_ctrl + + + + + + + + + + s0_ctrl + + + + + + + + + + s1_ctrl + + + + clk + + + + + resetn + + + + + + + + + + + + + + spi_pulsar_adc_offload + + + spi_engine_offload_v1_0 + + + + + + + + + + spi_engine_ctrl + + + + + + + + + + spi_engine_offload_ctrl + + + + + + + + + + offload_sdi + + + + ctrl_clk + + + + spi_clk + + + + + spi_resetn + + + + trigger + + + + + + + + + + + + + + spi_pulsar_adc_execution + + + spi_engine_execution_v1_0 + + + + + + + + + + ctrl + + + + + + + + + + spi + + + + clk + + + + + resetn + + + + active + + + + + + + + + + + + + + + m_axis_sample + + + + + m_spi + + + + + irq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/library/spi_engine/tutorial/pulsar_hdl_timing_2.png b/docs/library/spi_engine/tutorial/pulsar_hdl_timing_2.png new file mode 100644 index 000000000..19014e2e4 Binary files /dev/null and b/docs/library/spi_engine/tutorial/pulsar_hdl_timing_2.png differ diff --git a/docs/library/spi_engine/tutorial/pulsar_hdl_timing_3.png b/docs/library/spi_engine/tutorial/pulsar_hdl_timing_3.png new file mode 100644 index 000000000..2706246ab Binary files /dev/null and b/docs/library/spi_engine/tutorial/pulsar_hdl_timing_3.png differ diff --git a/docs/library/spi_engine/tutorial/pulsar_hdl_timing_4.png b/docs/library/spi_engine/tutorial/pulsar_hdl_timing_4.png new file mode 100644 index 000000000..23eea3ad8 Binary files /dev/null and b/docs/library/spi_engine/tutorial/pulsar_hdl_timing_4.png differ diff --git a/docs/library/spi_engine/tutorial/pwm_trigger_1.svg b/docs/library/spi_engine/tutorial/pwm_trigger_1.svg new file mode 100644 index 000000000..feda810b9 --- /dev/null +++ b/docs/library/spi_engine/tutorial/pwm_trigger_1.svg @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + axi_sysid_v1_0 + + + + + + + + + + + + + pulsar_adc_trigger_gen + + + ADI AXI PWM Generator + + + + + + + + + + + + s_axi + + + + + + s_axi_aclk + + + + + + + s_axi_aresetn + + + + + + ext_clk + + + + + + pwm_0 + + + + + + + + + + + + + + + + spi_pulsar_adc + + + + + + + + + + + + + + + + + m_spi + + + + + + + + + + + + m_axis_sample + + + + + + + + + + + + s_axi + + + + + + spi_clk + + + + + + clk + + + + + + resetn + + + + + + trigger + + + + + + irq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/library/template_framework/index.rst b/docs/library/template_framework/index.rst new file mode 100644 index 000000000..b6b7233c7 --- /dev/null +++ b/docs/library/template_framework/index.rst @@ -0,0 +1,51 @@ +:orphan: + +.. _template_framework: + +Framework Template +================================================================================ + +.. toctree:: + :hidden: + + Template Module + Template Interface + Instruction Set Template + +{brief introdution}. + +Sub-modules +-------------------------------------------------------------------------------- + +* :ref:`template_framework module`: {brief description}. + +Interfaces +-------------------------------------------------------------------------------- + +* :ref:`template_framework interface`: {brief description}. + +Software +-------------------------------------------------------------------------------- + +* :ref:`template_framework instruction-set`: {brief description}. + +Related IP Cores +-------------------------------------------------------------------------------- + +This list contains cores that are not part of the core {ip name} but +make use of its interfaces and are intend to be used together with the {ip name}. + +* :dokuwiki:`util-sigma-delta-spi:resources/fpga/peripherals/util_sigma_delta_spi`: + Helper module for interfacing ADCs from the Analog Devices Sigma-Delta family. + +Examples +-------------------------------------------------------------------------------- + +* :dokuwiki:`CN0363:resources/eval/user-guides/eval-cn0363-pmdz`: + Colorimeter application using the :part:`AD7175-2` Sigma-Delta ADC. + +Additional Resources +-------------------------------------------------------------------------------- + +* :download:`Presentation: SPI Engine Design Philosophy `. +* :ref:`spi_engine tutorial`. diff --git a/docs/library/template_framework/instruction-set.rst b/docs/library/template_framework/instruction-set.rst new file mode 100644 index 000000000..85d04a173 --- /dev/null +++ b/docs/library/template_framework/instruction-set.rst @@ -0,0 +1,125 @@ +.. _template_framework instruction-set: + +Template Instruction Set Specification +================================================================================ + +The {instruction set} set is a {brief description} + +Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Transfer Instruction +-------------------------------------------------------------------------------- + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 0 0 0 0 r w n n n n n n n n +== == == == == == = = = = = = = = = = + +{description} + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - r + - Read + - If set to 1 data will be read {...}. + * - w + - Write + - If set to 1 data will be taken from {...}. + * - n + - Length + - n + 1 number of words that {...}. + +Other Instruction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 0 1 0 0 t t s s s s s s s s +== == == == == == = = = = = = = = = = + +The {instruction name} instruction updates the {...}. + +.. math:: + + delay = t * \frac{div + 1}{f_{clk}} + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - t + - Delay + - Delay before and after setting the new configuration. + * - s + - Chip-select + - The new chip-select configuration. + +Yet Another Instruction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +== == == == == == = = = = = = = = = = +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +== == == == == == = = = = = = = = = = +0 0 1 0 0 0 r r v v v v v v v v +== == == == == == = = = = = = = = = = + +The {instruction name} instruction updates the {...}. + +The configuration writes instruction updates a +:ref:`template_framework configuration-registers` +of the {module name} module with a new value. + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - r + - Register + - Configuration register address. + 2'b00 = :ref:`template_framework register` + * - v + - Value + - New value for the configuration register. + +.. _template_framework configuration-registers: + +Configuration Registers +-------------------------------------------------------------------------------- + +The {module name} module has a set of {#}-bit configuration registers which +can be used to dynamically modify the behavior of the module at runtime. + +.. _template_framework register: + +Template Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The {registe name} register configures {description}. + +.. list-table:: + :widths: 10 15 75 + :header-rows: 1 + + * - Bits + - Name + - Description + * - [7:3] + - reserved + - Must always be 0. + * - [2] + - three_wire + - Configures {...}. diff --git a/docs/library/template_framework/interface.rst b/docs/library/template_framework/interface.rst new file mode 100644 index 000000000..f65482d38 --- /dev/null +++ b/docs/library/template_framework/interface.rst @@ -0,0 +1,47 @@ +.. _template_framework interface: + +Template Interface +================================================================================ + +The {interface name} is used to {brief description}. + +The interface consists of {#} streams: + +* The {stream name} stream which carries the {...}. + +{brief description, handshaking info} + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/interfaces/spi_engine_ctrl_rtl.xml` + - Interface definition file + +Signal Pins +-------------------------------------------------------------------------------- + +.. list-table:: + :widths: 10 10 10 70 + :header-rows: 1 + + * - Width + - Name + - Direction (Master) + - Description + * - + - ``cmd_ready`` + - Input + - Ready signal of the CMD stream + * - + - ``cmd_valid`` + - Output + - Valid signal of the CMD stream + * - [15:0] + - ``cmd_data`` + - Output + - Data signal of the CMD stream diff --git a/docs/library/template_framework/template_module.rst b/docs/library/template_framework/template_module.rst new file mode 100644 index 000000000..2f4ecaace --- /dev/null +++ b/docs/library/template_framework/template_module.rst @@ -0,0 +1,59 @@ +.. _template_framework module: + +Template Module +================================================================================ + +.. symbolator:: ../../../library/spi_engine/spi_engine_execution/spi_engine_execution.v + :caption: spi_engine_execution + +The {module name} is responsible for {brief description}. + +Files +------------------------------------------------------------------------------- + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/spi_engine/spi_engine_execution/spi_engine_execution.v` + - Verilog source for the peripheral. + * - :git-hdl:`master:library/spi_engine/spi_engine_execution/spi_engine_execution_ip.tcl` + - TCL script to generate the Vivado IP-integrator project for the peripheral. + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. hdl-parameters:: + :path: library/spi_engine/spi_engine_interconnect + + * - DATA_WIDTH + - Data width of the parallel SDI/SDO data interfaces. + +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}. + +Theory of Operation +-------------------------------------------------------------------------------- + +The {module name} module implements {brief description}. + +.. image:: ../spi_engine/spi_engine.svg diff --git a/docs/library/template_ip/index.rst b/docs/library/template_ip/index.rst new file mode 100644 index 000000000..2c835ea71 --- /dev/null +++ b/docs/library/template_ip/index.rst @@ -0,0 +1,152 @@ +:orphan: + +.. _template_ip: + +IP Template +================================================================================ + +Features +-------------------------------------------------------------------------------- + +* AXI-based configuration +* Vivado and Quartus Compatible + +Files +-------------------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + + * - Name + - Description + * - :git-hdl:`master:library/axi_dmac/axi_dmac.v` + - Verilog source for the peripheral. + + +Block Diagram +-------------------------------------------------------------------------------- + +.. image:: ../axi_dmac/block_diagram.svg + :alt: Template IP block diagram + :align: center + +Configuration Parameters +-------------------------------------------------------------------------------- + +.. hdl-parameters:: + :path: library/spi_engine/spi_engine_interconnect + + * - DATA_WIDTH + - Data width of the parallel SDI/SDO data interfaces. + +.. _template_ip interface: + +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 . + +Detailed Architecture +-------------------------------------------------------------------------------- + +:: + + .. image:: detailed_architecture.svg + :alt: Template IP detailed architecture + :align: center + +Detailed Description +-------------------------------------------------------------------------------- + +The top module instantiates + +* The ADC channel register map. +* The ADC common register map. +* The AXI handling interface. + +The data from the interface module is processed by the ADC channel module. +The Up_adc_common module implements the ADC COMMON register map, allowing for +basic monitoring and control of the ADC. +The Up_adc_channel module implements the ADC CHANNEL register map, allowing for +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 + +.. csv-table:: ADC Common (axi_ad*) + :file: ../common/regmap_adc_common.csv + :class: regmap + :header-rows: 2 + +.. csv-table:: ADC Channel (axi_ad*) + :file: ../common/regmap_adc_channel.csv + :class: regmap + :header-rows: 2 + +Design Guidelines +-------------------------------------------------------------------------------- + +The control of the chip is done through an SPI interface, which is needed at the +system level. +The :ref:`template_ip interface` must be connected directly to the top file of +the design, as IO primitives are part of the IP. + +The example design uses a DMA to move the data from the output of the IP to memory. +If the data needs to be processed in HDL before moving to the memory, it can be +done at the output of the IP (at the system level) or inside the ADC interface +module (at the IP level). +The example design uses a processor to program all the registers. +If no processor is available in your system, you can create your IP starting +from the interface module. + +Software Guidelines +-------------------------------------------------------------------------------- + +Linux is supported also using :git-linux:`/`. + +References +-------------------------------------------------------------------------------- + +* :git-hdl:`/`, :git-hdl:`library/axi_ad777x` library. +* :git-linux:`/`. +* :xilinx:`Zynq-7000 SoC Overview:support/documentation/data_sheets/ds190-Zynq-7000-Overview.pdf`. +* :xilinx:`Zynq-7000 SoC Packaging and Pinout:support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf`. diff --git a/docs/make.bat b/docs/make.bat new file mode 100755 index 000000000..922152e96 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..94f4c0fd3 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,9 @@ +sphinx +wavedrom +sphinxcontrib-wavedrom +sphinxcontrib-mermaid +sphinxcontrib-bibtex +sphinxcontrib-svg2pdfconverter +furo +https://github.com/hdl/pyhdlparser/tarball/master +https://github.com/hdl/symbolator/tarball/master diff --git a/docs/HDL_logo.png b/docs/sources/HDL_logo.png similarity index 100% rename from docs/HDL_logo.png rename to docs/sources/HDL_logo.png diff --git a/docs/HDL_logo.svg b/docs/sources/HDL_logo.svg similarity index 100% rename from docs/HDL_logo.svg rename to docs/sources/HDL_logo.svg diff --git a/docs/HDL_logo_w.png b/docs/sources/HDL_logo_w.png similarity index 100% rename from docs/HDL_logo_w.png rename to docs/sources/HDL_logo_w.png diff --git a/docs/sources/custom.css b/docs/sources/custom.css new file mode 100755 index 000000000..4eeeb8564 --- /dev/null +++ b/docs/sources/custom.css @@ -0,0 +1,61 @@ +.sidebar-brand { + background-color: #f8f9fb; + border-radius: .25em; + margin: var(--sidebar-item-spacing-vertical) + calc(var(--sidebar-item-spacing-horizontal)/2) + 0 + calc(var(--sidebar-item-spacing-horizontal)/2); + padding: 0; +} +.sidebar-brand::before { + content: ""; + display: inline-block; + width: 100%; + height: 4rem; + background-image: url(HDL_logo.svg); + background-size: auto 4rem; + background-position: center; + background-repeat: no-repeat; +} +.sidebar-brand-text { + display: none; +} +body[data-theme="dark"] .sidebar-brand { + color: #fff; +} +@media (min-width: 56em){ + .content { + width: 52em; + } +} +figure > object { + max-width: 100%; +} +img { + background: #fff; + border-radius: .25em; + padding: .5em 0; +} +iframe { + width: calc(50.625rem - 1rem); + height: calc(28.47rem - 0.5625rem); + margin-left: -1rem; +} +@media (max-width:50.625rem) { + iframe { + width: calc(100vw - 1rem); + height: calc(56.25vw - 1rem); + margin-left: -1rem; + } +} +.WaveDrom { + background: #fff; + border-radius: .25em; + padding: .5em 0; +} +table.regmap { + font-size: .75em; +} +table.regmap .caption-text{ + font-size: 1rem; +} diff --git a/docs/sources/icon.svg b/docs/sources/icon.svg new file mode 100755 index 000000000..86d6c3b53 --- /dev/null +++ b/docs/sources/icon.svg @@ -0,0 +1,313 @@ + + + +FPGA