From b96f5bed58b274fe300e4e3099f617c7a7057a80 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 19 Jan 2022 11:54:34 +0100 Subject: [PATCH 01/51] Add RST generator and templates --- docs/.gitignore | 1 + docs/Makefile | 225 ++++++++++++++++++++++++++++++++++++++++ docs/source/conf.py | 32 ++++++ docs/static/custom.css | 1 + docs/static/favico.png | Bin 0 -> 33435 bytes docs/static/logo.png | Bin 0 -> 15938 bytes docs/static/yosyshq.css | 64 ++++++++++++ kernel/register.cc | 49 +++++++++ 8 files changed, 372 insertions(+) create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/source/conf.py create mode 100644 docs/static/custom.css create mode 100644 docs/static/favico.png create mode 100644 docs/static/logo.png create mode 100644 docs/static/yosyshq.css diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000000..84c048a73cc --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000000..b5a71676635 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,225 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " dummy to check syntax errors of document sources" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SymbiYosys.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SymbiYosys.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/SymbiYosys" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SymbiYosys" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +.PHONY: dummy +dummy: + $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy + @echo + @echo "Build finished. Dummy builder generates no files." diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000000..5e37e6e72e7 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +project = 'YosysHQ Yosys' +author = 'YosysHQ GmbH' +copyright ='2022 YosysHQ GmbH' + +# select HTML theme +html_theme = 'press' +html_logo = '../static/logo.png' +html_favicon = '../static/favico.png' +html_css_files = ['yosyshq.css', 'custom.css'] +html_sidebars = {'**': ['util/searchbox.html', 'util/sidetoc.html']} + +# These folders are copied to the documentation's HTML output +html_static_path = ['../static', "../images"] + +# code blocks style +pygments_style = 'colorful' +highlight_language = 'systemverilog' + +html_theme_options = { + 'external_links' : [ + ('YosysHQ Docs', 'https://yosyshq.readthedocs.io'), + ('Blog', 'https://blog.yosyshq.com'), + ('Website', 'https://www.yosyshq.com'), + ], +} + +extensions = ['sphinx.ext.autosectionlabel'] + +# Ensure that autosectionlabel will produce unique names +autosectionlabel_prefix_document = True +autosectionlabel_maxdepth = 1 diff --git a/docs/static/custom.css b/docs/static/custom.css new file mode 100644 index 00000000000..40a8c178f10 --- /dev/null +++ b/docs/static/custom.css @@ -0,0 +1 @@ +/* empty */ diff --git a/docs/static/favico.png b/docs/static/favico.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5afba76569d0610c2f7efead58417c4c9ab050 GIT binary patch literal 33435 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 literal 0 HcmV?d00001 diff --git a/docs/static/logo.png b/docs/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e5a507c63c7525c8f316ba0affe35fbe5ad0d6d GIT binary patch literal 15938 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 literal 0 HcmV?d00001 diff --git a/docs/static/yosyshq.css b/docs/static/yosyshq.css new file mode 100644 index 00000000000..1ceebe911b6 --- /dev/null +++ b/docs/static/yosyshq.css @@ -0,0 +1,64 @@ +h1, h3, p.topic-title, .content li.toctree-l1 > a { + color: #d6368f !important; +} + +h2, p.admonition-title, dt, .content li.toctree-l2 > a { + color: #4b72b8; +} + +a { + color: #8857a3; +} + +a.current, a:hover, a.external { + color: #d6368f !important; +} + +a.external:hover { + text-decoration: underline; +} + +p { + text-align: justify; +} + +.vp-sidebar a { + color: #d6368f; +} + +.vp-sidebar li li a { + color: #4b72b8; +} + +.vp-sidebar li li li a { + color: #2c3e50; + font-weight: 400; +} + +.vp-sidebar h3 { + padding-left: 1.5rem !important; +} + +.vp-sidebar ul a { + padding-left: 1.5rem !important; +} + +.vp-sidebar ul ul a { + padding-left: 3rem !important; +} + +.vp-sidebar ul ul ul a { + padding-left: 4.5rem !important; +} + +.vp-sidebar .toctree-l1.current a { + border-left: 0.5rem solid #6ecbd7; +} + +.vp-sidebar .toctree-l1 a.current { + border-left: 0.5rem solid #8857a3; +} + +.injected .rst-current-version, .injected dt { + color: #6ecbd7 !important; +} diff --git a/kernel/register.cc b/kernel/register.cc index 226963fdaa7..273c00a63e7 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -822,6 +822,27 @@ struct HelpPass : public Pass { fclose(f); } + void write_rst(FILE *idxf, std::string cmd, std::string title, std::string text) + { + fprintf(idxf, "- :ref:`cmd_%s`: %s\n", cmd.c_str(), title.c_str()); + + FILE *f = fopen(stringf("docs/source/cmd_%s.rst", cmd.c_str()).c_str(), "wt"); + + fprintf(f, ".. _cmd_%s:\n\n", cmd.c_str()); + fprintf(f, "================================================================================\n"); + fprintf(f, "%s\n", cmd.c_str()); + fprintf(f, "================================================================================\n\n"); + fprintf(f, ".. only:: html\n\n"); + fprintf(f, " %s\n\n", title.c_str()); + fprintf(f, ".. Index:: cmd_%s\n\n", cmd.c_str()); + fprintf(f, "Description\n"); + fprintf(f, "-----------\n\n"); + fprintf(f, ".. code-block:: none\n\n"); + auto ss = std::stringstream{text}; + for (std::string line; std::getline(ss, line, '\n');) + fprintf(f, " %s\n", line.c_str()); + fclose(f); + } void execute(std::vector args, RTLIL::Design*) override { if (args.size() == 1) { @@ -882,6 +903,34 @@ struct HelpPass : public Pass { fclose(f); } // this option is undocumented as it is for internal use only + else if (args[1] == "-write-rst-command-reference-manual") { + FILE *f = fopen("docs/source/index.rst", "wt"); + fprintf(f, "================================================================================\n"); + fprintf(f, "Command line reference\n"); + fprintf(f, "================================================================================\n"); + fprintf(f, ".. _command_line_reference:\n\n"); + fprintf(f, ".. toctree::\n"); + fprintf(f, " :maxdepth: 1\n"); + fprintf(f, " :hidden:\n\n"); + for (auto &it : pass_register) { + fprintf(f, " cmd_%s\n", it.first.c_str()); + } + fprintf(f, "\n\n"); + for (auto &it : pass_register) { + std::ostringstream buf; + log_streams.push_back(&buf); + it.second->help(); + if (it.second->experimental_flag) { + log("\n"); + log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str()); + log("\n"); + } + log_streams.pop_back(); + write_rst(f, it.first, it.second->short_help, buf.str()); + } + fclose(f); + } + // this option is undocumented as it is for internal use only else if (args[1] == "-write-web-command-reference-manual") { FILE *f = fopen("templates/cmd_index.in", "wt"); for (auto &it : pass_register) { From fcea513f4d0c5bb1529267da125f773a42f3385e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 19 Jan 2022 14:02:01 +0100 Subject: [PATCH 02/51] Support older compilers --- kernel/register.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/register.cc b/kernel/register.cc index 273c00a63e7..47e4d039101 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -838,7 +838,8 @@ struct HelpPass : public Pass { fprintf(f, "Description\n"); fprintf(f, "-----------\n\n"); fprintf(f, ".. code-block:: none\n\n"); - auto ss = std::stringstream{text}; + std::stringstream ss; + ss << text; for (std::string line; std::getline(ss, line, '\n');) fprintf(f, " %s\n", line.c_str()); fclose(f); From 8ab7c353abe6e8250010e44f882795e5352090f0 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 1 Sep 2022 11:42:40 +1200 Subject: [PATCH 03/51] Cleaner rst dump Also use :glob: to find all cmd_*.rst instead of listing all of them. --- kernel/register.cc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/kernel/register.cc b/kernel/register.cc index 47e4d039101..40e77cc0a97 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -833,15 +833,14 @@ struct HelpPass : public Pass { fprintf(f, "%s\n", cmd.c_str()); fprintf(f, "================================================================================\n\n"); fprintf(f, ".. only:: html\n\n"); - fprintf(f, " %s\n\n", title.c_str()); - fprintf(f, ".. Index:: cmd_%s\n\n", cmd.c_str()); - fprintf(f, "Description\n"); - fprintf(f, "-----------\n\n"); + fprintf(f, " %s\n\n", title.c_str()); + fprintf(f, ":code:`yosys> help %s`\n", cmd.c_str()); + fprintf(f, "--------------------------------------------------------------------------------\n\n"); fprintf(f, ".. code-block:: none\n\n"); std::stringstream ss; ss << text; - for (std::string line; std::getline(ss, line, '\n');) - fprintf(f, " %s\n", line.c_str()); + for (std::string line; std::getline(ss, line, '\n');) + fprintf(f, " %s\n", line.c_str()); fclose(f); } void execute(std::vector args, RTLIL::Design*) override @@ -912,10 +911,9 @@ struct HelpPass : public Pass { fprintf(f, ".. _command_line_reference:\n\n"); fprintf(f, ".. toctree::\n"); fprintf(f, " :maxdepth: 1\n"); - fprintf(f, " :hidden:\n\n"); - for (auto &it : pass_register) { - fprintf(f, " cmd_%s\n", it.first.c_str()); - } + fprintf(f, " :hidden:\n"); + fprintf(f, " :glob:\n\n"); + fprintf(f, " cmd_*\n"); fprintf(f, "\n\n"); for (auto &it : pass_register) { std::ostringstream buf; From d356ec3848ebc4fb268f47e085bdbc8c15368759 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 1 Sep 2022 12:07:07 +1200 Subject: [PATCH 04/51] Python script to reformat Tries to separate the help output into more usable segments. Options are formatted into rst definition lists with code blocks for the definition. --- docs/format.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/format.py diff --git a/docs/format.py b/docs/format.py new file mode 100644 index 00000000000..ac4e7273858 --- /dev/null +++ b/docs/format.py @@ -0,0 +1,63 @@ + +import sys + +with open(sys.argv[1], 'r') as f: + rst = f.readlines() + +new_rst = [] +indent = "" +EoL = "\n" +code_start = f"::{EoL}{EoL}" +IsPreamble = True +WasDefinition = False +def_strip_count = 0 +IsUsage = False +WasBlank = False +for line in rst: + if line.isspace(): + # don't care about reformatting blank lines + new_rst.append(line) + WasBlank = True + elif IsPreamble: + # skip reformatting preamble + new_rst.append(line) + IsPreamble = '-'*80 not in line + elif line.startswith(".. code-block::"): + new_rst.append(f".. highlight:: none") + IsUsage = True + else: + lstrip_count = len(line) - len(line.lstrip()) + stripped_line = line.strip() + IsDefinition = stripped_line[0] == '-' and stripped_line[1] not in [' ','-'] + IsDedent = lstrip_count <= def_strip_count + + if IsUsage: + # should be the first line of help output + if stripped_line.startswith("See"): + new_line = f"{stripped_line}{EoL}" + else: + new_line = f"Usage: :code:`{stripped_line}` {code_start}" + IsUsage = False + elif lstrip_count in [4,6,8] and IsDefinition and (WasBlank or WasDefinition): + # format definition term + new_line = f":code:`{stripped_line}` {code_start}" + indent = " " + WasDefinition = True + def_strip_count = lstrip_count + elif WasDefinition and IsDedent: + # no longer in definition, start new code block + new_rst.append(code_start) + new_line = line + WasDefinition = False + elif WasDefinition: + # format definition + new_line = f"{indent}{line[def_strip_count:]}" + else: + new_line = line + + new_rst.append(new_line) + WasBlank = False + +with open(sys.argv[1], 'w') as f: + f.writelines(new_rst) + From 665fe80c9bd1f2f194768bba9920f90b353a9074 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 1 Sep 2022 12:08:07 +1200 Subject: [PATCH 05/51] Makefile target for generation and formatting --- docs/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index b5a71676635..1760936351b 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -44,12 +44,17 @@ help: @echo " coverage to run coverage check of the documentation (if enabled)" @echo " dummy to check syntax errors of document sources" +gen_source: format.py ../yosys Makefile + @cd .. && yosys -p 'help -write-rst-command-reference-manual' + @find ./source -iname 'cmd_*.rst' -exec python3 format.py {} \; + @touch gen_source + .PHONY: clean clean: rm -rf $(BUILDDIR)/* .PHONY: html -html: +html: gen_source $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." @@ -60,6 +65,7 @@ dirhtml: @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." +# singlehtml section links are broken .PHONY: singlehtml singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml From fd661b2f03408e32913d6d12bd80dc993f36503b Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 1 Sep 2022 12:08:51 +1200 Subject: [PATCH 06/51] Tabs to spaces --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index b68783f2014..325abe26642 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2015,7 +2015,7 @@ struct SimPass : public Pass { log(" -r\n"); log(" read simulation results file\n"); log(" File formats supported: FST, VCD, AIW and WIT\n"); - log(" VCD support requires vcd2fst external tool to be present\n"); + log(" VCD support requires vcd2fst external tool to be present\n"); log("\n"); log(" -map \n"); log(" read file with port and latch symbols, needed for AIGER witness input\n"); From 60d26c1ed1400902be7e14f8217ea64536be4eb6 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 20 Sep 2022 10:39:24 +1200 Subject: [PATCH 07/51] Converting the manual --- docs/.gitignore | 1 + docs/source/appendix/index.rst | 15 +++++++++ docs/source/conf.py | 6 ++++ docs/source/index.rst | 61 ++++++++++++++++++++++++++++++++++ kernel/register.cc | 10 +++--- 5 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 docs/source/appendix/index.rst create mode 100644 docs/source/index.rst diff --git a/docs/.gitignore b/docs/.gitignore index 84c048a73cc..0d80a0285b1 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1 +1,2 @@ /build/ +gen_source diff --git a/docs/source/appendix/index.rst b/docs/source/appendix/index.rst new file mode 100644 index 00000000000..d26a95dfcb4 --- /dev/null +++ b/docs/source/appendix/index.rst @@ -0,0 +1,15 @@ +================================================================================ +Appendix +================================================================================ + +.. toctree:: + :maxdepth: 3 + :includehidden: + :caption: Appendix + + CHAPTER_Auxlibs.rst + CHAPTER_Auxprogs.rst + + CHAPTER_TextRtlil.rst + CHAPTER_Appnotes.rst + CHAPTER_StateOfTheArt.rst diff --git a/docs/source/conf.py b/docs/source/conf.py index 5e37e6e72e7..4c7b0d0d3cb 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -30,3 +30,9 @@ # Ensure that autosectionlabel will produce unique names autosectionlabel_prefix_document = True autosectionlabel_maxdepth = 1 + +# unused docs +exclude_patterns = [ + "CHAPTER_Eval.rst", + "appendix/CHAPTER_StateOfTheArt.rst" +] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000000..502563667c1 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,61 @@ +================================================================================ +Yosys manual +================================================================================ + +Abstract +======== + +Most of today's digital design is done in HDL code (mostly Verilog or VHDL) and +with the help of HDL synthesis tools. + +In special cases such as synthesis for coarse-grain cell libraries or when +testing new synthesis algorithms it might be necessary to write a custom HDL +synthesis tool or add new features to an existing one. In these cases the +availability of a Free and Open Source (FOSS) synthesis tool that can be used +as basis for custom tools would be helpful. + +In the absence of such a tool, the Yosys Open SYnthesis Suite (Yosys) was +developed. This document covers the design and implementation of this tool. +At the moment the main focus of Yosys lies on the high-level aspects of +digital synthesis. The pre-existing FOSS logic-synthesis tool ABC is used +by Yosys to perform advanced gate-level optimizations. + +An evaluation of Yosys based on real-world designs is included. It is shown +that Yosys can be used as-is to synthesize such designs. The results produced +by Yosys in this tests where successfully verified using formal verification +and are comparable in quality to the results produced by a commercial +synthesis tool. + +This document was originally published as bachelor thesis at the Vienna +University of Technology [1]_. + +.. toctree:: + :maxdepth: 2 + :caption: Manual + + CHAPTER_Intro + CHAPTER_Basics.rst + CHAPTER_Approach.rst + CHAPTER_Overview.rst + CHAPTER_CellLib.rst + CHAPTER_Prog.rst + + CHAPTER_Verilog.rst + CHAPTER_Optimize.rst + CHAPTER_Techmap.rst + CHAPTER_Eval.rst + +.. toctree:: + :maxdepth: 2 + :includehidden: + + appendix/index + +.. toctree:: + :maxdepth: 1 + :includehidden: + + cmd_ref + + +.. [1] Design and Implementation of the Yosys Open SYnthesis Suite, C. Wolf, 2013 diff --git a/kernel/register.cc b/kernel/register.cc index 40e77cc0a97..02c40374dc7 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -826,7 +826,7 @@ struct HelpPass : public Pass { { fprintf(idxf, "- :ref:`cmd_%s`: %s\n", cmd.c_str(), title.c_str()); - FILE *f = fopen(stringf("docs/source/cmd_%s.rst", cmd.c_str()).c_str(), "wt"); + FILE *f = fopen(stringf("docs/source/cmd/%s.rst", cmd.c_str()).c_str(), "wt"); fprintf(f, ".. _cmd_%s:\n\n", cmd.c_str()); fprintf(f, "================================================================================\n"); @@ -904,16 +904,16 @@ struct HelpPass : public Pass { } // this option is undocumented as it is for internal use only else if (args[1] == "-write-rst-command-reference-manual") { - FILE *f = fopen("docs/source/index.rst", "wt"); + FILE *f = fopen("docs/source/cmd_ref.rst", "wt"); fprintf(f, "================================================================================\n"); - fprintf(f, "Command line reference\n"); + fprintf(f, "Command reference\n"); fprintf(f, "================================================================================\n"); - fprintf(f, ".. _command_line_reference:\n\n"); fprintf(f, ".. toctree::\n"); + fprintf(f, " :caption: Command reference\n"); fprintf(f, " :maxdepth: 1\n"); fprintf(f, " :hidden:\n"); fprintf(f, " :glob:\n\n"); - fprintf(f, " cmd_*\n"); + fprintf(f, " cmd/*\n"); fprintf(f, "\n\n"); for (auto &it : pass_register) { std::ostringstream buf; From ab238138ee6ebfdbb502535cbc343411c5e510c0 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 20 Sep 2022 12:57:17 +1200 Subject: [PATCH 08/51] Moved format.py content into register.cc --- docs/Makefile | 3 +-- docs/format.py | 63 ---------------------------------------------- kernel/register.cc | 52 +++++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 68 deletions(-) delete mode 100644 docs/format.py diff --git a/docs/Makefile b/docs/Makefile index 1760936351b..096e7285a00 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -44,9 +44,8 @@ help: @echo " coverage to run coverage check of the documentation (if enabled)" @echo " dummy to check syntax errors of document sources" -gen_source: format.py ../yosys Makefile +gen_source: ../yosys @cd .. && yosys -p 'help -write-rst-command-reference-manual' - @find ./source -iname 'cmd_*.rst' -exec python3 format.py {} \; @touch gen_source .PHONY: clean diff --git a/docs/format.py b/docs/format.py deleted file mode 100644 index ac4e7273858..00000000000 --- a/docs/format.py +++ /dev/null @@ -1,63 +0,0 @@ - -import sys - -with open(sys.argv[1], 'r') as f: - rst = f.readlines() - -new_rst = [] -indent = "" -EoL = "\n" -code_start = f"::{EoL}{EoL}" -IsPreamble = True -WasDefinition = False -def_strip_count = 0 -IsUsage = False -WasBlank = False -for line in rst: - if line.isspace(): - # don't care about reformatting blank lines - new_rst.append(line) - WasBlank = True - elif IsPreamble: - # skip reformatting preamble - new_rst.append(line) - IsPreamble = '-'*80 not in line - elif line.startswith(".. code-block::"): - new_rst.append(f".. highlight:: none") - IsUsage = True - else: - lstrip_count = len(line) - len(line.lstrip()) - stripped_line = line.strip() - IsDefinition = stripped_line[0] == '-' and stripped_line[1] not in [' ','-'] - IsDedent = lstrip_count <= def_strip_count - - if IsUsage: - # should be the first line of help output - if stripped_line.startswith("See"): - new_line = f"{stripped_line}{EoL}" - else: - new_line = f"Usage: :code:`{stripped_line}` {code_start}" - IsUsage = False - elif lstrip_count in [4,6,8] and IsDefinition and (WasBlank or WasDefinition): - # format definition term - new_line = f":code:`{stripped_line}` {code_start}" - indent = " " - WasDefinition = True - def_strip_count = lstrip_count - elif WasDefinition and IsDedent: - # no longer in definition, start new code block - new_rst.append(code_start) - new_line = line - WasDefinition = False - elif WasDefinition: - # format definition - new_line = f"{indent}{line[def_strip_count:]}" - else: - new_line = line - - new_rst.append(new_line) - WasBlank = False - -with open(sys.argv[1], 'w') as f: - f.writelines(new_rst) - diff --git a/kernel/register.cc b/kernel/register.cc index 02c40374dc7..47e4d04ef01 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -836,11 +836,57 @@ struct HelpPass : public Pass { fprintf(f, " %s\n\n", title.c_str()); fprintf(f, ":code:`yosys> help %s`\n", cmd.c_str()); fprintf(f, "--------------------------------------------------------------------------------\n\n"); - fprintf(f, ".. code-block:: none\n\n"); + fprintf(f, ".. highlight:: none\n"); std::stringstream ss; ss << text; - for (std::string line; std::getline(ss, line, '\n');) - fprintf(f, " %s\n", line.c_str()); + bool IsUsage = true; + bool WasBlank = false; + size_t def_strip_count = 0; + bool WasDefinition = false; + for (std::string line; std::getline(ss, line, '\n');) { + // find position of first non space character + std::size_t first_pos = line.find_first_not_of(" \t"); + std::size_t last_pos = line.find_last_not_of(" \t"); + if (first_pos == std::string::npos) { + // skip formatting empty lines + fputc('\n', f); + WasBlank = true; + continue; + } + + // strip leading and trailing whitespace + std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1); + bool IsDefinition = stripped_line[0] == '-' && stripped_line[1] != ' '; + bool IsDedent = first_pos <= def_strip_count; + bool IsIndent = first_pos == 2 || first_pos == 4; + if (cmd.compare(0, 7, "verific") == 0) + // verific.cc has strange and different formatting from the rest + IsIndent = false; + + if (IsUsage) { + if (stripped_line.compare(0, 3, "See")) + // usage should be the first line of help output + fprintf(f, "Usage: :code:`%s` ::\n\n", stripped_line.c_str()); + else + // description refers to another function + fprintf(f, "%s\n", stripped_line.c_str()); + IsUsage = false; + } else if (IsIndent && IsDefinition && (WasBlank || WasDefinition)) { + // format definition term + fprintf(f, ":code:`%s` ::\n\n", stripped_line.c_str()); + WasDefinition = true; + def_strip_count = first_pos; + } else if (WasDefinition and IsDedent) { + // no longer in definition, start new code block + fprintf(f, "::\n\n %s\n", line.c_str()); + WasDefinition = false; + } else if (WasDefinition) { + // format definition + fprintf(f, " %s\n", line.substr(def_strip_count, std::string::npos).c_str()); + } else { + fprintf(f, " %s\n", line.c_str()); + } + } fclose(f); } void execute(std::vector args, RTLIL::Design*) override From 33602fd9ef651e663066c44f77c4f3361aa250e0 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 27 Sep 2022 09:25:47 +1300 Subject: [PATCH 09/51] Changing formatting to a fixed cmd_ref No more printing to the command index file. Also moves the appendix ToC into the main index. --- docs/source/appendix/index.rst | 15 -------- docs/source/cmd_ref.rst | 9 +++++ docs/source/index.rst | 46 ++++++++++++++---------- kernel/register.cc | 66 +++++++++++++++++----------------- 4 files changed, 71 insertions(+), 65 deletions(-) delete mode 100644 docs/source/appendix/index.rst create mode 100644 docs/source/cmd_ref.rst diff --git a/docs/source/appendix/index.rst b/docs/source/appendix/index.rst deleted file mode 100644 index d26a95dfcb4..00000000000 --- a/docs/source/appendix/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -================================================================================ -Appendix -================================================================================ - -.. toctree:: - :maxdepth: 3 - :includehidden: - :caption: Appendix - - CHAPTER_Auxlibs.rst - CHAPTER_Auxprogs.rst - - CHAPTER_TextRtlil.rst - CHAPTER_Appnotes.rst - CHAPTER_StateOfTheArt.rst diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst new file mode 100644 index 00000000000..cc26af6717e --- /dev/null +++ b/docs/source/cmd_ref.rst @@ -0,0 +1,9 @@ +================================================================================ +Command line reference +================================================================================ +.. toctree:: + :caption: Command reference + :maxdepth: 1 + :glob: + + cmd/* diff --git a/docs/source/index.rst b/docs/source/index.rst index 502563667c1..439754221dc 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -30,32 +30,42 @@ This document was originally published as bachelor thesis at the Vienna University of Technology [1]_. .. toctree:: - :maxdepth: 2 - :caption: Manual + :maxdepth: 2 + :caption: Manual - CHAPTER_Intro - CHAPTER_Basics.rst - CHAPTER_Approach.rst - CHAPTER_Overview.rst - CHAPTER_CellLib.rst - CHAPTER_Prog.rst + CHAPTER_Intro + CHAPTER_Basics.rst + CHAPTER_Approach.rst + CHAPTER_Overview.rst + CHAPTER_CellLib.rst + CHAPTER_Prog.rst - CHAPTER_Verilog.rst - CHAPTER_Optimize.rst - CHAPTER_Techmap.rst - CHAPTER_Eval.rst + CHAPTER_Verilog.rst + CHAPTER_Optimize.rst + CHAPTER_Techmap.rst + CHAPTER_Eval.rst + +.. raw:: latex + + \appendix .. toctree:: - :maxdepth: 2 - :includehidden: + :maxdepth: 3 + :includehidden: + :caption: Appendix + + appendix/CHAPTER_Auxlibs.rst + appendix/CHAPTER_Auxprogs.rst - appendix/index + appendix/CHAPTER_TextRtlil.rst + appendix/CHAPTER_Appnotes.rst + appendix/CHAPTER_StateOfTheArt.rst .. toctree:: - :maxdepth: 1 - :includehidden: + :maxdepth: 1 + :includehidden: - cmd_ref + cmd_ref .. [1] Design and Implementation of the Yosys Open SYnthesis Suite, C. Wolf, 2013 diff --git a/kernel/register.cc b/kernel/register.cc index 47e4d04ef01..ff8f3fb63cb 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -822,22 +822,26 @@ struct HelpPass : public Pass { fclose(f); } - void write_rst(FILE *idxf, std::string cmd, std::string title, std::string text) + void write_rst(std::string cmd, std::string title, std::string text) { - fprintf(idxf, "- :ref:`cmd_%s`: %s\n", cmd.c_str(), title.c_str()); - FILE *f = fopen(stringf("docs/source/cmd/%s.rst", cmd.c_str()).c_str(), "wt"); - - fprintf(f, ".. _cmd_%s:\n\n", cmd.c_str()); - fprintf(f, "================================================================================\n"); - fprintf(f, "%s\n", cmd.c_str()); - fprintf(f, "================================================================================\n\n"); + // make header + size_t char_len = cmd.length() + 3 + title.length(); + std::string title_line = "\n"; + title_line.insert(0, char_len, '='); + fprintf(f, "%s", title_line.c_str()); + fprintf(f, "%s - %s\n", cmd.c_str(), title.c_str()); + fprintf(f, "%s\n", title_line.c_str()); + + // turn off syntax highlighting because it's all text + fprintf(f, ".. highlight:: none\n\n"); + + // render html fprintf(f, ".. only:: html\n\n"); - fprintf(f, " %s\n\n", title.c_str()); - fprintf(f, ":code:`yosys> help %s`\n", cmd.c_str()); - fprintf(f, "--------------------------------------------------------------------------------\n\n"); - fprintf(f, ".. highlight:: none\n"); + fprintf(f, " :code:`yosys> help %s`\n", cmd.c_str()); + fprintf(f, " ----------------------------------------------------------------------------\n\n"); std::stringstream ss; + std::string textcp = text; ss << text; bool IsUsage = true; bool WasBlank = false; @@ -856,7 +860,8 @@ struct HelpPass : public Pass { // strip leading and trailing whitespace std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1); - bool IsDefinition = stripped_line[0] == '-' && stripped_line[1] != ' '; + bool IsDefinition = stripped_line[0] == '-'; + IsDefinition &= stripped_line[1] != ' ' && stripped_line[1] != '>'; bool IsDedent = first_pos <= def_strip_count; bool IsIndent = first_pos == 2 || first_pos == 4; if (cmd.compare(0, 7, "verific") == 0) @@ -866,27 +871,36 @@ struct HelpPass : public Pass { if (IsUsage) { if (stripped_line.compare(0, 3, "See")) // usage should be the first line of help output - fprintf(f, "Usage: :code:`%s` ::\n\n", stripped_line.c_str()); + fprintf(f, " Usage: :code:`%s` ::\n\n", stripped_line.c_str()); else // description refers to another function - fprintf(f, "%s\n", stripped_line.c_str()); + fprintf(f, " %s\n", stripped_line.c_str()); IsUsage = false; } else if (IsIndent && IsDefinition && (WasBlank || WasDefinition)) { // format definition term - fprintf(f, ":code:`%s` ::\n\n", stripped_line.c_str()); + fprintf(f, " :code:`%s` ::\n\n", stripped_line.c_str()); WasDefinition = true; def_strip_count = first_pos; } else if (WasDefinition and IsDedent) { // no longer in definition, start new code block - fprintf(f, "::\n\n %s\n", line.c_str()); + fprintf(f, " ::\n\n %s\n", line.c_str()); WasDefinition = false; } else if (WasDefinition) { // format definition - fprintf(f, " %s\n", line.substr(def_strip_count, std::string::npos).c_str()); + fprintf(f, " %s\n", line.substr(def_strip_count, std::string::npos).c_str()); } else { - fprintf(f, " %s\n", line.c_str()); + fprintf(f, " %s\n", line.c_str()); } } + + // render latex + fprintf(f, ".. only:: latex\n\n"); + fprintf(f, " ::\n\n"); + std::stringstream ss2; + ss2 << textcp; + for (std::string line; std::getline(ss2, line, '\n');) { + fprintf(f, " %s\n", line.c_str()); + } fclose(f); } void execute(std::vector args, RTLIL::Design*) override @@ -950,17 +964,6 @@ struct HelpPass : public Pass { } // this option is undocumented as it is for internal use only else if (args[1] == "-write-rst-command-reference-manual") { - FILE *f = fopen("docs/source/cmd_ref.rst", "wt"); - fprintf(f, "================================================================================\n"); - fprintf(f, "Command reference\n"); - fprintf(f, "================================================================================\n"); - fprintf(f, ".. toctree::\n"); - fprintf(f, " :caption: Command reference\n"); - fprintf(f, " :maxdepth: 1\n"); - fprintf(f, " :hidden:\n"); - fprintf(f, " :glob:\n\n"); - fprintf(f, " cmd/*\n"); - fprintf(f, "\n\n"); for (auto &it : pass_register) { std::ostringstream buf; log_streams.push_back(&buf); @@ -971,9 +974,8 @@ struct HelpPass : public Pass { log("\n"); } log_streams.pop_back(); - write_rst(f, it.first, it.second->short_help, buf.str()); + write_rst(it.first, it.second->short_help, buf.str()); } - fclose(f); } // this option is undocumented as it is for internal use only else if (args[1] == "-write-web-command-reference-manual") { From d6e64034b22e16a4b92f6c0a72f671e2f6bbb705 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 27 Sep 2022 09:26:34 +1300 Subject: [PATCH 10/51] Working on formatting for latexpdf Includes .bib files for references. --- docs/source/conf.py | 13 ++- docs/source/index.rst | 65 ++++++++------ docs/source/literature.bib | 174 +++++++++++++++++++++++++++++++++++++ docs/source/weblinks.bib | 134 ++++++++++++++++++++++++++++ 4 files changed, 357 insertions(+), 29 deletions(-) create mode 100644 docs/source/literature.bib create mode 100644 docs/source/weblinks.bib diff --git a/docs/source/conf.py b/docs/source/conf.py index 4c7b0d0d3cb..04c735a9383 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,14 +25,25 @@ ], } -extensions = ['sphinx.ext.autosectionlabel'] +extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex'] # Ensure that autosectionlabel will produce unique names autosectionlabel_prefix_document = True autosectionlabel_maxdepth = 1 +bibtex_bibfiles = ['literature.bib', 'weblinks.bib'] +bibtext_reference_style = 'author_year' + # unused docs exclude_patterns = [ "CHAPTER_Eval.rst", "appendix/CHAPTER_StateOfTheArt.rst" ] + +latex_elements = { + 'preamble': r''' +\usepackage[T1]{fontenc} % required for luximono! +\usepackage{lmodern} +\usepackage[scaled=0.8]{luximono} % typewriter font with bold face +''' +} diff --git a/docs/source/index.rst b/docs/source/index.rst index 439754221dc..a7b1403eaa1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,34 +1,32 @@ +:Abstract: + Most of today's digital design is done in HDL code (mostly Verilog or + VHDL) and with the help of HDL synthesis tools. + + In special cases such as synthesis for coarse-grain cell libraries or + when testing new synthesis algorithms it might be necessary to write a + custom HDL synthesis tool or add new features to an existing one. In + these cases the availability of a Free and Open Source (FOSS) synthesis + tool that can be used as basis for custom tools would be helpful. + + In the absence of such a tool, the Yosys Open SYnthesis Suite (Yosys) + was developed. This document covers the design and implementation of + this tool. At the moment the main focus of Yosys lies on the high-level + aspects of digital synthesis. The pre-existing FOSS logic-synthesis tool + ABC is used by Yosys to perform advanced gate-level optimizations. + + An evaluation of Yosys based on real-world designs is included. It is + shown that Yosys can be used as-is to synthesize such designs. The + results produced by Yosys in this tests where successfully verified + using formal verification and are comparable in quality to the results + produced by a commercial synthesis tool. + + This document was originally published as bachelor thesis at the Vienna + University of Technology :cite:p:`BACC`. + ================================================================================ Yosys manual ================================================================================ -Abstract -======== - -Most of today's digital design is done in HDL code (mostly Verilog or VHDL) and -with the help of HDL synthesis tools. - -In special cases such as synthesis for coarse-grain cell libraries or when -testing new synthesis algorithms it might be necessary to write a custom HDL -synthesis tool or add new features to an existing one. In these cases the -availability of a Free and Open Source (FOSS) synthesis tool that can be used -as basis for custom tools would be helpful. - -In the absence of such a tool, the Yosys Open SYnthesis Suite (Yosys) was -developed. This document covers the design and implementation of this tool. -At the moment the main focus of Yosys lies on the high-level aspects of -digital synthesis. The pre-existing FOSS logic-synthesis tool ABC is used -by Yosys to perform advanced gate-level optimizations. - -An evaluation of Yosys based on real-world designs is included. It is shown -that Yosys can be used as-is to synthesize such designs. The results produced -by Yosys in this tests where successfully verified using formal verification -and are comparable in quality to the results produced by a commercial -synthesis tool. - -This document was originally published as bachelor thesis at the Vienna -University of Technology [1]_. - .. toctree:: :maxdepth: 2 :caption: Manual @@ -68,4 +66,15 @@ University of Technology [1]_. cmd_ref -.. [1] Design and Implementation of the Yosys Open SYnthesis Suite, C. Wolf, 2013 +.. rubric:: Bibliography + +.. bibliography:: literature.bib + :all: + +.. rubric:: Internet References + +.. bibliography:: weblinks.bib + :list: enumerated + :start: continue + :all: + diff --git a/docs/source/literature.bib b/docs/source/literature.bib new file mode 100644 index 00000000000..5a871945f7a --- /dev/null +++ b/docs/source/literature.bib @@ -0,0 +1,174 @@ + +@inproceedings{intersynth, + title={Example-driven interconnect synthesis for heterogeneous coarse-grain reconfigurable logic}, + author={C. Wolf and Johann Glaser and Florian Schupfer and Jan Haase and Christoph Grimm}, + booktitle={FDL Proceeding of the 2012 Forum on Specification and Design Languages}, + pages={194--201}, + year={2012} +} + +@incollection{intersynthFdlBookChapter, + title={Methodology and Example-Driven Interconnect Synthesis for Designing Heterogeneous Coarse-Grain Reconfigurable Architectures}, + author={Johann Glaser and C. Wolf}, + booktitle={Advances in Models, Methods, and Tools for Complex Chip Design --- Selected contributions from FDL'12}, + editor={Jan Haase}, + publisher={Springer}, + year={2013}, + note={to appear} +} + +@unpublished{BACC, + author = {C. Wolf}, + title = {Design and Implementation of the Yosys Open SYnthesis Suite}, + note = {Bachelor Thesis, Vienna University of Technology}, + year = {2013} +} + +@unpublished{VerilogFossEval, + author = {C. Wolf}, + title = {Evaluation of Open Source Verilog Synthesis Tools for Feature-Completeness and Extensibility}, + note = {Unpublished Student Research Paper, Vienna University of Technology}, + year = {2012} +} + +@article{ABEL, + title={A High-Level Design Language for Programmable Logic Devices}, + author={Kyu Y. Lee and Michael Holley and Mary Bailey and Walter Bright}, + journal={VLSI Design (Manhasset NY: CPM Publications)}, + year={June 1985}, + pages={50-62} +} + +@MISC{Cheng93vl2mv:a, + author = {S-T Cheng and G York and R K Brayton}, + title = {VL2MV: A Compiler from Verilog to BLIF-MV}, + year = {1993} +} + +@MISC{Odin, + author = {Peter Jamieson and Jonathan Rose}, + title = {A VERILOG RTL SYNTHESIS TOOL FOR HETEROGENEOUS FPGAS}, + year = {2005} +} + +@inproceedings{vtr2012, + title={The VTR Project: Architecture and CAD for FPGAs from Verilog to Routing}, + author={Jonathan Rose and Jason Luu and Chi Wai Yu and Opal Densmore and Jeff Goeders and Andrew Somerville and Kenneth B. Kent and Peter Jamieson and Jason Anderson}, + booktitle={Proceedings of the 20th ACM/SIGDA International Symposium on Field-Programmable Gate Arrays}, + pages={77--86}, + year={2012}, + organization={ACM} +} + +@MISC{LogicSynthesis, + author = {G D Hachtel and F Somenzi}, + title = {Logic Synthesis and Verification Algorithms}, + year = {1996} +} + +@ARTICLE{Verilog2005, + journal={IEEE Std 1364-2005 (Revision of IEEE Std 1364-2001)}, + title={IEEE Standard for Verilog Hardware Description Language}, + author={IEEE Standards Association and others}, + year={2006}, + doi={10.1109/IEEESTD.2006.99495} +} + +@ARTICLE{VerilogSynth, + journal={IEEE Std 1364.1-2002}, + title={IEEE Standard for Verilog Register Transfer Level Synthesis}, + author={IEEE Standards Association and others}, + year={2002}, + doi={10.1109/IEEESTD.2002.94220} +} + +@ARTICLE{VHDL, + journal={IEEE Std 1076-2008 (Revision of IEEE Std 1076-2002)}, + title={IEEE Standard VHDL Language Reference Manual}, + author={IEEE Standards Association and others}, + year={2009}, + month={26}, + doi={10.1109/IEEESTD.2009.4772740} +} + +@ARTICLE{VHDLSynth, + journal={IEEE Std 1076.6-2004 (Revision of IEEE Std 1076.6-1999)}, + title={IEEE Standard for VHDL Register Transfer Level (RTL) Synthesis}, + author={IEEE Standards Association and others}, + year={2004}, + doi={10.1109/IEEESTD.2004.94802} +} + +@ARTICLE{IP-XACT, + journal={IEEE Std 1685-2009}, + title={IEEE Standard for IP-XACT, Standard Structure for Packaging, Integrating, and Reusing IP within Tools Flows}, + author={IEEE Standards Association and others}, + year={2010}, + pages={C1-360}, + keywords={abstraction definitions, address space specification, bus definitions, design environment, EDA, electronic design automation, electronic system level, ESL, implementation constraints, IP-XACT, register transfer level, RTL, SCRs, semantic consistency rules, TGI, tight generator interface, tool and data interoperability, use models, XML design meta-data, XML schema}, + doi={10.1109/IEEESTD.2010.5417309} +} + +@book{Dragonbook, + author = {Aho, Alfred V. and Sethi, Ravi and Ullman, Jeffrey D.}, + title = {Compilers: principles, techniques, and tools}, + year = {1986}, + isbn = {0-201-10088-6}, + publisher = {Addison-Wesley Longman Publishing Co., Inc.}, + address = {Boston, MA, USA} +} + +@INPROCEEDINGS{Cummings00, + author = {Clifford E. Cummings and Sunburst Design Inc}, + title = {Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill}, + booktitle = {SNUG (Synopsys Users Group) 2000 User Papers, section-MC1 (1 st paper}, + year = {2000} +} + +@ARTICLE{MURPHY, + author={D. L. Klipstein}, + journal={Cahners Publishing Co., EEE Magazine, Vol. 15, No. 8}, + title={The Contributions of Edsel Murphy to the Understanding of the Behavior of Inanimate Objects}, + year={August 1967} +} + +@INPROCEEDINGS{fsmextract, + author={Yiqiong Shi and Chan Wai Ting and Bah-Hwee Gwee and Ye Ren}, + booktitle={Circuits and Systems (ISCAS), Proceedings of 2010 IEEE International Symposium on}, + title={A highly efficient method for extracting FSMs from flattened gate-level netlist}, + year={2010}, + pages={2610-2613}, + keywords={circuit CAD;finite state machines;microcontrollers;FSM;control-intensive circuits;finite state machines;flattened gate-level netlist;state register elimination technique;Automata;Circuit synthesis;Continuous wavelet transforms;Design automation;Digital circuits;Hardware design languages;Logic;Microcontrollers;Registers;Signal processing}, + doi={10.1109/ISCAS.2010.5537093}, +} + +@ARTICLE{MultiLevelLogicSynth, + author={Brayton, R.K. and Hachtel, G.D. and Sangiovanni-Vincentelli, A.L.}, + journal={Proceedings of the IEEE}, + title={Multilevel logic synthesis}, + year={1990}, + volume={78}, + number={2}, + pages={264-300}, + keywords={circuit layout CAD;integrated logic circuits;logic CAD;capsule summaries;definitions;detailed analysis;in-depth background;logic decomposition;logic minimisation;logic synthesis;logic synthesis techniques;multilevel combinational logic;multilevel logic synthesis;notation;perspective;survey;synthesis methods;technology mapping;testing;Application specific integrated circuits;Design automation;Integrated circuit synthesis;Logic design;Logic devices;Logic testing;Network synthesis;Programmable logic arrays;Signal synthesis;Silicon}, + doi={10.1109/5.52213}, + ISSN={0018-9219}, +} + +@article{UllmannSubgraphIsomorphism, + author = {Ullmann, J. R.}, + title = {An Algorithm for Subgraph Isomorphism}, + journal = {J. ACM}, + issue_date = {Jan. 1976}, + volume = {23}, + number = {1}, + month = jan, + year = {1976}, + issn = {0004-5411}, + pages = {31--42}, + numpages = {12}, + doi = {10.1145/321921.321925}, + acmid = {321925}, + publisher = {ACM}, + address = {New York, NY, USA}, +} diff --git a/docs/source/weblinks.bib b/docs/source/weblinks.bib new file mode 100644 index 00000000000..23ddbc38b99 --- /dev/null +++ b/docs/source/weblinks.bib @@ -0,0 +1,134 @@ + +@misc{YosysGit, + author = {Claire Xenia Wolf}, + title = {{Yosys Open SYnthesis Suite (YOSYS)}}, + note = {\url{http://github.com/YosysHQ/yosys}} +} + +@misc{YosysTestsGit, + author = {Claire Xenia Wolf}, + title = {{Yosys Test Bench}}, + note = {\url{http://github.com/YosysHQ/yosys-tests}} +} + +@misc{VlogHammer, + author = {Claire Xenia Wolf}, + title = {{VlogHammer Verilog Synthesis Regression Tests}}, + note = {\url{http://github.com/YosysHQ/VlogHammer}} +} + +@misc{Icarus, + author = {Stephen Williams}, + title = {{Icarus Verilog}}, + note = {Version 0.8.7, \url{http://iverilog.icarus.com/}} +} + +@misc{VTR, + author= {Jonathan Rose and Jason Luu and Chi Wai Yu and Opal Densmore and Jeff Goeders and Andrew Somerville and Kenneth B. Kent and Peter Jamieson and Jason Anderson}, + title = {{The Verilog-to-Routing (VTR) Project for FPGAs}}, + note = {Version 1.0, \url{https://code.google.com/p/vtr-verilog-to-routing/}} +} + +@misc{HANA, + author = {Parvez Ahmad}, + title = {{HDL Analyzer and Netlist Architect (HANA)}}, + note = {Verison linux64-1.0-alpha (2012-10-14), \url{http://sourceforge.net/projects/sim-sim/}} +} + +@misc{MVSIS, + author = {MVSIS group at Berkeley studies logic synthesis and verification for VLSI design}, + title = {{MVSIS: Logic Synthesis and Verification}}, + note = {Version 3.0, \url{http://embedded.eecs.berkeley.edu/mvsis/}} +} + +@misc{VIS, + author = {{The VIS group}}, + title = {{VIS: A system for Verification and Synthesis}}, + note = {Version 2.4, \url{http://vlsi.colorado.edu/~vis/}} +} + +@misc{ABC, + author = {{Berkeley Logic Synthesis and Verification Group}}, + title = {{ABC: A System for Sequential Synthesis and Verification}}, + note = {HQ Rev b5750272659f, 2012-10-28, \url{http://www.eecs.berkeley.edu/~alanmi/abc/}} +} + +@misc{AIGER, + author = {{Armin Biere, Johannes Kepler University Linz, Austria}}, + title = {{AIGER}}, + note = {\url{http://fmv.jku.at/aiger/}} +} + +@misc{XilinxWebPACK, + author = {{Xilinx, Inc.}}, + title = {{ISE WebPACK Design Software}}, + note = {\url{http://www.xilinx.com/products/design-tools/ise-design-suite/ise-webpack.htm}} +} + +@misc{QuartusWeb, + author = {{Altera, Inc.}}, + title = {{Quartus II Web Edition Software}}, + note = {\url{http://www.altera.com/products/software/quartus-ii/web-edition/qts-we-index.html}} +} + +@misc{OR1200, + title = {{OpenRISC 1200 CPU}}, + note = {\url{http://opencores.org/or1k/OR1200\_OpenRISC\_Processor}} +} + +@misc{openMSP430, + title = {{openMSP430 CPU}}, + note = {\url{http://opencores.org/project,openmsp430}} +} + +@misc{i2cmaster, + title = {{OpenCores I$^2$C Core}}, + note = {\url{http://opencores.org/project,i2c}} +} + +@misc{k68, + title = {{OpenCores k68 Core}}, + note = {\url{http://opencores.org/project,k68}} +} + +@misc{bison, + title = {{GNU Bison}}, + note = {\url{http://www.gnu.org/software/bison/}} +} + +@misc{flex, + title = {{Flex}}, + note = {\url{http://flex.sourceforge.net/}} +} + +@misc{C_to_Verilog, + title = {{C-to-Verilog}}, + note = {\url{http://www.c-to-verilog.com/}} +} + +@misc{LegUp, + title = {{LegUp}}, + note = {\url{http://legup.eecg.utoronto.ca/}} +} + +@misc{LibertyFormat, + title = {{The Liberty Library Modeling Standard}}, + note = {\url{http://www.opensourceliberty.org/}} +} + +@misc{ASIC-WORLD, + title = {{World of ASIC}}, + note = {\url{http://www.asic-world.com/}} +} + +@misc{Formality, + title = {{Synopsys Formality Equivalence Checking}}, + note = {\url{http://www.synopsys.com/Tools/Verification/FormalEquivalence/Pages/Formality.aspx}}, +} + +@misc{bigint, + author = {Matt McCutchen}, + title = {{C++ Big Integer Library}}, + note = {\url{http://mattmccutchen.net/bigint/}} +} + From effb85db335445013262b08c84024d9512c64b92 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 27 Sep 2022 12:41:46 +1300 Subject: [PATCH 11/51] Including Chapters (part.1) --- docs/source/CHAPTER_Approach.rst | 146 ++++++++ docs/source/CHAPTER_Eval.rst | 231 +++++++++++++ docs/source/CHAPTER_Intro.rst | 96 ++++++ docs/source/CHAPTER_Optimize.rst | 326 ++++++++++++++++++ docs/source/CHAPTER_Overview.rst | 555 +++++++++++++++++++++++++++++++ docs/source/cmd_ref.rst | 2 + docs/source/conf.py | 2 +- docs/source/index.rst | 14 +- 8 files changed, 1365 insertions(+), 7 deletions(-) create mode 100644 docs/source/CHAPTER_Approach.rst create mode 100644 docs/source/CHAPTER_Eval.rst create mode 100644 docs/source/CHAPTER_Intro.rst create mode 100644 docs/source/CHAPTER_Optimize.rst create mode 100644 docs/source/CHAPTER_Overview.rst diff --git a/docs/source/CHAPTER_Approach.rst b/docs/source/CHAPTER_Approach.rst new file mode 100644 index 00000000000..8b836043593 --- /dev/null +++ b/docs/source/CHAPTER_Approach.rst @@ -0,0 +1,146 @@ +.. _chapter:approach: + +Approach +======== + +Yosys is a tool for synthesising (behavioural) Verilog HDL code to +target architecture netlists. Yosys aims at a wide range of application +domains and thus must be flexible and easy to adapt to new tasks. This +chapter covers the general approach followed in the effort to implement +this tool. + +Data- and Control-Flow +---------------------- + +The data- and control-flow of a typical synthesis tool is very similar +to the data- and control-flow of a typical compiler: different +subsystems are called in a predetermined order, each consuming the data +generated by the last subsystem and generating the data for the next +subsystem (see :numref:`Fig. %s `). + +[fig:approach_flow] + +The first subsystem to be called is usually called a frontend. It does +not process the data generated by another subsystem but instead reads +the user input—in the case of a HDL synthesis tool, the behavioural HDL +code. + +The subsystems that consume data from previous subsystems and produce +data for the next subsystems (usually in the same or a similar format) +are called passes. + +The last subsystem that is executed transforms the data generated by the +last pass into a suitable output format and writes it to a disk file. +This subsystem is usually called the backend. + +In Yosys all frontends, passes and backends are directly available as +commands in the synthesis script. Thus the user can easily create a +custom synthesis flow just by calling passes in the right order in a +synthesis script. + +Internal Formats in Yosys +------------------------- + +Yosys uses two different internal formats. The first is used to store an +abstract syntax tree (AST) of a Verilog input file. This format is +simply called AST and is generated by the Verilog Frontend. This data +structure is consumed by a subsystem called AST Frontend [1]_. This AST +Frontend then generates a design in Yosys' main internal format, the +Register-Transfer-Level-Intermediate-Language (RTLIL) representation. It +does that by first performing a number of simplifications within the AST +representation and then generating RTLIL from the simplified AST data +structure. + +The RTLIL representation is used by all passes as input and outputs. +This has the following advantages over using different representational +formats between different passes: + +- The passes can be rearranged in a different order and passes can be + removed or inserted. + +- Passes can simply pass-thru the parts of the design they don't change + without the need to convert between formats. In fact Yosys passes + output the same data structure they received as input and performs + all changes in place. + +- All passes use the same interface, thus reducing the effort required + to understand a pass when reading the Yosys source code, e.g. when + adding additional features. + +The RTLIL representation is basically a netlist representation with the +following additional features: + +- An internal cell library with fixed-function cells to represent RTL + datapath and register cells as well as logical gate-level cells + (single-bit gates and registers). + +- Support for multi-bit values that can use individual bits from wires + as well as constant bits to represent coarse-grain netlists. + +- Support for basic behavioural constructs (if-then-else structures and + multi-case switches with a sensitivity list for updating the + outputs). + +- Support for multi-port memories. + +The use of RTLIL also has the disadvantage of having a very powerful +format between all passes, even when doing gate-level synthesis where +the more advanced features are not needed. In order to reduce complexity +for passes that operate on a low-level representation, these passes +check the features used in the input RTLIL and fail to run when +unsupported high-level constructs are used. In such cases a pass that +transforms the higher-level constructs to lower-level constructs must be +called from the synthesis script first. + +.. _sec:typusecase: + +Typical Use Case +---------------- + +The following example script may be used in a synthesis flow to convert +the behavioural Verilog code from the input file design.v to a +gate-level netlist synth.v using the cell library described by the +Liberty file : + +.. code:: sh + :number-lines: + + # read input file to internal representation + read_verilog design.v + + # convert high-level behavioral parts ("processes") to d-type flip-flops and muxes + proc + + # perform some simple optimizations + opt + + # convert high-level memory constructs to d-type flip-flops and multiplexers + memory + + # perform some simple optimizations + opt + + # convert design to (logical) gate-level netlists + techmap + + # perform some simple optimizations + opt + + # map internal register types to the ones from the cell library + dfflibmap -liberty cells.lib + + # use ABC to map remaining logic to cells from the cell library + abc -liberty cells.lib + + # cleanup + opt + + # write results to output file + write_verilog synth.v + +A detailed description of the commands available in Yosys can be found +in App. \ `[commandref] <#commandref>`__. + +.. [1] + In Yosys the term pass is only used to refer to commands that operate + on the RTLIL data structure. diff --git a/docs/source/CHAPTER_Eval.rst b/docs/source/CHAPTER_Eval.rst new file mode 100644 index 00000000000..3a2a519fc11 --- /dev/null +++ b/docs/source/CHAPTER_Eval.rst @@ -0,0 +1,231 @@ +.. _chapter:eval: + +Evaluation, Conclusion, Future Work +=================================== + +The Yosys source tree contains over 200 test cases [1]_ which are used +in the make test make-target. Besides these there is an external Yosys +benchmark and test case package that contains a few larger designs . +This package contains the designs listed in +Tab. \ `[tab:yosys-test-designs] <#tab:yosys-test-designs>`__. + +.. table:: Tests included in the yosys-tests package. + + =========== ========= ================ + ====================================================== + Test-Design Source Gates Description / Comments + =========== ========= ================ + ====================================================== + aes_core IWLS2005 :math:`41{,}837` AES Cipher written by Rudolf Usselmann + i2c IWLS2005 :math:`1{,}072` WISHBONE compliant I2C Master by Richard Herveille + openmsp430 OpenCores :math:`7{,}173` MSP430 compatible CPU by Olivier Girard + or1200 OpenCores :math:`42{,}675` The OpenRISC 1200 CPU by Damjan Lampret + sasc IWLS2005 :math:`456` Simple Async. Serial Comm. Device by Rudolf Usselmann + simple_spi IWLS2005 :math:`690` MC68HC11E based SPI interface by Richard Herveille + spi IWLS2005 :math:`2{,}478` SPI IP core by Simon Srot + ss_pcm IWLS2005 :math:`279` PCM IO Slave by Rudolf Usselmann + systemcaes IWLS2005 :math:`6{,}893` AES core (using SystemC to Verilog) by Javier Castillo + usb_phy IWLS2005 :math:`515` USB 1.1 PHY by Rudolf Usselmann + =========== ========= ================ + ====================================================== + +Correctness of Synthesis Results +-------------------------------- + +The following measures were taken to increase the confidence in the +correctness of the Yosys synthesis results: + +- Yosys comes with a large selection [2]_ of small test cases that are + evaluated when the command make test is executed. During development + of Yosys it was shown that this collection of test cases is + sufficient to catch most bugs. The following more sophisticated test + procedures only caught a few additional bugs. Whenever this happened, + an appropriate test case was added to the collection of small test + cases for make test to ensure better testability of the feature in + question in the future. + +- The designs listed in + Tab. \ `[tab:yosys-test-designs] <#tab:yosys-test-designs>`__ where + validated using the formal verification tool Synopsys Formality. The + Yosys synthesis scripts used to synthesize the individual designs for + this test are slightly different per design in order to broaden the + coverage of Yosys features. The large majority of all errors + encountered using these tests are false-negatives, mostly related to + FSM encoding or signal naming in large array logic (such as in memory + blocks). Therefore the fsm_recode pass was extended so it can be used + to generate TCL commands for Synopsys Formality that describe the + relationship between old and new state encodings. Also the method + used to generate signal and cell names in the Verilog backend was + slightly modified in order to improve the automatic matching of net + names in Synopsys Formality. With these changes in place all designs + in Tab. \ `[tab:yosys-test-designs] <#tab:yosys-test-designs>`__ + validate successfully using Formality. + +- VlogHammer is a set of scripts that auto-generate a large collection + of test cases [3]_ and synthesize them using Yosys and the following + freely available proprietary synthesis tools. + + - Xilinx Vivado WebPack (2013.2) + + - Xilinx ISE (XST) WebPack (14.5) + + - Altera Quartus II Web Edition (13.0) + + The built-in SAT solver of Yosys is used to formally verify the Yosys + RTL- and Gate-Level netlists against the netlists generated by this + other tools. [4]_ When differences are found, the input pattern that + result in different outputs are used for simulating the original + Verilog code as well as the synthesis results using the following + Verilog simulators. + + - Xilinx ISIM (from Xilinx ISE 14.5 ) + + - Modelsim 10.1d (from Quartus II 13.0 ) + + - Icarus Verilog (no specific version) + + The set of tests performed by VlogHammer systematically verify the + correct behaviour of + + - Yosys Verilog Frontend and RTL generation + + - Yosys Gate-Level Technology Mapping + + - Yosys SAT Models for RTL- and Gate-Level cells + + - Yosys Constant Evaluator Models for RTL- and Gate-Level cells + + against the reference provided by the other tools. A few bugs related + to sign extensions and bit-width extensions where found (and have + been fixed meanwhile) using this approach. This test also revealed a + small number of bugs in the other tools (i.e. Vivado, XST, Quartus, + ISIM and Icarus Verilog; no bugs where found in Modelsim using + vlogHammer so far). + +Although complex software can never be expected to be fully bug-free +cite:p:`MURPHY`, it has been shown that Yosys is mature and +feature-complete enough to handle most real-world cases correctly. + +Quality of synthesis results +---------------------------- + +In this section an attempt to evaluate the quality of Yosys synthesis +results is made. To this end the synthesis results of a commercial FPGA +synthesis tool when presented with the original HDL code vs. when +presented with the Yosys synthesis result are compared. + +The OpenMSP430 and the OpenRISC 1200 test cases were synthesized using +the following Yosys synthesis script: + +:: + + hierarchy -check + proc; opt; fsm; opt; memory; opt + techmap; opt; abc; opt + +The original RTL and the Yosys output where both passed to the Xilinx +XST 14.5 FPGA synthesis tool. The following setting where used for XST: + +:: + + -p artix7 + -use_dsp48 NO + -iobuf NO + -ram_extract NO + -rom_extract NO + -fsm_extract YES + -fsm_encoding Auto + +The results of this comparison is summarized in +Tab. \ `[tab:synth-test] <#tab:synth-test>`__. The used FPGA resources +(registers and LUTs) and performance (maximum frequency as reported by +XST) are given per module (indentation indicates module hierarchy, the +numbers are including all contained modules). + +For most modules the results are very similar between XST and Yosys. XST +is used in both cases for the final mapping of logic to LUTs. So this +comparison only compares the high-level synthesis functions (such as FSM +extraction and encoding) of Yosys and XST. + +.. table:: Synthesis results (as reported by XST) for OpenMSP430 and +OpenRISC 1200 + + ============================ ==== ==== ========== ==== ===== + ========== + \ + Module Regs LUTs Max. Freq. Regs LUTs Max. Freq. + openMSP430 689 2210 71 MHz 719 2779 53 MHz + 1em omsp_clock_module 21 30 645 MHz 21 30 644 MHz + 1em 1em omsp_sync_cell 2 — 1542 MHz 2 — 1542 MHz + 1em 1em omsp_sync_reset 2 — 1542 MHz 2 — 1542 MHz + 1em omsp_dbg 143 344 292 MHz 149 430 353 MHz + 1em 1em omsp_dbg_uart 76 135 377 MHz 79 139 389 MHz + 1em omsp_execution_unit 266 911 80 MHz 266 1034 137 MHz + 1em 1em omsp_alu — 202 — — 263 — + 1em 1em omsp_register_file 231 478 285 MHz 231 506 293 MHz + 1em omsp_frontend 115 340 178 MHz 118 527 206 MHz + 1em omsp_mem_backbone 38 141 1087 MHz 38 144 1087 MHz + 1em omsp_multiplier 73 397 129 MHz 102 1053 55 MHz + 1em omsp_sfr 6 18 1023 MHz 6 20 1023 MHz + 1em omsp_watchdog 24 53 362 MHz 24 70 360 MHz + or1200_top 7148 9969 135 MHz 7173 10238 108 MHz + 1em or1200_alu — 681 — — 641 — + 1em or1200_cfgr — 11 — — 11 — + 1em or1200_ctrl 175 186 464 MHz 174 279 377 MHz + 1em or1200_except 241 451 313 MHz 241 353 301 MHz + 1em or1200_freeze 6 18 507 MHz 6 16 515 MHz + 1em or1200_if 68 143 806 MHz 68 139 790 MHz + 1em or1200_lsu 8 138 — 12 205 1306 MHz + 1em 1em or1200_mem2reg — 60 — — 66 — + 1em 1em or1200_reg2mem — 29 — — 29 — + 1em or1200_mult_mac 394 2209 240 MHz 394 2230 241 MHz + 1em 1em or1200_amultp2_32x32 256 1783 240 MHz 256 1770 241 MHz + 1em or1200_operandmuxes 65 129 1145 MHz 65 129 1145 MHz + 1em or1200_rf 1041 1722 822 MHz 1042 1722 581 MHz + 1em or1200_sprs 18 432 724 MHz 18 469 722 MHz + 1em or1200_wbmux 33 93 — 33 78 — + 1em or1200_dc_top — 5 — — 5 — + 1em or1200_dmmu_top 2445 1004 — 2445 1043 — + 1em 1em or1200_dmmu_tlb 2444 975 — 2444 1013 — + 1em or1200_du 67 56 859 MHz 67 56 859 MHz + 1em or1200_ic_top 39 100 527 MHz 41 136 514 MHz + 1em 1em or1200_ic_fsm 40 42 408 MHz 40 75 484 MHz + 1em or1200_pic 38 50 1169 MHz 38 50 1177 MHz + 1em or1200_tt 64 112 370 MHz 64 186 437 MHz + ============================ ==== ==== ========== ==== ===== + ========== + +Conclusion and Future Work +-------------------------- + +Yosys is capable of correctly synthesizing real-world Verilog designs. +The generated netlists are of a decent quality. However, in cases where +dedicated hardware resources should be used for certain functions it is +of course necessary to implement proper technology mapping for these +functions in Yosys. This can be as easy as calling the techmap pass with +an architecture-specific mapping file in the synthesis script. As no +such thing has been done in the above tests, it is only natural that the +resulting designs cannot benefit from these dedicated hardware +resources. + +Therefore future work includes the implementation of +architecture-specific technology mappings besides additional frontends +(VHDL), backends (EDIF), and above all else, application specific +passes. After all, this was the main motivation for the development of +Yosys in the first place. + +.. [1] + Most of this test cases are copied from HANA or the ASIC-WORLD + website . + +.. [2] + At the time of this writing 269 test cases. + +.. [3] + At the time of this writing over 6600 test cases. + +.. [4] + A SAT solver is a program that can solve the boolean satisfiability + problem. The built-in SAT solver in Yosys can be used for formal + equivalence checking, amongst other things. See + Sec. \ \ `[cmd:sat] <#cmd:sat>`__ for details. diff --git a/docs/source/CHAPTER_Intro.rst b/docs/source/CHAPTER_Intro.rst new file mode 100644 index 00000000000..032924f28ce --- /dev/null +++ b/docs/source/CHAPTER_Intro.rst @@ -0,0 +1,96 @@ +.. _chapter:intro: + +Introduction +============ + +This document presents the Free and Open Source (FOSS) Verilog HDL synthesis +tool "Yosys". Its design and implementation as well as its performance on +real-world designs is discussed in this document. + +History of Yosys +---------------- + +A Hardware Description Language (HDL) is a computer language used to describe +circuits. A HDL synthesis tool is a computer program that takes a formal +description of a circuit written in an HDL as input and generates a netlist that +implements the given circuit as output. + +Currently the most widely used and supported HDLs for digital circuits are +Verilog :cite:p:`Verilog2005,VerilogSynth` and :abbr:`VHDL (VHSIC HDL, where +VHSIC is an acronym for Very-High-Speed Integrated Circuits)` +:cite:p:`VHDL,VHDLSynth`. Both HDLs are used for test and verification purposes +as well as logic synthesis, resulting in a set of synthesizable and a set of +non-synthesizable language features. In this document we only look at the +synthesizable subset of the language features. + +In recent work on heterogeneous coarse-grain reconfigurable logic +:cite:p:`intersynth` the need for a custom application-specific HDL synthesis +tool emerged. It was soon realised that a synthesis tool that understood Verilog +or VHDL would be preferred over a synthesis tool for a custom HDL. Given an +existing Verilog or VHDL front end, the work for writing the necessary +additional features and integrating them in an existing tool can be estimated to +be about the same as writing a new tool with support for a minimalistic custom +HDL. + +The proposed custom HDL synthesis tool should be licensed under a Free and Open +Source Software (FOSS) licence. So an existing FOSS Verilog or VHDL synthesis +tool would have been needed as basis to build upon. The main advantages of +choosing Verilog or VHDL is the ability to synthesize existing HDL code and to +mitigate the requirement for circuit-designers to learn a new language. In order +to take full advantage of any existing FOSS Verilog or VHDL tool, such a tool +would have to provide a feature-complete implementation of the synthesizable HDL +subset. + +Basic RTL synthesis is a well understood field :cite:p:`LogicSynthesis`. Lexing, +parsing and processing of computer languages :cite:p:`Dragonbook` is a +thoroughly researched field. All the information required to write such tools +has been openly available for a long time, and it is therefore likely that a +FOSS HDL synthesis tool with a feature-complete Verilog or VHDL front end must +exist which can be used as a basis for a custom RTL synthesis tool. + +Due to the author's preference for Verilog over VHDL it was decided early on to +go for Verilog instead of VHDL [#]_. So the existing FOSS Verilog synthesis +tools were evaluated. The results of this evaluation are utterly devastating. +Therefore a completely new Verilog synthesis tool was implemented and is +recommended as basis for custom synthesis tools. This is the tool that is +discussed in this document. + +Structure of this Document +-------------------------- + +The structure of this document is as follows: + +:numref:`Chapter %s ` is this introduction. + +:numref:`Chapter %s ` covers a short introduction to the world +of HDL synthesis. Basic principles and the terminology are outlined in this +chapter. + +:numref:`Chapter %s ` gives the quickest possible outline to +how the problem of implementing a HDL synthesis tool is approached in the case +of Yosys. + +:numref:`Chapter %s ` contains a more detailed overview of the +implementation of Yosys. This chapter covers the data structures used in Yosys +to represent a design in detail and is therefore recommended reading for +everyone who is interested in understanding the Yosys internals. + +:numref:`Chapter %s ` covers the internal cell library used by +Yosys. This is especially important knowledge for anyone who wants to understand +the intermediate netlists used internally by Yosys. + +:numref:`Chapter %s ` gives a tour to the internal APIs of Yosys. +This is recommended reading for everyone who actually wants to read or write +Yosys source code. The chapter concludes with an example loadable module for +Yosys. + +Chapters :numref:`%s `, :numref:`%s ` and +:numref:`%s ` cover three important pieces of the synthesis +pipeline: The Verilog frontend, the optimization passes and the technology +mapping to the target architecture, respectively. + +Various appendices, including a :ref:`cmd_ref`, complete this document. + +.. [#] + A quick investigation into FOSS VHDL tools yielded similar grim results for + FOSS VHDL synthesis tools. diff --git a/docs/source/CHAPTER_Optimize.rst b/docs/source/CHAPTER_Optimize.rst new file mode 100644 index 00000000000..3de18f07e07 --- /dev/null +++ b/docs/source/CHAPTER_Optimize.rst @@ -0,0 +1,326 @@ +.. _chapter:opt: + +Optimizations +============= + +Yosys employs a number of optimizations to generate better and cleaner results. +This chapter outlines these optimizations. + +Simple Optimizations +-------------------- + +The Yosys pass opt runs a number of simple optimizations. This includes removing +unused signals and cells and const folding. It is recommended to run this pass +after each major step in the synthesis script. At the time of this writing the +opt pass executes the following passes that each perform a simple optimization: + +- Once at the beginning of opt: + + - opt_expr + - opt_merge -nomux + +- Repeat until result is stable: + + - opt_muxtree + - opt_reduce + - opt_merge + - opt_rmdff + - opt_clean + - opt_expr + +The following section describes each of the opt\_ passes. + +The opt_expr pass +~~~~~~~~~~~~~~~~~ + +This pass performs const folding on the internal combinational cell types +described in :numref:`Chap. %s `. This means a cell with all +constant inputs is replaced with the constant value this cell drives. In some +cases this pass can also optimize cells with some constant inputs. + +.. table:: Const folding rules for $_AND\_ cells as used in opt_expr. + :name: tab:opt_expr_and + :align: center + + ========= ========= =========== + A-Input B-Input Replacement + ========= ========= =========== + any 0 0 + 0 any 0 + 1 1 1 + --------- --------- ----------- + X/Z X/Z X + 1 X/Z X + X/Z 1 X + --------- --------- ----------- + any X/Z 0 + X/Z any 0 + --------- --------- ----------- + :math:`a` 1 :math:`a` + 1 :math:`b` :math:`b` + ========= ========= =========== + +.. How to format table? + +:numref:`Table %s ` shows the replacement rules used for +optimizing an $_AND\_ gate. The first three rules implement the obvious const +folding rules. Note that ‘any' might include dynamic values calculated by other +parts of the circuit. The following three lines propagate undef (X) states. +These are the only three cases in which it is allowed to propagate an undef +according to Sec. 5.1.10 of IEEE Std. 1364-2005 :cite:p:`Verilog2005`. + +The next two lines assume the value 0 for undef states. These two rules are only +used if no other substitutions are possible in the current module. If other +substitutions are possible they are performed first, in the hope that the ‘any' +will change to an undef value or a 1 and therefore the output can be set to +undef. + +The last two lines simply replace an $_AND\_ gate with one constant-1 input with +a buffer. + +Besides this basic const folding the opt_expr pass can replace 1-bit wide $eq +and $ne cells with buffers or not-gates if one input is constant. + +The opt_expr pass is very conservative regarding optimizing $mux cells, as these +cells are often used to model decision-trees and breaking these trees can +interfere with other optimizations. + +The opt_muxtree pass +~~~~~~~~~~~~~~~~~~~~ + +This pass optimizes trees of multiplexer cells by analyzing the select inputs. +Consider the following simple example: + +.. code:: verilog + :number-lines: + + module uut(a, y); input a; output [1:0] y = a ? (a ? 1 : 2) : 3; endmodule + +The output can never be 2, as this would require ``a`` to be 1 for the outer +multiplexer and 0 for the inner multiplexer. The opt_muxtree pass detects this +contradiction and replaces the inner multiplexer with a constant 1, yielding the +logic for ``y = a ? 1 : 3``. + +The opt_reduce pass +~~~~~~~~~~~~~~~~~~~ + +This is a simple optimization pass that identifies and consolidates identical +input bits to $reduce_and and $reduce_or cells. It also sorts the input bits to +ease identification of shareable $reduce_and and $reduce_or cells in other +passes. + +This pass also identifies and consolidates identical inputs to multiplexer +cells. In this case the new shared select bit is driven using a $reduce_or cell +that combines the original select bits. + +Lastly this pass consolidates trees of $reduce_and cells and trees of $reduce_or +cells to single large $reduce_and or $reduce_or cells. + +These three simple optimizations are performed in a loop until a stable result +is produced. + +The opt_rmdff pass +~~~~~~~~~~~~~~~~~~ + +This pass identifies single-bit d-type flip-flops ($_DFF\_, $dff, and $adff +cells) with a constant data input and replaces them with a constant driver. + +The opt_clean pass +~~~~~~~~~~~~~~~~~~ + +This pass identifies unused signals and cells and removes them from the design. +It also creates an attribute on wires with unused bits. This attribute can be +used for debugging or by other optimization passes. + +The opt_merge pass +~~~~~~~~~~~~~~~~~~ + +This pass performs trivial resource sharing. This means that this pass +identifies cells with identical inputs and replaces them with a single instance +of the cell. + +The option -nomux can be used to disable resource sharing for multiplexer cells +($mux and $pmux. This can be useful as it prevents multiplexer trees to be +merged, which might prevent opt_muxtree to identify possible optimizations. + +FSM Extraction and Encoding +--------------------------- + +The fsm pass performs finite-state-machine (FSM) extraction and recoding. The +fsm pass simply executes the following other passes: + +- Identify and extract FSMs: + + - fsm_detect + - fsm_extract + +- Basic optimizations: + + - fsm_opt + - opt_clean + - fsm_opt + +- Expanding to nearby gate-logic (if called with -expand): + + - fsm_expand + - opt_clean + - fsm_opt + +- Re-code FSM states (unless called with -norecode): + + - fsm_recode + +- Print information about FSMs: + + - fsm_info + +- Export FSMs in KISS2 file format (if called with -export): + + - fsm_export + +- Map FSMs to RTL cells (unless called with -nomap): + + - fsm_map + +The fsm_detect pass identifies FSM state registers and marks them using the +attribute. The fsm_extract extracts all FSMs marked using the attribute (unless +is set to "none") and replaces the corresponding RTL cells with a $fsm cell. All +other fsm\_ passes operate on these $fsm cells. The fsm_map call finally +replaces the $fsm cells with RTL cells. + +Note that these optimizations operate on an RTL netlist. I.e. the fsm pass +should be executed after the proc pass has transformed all RTLIL::Process +objects to RTL cells. + +The algorithms used for FSM detection and extraction are influenced by a more +general reported technique :cite:p:`fsmextract`. + +FSM Detection +~~~~~~~~~~~~~ + +The fsm_detect pass identifies FSM state registers. It sets the attribute on any +(multi-bit) wire that matches the following description: + +- Does not already have the attribute. +- Is not an output of the containing module. +- Is driven by single $dff or $adff cell. +- The -Input of this $dff or $adff cell is driven by a multiplexer tree that + only has constants or the old state value on its leaves. +- The state value is only used in the said multiplexer tree or by simple + relational cells that compare the state value to a constant (usually $eq + cells). + +This heuristic has proven to work very well. It is possible to overwrite it by +setting on registers that should be considered FSM state registers and setting +on registers that match the above criteria but should not be considered FSM +state registers. + +Note however that marking state registers with that are not suitable for FSM +recoding can cause synthesis to fail or produce invalid results. + +FSM Extraction +~~~~~~~~~~~~~~ + +The fsm_extract pass operates on all state signals marked with the (!= "none") +attribute. For each state signal the following information is determined: + +- The state registers + +- The asynchronous reset state if the state registers use asynchronous reset + +- All states and the control input signals used in the state transition + functions + +- The control output signals calculated from the state signals and control + inputs + +- A table of all state transitions and corresponding control inputs- and + outputs + +The state registers (and asynchronous reset state, if applicable) is simply +determined by identifying the driver for the state signal. + +From there the $mux-tree driving the state register inputs is recursively +traversed. All select inputs are control signals and the leaves of the $mux-tree +are the states. The algorithm fails if a non-constant leaf that is not the state +signal itself is found. + +The list of control outputs is initialized with the bits from the state signal. +It is then extended by adding all values that are calculated by cells that +compare the state signal with a constant value. + +In most cases this will cover all uses of the state register, thus rendering the +state encoding arbitrary. If however a design uses e.g. a single bit of the +state value to drive a control output directly, this bit of the state signal +will be transformed to a control output of the same value. + +Finally, a transition table for the FSM is generated. This is done by using the +ConstEval C++ helper class (defined in kernel/consteval.h) that can be used to +evaluate parts of the design. The ConstEval class can be asked to calculate a +given set of result signals using a set of signal-value assignments. It can also +be passed a list of stop-signals that abort the ConstEval algorithm if the value +of a stop-signal is needed in order to calculate the result signals. + +The fsm_extract pass uses the ConstEval class in the following way to create a +transition table. For each state: + +1. Create a ConstEval object for the module containing the FSM +2. Add all control inputs to the list of stop signals +3. Set the state signal to the current state +4. Try to evaluate the next state and control output +5. If step 4 was not successful: + + - Recursively goto step 4 with the offending stop-signal set to 0. + - Recursively goto step 4 with the offending stop-signal set to 1. + +6. If step 4 was successful: Emit transition + +Finally a $fsm cell is created with the generated transition table and added to +the module. This new cell is connected to the control signals and the old +drivers for the control outputs are disconnected. + +FSM Optimization +~~~~~~~~~~~~~~~~ + +The fsm_opt pass performs basic optimizations on $fsm cells (not including state +recoding). The following optimizations are performed (in this order): + +- Unused control outputs are removed from the $fsm cell. The attribute (that is + usually set by the opt_clean pass) is used to determine which control outputs + are unused. + +- Control inputs that are connected to the same driver are merged. + +- When a control input is driven by a control output, the control input is + removed and the transition table altered to give the same performance without + the external feedback path. + +- Entries in the transition table that yield the same output and only differ in + the value of a single control input bit are merged and the different bit is + removed from the sensitivity list (turned into a don't-care bit). + +- Constant inputs are removed and the transition table is altered to give an + unchanged behaviour. + +- Unused inputs are removed. + +FSM Recoding +~~~~~~~~~~~~ + +The fsm_recode pass assigns new bit pattern to the states. Usually this also +implies a change in the width of the state signal. At the moment of this writing +only one-hot encoding with all-zero for the reset state is supported. + +The fsm_recode pass can also write a text file with the changes performed by it +that can be used when verifying designs synthesized by Yosys using Synopsys +Formality . + +Logic Optimization +------------------ + +Yosys can perform multi-level combinational logic optimization on gate-level +netlists using the external program ABC . The abc pass extracts the +combinational gate-level parts of the design, passes it through ABC, and +re-integrates the results. The abc pass can also be used to perform other +operations using ABC, such as technology mapping (see :numref:`Sec %s +` for details). diff --git a/docs/source/CHAPTER_Overview.rst b/docs/source/CHAPTER_Overview.rst new file mode 100644 index 00000000000..c47784cae4b --- /dev/null +++ b/docs/source/CHAPTER_Overview.rst @@ -0,0 +1,555 @@ +.. _chapter:overview: + +Implementation Overview +======================= + +Yosys is an extensible open source hardware synthesis tool. It is aimed at +designers who are looking for an easily accessible, universal, and +vendor-independent synthesis tool, as well as scientists who do research in +electronic design automation (EDA) and are looking for an open synthesis +framework that can be used to test algorithms on complex real-world designs. + +Yosys can synthesize a large subset of Verilog 2005 and has been tested with a +wide range of real-world designs, including the OpenRISC 1200 CPU +:cite:p:`OR1200`, the openMSP430 CPU :cite:p:`openMSP430`, the OpenCores I$^2$C +master :cite:p:`i2cmaster` and the k68 CPU :cite:p:`k68`. + +As of this writing a Yosys VHDL frontend is in development. + +Yosys is written in C++ (using some features from the new C++11 standard). This +chapter describes some of the fundamental Yosys data structures. For the sake of +simplicity the C++ type names used in the Yosys implementation are used in this +chapter, even though the chapter only explains the conceptual idea behind it and +can be used as reference to implement a similar system in any language. + +Simplified Data Flow +-------------------- + +:numref:`Figure %s ` shows the simplified data flow within +Yosys. Rectangles in the figure represent program modules and ellipses internal +data structures that are used to exchange design data between the program +modules. + +Design data is read in using one of the frontend modules. The high-level HDL +frontends for Verilog and VHDL code generate an abstract syntax tree (AST) that +is then passed to the AST frontend. Note that both HDL frontends use the same +AST representation that is powerful enough to cover the Verilog HDL and VHDL +language. + +The AST Frontend then compiles the AST to Yosys's main internal data format, the +RTL Intermediate Language (RTLIL). A more detailed description of this format is +given in the next section. + +There is also a text representation of the RTLIL data structure that can be +parsed using the RTLIL Frontend. + +The design data may then be transformed using a series of passes that all +operate on the RTLIL representation of the design. + +Finally the design in RTLIL representation is converted back to text by one of +the backends, namely the Verilog Backend for generating Verilog netlists and the +RTLIL Backend for writing the RTLIL data in the same format that is understood +by the RTLIL Frontend. + +With the exception of the AST Frontend, which is called by the high-level HDL +frontends and can't be called directly by the user, all program modules are +called by the user (usually using a synthesis script that contains text commands +for Yosys). + +By combining passes in different ways and/or adding additional passes to Yosys +it is possible to adapt Yosys to a wide range of applications. For this to be +possible it is key that (1) all passes operate on the same data structure +(RTLIL) and (2) that this data structure is powerful enough to represent the +design in different stages of the synthesis. + +.. figure:: ../images/overview_flow.png + :name: fig:Overview_flow + + Yosys simplified data flow (ellipses: data structures, rectangles: + program modules) + +The RTL Intermediate Language +----------------------------- + +All frontends, passes and backends in Yosys operate on a design in RTLIL +representation. The only exception are the high-level frontends that use the AST +representation as an intermediate step before generating RTLIL data. + +In order to avoid reinventing names for the RTLIL classes, they are simply +referred to by their full C++ name, i.e. including the RTLIL:: namespace prefix, +in this document. + +:numref:`Figure %s ` shows a simplified Entity-Relationship +Diagram (ER Diagram) of RTLIL. In :math:`1:N` relationships the arrow points +from the :math:`N` side to the :math:`1`. For example one RTLIL::Design contains +:math:`N` (zero to many) instances of RTLIL::Module. A two-pointed arrow +indicates a :math:`1:1` relationship. + +The RTLIL::Design is the root object of the RTLIL data structure. There is +always one "current design" in memory which passes operate on, frontends add +data to and backends convert to exportable formats. But in some cases passes +internally generate additional RTLIL::Design objects. For example when a pass is +reading an auxiliary Verilog file such as a cell library, it might create an +additional RTLIL::Design object and call the Verilog frontend with this other +object to parse the cell library. + +.. figure:: ../images/overview_rtlil.png + :name: fig:Overview_RTLIL + + Simplified RTLIL Entity-Relationship Diagram + +There is only one active RTLIL::Design object that is used by all frontends, +passes and backends called by the user, e.g. using a synthesis script. The +RTLIL::Design then contains zero to many RTLIL::Module objects. This corresponds +to modules in Verilog or entities in VHDL. Each module in turn contains objects +from three different categories: + +- RTLIL::Cell and RTLIL::Wire objects represent classical netlist data. + +- RTLIL::Process objects represent the decision trees (if-then-else statements, + etc.) and synchronization declarations (clock signals and sensitivity) from + Verilog always and VHDL process blocks. + +- RTLIL::Memory objects represent addressable memories (arrays). + +Usually the output of the synthesis procedure is a netlist, i.e. all +RTLIL::Process and RTLIL::Memory objects must be replaced by RTLIL::Cell and +RTLIL::Wire objects by synthesis passes. + +All features of the HDL that cannot be mapped directly to these RTLIL classes +must be transformed to an RTLIL-compatible representation by the HDL frontend. +This includes Verilog-features such as generate-blocks, loops and parameters. + +The following sections contain a more detailed description of the different +parts of RTLIL and rationale behind some of the design decisions. + +RTLIL Identifiers +~~~~~~~~~~~~~~~~~ + +All identifiers in RTLIL (such as module names, port names, signal names, cell +types, etc.) follow the following naming convention: they must either start with +a backslash (\) or a dollar sign ($). + +Identifiers starting with a backslash are public visible identifiers. Usually +they originate from one of the HDL input files. For example the signal name +"\\sig42" is most likely a signal that was declared using the name "sig42" in an +HDL input file. On the other hand the signal name "$sig42" is an auto-generated +signal name. The backends convert all identifiers that start with a dollar sign +to identifiers that do not collide with identifiers that start with a backslash. + +This has three advantages: + +- First, it is impossible that an auto-generated identifier collides with an + identifier that was provided by the user. + +- Second, the information about which identifiers were originally provided by + the user is always available which can help guide some optimizations. For + example the "opt_rmunused" tries to preserve signals with a user-provided + name but doesn't hesitate to delete signals that have auto-generated names + when they just duplicate other signals. + +- Third, the delicate job of finding suitable auto-generated public visible + names is deferred to one central location. Internally auto-generated names + that may hold important information for Yosys developers can be used without + disturbing external tools. For example the Verilog backend assigns names in + the form \_integer\_. + +Whitespace and control characters (any character with an ASCII code 32 or less) +are not allowed in RTLIL identifiers; most frontends and backends cannot support +these characters in identifiers. + +In order to avoid programming errors, the RTLIL data structures check if all +identifiers start with either a backslash or a dollar sign, and contain no +whitespace or control characters. Violating these rules results in a runtime +error. + +All RTLIL identifiers are case sensitive. + +Some transformations, such as flattening, may have to change identifiers +provided by the user to avoid name collisions. When that happens, attribute +"hdlname" is attached to the object with the changed identifier. This attribute +contains one name (if emitted directly by the frontend, or is a result of +disambiguation) or multiple names separated by spaces (if a result of +flattening). All names specified in the "hdlname" attribute are public and do +not include the leading "\". + +RTLIL::Design and RTLIL::Module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The RTLIL::Design object is basically just a container for RTLIL::Module +objects. In addition to a list of RTLIL::Module objects the RTLIL::Design also +keeps a list of selected objects, i.e. the objects that passes should operate +on. In most cases the whole design is selected and therefore passes operate on +the whole design. But this mechanism can be useful for more complex synthesis +jobs in which only parts of the design should be affected by certain passes. + +Besides the objects shown in the ER diagram in :numref:`Fig. %s +` an RTLIL::Module object contains the following additional +properties: + +- The module name +- A list of attributes +- A list of connections between wires +- An optional frontend callback used to derive parametrized variations of the + module + +The attributes can be Verilog attributes imported by the Verilog frontend or +attributes assigned by passes. They can be used to store additional metadata +about modules or just mark them to be used by certain part of the synthesis +script but not by others. + +Verilog and VHDL both support parametric modules (known as "generic entities" in +VHDL). The RTLIL format does not support parametric modules itself. Instead each +module contains a callback function into the AST frontend to generate a +parametrized variation of the RTLIL::Module as needed. This callback then +returns the auto-generated name of the parametrized variation of the module. (A +hash over the parameters and the module name is used to prohibit the same +parametrized variation from being generated twice. For modules with only a few +parameters, a name directly containing all parameters is generated instead of a +hash string.) + +.. _sec:rtlil_cell_wire: + +RTLIL::Cell and RTLIL::Wire +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A module contains zero to many RTLIL::Cell and RTLIL::Wire objects. Objects of +these types are used to model netlists. Usually the goal of all synthesis +efforts is to convert all modules to a state where the functionality of the +module is implemented only by cells from a given cell library and wires to +connect these cells with each other. Note that module ports are just wires with +a special property. + +An RTLIL::Wire object has the following properties: + +- The wire name +- A list of attributes +- A width (buses are just wires with a width > 1) +- Bus direction (MSB to LSB or vice versa) +- Lowest valid bit index (LSB or MSB depending on bus direction) +- If the wire is a port: port number and direction (input/output/inout) + +As with modules, the attributes can be Verilog attributes imported by the +Verilog frontend or attributes assigned by passes. + +In Yosys, busses (signal vectors) are represented using a single wire object +with a width > 1. So Yosys does not convert signal vectors to individual +signals. This makes some aspects of RTLIL more complex but enables Yosys to be +used for coarse grain synthesis where the cells of the target architecture +operate on entire signal vectors instead of single bit wires. + +In Verilog and VHDL, busses may have arbitrary bounds, and LSB can have either +the lowest or the highest bit index. In RTLIL, bit 0 always corresponds to LSB; +however, information from the HDL frontend is preserved so that the bus will be +correctly indexed in error messages, backend output, constraint files, etc. + +An RTLIL::Cell object has the following properties: + +- The cell name and type +- A list of attributes +- A list of parameters (for parametric cells) +- Cell ports and the connections of ports to wires and constants + +The connections of ports to wires are coded by assigning an RTLIL::SigSpec to +each cell port. The RTLIL::SigSpec data type is described in the next section. + +.. _sec:rtlil_sigspec: + +RTLIL::SigSpec +~~~~~~~~~~~~~~ + +A "signal" is everything that can be applied to a cell port. I.e. + +- | Any constant value of arbitrary bit-width + | 1em For example: ``1337, 16'b0000010100111001, 1'b1, 1'bx`` + +- | All bits of a wire or a selection of bits from a wire + | 1em For example: ``mywire, mywire[24], mywire[15:8]`` + +- | Concatenations of the above + | 1em For example: ``{16'd1337, mywire[15:8]}`` + +The RTLIL::SigSpec data type is used to represent signals. The RTLIL::Cell +object contains one RTLIL::SigSpec for each cell port. + +In addition, connections between wires are represented using a pair of +RTLIL::SigSpec objects. Such pairs are needed in different locations. Therefore +the type name RTLIL::SigSig was defined for such a pair. + +.. _sec:rtlil_process: + +RTLIL::Process +~~~~~~~~~~~~~~ + +When a high-level HDL frontend processes behavioural code it splits it up into +data path logic (e.g. the expression a + b is replaced by the output of an adder +that takes a and b as inputs) and an RTLIL::Process that models the control +logic of the behavioural code. Let's consider a simple example: + +.. code:: verilog + :number-lines: + + module ff_with_en_and_async_reset(clock, reset, enable, d, q); + input clock, reset, enable, d; + output reg q; + always @(posedge clock, posedge reset) + if (reset) + q <= 0; + else if (enable) + q <= d; + endmodule + +In this example there is no data path and therefore the RTLIL::Module generated +by the frontend only contains a few RTLIL::Wire objects and an RTLIL::Process. +The RTLIL::Process in RTLIL syntax: + +:: + + process $proc$ff_with_en_and_async_reset.v:4$1 + assign $0\q[0:0] \q + switch \reset + case 1'1 + assign $0\q[0:0] 1'0 + case + switch \enable + case 1'1 + assign $0\q[0:0] \d + case + end + end + sync posedge \clock + update \q $0\q[0:0] + sync posedge \reset + update \q $0\q[0:0] + end + +This RTLIL::Process contains two RTLIL::SyncRule objects, two RTLIL::SwitchRule +objects and five RTLIL::CaseRule objects. The wire $0\q[0:0] is an automatically +created wire that holds the next value of \\q. The lines :math:`2 \dots 12` +describe how $0\q[0:0] should be calculated. The lines :math:`13 \dots 16` +describe how the value of $0\q[0:0] is used to update \\q. + +An RTLIL::Process is a container for zero or more RTLIL::SyncRule objects and +exactly one RTLIL::CaseRule object, which is called the root case. + +An RTLIL::SyncRule object contains an (optional) synchronization condition +(signal and edge-type), zero or more assignments (RTLIL::SigSig), and zero or +more memory writes (RTLIL::MemWriteAction). The always synchronization condition +is used to break combinatorial loops when a latch should be inferred instead. + +An RTLIL::CaseRule is a container for zero or more assignments (RTLIL::SigSig) +and zero or more RTLIL::SwitchRule objects. An RTLIL::SwitchRule objects is a +container for zero or more RTLIL::CaseRule objects. + +In the above example the lines :math:`2 \dots 12` are the root case. Here +$0\q[0:0] is first assigned the old value \\q as default value (line 2). The +root case also contains an RTLIL::SwitchRule object (lines :math:`3 \dots 12`). +Such an object is very similar to the C switch statement as it uses a control +signal (\\reset in this case) to determine which of its cases should be active. +The RTLIL::SwitchRule object then contains one RTLIL::CaseRule object per case. +In this example there is a case [1]_ for \\reset == 1 that causes $0\q[0:0] to +be set (lines 4 and 5) and a default case that in turn contains a switch that +sets $0\q[0:0] to the value of \\d if \\enable is active (lines :math:`6 \dots +11`). + +A case can specify zero or more compare values that will determine whether it +matches. Each of the compare values must be the exact same width as the control +signal. When more than one compare value is specified, the case matches if any +of them matches the control signal; when zero compare values are specified, the +case always matches (i.e. it is the default case). + +A switch prioritizes cases from first to last: multiple cases can match, but +only the first matched case becomes active. This normally synthesizes to a +priority encoder. The parallel_case attribute allows passes to assume that no +more than one case will match, and full_case attribute allows passes to assume +that exactly one case will match; if these invariants are ever dynamically +violated, the behavior is undefined. These attributes are useful when an +invariant invisible to the synthesizer causes the control signal to never take +certain bit patterns. + +The lines :math:`13 \dots 16` then cause \\q to be updated whenever there is a +positive clock edge on \\clock or \\reset. + +In order to generate such a representation, the language frontend must be able +to handle blocking and nonblocking assignments correctly. However, the language +frontend does not need to identify the correct type of storage element for the +output signal or generate multiplexers for the decision tree. This is done by +passes that work on the RTLIL representation. Therefore it is relatively easy to +substitute these steps with other algorithms that target different target +architectures or perform optimizations or other transformations on the decision +trees before further processing them. + +One of the first actions performed on a design in RTLIL representation in most +synthesis scripts is identifying asynchronous resets. This is usually done using +the proc_arst pass. This pass transforms the above example to the following +RTLIL::Process: + +:: + + process $proc$ff_with_en_and_async_reset.v:4$1 + assign $0\q[0:0] \q + switch \enable + case 1'1 + assign $0\q[0:0] \d + case + end + sync posedge \clock + update \q $0\q[0:0] + sync high \reset + update \q 1'0 + end + +This pass has transformed the outer RTLIL::SwitchRule into a modified +RTLIL::SyncRule object for the \\reset signal. Further processing converts the +RTLIL::Process into e.g. a d-type flip-flop with asynchronous reset and a +multiplexer for the enable signal: + +:: + + cell $adff $procdff$6 + parameter \ARST_POLARITY 1'1 + parameter \ARST_VALUE 1'0 + parameter \CLK_POLARITY 1'1 + parameter \WIDTH 1 + connect \ARST \reset + connect \CLK \clock + connect \D $0\q[0:0] + connect \Q \q + end + cell $mux $procmux$3 + parameter \WIDTH 1 + connect \A \q + connect \B \d + connect \S \enable + connect \Y $0\q[0:0] + end + +Different combinations of passes may yield different results. Note that $adff +and $mux are internal cell types that still need to be mapped to cell types from +the target cell library. + +Some passes refuse to operate on modules that still contain RTLIL::Process +objects as the presence of these objects in a module increases the complexity. +Therefore the passes to translate processes to a netlist of cells are usually +called early in a synthesis script. The proc pass calls a series of other passes +that together perform this conversion in a way that is suitable for most +synthesis tasks. + +.. _sec:rtlil_memory: + +RTLIL::Memory +~~~~~~~~~~~~~ + +For every array (memory) in the HDL code an RTLIL::Memory object is created. A +memory object has the following properties: + +- The memory name +- A list of attributes +- The width of an addressable word +- The size of the memory in number of words + +All read accesses to the memory are transformed to $memrd cells and all write +accesses to $memwr cells by the language frontend. These cells consist of +independent read- and write-ports to the memory. Memory initialization is +transformed to $meminit cells by the language frontend. The parameter on these +cells is used to link them together and to the RTLIL::Memory object they belong +to. + +The rationale behind using separate cells for the individual ports versus +creating a large multiport memory cell right in the language frontend is that +the separate $memrd and $memwr cells can be consolidated using resource sharing. +As resource sharing is a non-trivial optimization problem where different +synthesis tasks can have different requirements it lends itself to do the +optimisation in separate passes and merge the RTLIL::Memory objects and $memrd +and $memwr cells to multiport memory blocks after resource sharing is completed. + +The memory pass performs this conversion and can (depending on the options +passed to it) transform the memories directly to d-type flip-flops and address +logic or yield multiport memory blocks (represented using $mem cells). + +See :numref:`Sec. %s ` for details about the memory cell types. + +Command Interface and Synthesis Scripts +--------------------------------------- + +Yosys reads and processes commands from synthesis scripts, command line +arguments and an interactive command prompt. Yosys commands consist of a command +name and an optional whitespace separated list of arguments. Commands are +terminated using the newline character or a semicolon (;). Empty lines and lines +starting with the hash sign (#) are ignored. See :numref:`Sec. %s +` for an example synthesis script. + +The command help can be used to access the command reference manual. + +Most commands can operate not only on the entire design but also specifically on +selected parts of the design. For example the command dump will print all +selected objects in the current design while dump foobar will only print the +module foobar and dump \* will print the entire design regardless of the current +selection. + +The selection mechanism is very powerful. For example the command dump \*/t:$add +%x:+[A] \*/w:\* %i will print all wires that are connected to the port of a $add +cell. Detailed documentation of the select framework can be found in the command +reference for the select command. + +Source Tree and Build System +---------------------------- + +The Yosys source tree is organized into the following top-level +directories: + +- | backends/ + | This directory contains a subdirectory for each of the backend modules. + +- | frontends/ + | This directory contains a subdirectory for each of the frontend modules. + +- | kernel/ + | This directory contains all the core functionality of Yosys. This includes + the functions and definitions for working with the RTLIL data structures + (rtlil.h and rtlil.cc), the main() function (driver.cc), the internal + framework for generating log messages (log.h and log.cc), the internal + framework for registering and calling passes (register.h and register.cc), + some core commands that are not really passes (select.cc, show.cc, …) and a + couple of other small utility libraries. + +- | passes/ + | This directory contains a subdirectory for each pass or group of passes. + For example as of this writing the directory passes/opt/ contains the code + for seven passes: opt, opt_expr, opt_muxtree, opt_reduce, opt_rmdff, + opt_rmunused and opt_merge. + +- | techlibs/ + | This directory contains simulation models and standard implementations for + the cells from the internal cell library. + +- | tests/ + | This directory contains a couple of test cases. Most of the smaller tests + are executed automatically when make test is called. The larger tests must + be executed manually. Most of the larger tests require downloading external + HDL source code and/or external tools. The tests range from comparing + simulation results of the synthesized design to the original sources to + logic equivalence checking of entire CPU cores. + +The top-level Makefile includes frontends/\*/Makefile.inc, +passes/\*/Makefile.inc and backends/\*/Makefile.inc. So when extending Yosys it +is enough to create a new directory in frontends/, passes/ or backends/ with +your sources and a Makefile.inc. The Yosys kernel automatically detects all +commands linked with Yosys. So it is not needed to add additional commands to a +central list of commands. + +Good starting points for reading example source code to learn how to write +passes are passes/opt/opt_rmdff.cc and passes/opt/opt_merge.cc. + +See the top-level README file for a quick Getting Started guide and build +instructions. The Yosys build is based solely on Makefiles. + +Users of the Qt Creator IDE can generate a QT Creator project file using make +qtcreator. Users of the Eclipse IDE can use the "Makefile Project with Existing +Code" project type in the Eclipse "New Project" dialog (only available after the +CDT plugin has been installed) to create an Eclipse project in order to +programming extensions to Yosys or just browse the Yosys code base. + +.. [1] + The syntax 1'1 in the RTLIL code specifies a constant with a length of one + bit (the first "1"), and this bit is a one (the second "1"). diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst index cc26af6717e..4b9dc91f3e1 100644 --- a/docs/source/cmd_ref.rst +++ b/docs/source/cmd_ref.rst @@ -1,3 +1,5 @@ +.. _cmd_ref: + ================================================================================ Command line reference ================================================================================ diff --git a/docs/source/conf.py b/docs/source/conf.py index 04c735a9383..ffea17c4d0a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -30,9 +30,9 @@ # Ensure that autosectionlabel will produce unique names autosectionlabel_prefix_document = True autosectionlabel_maxdepth = 1 +numfig = True bibtex_bibfiles = ['literature.bib', 'weblinks.bib'] -bibtext_reference_style = 'author_year' # unused docs exclude_patterns = [ diff --git a/docs/source/index.rst b/docs/source/index.rst index a7b1403eaa1..02402f00aaa 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -30,6 +30,7 @@ Yosys manual .. toctree:: :maxdepth: 2 :caption: Manual + :numbered: CHAPTER_Intro CHAPTER_Basics.rst @@ -66,15 +67,16 @@ Yosys manual cmd_ref -.. rubric:: Bibliography +.. only:: html + + .. rubric:: Bibliography .. bibliography:: literature.bib - :all: -.. rubric:: Internet References +.. only:: html + + .. rubric:: Internet References .. bibliography:: weblinks.bib - :list: enumerated - :start: continue - :all: + :style: unsrt From 3acdbb8aed0c6b81fa1b33367243a9a87da5e40b Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 29 Sep 2022 22:29:15 +1300 Subject: [PATCH 12/51] Changing default highlight_language to none Removes need for highlight: none in cmd rst files. --- docs/source/conf.py | 4 +++- kernel/register.cc | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index ffea17c4d0a..326896237da 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -15,7 +15,7 @@ # code blocks style pygments_style = 'colorful' -highlight_language = 'systemverilog' +highlight_language = 'none' html_theme_options = { 'external_links' : [ @@ -30,6 +30,8 @@ # Ensure that autosectionlabel will produce unique names autosectionlabel_prefix_document = True autosectionlabel_maxdepth = 1 + +# assign figure numbers numfig = True bibtex_bibfiles = ['literature.bib', 'weblinks.bib'] diff --git a/kernel/register.cc b/kernel/register.cc index ff8f3fb63cb..4cd6efde6df 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -833,9 +833,6 @@ struct HelpPass : public Pass { fprintf(f, "%s - %s\n", cmd.c_str(), title.c_str()); fprintf(f, "%s\n", title_line.c_str()); - // turn off syntax highlighting because it's all text - fprintf(f, ".. highlight:: none\n\n"); - // render html fprintf(f, ".. only:: html\n\n"); fprintf(f, " :code:`yosys> help %s`\n", cmd.c_str()); From 37751cc102baec8b1b589df5bc34696783fd53ed Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 29 Sep 2022 22:39:34 +1300 Subject: [PATCH 13/51] Adding images for Approach and Overview --- docs/images/approach_flow.png | Bin 0 -> 9709 bytes docs/images/overview_flow.png | Bin 0 -> 17668 bytes docs/images/overview_rtlil.png | Bin 0 -> 16034 bytes docs/source/CHAPTER_Approach.rst | 5 ++++- 4 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 docs/images/approach_flow.png create mode 100644 docs/images/overview_flow.png create mode 100644 docs/images/overview_rtlil.png diff --git a/docs/images/approach_flow.png b/docs/images/approach_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..a5fc53b08aa5f84ae7a5126ff11df1a5f351814e GIT binary patch literal 9709 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 JDs_j5{{iZXWUc@J literal 0 HcmV?d00001 diff --git a/docs/images/overview_flow.png b/docs/images/overview_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..c1b13a000b6e20751cb7a59bb0958f15fa2ccbff GIT binary patch literal 17668 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 literal 0 HcmV?d00001 diff --git a/docs/images/overview_rtlil.png b/docs/images/overview_rtlil.png new file mode 100644 index 0000000000000000000000000000000000000000..f79c667e8b4c4c043bca4085c02dd6292dd3dc03 GIT binary patch literal 16034 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. -[fig:approach_flow] +.. figure:: ../images/approach_flow.png + :name: fig:approach_flow + + General data- and control-flow of a synthesis tool The first subsystem to be called is usually called a frontend. It does not process the data generated by another subsystem but instead reads From 00bcdf2ca37b47fb08e655f9a11cfc4208fef776 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 29 Sep 2022 23:58:36 +1300 Subject: [PATCH 14/51] Including Chapters (part.2) --- docs/images/verilog_flow.png | Bin 0 -> 15934 bytes docs/source/CHAPTER_Prog.rst | 46 +++ docs/source/CHAPTER_Techmap.rst | 105 +++++ docs/source/CHAPTER_Verilog.rst | 662 ++++++++++++++++++++++++++++++++ 4 files changed, 813 insertions(+) create mode 100644 docs/images/verilog_flow.png create mode 100644 docs/source/CHAPTER_Prog.rst create mode 100644 docs/source/CHAPTER_Techmap.rst create mode 100644 docs/source/CHAPTER_Verilog.rst diff --git a/docs/images/verilog_flow.png b/docs/images/verilog_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..1f3d82780f34c2682013eda28b36a05fc27d940e GIT binary patch literal 15934 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