From 715d585e2b75cb51a541db1232100a988e2c2f72 Mon Sep 17 00:00:00 2001 From: Vijayvithal Date: Mon, 13 Nov 2023 18:40:14 +0530 Subject: [PATCH] Initial commit of documentation System (#66) Add documentation and its build environment. --- .gitignore | 3 + .readthedocs.yml | 34 +++ docs/requirements.txt | 13 + docs/source/_static/cocotb-logo-white.svg | 118 ++++++++ docs/source/conf.py | 352 ++++++++++++++++++++++ docs/source/glossary.rst | 71 +++++ docs/source/index.rst | 152 ++++++++++ docs/source/library_reference.rst | 76 +++++ docs/source/spelling_wordlist.txt | 130 ++++++++ docs/source/testbench_tools.rst | 156 ++++++++++ noxfile.py | 69 +++++ pyproject.toml | 35 +++ 12 files changed, 1209 insertions(+) create mode 100644 .readthedocs.yml create mode 100644 docs/requirements.txt create mode 100644 docs/source/_static/cocotb-logo-white.svg create mode 100644 docs/source/conf.py create mode 100644 docs/source/glossary.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/library_reference.rst create mode 100644 docs/source/spelling_wordlist.txt create mode 100644 docs/source/testbench_tools.rst diff --git a/.gitignore b/.gitignore index 360eec39..5ce8278f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ # ignore files created during build build/ src/cocotb_bus.egg-info/ +*.vcd +*.xml +sim_build diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..a1c951ff --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,34 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt + - method: pip + path: . diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..df0f030e --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,13 @@ +# Python dependencies to build the documentation + +Sphinx ~= 7.0 +sphinx-rtd-theme >= 1.3.0 +sphinxcontrib-svg2pdfconverter[CairoSVG] +sphinxcontrib-spelling >= 5.3.0 +pyenchant +sphinx-issues +sphinx-argparse-cli +towncrier +sphinx-tabs +sphinxcontrib-details-directive +looseversion diff --git a/docs/source/_static/cocotb-logo-white.svg b/docs/source/_static/cocotb-logo-white.svg new file mode 100644 index 00000000..0999d419 --- /dev/null +++ b/docs/source/_static/cocotb-logo-white.svg @@ -0,0 +1,118 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..34c7fdc3 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,352 @@ +# -*- coding: utf-8 -*- +# +# cocotb documentation build configuration file +# +# This file is execfile()d with the current directory set to its containing dir. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import datetime +import os +import subprocess +import sys + +# Add in-tree extensions to path +sys.path.insert(0, os.path.abspath("../sphinxext")) + +import cocotb_bus +from looseversion import LooseVersion + +os.environ["SPHINX_BUILD"] = "1" + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.imgmath", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinx.ext.extlinks", + "sphinx.ext.intersphinx", + "sphinx.ext.inheritance_diagram", + "sphinxcontrib.cairosvgconverter", + "sphinx_issues", + "sphinx_argparse_cli", + "sphinxcontrib.spelling", + "sphinx_tabs.tabs", + "sphinxcontrib.details.directive", +] + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "ghdl": ("https://ghdl.github.io/ghdl", None), + "scapy": ("https://scapy.readthedocs.io/en/latest", None), + "pytest": ("https://docs.pytest.org/en/latest/", None), + #"cocotb": ("https://docs.cocotb.org/en/latest/", None), +} + +# Github repo +issues_github_path = "cocotb/cocotb-bus" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix of source filenames. +source_suffix = ".rst" + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "cocotb-bus" +copyright = "2014-{0}, cocotb contributors".format(datetime.datetime.now().year) + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = cocotb_bus.__version__ +# The short X.Y version. +v_major, v_minor = LooseVersion(release).version[:2] +version = "{}.{}".format(v_major, v_minor) + +autoclass_content = "both" + +autodoc_typehints = "description" # show type hints in the list of parameters + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [ + # these are compiled into a single file at build-time, + # so there is no need to build them separately: + "newsfragments/*.rst", +] + +# The reST default role (used for this markup: `text`) to use for all documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. + +# The Read the Docs theme is available from +# https://github.com/snide/sphinx_rtd_theme +# +# Install with +# - pip install sphinx_rtd_theme +# or +# - apt-get install python-sphinx-rtd-theme + +try: + import sphinx_rtd_theme + + html_theme = "sphinx_rtd_theme" +except ImportError: + sys.stderr.write( + "Warning: The Sphinx 'sphinx_rtd_theme' HTML theme was " + + "not found. Make sure you have the theme installed to produce pretty " + + "HTML output. Falling back to the default theme.\n" + ) + + html_theme = "default" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = dict( + logo_only=True, +) + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = "_static/cocotb-logo-white.svg" + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = "cocotb_bus_doc" + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ("index", "cocotb_bus.tex", "cocotb-bus Documentation", "cocotb-bus contributors", "manual"), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [("index", "cocotb_bus", "cocotb-bus Documentation", ["cocotb-bus Contributors"], 1)] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + "index", + "cocotb_bus", + "cocotb-bus Documentation", + "cocotb-bus Contributors", + "cocotb", + '''Bus Drivers and Monitors for the + COroutine COsimulation TestBench + environment for efficient verification of RTL using Python.''', + "Miscellaneous", + ), +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + +todo_include_todos = False + +# -- Extra setup for spelling check -------------------------------------------- + +# Spelling language. +spelling_lang = "en_US" +tokenizer_lang = spelling_lang + +# Location of word list. +spelling_word_list_filename = ["spelling_wordlist.txt"] +spelling_exclude_patterns = ["generated/**", "master-notes.rst"] + +spelling_ignore_pypi_package_names = False +spelling_ignore_wiki_words = False +spelling_show_suggestions = True +spelling_ignore_acronyms = True + +# -- Extra setup for inheritance_diagram directive which uses graphviz --------- + +graphviz_output_format = "svg" + +# -- Extra setup for towncrier ------------------------------------------------- +# see also https://towncrier.readthedocs.io/en/actual-freaking-docs/ + +# we pass the name and version directly, to avoid towncrier failing to import the non-installed version +in_progress_notes = subprocess.check_output( + ["towncrier", "--draft", "--name", "cocotb_bus", "--version", release], + cwd="../..", + universal_newlines=True, +) +with open("master-notes.rst", "w") as f: + f.write(in_progress_notes) + +# -- External link helpers ----------------------------------------------------- + +extlinks = { + "wikipedia": ("https://en.wikipedia.org/wiki/%s", None), + "reposharp": ("https://github.com/cocotb/cocotb-bus/issues/%s", "#"), + "reposrc": ("https://github.com/cocotb/cocotb-bus/blob/master/%s", None), +} diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst new file mode 100644 index 00000000..a4480cb7 --- /dev/null +++ b/docs/source/glossary.rst @@ -0,0 +1,71 @@ +.. _glossary: + +Glossary +======== + +.. glossary:: + + BFM + Bus Functional Model + + coroutine function + The definition of a function that, when called, returns a coroutine object. + Implemented using :keyword:`async` functions. + See also the :term:`Python glossary `. + + coroutine + The result of calling a :term:`coroutine function`. + Coroutines are not run immediately, you must either + :keyword:`await` on them which blocks the awaiting coroutine until it is finished; + or turn them into a :term:`task`, which can be run concurrently. + See also the :term:`Python glossary `. + + DUT + Design under Test + + DUV + Design under Verification + + FLI + Foreign Language Interface. Mentor Graphics' equivalent to :term:`VHPI` + + GPI + Generic Procedural Interface, cocotb's abstraction over :term:`VPI`, :term:`VHPI`, and :term:`FLI`. + + HAL + Hardware Abstraction Layer + + HDL + Hardware Description Language + + MDV + Metric-driven Verification + + RTL + Register Transfer Level + + task + A :term:`coroutine` that can be run concurrently. + + UVM + Universal Verification Methodology + + VHPI + The VHDL Procedural Interface, an application-programming interface to VHDL tools. + + VIP + Verification IP + + VPI + The Verilog Procedural Interface, an application-programming interface to (System)Verilog tools. + Its original name was "PLI 2.0". + +.. + Driver + TBD + + Monitor + TBD + + Scoreboard + TBD diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..3616cbd7 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,152 @@ +###################################### +Welcome to cocotb-bus's documentation! +###################################### + +.. + This documentation tries to follow https://www.divio.com/blog/documentation/ (Daniele Procida) + Other media about the same topic: + - https://ep2018.europython.eu/media/conference/slides/get-your-documentation-right.pdf + - https://www.youtube.com/watch?v=t4vKPhjcMZg + - A good example: http://docs.django-cms.org/en/latest/contributing/documentation.html#contributing-documentation + + See also https://github.com/cocotb/cocotb/wiki/Howto:-Writing-Documentation + +******************* +What is cocotb-bus? +******************* + +**cocotb-bus** is: + +* A set of Driver's & Monitor base classes to assist in creating cocotb VIP's. +* An implementation of scoreboard class for cocotb. +* Sample implementation of Protocol Bus drivers using these classes. + + +.. toctree:: + :maxdepth: 1 + :hidden: + + testbench_tools + +.. + install + quickstart + Tutorials - lessons that take the reader by the hand through a series of steps to complete a project + (Example: kid cooking; learning-oriented) + + - learning by doing + - getting started + - inspiring confidence + - repeatability + - immediate sense of achievement + - concreteness, not abstraction + - minimum necessary explanation + - no distractions + +.. +.. toctree:: + :maxdepth: 1 + :caption: Tutorials + :name: tutorials + :hidden: + + examples + + +.. + How-To Guides - guides that take the reader through the steps required to solve a common problem + (Example: recipe; problem-oriented) + + - a series of steps + - a focus on the goal + - addressing a specific question + - no unnecessary explanation + - a little flexibility + - practical usability + - good naming + +.. +.. toctree:: + :maxdepth: 1 + :caption: How-to Guides + :name: howto_guides + :hidden: + + writing_testbenches + runner + coroutines + triggers + custom_flows + rotating_logger + +.. todo:: + - Howto use the baseclasses to create VIP + - Roadmap + + +.. + Explanation (Background, Discussions) - discussions that clarify and illuminate a particular topic + (Example: history of cooking; understanding-oriented) + + - giving context + - explaining why + - multiple examples, alternative approaches + - making connections + - no instruction or technical description + +.. +.. toctree:: + :maxdepth: 1 + :caption: Key topics + :name: key_topics + :hidden: + + install_devel + troubleshooting + + + +.. + Reference - technical descriptions of the machinery and its operation + (Example: Wikipedia pages of ingredients; information-oriented) + + - structure + - consistency + - description + - accuracy + +.. +.. toctree:: + :maxdepth: 1 + :caption: Reference + :name: reference + :hidden: + + Python Code Library Reference + +.. +.. toctree:: + :maxdepth: 1 + :caption: Development & Community + :name: development_community + :hidden: + + roadmap + contributors + release_notes + further_resources +.. +.. todo:: + - Add "Join us online" and "Contributing" + - In Contributing, add explanation on how to provide a PR, how to test existing PRs, etc. + - merge `further_resources` into Contributing + +.. toctree:: + :maxdepth: 1 + :caption: Index + :name: index + :hidden: + + Classes, Methods, Variables etc. + Python Modules + glossary diff --git a/docs/source/library_reference.rst b/docs/source/library_reference.rst new file mode 100644 index 00000000..37c3cb63 --- /dev/null +++ b/docs/source/library_reference.rst @@ -0,0 +1,76 @@ +***************** +Library Reference +***************** + +.. spelling:: + AXIProtocolError + BusDriver + De + Re + ReadOnly + args + cbNextSimTime + ing + sim + stdout + un + +Modules +======= + +Bus +--- + +.. autoclass:: cocotb_bus.bus.Bus + :members: + :member-order: bysource + +Driver +------ + +.. autoclass:: cocotb_bus.drivers.Driver + :members: + :member-order: bysource + :private-members: + +.. autoclass:: cocotb_bus.drivers.BitDriver + :members: + :member-order: bysource + :show-inheritance: + :private-members: + +.. autoclass:: cocotb_bus.drivers.BusDriver + :members: + :member-order: bysource + :show-inheritance: + :private-members: + +.. autoclass:: cocotb_bus.drivers.ValidatedBusDriver + :members: + :member-order: bysource + :show-inheritance: + :private-members: + +Monitor +------- + +.. autoclass:: cocotb_bus.monitors.Monitor + :members: + :member-order: bysource + :private-members: + +.. autoclass:: cocotb_bus.monitors.BusMonitor + :members: + :member-order: bysource + :show-inheritance: + :private-members: + +Scoreboard +---------- + +.. automodule:: cocotb_bus.scoreboard + :members: + :member-order: bysource + :show-inheritance: + :synopsis: Class for scoreboards. + diff --git a/docs/source/spelling_wordlist.txt b/docs/source/spelling_wordlist.txt new file mode 100644 index 00000000..e95bd571 --- /dev/null +++ b/docs/source/spelling_wordlist.txt @@ -0,0 +1,130 @@ +AMS +AXI +Aldec +Altera +Avalon +Cosimulation +Deprecations +FLI +GPI +GTKWave +Gigabit +GitHub +GitLab +HDL +IPython +Indices +Lite +MiB +Microsemi +MinGW +ModelSim +Msys +NVC +PyPi +Questa +Quickstart +README +Roadmap +Synopsys +SystemVerilog +TODO +Tachyon +Tcl +Ubuntu +VHDL +VHPI +VPI +Verilator +Verilog +WaveDrom +Wiki +XML +Xcelium +backpressure +bugfixes +builtin +callgraph +cartesian +cocotb +coroutine +coroutines +diff +docstring +durations +endian +endianness +filename +gotchas +hexdump +implementors +incrementing +indexable +installable +instantiation +iterable +libgpi +libpython +lookup +loopback +macOS +makefile +makefiles +metaclass +metadata +microcontroller +msys +multimeter +mutex +namespace +namespaced +namespaces +ns +packetized +picoseconds +plusargs +postfix +pre +prebuilt +prepend +prepends +ps +refactorings +runtime +schedulable +scoreboarded +scoreboarding +signedness +simulatormodule +stacktrace +subclassed +subclasses +subdirectories +subdirectory +subtypes +swapper +testbench +testbenches +testbenching +testcase +testcases +timeout +timestamps +timestep +timesteps +todo +toplevel +tracebacks +trimmable +tuple +tuples +unhandled +unresolvable +unselect +utils +versa +waitable +waveform +waveforms +whitespace +xUnit diff --git a/docs/source/testbench_tools.rst b/docs/source/testbench_tools.rst new file mode 100644 index 00000000..2d0512ca --- /dev/null +++ b/docs/source/testbench_tools.rst @@ -0,0 +1,156 @@ +*************** +Testbench Tools +*************** + +Buses +===== + +Buses are simply defined as collection of signals. The :class:`.Bus` class +will automatically bundle any group of signals together that are named similar +to ``dut.``. For instance, + +.. code-block:: python3 + + dut.stream_in_valid + dut.stream_in_data + +have a bus name of ``stream_in``, a separator of ``_``, and signal names of +``valid`` and ``data``. A list of signal names, or a dictionary mapping attribute +names to signal names is also passed into the :class:`.Bus` class. Buses can +have values driven onto them, be captured (returning a dictionary), or sampled +and stored into a similar object. + +.. code-block:: python3 + + stream_in_bus = Bus(dut, "stream_in", ["valid", "data"]) # '_' is the default separator + + +Driving Buses +============= + +Examples and specific bus implementation bus drivers (AMBA, Avalon, XGMII, and +others) exist in the :class:`.Driver` class enabling a test to append +transactions to perform the serialization of transactions onto a physical +interface. Here is an example using the Avalon bus driver in the ``endian_swapper`` +example: + +.. code-block:: python3 + + class EndianSwapperTB(object): + + def __init__(self, dut, debug=False): + self.dut = dut + self.stream_in = AvalonSTDriver(dut, "stream_in", dut.clk) + + async def run_test(dut, data_in=None, config_coroutine=None, idle_inserter=None, + backpressure_inserter=None): + + cocotb.fork(Clock(dut.clk, 5000).start()) + tb = EndianSwapperTB(dut) + + await tb.reset() + dut.stream_out_ready <= 1 + + if idle_inserter is not None: + tb.stream_in.set_valid_generator(idle_inserter()) + + # Send in the packets + for transaction in data_in(): + await tb.stream_in.send(transaction) + + +Monitoring Buses +================ + +For our testbenches to actually be useful, we have to monitor some of these +buses, and not just drive them. That's where the :class:`.Monitor` class +comes in, with pre-built monitors for Avalon and XGMII buses. The +Monitor class is a base class which you are expected to derive for your +particular purpose. You must create a :any:`_monitor_recv()` function which is +responsible for determining 1) at what points in simulation to call the +:any:`_recv()` function, and 2) what transaction values to pass to be stored in the +monitors receiving queue. Monitors are good for both outputs of the :term:`DUT` for +verification, and for the inputs of the :term:`DUT`, to drive a test model of the :term:`DUT` +to be compared to the actual :term:`DUT`. For this purpose, input monitors will often +have a callback function passed that is a model. This model will often generate +expected transactions, which are then compared using the :class:`.Scoreboard` +class. + +.. code-block:: python3 + + # ============================================================================== + class BitMonitor(Monitor): + """Observes single input or output of DUT.""" + def __init__(self, name, signal, clock, callback=None, event=None): + self.name = name + self.signal = signal + self.clock = clock + Monitor.__init__(self, callback, event) + + async def _monitor_recv(self): + clkedge = RisingEdge(self.clock) + + while True: + # Capture signal at rising edge of clock + await clkedge + vec = self.signal.value + self._recv(vec) + + # ============================================================================== + def input_gen(): + """Generator for input data applied by BitDriver""" + while True: + yield random.randint(1,5), random.randint(1,5) + + # ============================================================================== + class DFF_TB(object): + def __init__(self, dut, init_val): + + self.dut = dut + + # Create input driver and output monitor + self.input_drv = BitDriver(dut.d, dut.c, input_gen()) + self.output_mon = BitMonitor("output", dut.q, dut.c) + + # Create a scoreboard on the outputs + self.expected_output = [ init_val ] + + # Reconstruct the input transactions from the pins + # and send them to our 'model' + self.input_mon = BitMonitor("input", dut.d, dut.c, callback=self.model) + + def model(self, transaction): + """Model the DUT based on the input transaction.""" + # Do not append an output transaction for the last clock cycle of the + # simulation, that is, after stop() has been called. + if not self.stopped: + self.expected_output.append(transaction) + + +Tracking testbench errors +========================= + +The :class:`.Scoreboard` class is used to compare the actual outputs to +expected outputs. Monitors are added to the scoreboard for the actual outputs, +and the expected outputs can be either a simple list, or a function that +provides a transaction. Here is some code from the ``dff`` example, similar to +above with the scoreboard added. + +.. code-block:: python3 + + class DFF_TB(object): + def __init__(self, dut, init_val): + self.dut = dut + + # Create input driver and output monitor + self.input_drv = BitDriver(dut.d, dut.c, input_gen()) + self.output_mon = BitMonitor("output", dut.q, dut.c) + + # Create a scoreboard on the outputs + self.expected_output = [ init_val ] + self.scoreboard = Scoreboard(dut) + self.scoreboard.add_interface(self.output_mon, self.expected_output) + + # Reconstruct the input transactions from the pins + # and send them to our 'model' + self.input_mon = BitMonitor("input", dut.d, dut.c,callback=self.model) diff --git a/noxfile.py b/noxfile.py index 525e1929..6a17bf48 100644 --- a/noxfile.py +++ b/noxfile.py @@ -6,3 +6,72 @@ def tests(session): session.install("pytest", "coverage") session.install(".") session.run("make", external=True) + + +@nox.session +def doc(session: nox.Session) -> None: + create_env_for_docs_build(session) + session.run("pip", "install", ".") + outdir = session.cache_dir / "docs_out" + session.run("sphinx-build", "./docs/source", + str(outdir), "--color", "-b", "html") + index = (outdir / "index.html").resolve().as_uri() + session.log(f"Documentation is available at {index}") + + +def create_env_for_docs_build(session: nox.Session) -> None: + session.run("pip", "install", "-r", "docs/requirements.txt") + + +@nox.session +def docs_preview(session: nox.Session) -> None: + """Build a live preview of the documentation""" + create_env_for_docs_build(session) + # Editable install allows editing cocotb_bus source and seing it updated in the live preview + session.run("pip", "install", "-e", ".") + session.run("pip", "install", "sphinx-autobuild") + outdir = session.cache_dir / "docs_out" + session.run( + "sphinx-autobuild", + # Ignore directories which cause a rebuild loop. + "--ignore", + "*/source/master-notes.rst", + # Also watch the cocotb source directory to rebuild the API docs on + # changes to cocotb code. + "--watch", + "cocotb_bus", + "./docs/source", + str(outdir), + ) + + +@nox.session +def docs_linkcheck(session: nox.Session) -> None: + """invoke sphinx-build to linkcheck the docs""" + create_env_for_docs_build(session) + session.run("pip", "install", ".") + outdir = session.cache_dir / "docs_out" + session.run( + "sphinx-build", + "./docs/source", + str(outdir), + "--color", + "-b", + "linkcheck", + ) + + +@nox.session +def docs_spelling(session: nox.Session) -> None: + """invoke sphinx-build to spellcheck the docs""" + create_env_for_docs_build(session) + session.run("pip", "install", ".") + outdir = session.cache_dir / "docs_out" + session.run( + "sphinx-build", + "./docs/source", + str(outdir), + "--color", + "-b", + "spelling", + ) diff --git a/pyproject.toml b/pyproject.toml index 9787c3bd..e663effe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,38 @@ [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" + +[tool.towncrier] + package = "cocotb_bus" + directory = "docs/source/newsfragments" + filename = "docs/source/release_notes.rst" + issue_format = ":pr:`{issue}`" + # The first underline is used for the version/date header, + # the second underline for the subcategories (like 'Features') + underlines = ["=", "-"] + all_bullets = false + + [[tool.towncrier.type]] + directory = "feature" + name = "Features" + showcontent = true + + [[tool.towncrier.type]] + directory = "bugfix" + name = "Bugfixes" + showcontent = true + + [[tool.towncrier.type]] + directory = "doc" + name = "Improved Documentation" + showcontent = true + + [[tool.towncrier.type]] + directory = "removal" + name = "Deprecations and Removals" + showcontent = true + + [[tool.towncrier.type]] + directory = "change" + name = "Changes" + showcontent = true