Merge pull request #78 from antmicro/complete-docs

Complete docs
diff --git a/MANIFEST.in b/MANIFEST.in
index d6ba619..e278e4f 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -23,6 +23,7 @@
 recursive-include docs *.txt
 recursive-include docs *.yml
 recursive-include docs Makefile
+recursive-include docs *.rst.template
 prune docs/_*
 prune docs/env
 
diff --git a/docs/Makefile b/docs/Makefile
index e0fbd13..4673ff7 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -13,6 +13,7 @@
 MAKEDIR := $(dir $(lastword $(MAKEFILE_LIST)))
 
 # You can set these variables from the command line.
+COLLECTEXAMPLES = [ -e env/bin/activate ] && source env/bin/activate; python -c "from collect_examples import collect_examples; collect_examples()"
 SPHINXOPTS      =
 SPHINXBUILD     = [ -e env/bin/activate ] && source env/bin/activate; sphinx-build
 SPHINXAUTOBUILD = [ -e env/bin/activate ] && source env/bin/activate; sphinx-autobuild --watch $(MAKEDIR)../tests
@@ -20,6 +21,9 @@
 SOURCEDIR       = .
 BUILDDIR        = _build
 OSFLAG          =
+LIVEHTML_HOST   = 127.0.0.1
+LIVEHTML_PORT   = 8000
+
 UNAME_S := $(shell uname -s)
 ifneq (, $(findstring Linux, $(UNAME_S)))
 	OSFLAG := Linux
@@ -40,7 +44,9 @@
 	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 livehtml:
-	@$(SPHINXAUTOBUILD) -b html --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
+	rm -rf examples
+	@$(COLLECTEXAMPLES) # Do this here to prevent sphinx-autobuild from slowly detecting all the changes
+	@$(SPHINXAUTOBUILD) -b html --host ${LIVEHTML_HOST} --port ${LIVEHTML_PORT} --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
 
 .PHONY: help livehtml Makefile
 
@@ -60,32 +66,7 @@
 
 .PHONY: env
 
-# Update fuzzer / minitest markdown links.
-tests-links:
-	@mkdir -p $(MAKEDIR)/examples
-	@cd $(MAKEDIR)/examples && find -name '*.md' -delete && find -type d -empty -delete
-	@cd $(MAKEDIR)/examples && \
-		for I in $$(cd ../../tests/ ; find -name '*.md' | sort); do \
-			F=$$(dirname $$I); D=$$(dirname $$F); N=$$(basename $$F); \
-			S=../../tests/$$I; O=$$D/$$N.md; \
-			if [ ! -d $$D ]; then \
-				mkdir -p $$D; \
-			fi; \
-			ln -sf $$(realpath $$S --relative-to=$$D) $$O; \
-		done
-	@cd $(MAKEDIR)/examples && \
-		for I in $$(cd ../../tests/ ; find -name '*.svg' -o -name '*.png' | sort); do \
-			F=$$(dirname $$I); D=$$(dirname $$F); N=$$(basename $$I); \
-			S=../../tests/$$I; O=$$D/$$N; \
-			ln -sf $$(realpath $$S --relative-to=$$D) $$O; \
-		done
-
-links: tests-links
-	@true
-
-.PHONY: tests-links links
-
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile links
+%: Makefile
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/collect_examples.py b/docs/collect_examples.py
new file mode 100644
index 0000000..d640df1
--- /dev/null
+++ b/docs/collect_examples.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020  The SymbiFlow Authors.
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier:	ISC
+
+import os
+from shutil import copy, copytree, ignore_patterns
+
+from make_xml_for_docs import make_xml_for_docs
+
+# =============================================================================
+
+
+README_NAME = "README.rst"
+TEMPLATE_NAME = "examples.rst.template"
+INDEX_NAME = "examples.rst"
+
+
+def process_verilog_files(src_dir, dst_dir):
+    """
+    Looks for Verilog models for V2X and runs make_xml_for_docs on them.
+
+    If at least one Verilog model is found at a directory level then
+    the function does not look deeper. Otherwise it searches for models
+    recursively.
+    """
+
+    got_verilog = False
+
+    # Find and process all verilog files at this directory level
+    for f in os.listdir(src_dir):
+        f_name = os.path.join(src_dir, f)
+        if os.path.isfile(f_name) and f_name.endswith(".sim.v"):
+            got_verilog = True
+
+            make_xml_for_docs(f_name, dst_dir)
+
+    # Don't go deeper if one was found
+    if got_verilog is True:
+        return
+
+    # Look into subdirectories
+    for d in os.listdir(src_dir):
+        d_name = os.path.join(src_dir, d)
+        if os.path.isdir(d_name):
+
+            process_verilog_files(
+                os.path.join(src_dir, d),
+                os.path.join(dst_dir, d)
+            )
+
+
+def collect_examples():
+    """
+    Collects test designs that have readme files and converts them for
+    documentation examples.
+    """
+
+    # Base directory for tests
+    tests_dir = os.path.abspath(
+        os.path.join(
+            os.path.dirname(__file__),
+            "../tests"
+        )
+    )
+
+    # Base directory for examples
+    examples_dir = os.path.abspath(
+        os.path.join(
+            os.path.dirname(__file__),
+            "examples"
+        )
+    )
+
+    # Skip if the directory already exist
+    if os.path.isdir(examples_dir):
+        return
+
+    print("Collecting test designs and including them in \"examples\" section")
+
+    # Create the directory
+    os.makedirs(examples_dir, exist_ok=True)
+
+    # Look for all subdirectories that have "readme.rst" file inside
+    tests = []
+    for d in os.listdir(tests_dir):
+
+        # Only directories
+        d_name = os.path.join(tests_dir, d)
+        if os.path.isdir(d_name):
+
+            # Must contain the readme file
+            f_name = os.path.join(d_name, README_NAME)
+            if os.path.isfile(f_name):
+                tests.append((d, d_name,))
+
+    # Process each test
+    check_ignore = ignore_patterns("*.v", "golden.*.xml")
+    for test_name, test_src in tests:
+
+        test_rel = os.path.relpath(test_src, tests_dir)
+        test_dst = os.path.join(examples_dir, test_rel)
+
+        print("", test_name)
+
+        # Copy files
+        copytree(test_src, test_dst, ignore=check_ignore)
+
+        # Build XMLs for verilog giles
+        process_verilog_files(test_src, test_dst)
+
+    # Build examples.rst
+    tname = os.path.join(os.path.dirname(__file__), TEMPLATE_NAME)
+    fname = os.path.join(examples_dir, INDEX_NAME)
+
+    with open(tname, "r") as fsrc, open(fname, "w") as fdst:
+
+        # Copy
+        for line in fsrc:
+            fdst.write(line)
+
+        # Append included tests
+        tests = sorted(tests, key=lambda t:t[0])
+        for test_name, _ in tests:
+            fdst.write("   {}/{}\n".format(test_name, README_NAME))
+
+
+if __name__ == "__main__":
+    collect_examples()
diff --git a/docs/conf.py b/docs/conf.py
index e41a90e..7cd5003 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -35,6 +35,13 @@
 sys.path.insert(0, os.path.abspath('.'))
 from markdown_code_symlinks import LinkParser, MarkdownSymlinksDomain  # noqa
 
+from sphinx.highlighting import lexers
+from pygments.lexers.hdl import VerilogLexer
+
+from collect_examples import collect_examples
+
+lexers['verilog'] = VerilogLexer(tabsize=2)
+
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
@@ -53,9 +60,12 @@
     'sphinx.ext.todo',
     'sphinx_markdown_tables',
     'symbolator_sphinx',
-    'sphinxcontrib_verilog_diagrams'
+    'sphinxcontrib_hdl_diagrams'
 ]
 
+# Make sphinxcontrib_verilog_diagrams use Yosys installed in conda
+hdl_diagram_yosys = "system"
+
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
@@ -90,7 +100,6 @@
     import subprocess
     subprocess.call('git fetch origin --unshallow', cwd=docs_dir, shell=True)
     subprocess.check_call('git fetch origin --tags', cwd=docs_dir, shell=True)
-    subprocess.check_call('make links', cwd=docs_dir, shell=True)
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -244,6 +253,9 @@
 
 
 def setup(app):
+    # Collect tests to form examples
+    collect_examples()
+
     github_code_repo = 'https://github.com/SymbiFlow/python-symbiflow-v2x/'
     github_code_branch = 'blob/master/'
 
diff --git a/docs/environment.yml b/docs/environment.yml
index 794b84c..2cf62d9 100644
--- a/docs/environment.yml
+++ b/docs/environment.yml
@@ -1,20 +1,20 @@
 name: v2x-docs
 channels:
-- SymbiFlow
+- symbiflow
 - conda-forge
-- defaults
 dependencies:
 - python=3.7
 - pip
 - pycairo
 - pango
 - pygobject
-- yosys
+- symbiflow-yosys
 - netlistsvg
-# ReadTheDoc dependencies
+# ReadTheDocs dependencies (installed here but also by the docs build CI)
 - mock
 - pillow
-- sphinx=2.4.4
+- sphinx
+- sphinx_rtd_theme
 # Packages installed from PyPI
 - pip:
   - -r file:requirements.txt
diff --git a/docs/examples.rst b/docs/examples.rst.template
similarity index 78%
rename from docs/examples.rst
rename to docs/examples.rst.template
index 158bdd3..68a49e4 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst.template
@@ -5,6 +5,3 @@
 
 .. toctree::
 
-   examples/clocks.rst
-   examples/dsp.rst
-   examples/vtr-examples.rst
\ No newline at end of file
diff --git a/docs/examples/clocks/autodetection.rst b/docs/examples/clocks/autodetection.rst
deleted file mode 100644
index 789cf52..0000000
--- a/docs/examples/clocks/autodetection.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Autodetection of clock from flipflop
-====================================
-
-.. include:: ../../../tests/clocks/dff_one_clock/README.rst
-.. include:: ../../../tests/clocks/dff_comb_one_clock/README.rst
-.. include:: ../../../tests/clocks/dff_two_clocks/README.rst
diff --git a/docs/examples/clocks/manual_input.rst b/docs/examples/clocks/manual_input.rst
deleted file mode 100644
index a5d6b39..0000000
--- a/docs/examples/clocks/manual_input.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Manually set inputs as clock
-============================
-
-.. include:: ../../../tests/clocks/input_attr_clock/README.rst
-.. include:: ../../../tests/clocks/input_attr_not_clock/README.rst
-.. include:: ../../../tests/clocks/input_named_clk/README.rst
-.. include:: ../../../tests/clocks/input_named_regex/README.rst
diff --git a/docs/examples/clocks/manual_output.rst b/docs/examples/clocks/manual_output.rst
deleted file mode 100644
index 39e7894..0000000
--- a/docs/examples/clocks/manual_output.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Manually set outputs as clock
-=============================
-
-.. include:: ../../../tests/clocks/output_attr_clock/README.rst
-.. include:: ../../../tests/clocks/output_named_clk/README.rst
diff --git a/docs/examples/clocks/multiple.rst b/docs/examples/clocks/multiple.rst
deleted file mode 100644
index 596ad4b..0000000
--- a/docs/examples/clocks/multiple.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Multiple clocks
-===============
-
-.. include:: ../../../tests/clocks/multiple_inputs_named_clk/README.rst
-.. include:: ../../../tests/clocks/multiple_outputs_named_clk/README.rst
diff --git a/docs/examples/dsp.rst b/docs/examples/dsp.rst
deleted file mode 100644
index 408007b..0000000
--- a/docs/examples/dsp.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-.. DSP Based Example Tests
-
-DSP
-===
-
-.. toctree::
-
-   dsp/dsp_combinational.md
-   dsp/dsp_in_registered.md
-   dsp/dsp_out_registered.md
-   dsp/dsp_inout_registered.md
-   dsp/dsp_inout_registered_dualclk.md
-   dsp/dsp_partial_registered.md
-   dsp/dsp_modes.md
diff --git a/docs/examples/vtr-examples.rst b/docs/examples/vtr-examples.rst
deleted file mode 100644
index aef1d74..0000000
--- a/docs/examples/vtr-examples.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-.. Examples from the Verilog to Routing documentation / tutorials.
-
-Verilog to Routing
-==================
-
-Primitive Block Timing Modeling Tutorial
-----------------------------------------
-
-.. toctree::
-
-  vtr/lutff-pair.md
-  vtr/full-adder.md
-  vtr/dff.md
diff --git a/docs/index.rst b/docs/index.rst
index 6c144c0..2ed4c79 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -5,4 +5,4 @@
    :glob:
    :hidden:
 
-   examples.rst
+   examples/examples.rst
diff --git a/docs/make_xml_for_docs.py b/docs/make_xml_for_docs.py
new file mode 100644
index 0000000..92d0adc
--- /dev/null
+++ b/docs/make_xml_for_docs.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020  The SymbiFlow Authors.
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier:	ISC
+
+import argparse
+import os
+import shlex
+import re
+
+from v2x import vlog_to_model
+from v2x import vlog_to_pbtype
+from v2x.xmlinc import xmlinc
+
+from vtr_xml_utils.convert import vtr_stylize_xml
+
+# =============================================================================
+
+
+MODULE_RE = re.compile(r"^module\s+(?P<module>[\w$]+)")
+
+
+def make_xml_for_docs(vlog_src, output_dir):
+    """
+    Recursively runs V2X (model and pb_type) on the given Verilog file and
+    all its includes. Output XMLs are stylized using vtr-xml-utils.
+
+    The Verilog file is copied to the output_dir. All include paths are
+    updated so that they reflect the module hierarchy. It is assumed that
+    a Verilog file is named <module>.sim.v. Next V2X is run followed by XML
+    stylization using vtr-xml-utils. 
+
+    The process continues recursively (depth-first).
+    """
+
+    # Make absolute paths
+    vlog_src = os.path.abspath(vlog_src)
+    output_dir = os.path.abspath(output_dir)
+
+    # Make the output directory
+    os.makedirs(output_dir, exist_ok=True)
+
+    # Copy the verilog file, rearrange includes
+    vlog_title = os.path.basename(vlog_src)
+    vlog_dir = os.path.dirname(vlog_src)
+    vlog_dst = os.path.join(output_dir, vlog_title)
+
+    # Scan it for dependencies (includes), rewrite them
+    # Try also to guess the top-level module name (assuming that there is only
+    # one module per file!).
+    vlog_deps = []
+    vlog_top = None
+
+    with open(vlog_src, "r") as fsrc, open(vlog_dst, "w") as fdst:
+        for src_line in fsrc:
+            line = src_line.strip()
+
+            # Modify included file path
+            if line.startswith("`include"):
+                fields = shlex.split(line)
+                assert len(fields) == 2, fields
+
+                dep_src = fields[1]
+                dep_mod = os.path.basename(dep_src).split(".")[0]
+                dep_dst = "./{f}/{f}.sim.v".format(f=dep_mod)
+
+                vlog_deps.append((dep_src, dep_dst,))
+
+                dst_line = "`include \"{}\"\n".format(dep_dst)
+
+            # Pass unchanges
+            else:
+                dst_line = src_line
+
+            # Detect top-level module
+            # FIXME: This is crude and assumes the syntax "module <name>...".
+            # Both the keyword and module name must be in the same line
+            match = MODULE_RE.match(line)
+            if vlog_top is None and match is not None:
+                vlog_top = match.group("module")
+
+            # Write the line
+            fdst.write(dst_line)
+
+    # Process dependencies recursively first
+    for dep_src, dep_dst in vlog_deps:
+        dep_file = os.path.join(vlog_dir, dep_src)
+        dep_dir = os.path.join(output_dir, os.path.dirname(dep_dst))
+
+        make_xml_for_docs(dep_file, dep_dir)
+
+    # Run V2X, but only if an XML is not already provided
+    vlog_mod = vlog_title.split(".")[0]
+
+    model_file = os.path.join(output_dir, vlog_mod + ".model.xml")
+    pbtype_file = os.path.join(output_dir, vlog_mod + ".pb_type.xml")
+
+    if not os.path.isfile(model_file):
+        xml = vlog_to_model.vlog_to_model([vlog_dst], None, vlog_top, model_file)
+        with open(model_file, "w") as fp:
+            fp.write(xml)
+
+        xml = vtr_stylize_xml(model_file)
+        with open(model_file, "w") as fp:
+            fp.write(xml)
+
+    if not os.path.isfile(pbtype_file):
+        xml = vlog_to_pbtype.vlog_to_pbtype([vlog_dst], pbtype_file, vlog_top)
+        with open(pbtype_file, "w") as fp:
+            fp.write(xml)
+
+        xml = vtr_stylize_xml(pbtype_file)
+        with open(pbtype_file, "w") as fp:
+            fp.write(xml)
+
+
+# =============================================================================
+
+
+if __name__ == "__main__":
+
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument(
+        "verilog",
+        help="Input Verilog file"
+    )
+    parser.add_argument(
+        "path",
+        help="Output path"
+    )
+
+    args = parser.parse_args()
+    make_xml_for_docs(args.verilog, args.path)
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 4e1216a..676c8ee 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -8,13 +8,16 @@
 sphinxcontrib-napoleon
 
 # Markdown cross-reference solver library
-git+https://github.com/SymbiFlow/sphinxcontrib-markdown-symlinks.git#egg=markdown_code_symlinks
+git+https://github.com/SymbiFlow/sphinxcontrib-markdown-symlinks.git@master#egg=markdown_code_symlinks
 
-# Verilog diagrams using Yosys + netlistsvg
-git+https://github.com/SymbiFlow/sphinxcontrib-verilog-diagrams.git@dca04723ec07209bd7be3e883e780ca9dd4f271e#egg=sphinxcontrib-verilog-diagrams
+# HDL diagrams using Yosys + netlistsvg
+git+https://github.com/SymbiFlow/sphinxcontrib-hdl-diagrams.git@master#egg=sphinxcontrib-hdl-diagrams
 
 # Module diagrams
-symbolator
+git+https://github.com/SymbiFlow/symbolator.git@master#egg=symbolator
 
 pycairo
 # vext.gi
+
+# V2X
+-e ../
diff --git a/tests/clocks/README.md b/tests/clocks/README.md
deleted file mode 100644
index e969e29..0000000
--- a/tests/clocks/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# `clocks` tests
-
-This directory contains test for the clock detection functionality for the
-`vlog_to_model.py` and `vlog_to_pbtype.py` tool.
-
-
-## Detection of clock signals
-
- - [ ] Signal name matches the regexp `[a-z_]*clk[a-z0-9]*$`
- - [ ] Manually set via the `(* CLOCK *)` or `(* CLOCK=1 *)` Verilog attribute.
- - [ ] Manually cleared via the `(* CLOCK=0 *)` Verilog attribute.
- - [ ] Signal drives synchronous logic (IE flipflop).
- - [ ] Detection in recursive module includes.
-
-## Detection of clock association
-
- - [ ] Clock comes from synchronous logic
- - [ ] Manually associated via `(* ASSOC_CLOCK="<clock signal"> *)` Verilog
-       attribute.
- - [ ] Detection in recursive module includes.
-
diff --git a/docs/examples/clocks.rst b/tests/clocks/README.rst
similarity index 61%
rename from docs/examples/clocks.rst
rename to tests/clocks/README.rst
index fc6adc5..36c3f20 100644
--- a/docs/examples/clocks.rst
+++ b/tests/clocks/README.rst
@@ -6,7 +6,7 @@
 There are various ways for an input or output port to be detected as a clock by v2x. Here are examples on ways to do so.
 
 .. toctree::
-   clocks/autodetection.rst
-   clocks/manual_input.rst
-   clocks/manual_output.rst
-   clocks/multiple.rst
+   autodetection.rst
+   manual_input.rst
+   manual_output.rst
+   multiple.rst
diff --git a/tests/clocks/autodetection.rst b/tests/clocks/autodetection.rst
new file mode 100644
index 0000000..0de1715
--- /dev/null
+++ b/tests/clocks/autodetection.rst
@@ -0,0 +1,7 @@
+Autodetection of clock from flipflop
+====================================
+
+.. toctree::
+   dff_one_clock/README.rst
+   dff_comb_one_clock/README.rst
+   dff_two_clocks/README.rst
diff --git a/tests/clocks/dff_comb_one_clock/README.rst b/tests/clocks/dff_comb_one_clock/README.rst
index d2df31e..1cb714d 100644
--- a/tests/clocks/dff_comb_one_clock/README.rst
+++ b/tests/clocks/dff_comb_one_clock/README.rst
@@ -3,20 +3,20 @@
 
 The following shows a combinational logic design driven by a clock. ``input wire a`` should be detected as a clock because it drives the flip flop.
 
-.. symbolator:: ../../../tests/clocks/dff_comb_one_clock/dff_comb_one_clock.sim.v
+.. symbolator:: dff_comb_one_clock.sim.v
 
-.. verilog-diagram:: ../../../tests/clocks/dff_comb_one_clock/dff_comb_one_clock.sim.v
+.. verilog-diagram:: dff_comb_one_clock.sim.v
    :type: netlistsvg
    :module: BLOCK
 
 |
 
-.. no-license:: ../../../tests/clocks/dff_comb_one_clock/dff_comb_one_clock.sim.v
+.. no-license:: dff_comb_one_clock.sim.v
    :language: verilog
    :caption: tests/clocks/dff_comb_one_clock/dff_comb_one_clock.sim.v
 
 The ``is_clock`` attribute of the ``a`` port is set to 1, and the ports ``b``, ``c`` and ``d`` have their ``clock`` attribute set to ``a``.
 
-.. literalinclude:: ../../../tests/clocks/dff_comb_one_clock/golden.model.xml
+.. literalinclude:: dff_comb_one_clock.model.xml
    :language: xml
-   :caption: tests/clocks/dff_comb_one_clock/golden.model.xml
\ No newline at end of file
+   :caption: dff_comb_one_clock.model.xml
diff --git a/tests/clocks/dff_one_clock/README.rst b/tests/clocks/dff_one_clock/README.rst
index 5301f49..bc7ad5a 100644
--- a/tests/clocks/dff_one_clock/README.rst
+++ b/tests/clocks/dff_one_clock/README.rst
@@ -3,20 +3,20 @@
 
 The following shows a simple D-flip flop driven by one clock. ``input wire a`` should be detected as a clock because it drives the flip flop.
 
-.. symbolator:: ../../../tests/clocks/dff_one_clock/dff_one_clock.sim.v
+.. symbolator:: dff_one_clock.sim.v
 
-.. verilog-diagram:: ../../../tests/clocks/dff_one_clock/dff_one_clock.sim.v
+.. verilog-diagram:: dff_one_clock.sim.v
    :type: netlistsvg
    :module: BLOCK
 
 |
 
-.. no-license:: ../../../tests/clocks/dff_one_clock/dff_one_clock.sim.v
+.. no-license:: dff_one_clock.sim.v
    :language: verilog
    :caption: tests/clocks/dff_one_clock/dff_one_clock.sim.v
 
 As you can see in the generated model, the ``is_clock`` attribute of the ``a`` port is set to 1, while the ``b`` and ``c`` ports have their ``clock`` attribute set to ``a``.
 
-.. literalinclude:: ../../../tests/clocks/dff_one_clock/golden.model.xml
+.. literalinclude:: dff_one_clock.model.xml
    :language: xml
-   :caption: tests/clocks/dff_one_clock/golden.model.xml
+   :caption: dff_one_clock.model.xml
diff --git a/tests/clocks/dff_two_clocks/README.rst b/tests/clocks/dff_two_clocks/README.rst
index 12c9f9a..d58b384 100644
--- a/tests/clocks/dff_two_clocks/README.rst
+++ b/tests/clocks/dff_two_clocks/README.rst
@@ -3,20 +3,20 @@
 
 ``input wire c1`` and ``input wire c2`` should be detected as clocks because they drive the flip flop.
 
-.. symbolator:: ../../../tests/clocks/dff_two_clocks/dff_two_clocks.sim.v
+.. symbolator:: dff_two_clocks.sim.v
 
-.. verilog-diagram:: ../../../tests/clocks/dff_two_clocks/dff_two_clocks.sim.v
+.. verilog-diagram:: dff_two_clocks.sim.v
    :type: netlistsvg
    :module: BLOCK
 
 |
 
-.. no-license:: ../../../tests/clocks/dff_two_clocks/dff_two_clocks.sim.v
+.. no-license:: dff_two_clocks.sim.v
    :language: verilog
    :caption: tests/clocks/dff_two_clocks/dff_two_clocks.sim.v
 
 The ``is_clock`` attribute of the ``c1`` and ``c2`` ports are set to 1, and the ports ``a``, ``b``, ``c``, ``o1`` and ``o2`` have their ``clock`` attribute set to the respective clocks they are driven by.
 
-.. literalinclude:: ../../../tests/clocks/dff_two_clocks/golden.model.xml
+.. literalinclude:: dff_two_clocks.model.xml
    :language: xml
-   :caption: tests/clocks/dff_two_clocks/golden.model.xml
+   :caption: dff_two_clocks.model.xml
diff --git a/tests/clocks/input_attr_clock/README.rst b/tests/clocks/input_attr_clock/README.rst
index c1117d2..dd8ab55 100644
--- a/tests/clocks/input_attr_clock/README.rst
+++ b/tests/clocks/input_attr_clock/README.rst
@@ -3,16 +3,16 @@
 
 The following shows that ``input wire a`` is given the ``(* CLOCK *)`` attribute.
 
-.. symbolator:: ../../../tests/clocks/input_attr_clock/input_attr_clock.sim.v
+.. symbolator:: input_attr_clock.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/input_attr_clock/input_attr_clock.sim.v
+.. no-license:: input_attr_clock.sim.v
    :language: verilog
    :caption: tests/clocks/input_attr_clock/input_attr_clock.sim.v
 
 As such, the ``is_clock`` attribute of the ``a`` port is set to 1.
 
-.. literalinclude:: ../../../tests/clocks/input_attr_clock/golden.model.xml
+.. literalinclude:: input_attr_clock.model.xml
    :language: xml
-   :caption: tests/clocks/input_attr_clock/golden.model.xml
\ No newline at end of file
+   :caption: input_attr_clock.model.xml
diff --git a/tests/clocks/input_attr_not_clock/README.rst b/tests/clocks/input_attr_not_clock/README.rst
index 40a2f16..e3485fc 100644
--- a/tests/clocks/input_attr_not_clock/README.rst
+++ b/tests/clocks/input_attr_not_clock/README.rst
@@ -3,24 +3,24 @@
 
 ``input wire a`` should be detected as a clock because it drives the flip flop. However, it has the attribute CLOCK set to 0 which should force it to be a regular input.
 
-.. symbolator:: ../../../tests/clocks/input_attr_not_clock/block.sim.v
+.. symbolator:: block.sim.v
 
-.. verilog-diagram:: ../../../tests/clocks/input_attr_not_clock/block.sim.v
+.. verilog-diagram:: block.sim.v
    :type: netlistsvg
    :module: BLOCK
 
 |
 
-.. no-license:: ../../../tests/clocks/input_attr_not_clock/block.sim.v
+.. no-license:: block.sim.v
    :language: verilog
    :caption: tests/clocks/input_attr_not_clock/block.sim.v
 
 As such, the ``is_clock`` attribute of the ``a`` port is not set.
 
-.. literalinclude:: ../../../tests/clocks/input_attr_not_clock/golden.model.xml
+.. literalinclude:: block.model.xml
    :language: xml
-   :caption: tests/clocks/input_attr_not_clock/golden.model.xml
+   :caption: block.model.xml
 
-.. literalinclude:: ../../../tests/clocks/input_attr_not_clock/golden.pb_type.xml
+.. literalinclude:: block.pb_type.xml
    :language: xml
-   :caption: tests/clocks/input_attr_not_clock/golden.pb_type.xml
\ No newline at end of file
+   :caption: block.pb_type.xml
diff --git a/tests/clocks/input_named_clk/README.rst b/tests/clocks/input_named_clk/README.rst
index b0a8ee0..ac34c05 100644
--- a/tests/clocks/input_named_clk/README.rst
+++ b/tests/clocks/input_named_clk/README.rst
@@ -3,16 +3,16 @@
 
 An input wire can be set as a clock by assigning ``clk`` as its name.
 
-.. symbolator:: ../../../tests/clocks/input_named_clk/input_named_clk.sim.v
+.. symbolator:: input_named_clk.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/input_named_clk/input_named_clk.sim.v
+.. no-license:: input_named_clk.sim.v
    :language: verilog
    :caption: tests/clocks/input_named_clk/input_named_clk.sim.v
 
 As such, the ``is_clock`` attribute of the ``clk`` port is set to 1, without needing to set anything else in the verilog code.
 
-.. literalinclude:: ../../../tests/clocks/input_named_clk/golden.model.xml
+.. literalinclude:: input_named_clk.model.xml
    :language: xml
-   :caption: tests/clocks/input_named_clk/golden.model.xml
\ No newline at end of file
+   :caption: input_named_clk.model.xml
diff --git a/tests/clocks/input_named_regex/README.rst b/tests/clocks/input_named_regex/README.rst
index 04b7eed..3aabd8a 100644
--- a/tests/clocks/input_named_regex/README.rst
+++ b/tests/clocks/input_named_regex/README.rst
@@ -3,20 +3,20 @@
 
 An input wire can be set as a clock by having ``clk`` in its name (case insensitive).
 
-.. symbolator:: ../../../tests/clocks/input_named_regex/block.sim.v
+.. symbolator:: block.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/input_named_regex/block.sim.v
+.. no-license:: block.sim.v
    :language: verilog
    :caption: tests/clocks/input_named_regex/block.sim.v
 
 As such, the ``is_clock`` attribute of wires with a variation of ``clk`` in their name is set to 1.
 
-.. literalinclude:: ../../../tests/clocks/input_named_regex/golden.model.xml
+.. literalinclude:: block.model.xml
    :language: xml
-   :caption: tests/clocks/input_named_regex/golden.model.xml
+   :caption: block.model.xml
 
-.. literalinclude:: ../../../tests/clocks/input_named_regex/golden.pb_type.xml
+.. literalinclude:: block.pb_type.xml
    :language: xml
-   :caption: tests/clocks/input_named_regex/golden.pb_type.xml
\ No newline at end of file
+   :caption: block.pb_type.xml
diff --git a/tests/clocks/manual_input.rst b/tests/clocks/manual_input.rst
new file mode 100644
index 0000000..bf0fad9
--- /dev/null
+++ b/tests/clocks/manual_input.rst
@@ -0,0 +1,8 @@
+Manually set inputs as clock
+============================
+
+.. toctree::
+   input_attr_clock/README.rst
+   input_attr_not_clock/README.rst
+   input_named_clk/README.rst
+   input_named_regex/README.rst
diff --git a/tests/clocks/manual_output.rst b/tests/clocks/manual_output.rst
new file mode 100644
index 0000000..c2bf9d5
--- /dev/null
+++ b/tests/clocks/manual_output.rst
@@ -0,0 +1,6 @@
+Manually set outputs as clock
+=============================
+
+.. toctree::
+   output_attr_clock/README.rst
+   output_named_clk/README.rst
diff --git a/tests/clocks/multiple.rst b/tests/clocks/multiple.rst
new file mode 100644
index 0000000..5f78d17
--- /dev/null
+++ b/tests/clocks/multiple.rst
@@ -0,0 +1,6 @@
+Multiple clocks
+===============
+
+.. toctree::
+   multiple_inputs_named_clk/README.rst
+   multiple_outputs_named_clk/README.rst
diff --git a/tests/clocks/multiple_inputs_named_clk/README.rst b/tests/clocks/multiple_inputs_named_clk/README.rst
index 3e802b5..3b4e6fd 100644
--- a/tests/clocks/multiple_inputs_named_clk/README.rst
+++ b/tests/clocks/multiple_inputs_named_clk/README.rst
@@ -3,16 +3,16 @@
 
 ``input wire rdclk`` and ``input wire wrclk`` have ``clk`` in their names, hence are recognized as clock inputs by v2x.
 
-.. symbolator:: ../../../tests/clocks/multiple_inputs_named_clk/multiple_inputs_named_clk.sim.v
+.. symbolator:: multiple_inputs_named_clk.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/multiple_inputs_named_clk/multiple_inputs_named_clk.sim.v
+.. no-license:: multiple_inputs_named_clk.sim.v
    :language: verilog
    :caption: tests/clocks/multiple_inputs_named_clk/multiple_inputs_named_clk.sim.v
 
 As such, the ``is_clock`` attribute of the ``rdclk`` and ``wrclk`` ports are set to 1.
 
-.. literalinclude:: ../../../tests/clocks/multiple_inputs_named_clk/golden.model.xml
+.. literalinclude:: multiple_inputs_named_clk.model.xml
    :language: xml
-   :caption: tests/clocks/multiple_inputs_named_clk/golden.model.xml
\ No newline at end of file
+   :caption: multiple_inputs_named_clk.model.xml
diff --git a/tests/clocks/multiple_outputs_named_clk/README.rst b/tests/clocks/multiple_outputs_named_clk/README.rst
index 6c2ef3c..cf18bae 100644
--- a/tests/clocks/multiple_outputs_named_clk/README.rst
+++ b/tests/clocks/multiple_outputs_named_clk/README.rst
@@ -3,16 +3,16 @@
 
 ``output wire rdclk`` and ``output wire wrclk`` have ``clk`` in their names, hence are recognized as clock inputs by v2x.
 
-.. symbolator:: ../../../tests/clocks/multiple_outputs_named_clk/multiple_outputs_named_clk.sim.v
+.. symbolator:: multiple_outputs_named_clk.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/multiple_outputs_named_clk/multiple_outputs_named_clk.sim.v
+.. no-license:: multiple_outputs_named_clk.sim.v
    :language: verilog
    :caption: tests/clocks/multiple_outputs_named_clk/multiple_outputs_named_clk.sim.v
 
 As such, the ``is_clock`` attribute of the ``rdclk`` and ``wrclk`` ports are set to 1.
 
-.. literalinclude:: ../../../tests/clocks/multiple_outputs_named_clk/golden.model.xml
+.. literalinclude:: multiple_outputs_named_clk.model.xml
    :language: xml
-   :caption: tests/clocks/multiple_outputs_named_clk/golden.model.xml
\ No newline at end of file
+   :caption: multiple_outputs_named_clk.model.xml
diff --git a/tests/clocks/output_attr_clock/README.rst b/tests/clocks/output_attr_clock/README.rst
index 88ba93a..b928a77 100644
--- a/tests/clocks/output_attr_clock/README.rst
+++ b/tests/clocks/output_attr_clock/README.rst
@@ -3,16 +3,16 @@
 
 The following shows that ``output wire o`` is given the ``(* CLOCK *)`` attribute.
 
-.. symbolator:: ../../../tests/clocks/output_attr_clock/output_attr_clock.sim.v
+.. symbolator:: output_attr_clock.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/output_attr_clock/output_attr_clock.sim.v
+.. no-license:: output_attr_clock.sim.v
    :language: verilog
    :caption: tests/clocks/output_attr_clock/output_attr_clock.sim.v
 
 As such, the ``is_clock`` attribute of the ``o`` port is set to 1.
 
-.. literalinclude:: ../../../tests/clocks/output_attr_clock/golden.model.xml
+.. literalinclude:: output_attr_clock.model.xml
    :language: xml
-   :caption: tests/clocks/output_attr_clock/golden.model.xml
\ No newline at end of file
+   :caption: output_attr_clock.model.xml
diff --git a/tests/clocks/output_named_clk/README.rst b/tests/clocks/output_named_clk/README.rst
index 5a43c72..a93e3de 100644
--- a/tests/clocks/output_named_clk/README.rst
+++ b/tests/clocks/output_named_clk/README.rst
@@ -3,16 +3,16 @@
 
 An output wire can be set as a clock by assigning ``clk`` as its name.
 
-.. symbolator:: ../../../tests/clocks/output_named_clk/output_named_clk.sim.v
+.. symbolator:: output_named_clk.sim.v
 
 |
 
-.. no-license:: ../../../tests/clocks/output_named_clk/output_named_clk.sim.v
+.. no-license:: output_named_clk.sim.v
    :language: verilog
    :caption: tests/clocks/output_named_clk/output_named_clk.sim.v
 
 As such, the ``is_clock`` attribute of the ``clk`` output port is set to 1.
 
-.. literalinclude:: ../../../tests/clocks/output_named_clk/golden.model.xml
+.. literalinclude:: output_named_clk.model.xml
    :language: xml
-   :caption: tests/clocks/output_named_clk/golden.model.xml
\ No newline at end of file
+   :caption: output_named_clk.model.xml
diff --git a/tests/dsp/README.rst b/tests/dsp/README.rst
new file mode 100644
index 0000000..627ac28
--- /dev/null
+++ b/tests/dsp/README.rst
@@ -0,0 +1,13 @@
+DSP examples
+============
+
+These are examples of modeling DSP-like complex primitives
+
+.. toctree::
+   dsp_combinational/README.rst
+   dsp_in_registered/README.rst
+   dsp_out_registered/README.rst
+   dsp_inout_registered/README.rst
+   dsp_inout_registered_dualclk/README.rst
+   dsp_partial_registered/README.rst
+   dsp_modes/README.rst
diff --git a/tests/dsp/dsp_combinational/README.md b/tests/dsp/dsp_combinational/README.md
deleted file mode 100644
index f565755..0000000
--- a/tests/dsp/dsp_combinational/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# `dsp_combinational` test
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
-
diff --git a/tests/dsp/dsp_combinational/README.rst b/tests/dsp/dsp_combinational/README.rst
new file mode 100644
index 0000000..0bf3960
--- /dev/null
+++ b/tests/dsp/dsp_combinational/README.rst
@@ -0,0 +1,40 @@
+Combinational DSP
++++++++++++++++++
+
+A combinational DSP block capable of multiplication and division. Modeled as "combinational block" according to |fig60|_ of `Primitive Block Timing Modeling Tutorial <https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#primitive-block-timing-modeling-tutorial>`_.
+
+.. |fig60| replace:: ``Figure 60``
+.. _fig60: https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#combinational-block
+
+|
+
+.. symbolator::  dsp_combinational.sim.v
+
+.. verilog-diagram:: dsp_combinational.sim.v
+   :type: netlistsvg
+   :module: DSP_COMBINATIONAL
+
+|
+
+.. no-license:: dsp_combinational.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_combinational/dsp_combinational.sim.v
+
+.. no-license:: dsp_combinational.model.xml
+   :language: xml
+   :caption: dsp_combinational.model.xml
+
+.. no-license:: dsp_combinational.pb_type.xml
+   :language: xml
+   :caption: dsp_combinational.pb_type.xml
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
diff --git a/tests/dsp/dsp_in_registered/README.md b/tests/dsp/dsp_in_registered/README.md
deleted file mode 100644
index c40ab3f..0000000
--- a/tests/dsp/dsp_in_registered/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# `dsp_in_registered` test
-
-Test for "DSP style" block with all inputs registered.
-
-The tests use model from [`fig42-dff`](FIXME) and
-[`dsp_combinational`](../dsp_combinational/README.md) tests.
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
- - [ ] `pack_pattern` defined on wire connections with `pack` attribute
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
diff --git a/tests/dsp/dsp_in_registered/README.rst b/tests/dsp/dsp_in_registered/README.rst
new file mode 100644
index 0000000..da05f88
--- /dev/null
+++ b/tests/dsp/dsp_in_registered/README.rst
@@ -0,0 +1,37 @@
+DSP-style block with all inputs registered
+++++++++++++++++++++++++++++++++++++++++++
+
+A combinational DSP block with registered inputs. Modeled as a complex block. 
+
+.. symbolator::  dsp_in_registered.sim.v
+
+.. verilog-diagram:: dsp_in_registered.sim.v
+   :type: netlistsvg
+   :module: DSP_IN_REGISTERED
+
+|
+
+.. no-license::  dsp_in_registered.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_in_registered/dsp_in_registered.sim.v
+
+.. no-license:: dsp_in_registered.model.xml
+   :language: xml
+   :caption: dsp_in_registered.model.xml
+
+.. no-license:: dsp_in_registered.pb_type.xml
+   :language: xml
+   :caption: dsp_in_registered.pb_type.xml
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+* ``pack_pattern`` defined on wire connections with ``pack`` attribute
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
diff --git a/tests/dsp/dsp_inout_registered/README.md b/tests/dsp/dsp_inout_registered/README.md
deleted file mode 100644
index b66befe..0000000
--- a/tests/dsp/dsp_inout_registered/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# `dsp_inout_registered` test
-
-Test for "DSP style" block with both input and output is registered (using a
-single clock).
-
-The tests use model from [`fig42-dff`](FIXME) and
-[`dsp_combinational`](../dsp_combinational/README.md) tests.
-
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
- - [ ] `pack_pattern` defined on wire connections with `pack` attribute
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
diff --git a/tests/dsp/dsp_inout_registered/README.rst b/tests/dsp/dsp_inout_registered/README.rst
new file mode 100644
index 0000000..45a351b
--- /dev/null
+++ b/tests/dsp/dsp_inout_registered/README.rst
@@ -0,0 +1,35 @@
+DSP-style block with inputs and outputs registered (single clock)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. symbolator::  dsp_inout_registered.sim.v
+
+.. verilog-diagram:: dsp_inout_registered.sim.v
+   :type: netlistsvg
+   :module: DSP_INOUT_REGISTERED
+
+|
+
+.. no-license::  dsp_inout_registered.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_inout_registered/dsp_inout_registered.sim.v
+
+.. no-license:: dsp_inout_registered.model.xml
+   :language: xml
+   :caption: dsp_inout_registered.model.xml
+
+.. no-license:: dsp_inout_registered.pb_type.xml
+   :language: xml
+   :caption: dsp_inout_registered.pb_type.xml
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+* ``pack_pattern`` defined on wire connections with ``pack`` attribute
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
diff --git a/tests/dsp/dsp_inout_registered_dualclk/README.md b/tests/dsp/dsp_inout_registered_dualclk/README.md
deleted file mode 100644
index f5baa0e..0000000
--- a/tests/dsp/dsp_inout_registered_dualclk/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# `dsp_inout_registered_dualclk` test
-
-Test for "DSP style" block with both input and output is registered using
-separate clocks.
-
-The tests use model from [`fig42-dff`](FIXME) and
-[`dsp_combinational`](../dsp_combinational/README.md) tests.
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
- - [ ] `pack_pattern` defined on wire connections with `pack` attribute
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
diff --git a/tests/dsp/dsp_inout_registered_dualclk/README.rst b/tests/dsp/dsp_inout_registered_dualclk/README.rst
new file mode 100644
index 0000000..f0f8029
--- /dev/null
+++ b/tests/dsp/dsp_inout_registered_dualclk/README.rst
@@ -0,0 +1,37 @@
+DSP-style block with inputs and outputs registered using separate clocks
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+A combinational DSP block with registered inputs and outputs. Separate clock is used for inputs and outputs. Modeled as a complex block. 
+
+.. symbolator::  dsp_inout_registered_dualclk.sim.v
+
+.. verilog-diagram:: dsp_inout_registered_dualclk.sim.v
+   :type: netlistsvg
+   :module: DSP_INOUT_REGISTERED_DUALCLK
+
+|
+
+.. no-license::  dsp_inout_registered_dualclk.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_inout_registered_dualclk/dsp_inout_registered_dualclk.sim.v
+
+.. no-license:: dsp_inout_registered_dualclk.model.xml
+   :language: xml
+   :caption: dsp_inout_registered_dualclk.model.xml
+
+.. no-license:: dsp_inout_registered_dualclk.pb_type.xml
+   :language: xml
+   :caption: dsp_inout_registered_dualclk.pb_type.xml
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+* ``pack_pattern`` defined on wire connections with ``pack`` attribute
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
diff --git a/tests/dsp/dsp_modes/README.md b/tests/dsp/dsp_modes/README.md
deleted file mode 100644
index d0e25c7..0000000
--- a/tests/dsp/dsp_modes/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# `dsp_modes` test
-
-Test for "DSP style" block with multiple different modes.
-
-The modes possible are;
-
- * Combinational only
-   (IE [`dsp_combinational`](../dsp_combinational/README.md)).
-
- * Register on one input
-   (IE [`dsp_partial_registered`](../dsp_partial_registered/README.md)).
-
- * Register on all inputs
-   (IE [`dsp_in_registered`](../dsp_in_registered/README.md)).
-
- * Register on outputs
-   (IE [`dsp_out_registered`](../dsp_out_registered/README.md)).
-
- * Register on both inputs and outputs (with same clock)
-   (IE [`dsp_inout_registered`](../dsp_inout_registered/README.md)).
-
- * Register on both inputs and outputs (with independent clocks)
-   (IE [`dsp_inout_registered_dualclk`](../dsp_inout_registered_dualclk/README.md)).
-
- * Register on both inputs and outputs (with independent clocks)
-   (IE [`dsp_inout_registered_dualclk`](../dsp_inout_registered_dualclk/README.md)).
-
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
-## Modes generation
-
- - [ ] all the modes from list defined with `MODES` attribute
- - [ ] mode setting is included in `pb_type` generation (correct part of logic is used)
- - [ ] modes connections are generated correctly
diff --git a/tests/dsp/dsp_modes/README.rst b/tests/dsp/dsp_modes/README.rst
new file mode 100644
index 0000000..68c8e99
--- /dev/null
+++ b/tests/dsp/dsp_modes/README.rst
@@ -0,0 +1,59 @@
+DSP-style block with different modes
+++++++++++++++++++++++++++++++++++++
+
+The possible modes are
+
+* Combinational only (i.e. |dsp_combinational|_)
+* Register on one input (i.e. |dsp_partial_registered|_)
+* Register on all inputs (i.e. |dsp_in_registered|_)
+* Register on outputs (i.e. |dsp_out_registered|_).
+* Register on both inputs and outputs (with same clock) (i.e. |dsp_inout_registered|_).
+
+.. |dsp_combinational| replace:: ``dsp_combinational``
+.. _dsp_combinational: #dsp-style-block-with-only-one-input-registered
+
+.. |dsp_partial_registered| replace:: ``dsp_partial_registered``
+.. _dsp_partial_registered: #dsp-style-block-with-only-one-input-registered
+
+.. |dsp_in_registered| replace:: ``dsp_in_registered``
+.. _dsp_in_registered: #dsp-style-block-with-all-inputs-registered
+
+.. |dsp_out_registered| replace:: ``dsp_out_registered``
+.. _dsp_out_registered: #dsp-style-block-with-outputs-registered
+
+.. |dsp_inout_registered| replace:: ``dsp_inout_registered``
+.. _dsp_inout_registered: #dsp-style-block-with-inputs-and-outputs-registered-single-clock
+
+.. symbolator::  dsp_modes.sim.v
+
+.. verilog-diagram:: dsp_modes.sim.v
+   :type: netlistsvg
+   :module: DSP_MODES
+
+|
+
+.. no-license::  dsp_modes.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_modes/dsp_modes.sim.v
+
+.. no-license:: dsp_modes.model.xml
+   :language: xml
+   :caption: dsp_modes.model.xml
+
+.. no-license:: dsp_modes.pb_type.xml
+   :language: xml
+   :caption: dsp_modes.pb_type.xml
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
+
+Modes generation
+****************
+
+* All the modes from list defined with ``MODES`` attribute
+* Mode setting is included in ``pb_type`` generation (correct part of logic is used)
+* Modes connections are generated correctly
diff --git a/tests/dsp/dsp_out_registered/README.md b/tests/dsp/dsp_out_registered/README.md
deleted file mode 100644
index 27c46e2..0000000
--- a/tests/dsp/dsp_out_registered/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# `dsp_out_registered` test
-
-Test for "DSP style" block with outputs registered.
-
-The tests use model from [`fig42-dff`](FIXME) and
-[`dsp_combinational`](../dsp_combinational/README.md) tests.
-
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
- - [ ] `pack_pattern` defined on wire connections with `pack` attribute
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
diff --git a/tests/dsp/dsp_out_registered/README.rst b/tests/dsp/dsp_out_registered/README.rst
new file mode 100644
index 0000000..4baec55
--- /dev/null
+++ b/tests/dsp/dsp_out_registered/README.rst
@@ -0,0 +1,37 @@
+DSP-style block with outputs registered
++++++++++++++++++++++++++++++++++++++++
+
+A combinational DSP block with registered outputs. Modeled as a complex block. 
+
+.. symbolator:: dsp_out_registered.sim.v
+
+.. verilog-diagram:: dsp_out_registered.sim.v
+   :type: netlistsvg
+   :module: DSP_OUT_REGISTERED
+
+|
+
+.. no-license:: dsp_out_registered.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_out_registered/dsp_out_registered.sim.v
+
+.. no-license:: dsp_out_registered.model.xml
+   :language: xml
+   :caption: dsp_out_registered.model.xml
+
+.. no-license:: dsp_out_registered.pb_type.xml
+   :language: xml
+   :caption: dsp_out_registered.pb_type.xml
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+* ``pack_pattern`` defined on wire connections with ``pack`` attribute
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
diff --git a/tests/dsp/dsp_partial_registered/README.md b/tests/dsp/dsp_partial_registered/README.md
deleted file mode 100644
index 7fd5d26..0000000
--- a/tests/dsp/dsp_partial_registered/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# `dsp_partial_registered` test
-
-Test for "DSP style" block with one input registered.
-
-The tests use model from [`fig42-dff`](FIXME) and
-[`dsp_combinational`](../dsp_combinational/README.md) tests.
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
- - [ ] `pack_pattern` defined on wire connections with `pack` attribute
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
diff --git a/tests/dsp/dsp_partial_registered/README.rst b/tests/dsp/dsp_partial_registered/README.rst
new file mode 100644
index 0000000..69cf4da
--- /dev/null
+++ b/tests/dsp/dsp_partial_registered/README.rst
@@ -0,0 +1,37 @@
+DSP-style block with only one input registered
+++++++++++++++++++++++++++++++++++++++++++++++
+
+A combinational DSP block with all but one registered inputs. Modeled as a complex block. 
+
+.. symbolator:: dsp_partial_registered.sim.v
+
+.. verilog-diagram:: dsp_partial_registered.sim.v
+   :type: netlistsvg
+   :module: DSP_PARTIAL_REGISTERED
+
+|
+
+.. no-license:: dsp_partial_registered.sim.v
+   :language: verilog
+   :caption: tests/dsp/dsp_partial_registered/dsp_partial_registered.sim.v
+
+.. no-license:: dsp_partial_registered.model.xml
+   :language: xml
+   :caption: dsp_partial_registered.model.xml
+
+.. no-license:: dsp_partial_registered.pb_type.xml
+   :language: xml
+   :caption: dsp_partial_registered.pb_type.xml
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+* ``pack_pattern`` defined on wire connections with ``pack`` attribute
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
diff --git a/tests/gates/README.rst b/tests/gates/README.rst
new file mode 100644
index 0000000..8a3b79e
--- /dev/null
+++ b/tests/gates/README.rst
@@ -0,0 +1,12 @@
+.. Gates
+
+Basic logic gates
+=================
+
+These are some basic logic gates. NOT, AND and NOR are modeled as primitives while XOR is made up of 5 NOR gates.
+
+.. toctree::
+   not/README.rst
+   and/README.rst
+   nor/README.rst
+   xor/README.rst
diff --git a/tests/gates/and/README.rst b/tests/gates/and/README.rst
new file mode 100644
index 0000000..9cce6a2
--- /dev/null
+++ b/tests/gates/and/README.rst
@@ -0,0 +1,28 @@
+AND gate
+========
+
+This is an AND gate
+
+.. symbolator:: and.sim.v
+
+.. verilog-diagram:: and.sim.v
+   :type: netlistsvg
+   :module: AND
+
+|
+
+.. no-license:: and.sim.v
+   :language: verilog
+   :caption: and.sim.v
+
+The gate model generated by V2X
+
+.. literalinclude:: and.model.xml
+   :language: xml
+   :caption: and.model.xml
+
+The gate pb_type generated by V2X
+
+.. literalinclude:: and.pb_type.xml
+   :language: xml
+   :caption: and.pb_type.xml
diff --git a/tests/gates/and/and.sim.v b/tests/gates/and/and.sim.v
new file mode 100644
index 0000000..be2ee47
--- /dev/null
+++ b/tests/gates/and/and.sim.v
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020  The SymbiFlow Authors.
+ *
+ * Use of this source code is governed by a ISC-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/ISC
+ *
+ * SPDX-License-Identifier:	ISC
+ */
+
+module AND (
+    input  A,
+    input  B,
+    output Y
+);
+
+    assign Y = A & B;
+
+endmodule
diff --git a/tests/gates/and/golden.model.xml b/tests/gates/and/golden.model.xml
new file mode 100644
index 0000000..497ac6a
--- /dev/null
+++ b/tests/gates/and/golden.model.xml
@@ -0,0 +1,11 @@
+<models xmlns:xi="http://www.w3.org/2001/XInclude">
+  <model name="AND">
+    <input_ports>
+      <port name="A" combinational_sink_ports="Y"/>
+      <port name="B" combinational_sink_ports="Y"/>
+    </input_ports>
+    <output_ports>
+      <port name="Y"/>
+    </output_ports>
+  </model>
+</models>
diff --git a/tests/gates/and/golden.pb_type.xml b/tests/gates/and/golden.pb_type.xml
new file mode 100644
index 0000000..23ee9ee
--- /dev/null
+++ b/tests/gates/and/golden.pb_type.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" num_pb="1" name="AND">
+  <blif_model>.subckt AND</blif_model>
+  <input name="A" num_pins="1"/>
+  <input name="B" num_pins="1"/>
+  <output name="Y" num_pins="1"/>
+</pb_type>
diff --git a/tests/gates/nor/README.rst b/tests/gates/nor/README.rst
new file mode 100644
index 0000000..a28ada0
--- /dev/null
+++ b/tests/gates/nor/README.rst
@@ -0,0 +1,28 @@
+NOR gate
+========
+
+This is an NOR gate
+
+.. symbolator:: nor.sim.v
+
+.. verilog-diagram:: nor.sim.v
+   :type: netlistsvg
+   :module: NOR
+
+|
+
+.. no-license:: nor.sim.v
+   :language: verilog
+   :caption: nor.sim.v
+
+The gate model generated by V2X
+
+.. literalinclude:: nor.model.xml
+   :language: xml
+   :caption: nor.model.xml
+
+The gate pb_type generated by V2X
+
+.. literalinclude:: nor.pb_type.xml
+   :language: xml
+   :caption: nor.pb_type.xml
diff --git a/tests/gates/nor/golden.model.xml b/tests/gates/nor/golden.model.xml
new file mode 100644
index 0000000..d4900dd
--- /dev/null
+++ b/tests/gates/nor/golden.model.xml
@@ -0,0 +1,11 @@
+<models xmlns:xi="http://www.w3.org/2001/XInclude">
+  <model name="NOR">
+    <input_ports>
+      <port name="A" combinational_sink_ports="Y"/>
+      <port name="B" combinational_sink_ports="Y"/>
+    </input_ports>
+    <output_ports>
+      <port name="Y"/>
+    </output_ports>
+  </model>
+</models>
diff --git a/tests/gates/nor/golden.pb_type.xml b/tests/gates/nor/golden.pb_type.xml
new file mode 100644
index 0000000..d533ac5
--- /dev/null
+++ b/tests/gates/nor/golden.pb_type.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" num_pb="1" name="NOR">
+  <blif_model>.subckt NOR</blif_model>
+  <input name="A" num_pins="1"/>
+  <input name="B" num_pins="1"/>
+  <output name="Y" num_pins="1"/>
+</pb_type>
diff --git a/tests/gates/nor/nor.sim.v b/tests/gates/nor/nor.sim.v
new file mode 100644
index 0000000..7517e0e
--- /dev/null
+++ b/tests/gates/nor/nor.sim.v
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020  The SymbiFlow Authors.
+ *
+ * Use of this source code is governed by a ISC-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/ISC
+ *
+ * SPDX-License-Identifier:	ISC
+ */
+
+module NOR (
+    input  A,
+    input  B,
+    output Y
+);
+
+    assign Y = ~(A | B);
+
+endmodule
diff --git a/tests/gates/not/README.rst b/tests/gates/not/README.rst
new file mode 100644
index 0000000..5ba2b65
--- /dev/null
+++ b/tests/gates/not/README.rst
@@ -0,0 +1,28 @@
+NOT gate
+========
+
+This is an NOT gate
+
+.. symbolator:: not.sim.v
+
+.. verilog-diagram:: not.sim.v
+   :type: netlistsvg
+   :module: NOT
+
+|
+
+.. no-license:: not.sim.v
+   :language: verilog
+   :caption: not.sim.v
+
+The gate model generated by V2X
+
+.. literalinclude:: not.model.xml
+   :language: xml
+   :caption: not.model.xml
+
+The gate pb_type generated by V2X
+
+.. literalinclude:: not.pb_type.xml
+   :language: xml
+   :caption: not.pb_type.xml
diff --git a/tests/gates/not/golden.model.xml b/tests/gates/not/golden.model.xml
new file mode 100644
index 0000000..a9badad
--- /dev/null
+++ b/tests/gates/not/golden.model.xml
@@ -0,0 +1,10 @@
+<models xmlns:xi="http://www.w3.org/2001/XInclude">
+  <model name="NOT">
+    <input_ports>
+      <port name="A" combinational_sink_ports="Y"/>
+    </input_ports>
+    <output_ports>
+      <port name="Y"/>
+    </output_ports>
+  </model>
+</models>
diff --git a/tests/gates/not/golden.pb_type.xml b/tests/gates/not/golden.pb_type.xml
new file mode 100644
index 0000000..864b55f
--- /dev/null
+++ b/tests/gates/not/golden.pb_type.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" num_pb="1" name="NOT">
+  <blif_model>.subckt NOT</blif_model>
+  <input name="A" num_pins="1"/>
+  <output name="Y" num_pins="1"/>
+</pb_type>
diff --git a/tests/gates/not/not.sim.v b/tests/gates/not/not.sim.v
new file mode 100644
index 0000000..0452fd2
--- /dev/null
+++ b/tests/gates/not/not.sim.v
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2020  The SymbiFlow Authors.
+ *
+ * Use of this source code is governed by a ISC-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/ISC
+ *
+ * SPDX-License-Identifier:	ISC
+ */
+
+module NOT (
+    input  A,
+    output Y
+);
+
+    assign Y = ~A;
+
+endmodule
diff --git a/tests/gates/xor/README.rst b/tests/gates/xor/README.rst
new file mode 100644
index 0000000..1c13dd7
--- /dev/null
+++ b/tests/gates/xor/README.rst
@@ -0,0 +1,28 @@
+XOR gate
+========
+
+This is a XOR gate made of NOR gates
+
+.. symbolator:: xor.sim.v
+
+.. verilog-diagram:: xor.sim.v
+   :type: netlistsvg
+   :module: XOR
+
+|
+
+.. no-license:: xor.sim.v
+   :language: verilog
+   :caption: xor.sim.v
+
+The gate model generated by V2X
+
+.. literalinclude:: xor.model.xml
+   :language: xml
+   :caption: xor.model.xml
+
+The gate pb_type generated by V2X
+
+.. literalinclude:: xor.pb_type.xml
+   :language: xml
+   :caption: xor.pb_type.xml
diff --git a/tests/gates/xor/golden.model.xml b/tests/gates/xor/golden.model.xml
new file mode 100644
index 0000000..990bc88
--- /dev/null
+++ b/tests/gates/xor/golden.model.xml
@@ -0,0 +1,3 @@
+<models xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="../nor/nor.model.xml" xpointer="xpointer(models/child::node())"/>
+</models>
diff --git a/tests/gates/xor/golden.pb_type.xml b/tests/gates/xor/golden.pb_type.xml
new file mode 100644
index 0000000..7ea5823
--- /dev/null
+++ b/tests/gates/xor/golden.pb_type.xml
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" num_pb="1" name="XOR">
+  <input name="A" num_pins="1"/>
+  <input name="B" num_pins="1"/>
+  <output name="Y" num_pins="1"/>
+  <pb_type num_pb="1" name="nor00">
+    <!--old_name NOR-->
+    <xi:include href="../nor/nor.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <pb_type num_pb="1" name="nor10">
+    <!--old_name NOR-->
+    <xi:include href="../nor/nor.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <pb_type num_pb="1" name="nor11">
+    <!--old_name NOR-->
+    <xi:include href="../nor/nor.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <pb_type num_pb="1" name="nor20">
+    <!--old_name NOR-->
+    <xi:include href="../nor/nor.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <pb_type num_pb="1" name="nor30">
+    <!--old_name NOR-->
+    <xi:include href="../nor/nor.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <interconnect>
+    <direct>
+      <port name="A" type="input"/>
+      <port name="A" type="output" from="nor00"/>
+    </direct>
+    <direct>
+      <port name="A" type="input"/>
+      <port name="A" type="output" from="nor10"/>
+    </direct>
+    <direct>
+      <port name="B" type="input"/>
+      <port name="B" type="output" from="nor00"/>
+    </direct>
+    <direct>
+      <port name="B" type="input"/>
+      <port name="A" type="output" from="nor11"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor00"/>
+      <port name="B" type="output" from="nor10"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor00"/>
+      <port name="B" type="output" from="nor11"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor10"/>
+      <port name="A" type="output" from="nor20"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor11"/>
+      <port name="B" type="output" from="nor20"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor20"/>
+      <port name="A" type="output" from="nor30"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor20"/>
+      <port name="B" type="output" from="nor30"/>
+    </direct>
+    <direct>
+      <port name="Y" type="input" from="nor30"/>
+      <port name="Y" type="output"/>
+    </direct>
+  </interconnect>
+</pb_type>
diff --git a/tests/gates/xor/xor.sim.v b/tests/gates/xor/xor.sim.v
new file mode 100644
index 0000000..23adbb4
--- /dev/null
+++ b/tests/gates/xor/xor.sim.v
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020  The SymbiFlow Authors.
+ *
+ * Use of this source code is governed by a ISC-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/ISC
+ *
+ * SPDX-License-Identifier:	ISC
+ */
+
+`include "../nor/nor.sim.v"
+
+module XOR (
+    input  A,
+    input  B,
+    output Y
+);
+
+    wire S00;
+    NOR nor00 (.A(A), .B(B), .Y(S00));
+
+    wire S10;
+    wire S11;
+    NOR nor10 (.A(A), .B(S00), .Y(S10));
+    NOR nor11 (.A(B), .B(S00), .Y(S11));
+
+    wire S20;
+    NOR nor20 (.A(S10), .B(S11), .Y(S20));
+
+    NOR nor30 (.A(S20), .B(S20), .Y(Y));
+
+endmodule
diff --git a/tests/internal_conn/README.rst b/tests/internal_conn/README.rst.bak
similarity index 100%
rename from tests/internal_conn/README.rst
rename to tests/internal_conn/README.rst.bak
diff --git a/tests/io/README.rst b/tests/io/README.rst.bak
similarity index 100%
rename from tests/io/README.rst
rename to tests/io/README.rst.bak
diff --git a/tests/net_attr/README.rst b/tests/net_attr/README.rst.bak
similarity index 100%
rename from tests/net_attr/README.rst
rename to tests/net_attr/README.rst.bak
diff --git a/tests/no_comb/README.rst b/tests/no_comb/README.rst.bak
similarity index 100%
rename from tests/no_comb/README.rst
rename to tests/no_comb/README.rst.bak
diff --git a/tests/test_v2x.py b/tests/test_v2x.py
index 8c3c83c..34215d1 100644
--- a/tests/test_v2x.py
+++ b/tests/test_v2x.py
@@ -53,17 +53,6 @@
             name_mux='RMUX',
             name_inputs='I0,I1'
             )
-    # Generate tests/vtr/lutff-pair/omux for tests/vtr/lutff-pair
-    mux_gen(outdir=os.path.join(testdir, 'vtr/lutff-pair/omux'),
-            outfilename='omux',
-            datatype='routing',
-            width=2,
-            split_inputs=True,
-            name_output='O',
-            name_mux='omux',
-            name_inputs='L,F'
-            )
-
     # Generate dff.pb_type.xml required by various tests
     newpbfile = os.path.join(testdir, 'vtr/dff/dff.pb_type.xml')
     pbtypeout = vlog_to_pbtype.vlog_to_pbtype(
@@ -73,10 +62,10 @@
     with open(newpbfile, 'w') as model:
         model.write(pbtypeout)
 
-    # Generate ff.pb_type.xml required by various tests
-    newpbfile = os.path.join(testdir, 'vtr/lutff-pair/ff/ff.pb_type.xml')
+    # Generate dff.pb_type.xml required by various tests
+    newpbfile = os.path.join(testdir, 'vtr/lutff-pair/dff/dff.pb_type.xml')
     pbtypeout = vlog_to_pbtype.vlog_to_pbtype(
-        [os.path.join(testdir, 'vtr/lutff-pair/ff/ff.sim.v')],
+        [os.path.join(testdir, 'vtr/lutff-pair/dff/dff.sim.v')],
         newpbfile,
         'DFF')
     with open(newpbfile, 'w') as model:
diff --git a/tests/vtr/README.rst b/tests/vtr/README.rst
new file mode 100644
index 0000000..fe1cb76
--- /dev/null
+++ b/tests/vtr/README.rst
@@ -0,0 +1,9 @@
+.. Examples from the Verilog to Routing documentation / tutorials.
+
+Verilog to Routing
+==================
+
+The following shows some examples taken from the `Verilog to Routing documentation <https://docs.verilogtorouting.org>`_.
+
+.. toctree::
+   primitives.rst
diff --git a/tests/vtr/dff/README.md b/tests/vtr/dff/README.md
deleted file mode 100644
index c4c2fe3..0000000
--- a/tests/vtr/dff/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Classical D-Flip-Flop test
-
-An example of the classical D-Flip-Flop.
-
-This is shown in `Figure 43 - DFF` of the
-["Sequential block (no internal paths)"](https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#sequential-block-no-internal-paths)
-section in the
-[Primitive Block Timing Modeling Tutorial](https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#)
-of the
-[Verilog to Routing documentation](https://docs.verilogtorouting.org)
-and reproduced below;
-
-> ![Figure 43 from Verilog to Routing Documentation](dff.svg)
-> *Fig. 43 DFF*
-
-## Clock associations inference
-
- - [ ] automatic inference is signal is associated with any clock and include the info in the model
- - [ ] automatic clock detection (signals named `clk` are considered as clocks)
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
-
-## Timings
-
- - [ ] all the timings defined for wires with attributes should be included in `pb_type` XML
diff --git a/tests/vtr/dff/README.rst b/tests/vtr/dff/README.rst
new file mode 100644
index 0000000..0d0ee49
--- /dev/null
+++ b/tests/vtr/dff/README.rst
@@ -0,0 +1,46 @@
+Classical D-Flip-Flop test
+++++++++++++++++++++++++++
+
+An example of the classical D-Flip-Flop shown in |fig60|_.
+
+.. |fig60| replace:: ``Figure 60 - DFF``
+.. _fig60: https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#sequential-block-no-internal-paths
+
+.. image:: dff.svg
+   :alt: Figure 60 from Verilog to Routing Documentation
+
+*Fig. 60 - DFF*
+
+|
+
+
+|
+
+.. no-license:: dff.sim.v
+   :language: verilog
+   :caption: dff.sim.v
+
+.. no-license:: dff.model.xml
+   :language: xml
+   :caption: dff.model.xml
+
+.. no-license:: dff.pb_type.xml
+   :language: xml
+   :caption: dff.pb_type.xml
+
+Clock associations inference
+****************************
+
+* Automatic inference is signal is associated with any clock and include the info in the model
+* Automatic clock detection (signals named ``clk`` are considered as clocks)
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+
+Timings
+*******
+
+* All the timings defined for wires with attributes should be included in ``pb_type`` XML
diff --git a/tests/vtr/dff/dff.sim.v b/tests/vtr/dff/dff.sim.v
index 91c1c12..ed67b34 100644
--- a/tests/vtr/dff/dff.sim.v
+++ b/tests/vtr/dff/dff.sim.v
@@ -7,6 +7,8 @@
  *
  * SPDX-License-Identifier:	ISC
  */
+`ifndef DFF
+`define DFF
 
 (* whitebox *)
 module DFF (D, CLK, Q);
@@ -57,3 +59,5 @@
 `endif
 
 endmodule
+
+`endif
\ No newline at end of file
diff --git a/tests/vtr/full-adder/README.md b/tests/vtr/full-adder/README.md
deleted file mode 100644
index 08f302d..0000000
--- a/tests/vtr/full-adder/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Full Adder Example
-
-An example of the classical combinational ["full adder"](https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder) circuit.
-
-This is shown in `Figure 41 - Full Adder` of the
-["Combinational block"](https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#combinational-block)
-section in the
-[Primitive Block Timing Modeling Tutorial](https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#)
-of the
-[Verilog to Routing documentation](https://docs.verilogtorouting.org)
-and reproduced below;
-
-> ![Figure 41 from Verilog to Routing Documentation](full-adder.svg)
-> *Fig. 41 Full Adder*
-
-## Detection of combinational connections
-
- - [ ] output has combinational connection with input
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
-
-## Timings
-
- - [ ] all the timings defined for wires with attributes should be included in `pb_type` XML
diff --git a/tests/vtr/full-adder/README.rst b/tests/vtr/full-adder/README.rst
new file mode 100644
index 0000000..e9d7000
--- /dev/null
+++ b/tests/vtr/full-adder/README.rst
@@ -0,0 +1,51 @@
+Full Adder Example
+++++++++++++++++++
+
+An example of the classical combinational `"full adder" <https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder>`_ circuit shown in |fig60|_ of the `"Combinational block" <https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#combinational-block>`_ section in the Primitive Block Timing Modeling Tutorial of the Verilog to Routing documentation and reproduced below.
+
+.. |fig60| replace:: ``Figure 60 - Full Adder``
+.. _fig60: https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#combinational-block
+
+.. image:: full-adder.svg
+   :alt: Figure 59 from Verilog to Routing Documentation
+
+*Fig. 59 - Full Adder*
+
+|
+
+.. symbolator:: adder.sim.v
+
+.. verilog-diagram:: adder.sim.v
+   :type: netlistsvg
+   :module: ADDER
+
+|
+
+.. no-license::  adder.sim.v
+   :language: verilog
+   :caption: adder.sim.v
+
+.. no-license:: adder.model.xml
+   :language: xml
+   :caption: adder.model.xml
+
+.. no-license:: adder.pb_type.xml
+   :language: xml
+   :caption: adder.pb_type.xml
+
+
+Detection of combinational connections
+**************************************
+
+* Output has combinational connection with input
+
+Blackbox detection
+******************
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+
+Timings
+*******
+
+* All the timings defined for wires with attributes should be included in ``pb_type`` XML
diff --git a/tests/vtr/lutff-pair/README.md b/tests/vtr/lutff-pair/README.md
deleted file mode 100644
index dbd5796..0000000
--- a/tests/vtr/lutff-pair/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# LUT with FlipFlop Example
-
-An example of the classical LUT with FlipFlop pair.
-
-This is shown in `Figure 28` of the
-[Architecture Reference section of the Verilog to Routing Documentation](https://docs.verilogtorouting.org/en/latest/arch/reference)
-and reproduced below;
-
-> ![Figure 28 from Verilog to Routing Documentation](lutff-pair.png)
-> *Fig. 28 Pack Pattern Example.*
-
-## Blackbox detection
-
- - [ ] model of the leaf `pb_type` is generated
- - [ ] leaf `pb_type` XML is generated
- - [ ] all dependency models and `pb_type`s are included in the output files
-
-## Carry chain inference
-
- - [ ] `pack_pattern` inference - `pack_pattern`s defined on wires with `pack` attributes should be propagated to `pb_type` XMLs
diff --git a/tests/vtr/lutff-pair/README.rst b/tests/vtr/lutff-pair/README.rst
new file mode 100644
index 0000000..0c1961f
--- /dev/null
+++ b/tests/vtr/lutff-pair/README.rst
@@ -0,0 +1,46 @@
+LUT with FlipFlop Example
++++++++++++++++++++++++++
+
+An example of the classical LUT with FlipFlop pair shown in |fig31|_ of the `"Architecture Reference" <https://docs.verilogtorouting.org/en/latest/arch/reference/#architecture-reference>`_ section of the Verilog to Routing Documentation demonstrating the `<pack_pattern>` tag.
+
+.. |fig31| replace:: ``Figure 31 - Pack Pattern Example``
+.. _fig31: https://docs.verilogtorouting.org/en/latest/arch/reference/#id35
+
+.. image:: lutff-pair.png
+   :alt: Figure 31 from Verilog to Routing Documentation
+
+*Fig. 31 - Pack Pattern Example*
+
+|
+
+.. symbolator:: pair.sim.v
+
+.. verilog-diagram:: pair.sim.v
+   :type: netlistsvg
+   :module: PAIR
+
+|
+
+.. no-license::  pair.sim.v
+   :language: verilog
+   :caption: pair.sim.v
+
+.. no-license:: pair.model.xml
+   :language: xml
+   :caption: pair.model.xml
+
+.. no-license:: pair.pb_type.xml
+   :language: xml
+   :caption: pair.pb_type.xml
+
+Blackbox detection
+------------------
+
+* Model of the leaf ``pb_type`` is generated
+* Leaf ``pb_type`` XML is generated
+* All dependency models and ``pb_type``\ s are included in the output files
+
+Carry chain inference
+---------------------
+
+* ``pack_pattern`` inference - ``pack_pattern``\ s defined on wires with ``pack`` attributes should be propagated to ``pb_type`` XMLs
diff --git a/tests/vtr/lutff-pair/ff/ff.sim.v b/tests/vtr/lutff-pair/dff/dff.sim.v
similarity index 100%
rename from tests/vtr/lutff-pair/ff/ff.sim.v
rename to tests/vtr/lutff-pair/dff/dff.sim.v
diff --git a/tests/vtr/lutff-pair/ff/golden.model.xml b/tests/vtr/lutff-pair/dff/golden.model.xml
similarity index 100%
rename from tests/vtr/lutff-pair/ff/golden.model.xml
rename to tests/vtr/lutff-pair/dff/golden.model.xml
diff --git a/tests/vtr/lutff-pair/golden.model.xml b/tests/vtr/lutff-pair/golden.model.xml
index 59092ef..1a85f1e 100644
--- a/tests/vtr/lutff-pair/golden.model.xml
+++ b/tests/vtr/lutff-pair/golden.model.xml
@@ -1,5 +1,5 @@
 <models xmlns:xi="http://www.w3.org/2001/XInclude">
-  <xi:include href="ff/ff.model.xml" xpointer="xpointer(models/child::node())"/>
+  <xi:include href="dff/dff.model.xml" xpointer="xpointer(models/child::node())"/>
   <xi:include href="lut/lut4.model.xml" xpointer="xpointer(models/child::node())"/>
   <xi:include href="omux/omux.model.xml" xpointer="xpointer(models/child::node())"/>
 </models>
diff --git a/tests/vtr/lutff-pair/golden.pb_type.xml b/tests/vtr/lutff-pair/golden.pb_type.xml
index ea403db..66bb865 100644
--- a/tests/vtr/lutff-pair/golden.pb_type.xml
+++ b/tests/vtr/lutff-pair/golden.pb_type.xml
@@ -3,8 +3,8 @@
   <clock name="CLK" num_pins="1"/>
   <input name="I" num_pins="4"/>
   <output name="O" num_pins="1"/>
-  <pb_type name="ff" num_pb="1">
-    <xi:include href="ff/ff.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
+  <pb_type name="dff" num_pb="1">
+    <xi:include href="dff/dff.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
   </pb_type>
   <pb_type name="lut" num_pb="1">
     <xi:include href="lut/lut4.pb_type.xml" xpointer="xpointer(pb_type/child::node())"/>
@@ -12,14 +12,14 @@
   <interconnect>
     <direct>
       <port name="CLK" type="input"/>
-      <port from="ff" name="CLK" type="output"/>
+      <port from="dff" name="CLK" type="output"/>
     </direct>
     <direct>
       <port from="lut" name="O" type="input"/>
-      <port from="ff" name="D" type="output"/>
+      <port from="dff" name="D" type="output"/>
       <pack_pattern name="LUT2FF" type="pack">
         <port from="lut" name="O" type="input"/>
-        <port from="ff" name="D" type="output"/>
+        <port from="dff" name="D" type="output"/>
       </pack_pattern>
     </direct>
     <direct>
@@ -39,7 +39,7 @@
       <port from="lut" name="I[3]" type="output"/>
     </direct>
     <mux name="mux">
-      <port from="ff" name="Q" type="input">
+      <port from="dff" name="Q" type="input">
         <metadata>
           <meta name="fasm_mux">F</meta>
         </metadata>
diff --git a/tests/vtr/lutff-pair/omux/omux.model.xml b/tests/vtr/lutff-pair/omux/omux.model.xml
new file mode 100644
index 0000000..4d5beb1
--- /dev/null
+++ b/tests/vtr/lutff-pair/omux/omux.model.xml
@@ -0,0 +1 @@
+<models><!-- No models for routing elements.--></models>
diff --git a/tests/vtr/lutff-pair/omux/omux.pb_type.xml b/tests/vtr/lutff-pair/omux/omux.pb_type.xml
new file mode 100644
index 0000000..c435bc0
--- /dev/null
+++ b/tests/vtr/lutff-pair/omux/omux.pb_type.xml
@@ -0,0 +1,21 @@
+<pb_type name="omux" num_pb="1">
+  <metadata>
+    <meta name="type">bel</meta>
+    <meta name="subtype">routing</meta>
+  </metadata>
+  <input name="L" num_pins="1"/>
+  <input name="F" num_pins="1"/>
+  <output name="O" num_pins="1"/>
+  <interconnect>
+    <mux name="omux" input="omux.L omux.F" output="omux.O">
+      <metadata>
+        <meta name="type">bel</meta>
+        <meta name="subtype">routing</meta>
+        <meta key="fasm_mux">
+omux.L = omux.L
+omux.F = omux.F
+</meta>
+      </metadata>
+    </mux>
+  </interconnect>
+</pb_type>
diff --git a/tests/vtr/lutff-pair/omux/omux.sim.v b/tests/vtr/lutff-pair/omux/omux.sim.v
new file mode 100644
index 0000000..54258b5
--- /dev/null
+++ b/tests/vtr/lutff-pair/omux/omux.sim.v
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020  The SymbiFlow Authors.
+ *
+ * Use of this source code is governed by a ISC-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/ISC
+ *
+ * SPDX-License-Identifier:	ISC
+ */
+
+/* 
+ * Generated with v2x/mux_gen.py
+ */
+
+`default_nettype none
+
+
+(* CLASS="routing" *)
+(* MODES="L; F" *)
+(* whitebox *)
+module OMUX(L, F, O);
+
+	input wire L;
+	input wire F;
+
+	parameter MODE = "";
+
+	output wire O;
+
+	generate
+		if ( MODE == "L" )
+		begin:SELECT_L
+			assign O = L;
+		end
+		else if ( MODE == "F" )
+		begin:SELECT_F
+			assign O = F;
+		end
+		else
+		begin
+			//$error("omux: Invalid routing value %s (options are: L, F)", MODE);
+		end
+	endgenerate
+endmodule
diff --git a/tests/vtr/lutff-pair/pair.sim.v b/tests/vtr/lutff-pair/pair.sim.v
index 025bea2..7f7e8b5 100644
--- a/tests/vtr/lutff-pair/pair.sim.v
+++ b/tests/vtr/lutff-pair/pair.sim.v
@@ -9,7 +9,7 @@
  */
 
 `include "lut/lut4.sim.v"
-`include "ff/ff.sim.v"
+`include "dff/dff.sim.v"
 `include "omux/omux.sim.v"
 
 module PAIR (
@@ -28,7 +28,7 @@
 	LUT4 lut (.I(I), .O(lut_out));
 
 	wire ff_out;
-	DFF ff (.CLK(CLK), .D(lut_out), .Q(ff_out));
+	DFF dff (.CLK(CLK), .D(lut_out), .Q(ff_out));
 
 	parameter FF_BYPASS = "F";
 	OMUX #(.MODE(FF_BYPASS)) mux(.L(lut_out), .F(ff_out), .O(O));
diff --git a/tests/vtr/primitives.rst b/tests/vtr/primitives.rst
new file mode 100644
index 0000000..20281f4
--- /dev/null
+++ b/tests/vtr/primitives.rst
@@ -0,0 +1,11 @@
+Primitive Block Timing Modeling Tutorial
+========================================
+
+The following shows examples taken from the
+`Primitive Block Timing Modeling Tutorial <https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#>`_
+in the `Verilog to Routing documentation <https://docs.verilogtorouting.org>`_.
+
+.. toctree::
+   dff/README.rst
+   full-adder/README.rst
+   lutff-pair/README.rst
diff --git a/tox.ini b/tox.ini
index bfbc74c..7320ce1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -23,7 +23,7 @@
     # `setup.py check` is not needed. If your project contains a README.rst,
     # use `python setup.py check -m -r -s` instead.
     python setup.py check -m -s
-    flake8 .
+    flake8 setup.py v2x
     pytest --doctest-modules -vv v2x
     pytest -vv
 [flake8]
diff --git a/v2x/mux_gen.py b/v2x/mux_gen.py
index c16ea80..a742125 100755
--- a/v2x/mux_gen.py
+++ b/v2x/mux_gen.py
@@ -146,7 +146,7 @@
 )
 
 
-def mux_gen(argv='Python function',
+def mux_gen(argv=('Python function', ),
             width=8,
             data_width=1,
             datatype='logic',