diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml new file mode 100644 index 00000000000..e8064e485ae --- /dev/null +++ b/.github/workflows/test-docs.yml @@ -0,0 +1,42 @@ +name: Build and test doc code samples + +on: + pull_request: + branches: + - master + +jobs: + test-docs: + runs-on: ubuntu-latest + steps: + - name: Install Dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev + + - name: Setup GCC + uses: Dup4/actions-setup-gcc@v1 + + - name: Runtime environment + shell: bash + env: + WORKSPACE: ${{ github.workspace }} + run: | + echo "GITHUB_WORKSPACE=`pwd`" >> $GITHUB_ENV + echo "$GITHUB_WORKSPACE/.local/bin" >> $GITHUB_PATH + echo "procs=$(nproc)" >> $GITHUB_ENV + + - name: Checkout Yosys + uses: actions/checkout@v3 + + - name: Build yosys + shell: bash + run: | + make config-gcc + make -j${{ env.procs }} + + - name: Run tests + shell: bash + run: | + make -C docs test -j${{ env.procs }} diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index b3a6bd8468e..c4441a8843e 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -112,6 +112,13 @@ jobs: make config-${CC%%-*} make -j${{ env.procs }} CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC + - name: Store build artifact + if: (matrix.cpp_std == 'c++11') && (matrix.compiler == 'gcc-11') + uses: actions/upload-artifact@v4 + with: + name: compiled-yosys + path: yosys + - name: Run tests if: (matrix.cpp_std == 'c++11') && (matrix.compiler == 'gcc-11') shell: bash diff --git a/CODEOWNERS b/CODEOWNERS index a33a9a68ccb..7d680e9f2e4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,6 +18,7 @@ passes/techmap/flowmap.cc @whitequark passes/opt/opt_lut.cc @whitequark passes/techmap/abc9*.cc @eddiehung @Ravenslofty backends/aiger/xaiger.cc @eddiehung +docs/ @KrystalDelusion ## External Contributors diff --git a/Makefile b/Makefile index ff7b141a453..93a42a963d7 100644 --- a/Makefile +++ b/Makefile @@ -971,17 +971,27 @@ docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) mkdir -p docs/source/cmd ./$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual' -PHONY: docs/gen_images docs/guidelines +PHONY: docs/gen_examples docs/gen_images docs/guidelines docs/usage +docs/gen_examples: + $(Q) $(MAKE) -C docs examples + docs/gen_images: - $(Q) $(MAKE) -C docs/images all + $(Q) $(MAKE) -C docs images DOCS_GUIDELINE_FILES := GettingStarted CodingStyle docs/guidelines: $(Q) mkdir -p docs/source/temp $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/temp +# many of these will return an error which can be safely ignored, so we prefix +# the command with a '-' +DOCS_USAGE_PROGS := yosys yosys-config yosys-filterlib yosys-abc yosys-smtbmc yosys-witness +docs/usage: $(addprefix docs/source/temp/,$(DOCS_USAGE_PROGS)) +docs/source/temp/%: docs/guidelines + -$(Q) ./$(PROGRAM_PREFIX)$* --help > $@ 2>&1 + DOC_TARGET ?= html -docs: docs/source/cmd/abc.rst docs/gen_images docs/guidelines +docs: docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage $(Q) $(MAKE) -C docs $(DOC_TARGET) clean: @@ -1000,8 +1010,6 @@ clean: rm -f tests/svinterfaces/*.log_stdout tests/svinterfaces/*.log_stderr tests/svinterfaces/dut_result.txt tests/svinterfaces/reference_result.txt tests/svinterfaces/a.out tests/svinterfaces/*_syn.v tests/svinterfaces/*.diff rm -f tests/tools/cmp_tbdata $(MAKE) -C docs clean - $(MAKE) -C docs/images clean - rm -rf docs/source/cmd docs/util/__pycache__ clean-abc: $(MAKE) -C abc DEP= clean diff --git a/README.md b/README.md index 660bd5c6d57..c330d4f74f0 100644 --- a/README.md +++ b/README.md @@ -610,10 +610,12 @@ Simply visit https://yosys.readthedocs.io/en/latest/ instead. In addition to those packages listed above for building Yosys from source, the following are used for building the website: - $ sudo apt-get install pdf2svg faketime + $ sudo apt install pdf2svg faketime PDFLaTeX, included with most LaTeX distributions, is also needed during the -build process for the website. +build process for the website. Or, run the following: + + $ sudo apt install texlive-latex-base texlive-latex-extra latexmk The Python package, Sphinx, is needed along with those listed in `docs/source/requirements.txt`: diff --git a/docs/.gitignore b/docs/.gitignore index e36f2309a01..d7bfd8e956a 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,11 +1,9 @@ /build/ /source/cmd /source/temp -/images/*.log -/images/*.aux -/images/*.pdf -/images/*.svg -/images/011/*.log -/images/011/*.aux -/images/011/*.pdf -/images/011/*.svg +/source/_images/**/*.log +/source/_images/**/*.aux +/source/_images/**/*.pdf +/source/_images/**/*.svg +/source/_images/**/*.dot +/source/_images/code_examples diff --git a/docs/Makefile b/docs/Makefile index 2319e1665c3..c2e730fa82a 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -45,8 +45,10 @@ help: @echo " dummy to check syntax errors of document sources" .PHONY: clean -clean: +clean: clean-examples rm -rf $(BUILDDIR)/* + rm -rf source/cmd util/__pycache__ + $(MAKE) -C source/_images clean .PHONY: html html: @@ -224,3 +226,27 @@ dummy: $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy @echo @echo "Build finished. Dummy builder generates no files." + +PYTHON ?= python3 + +.PHONY: test test-examples test-macros examples +test: test-examples test-macros + +FORCE: +Makefile-%: FORCE + $(MAKE) -C $(@D) $(*F) + +CODE_EXAMPLES := $(wildcard source/code_examples/*/Makefile) +TEST_EXAMPLES := $(addsuffix -all,$(CODE_EXAMPLES)) +CLEAN_EXAMPLES := $(addsuffix -clean,$(CODE_EXAMPLES)) +test-examples: $(TEST_EXAMPLES) +clean-examples: $(CLEAN_EXAMPLES) +examples: $(TEST_EXAMPLES) + +test-macros: + $(PYTHON) tests/macro_commands.py + +.PHONY: images +images: + $(MAKE) -C source/_images + diff --git a/docs/images/011/example_out.tex b/docs/images/011/example_out.tex deleted file mode 100644 index 831b036e993..00000000000 --- a/docs/images/011/example_out.tex +++ /dev/null @@ -1,18 +0,0 @@ -\documentclass[12pt,tikz]{standalone} -\pdfinfoomitdate 1 -\pdfsuppressptexinfo 1 -\pdftrailerid{} -\usepackage[utf8]{inputenc} -\usepackage{tikz} -\pagestyle{empty} - -\begin{document} -\begin{tikzpicture} - \node[inner sep=0pt] at (0,0) - {\includegraphics[width=\linewidth]{example_00.pdf}}; - \node[inner sep=0pt] at (0,-3.8) - {\includegraphics[width=\linewidth]{example_01.pdf}}; - \node[inner sep=0pt] at (0,-7) - {\includegraphics[width=\linewidth]{example_02.pdf}}; -\end{tikzpicture} -\end{document} diff --git a/docs/images/011/select_prod.tex b/docs/images/011/select_prod.tex deleted file mode 100644 index c4a3c6e379b..00000000000 --- a/docs/images/011/select_prod.tex +++ /dev/null @@ -1,19 +0,0 @@ -\documentclass[12pt,tikz]{standalone} -\pdfinfoomitdate 1 -\pdfsuppressptexinfo 1 -\pdftrailerid{} -\usepackage[utf8]{inputenc} -\pagestyle{empty} - -\begin{document} -\begin{tikzpicture} - \node[inner sep=0pt] at (0,0) - {\hfill \includegraphics[width=4cm,trim=0 1cm 0 1cm]{sumprod_02.pdf}}; - \node[inner sep=0pt] at (0,-2.8) - {\includegraphics[width=\linewidth,trim=0 0cm 0 1cm]{sumprod_03.pdf}}; - \node[inner sep=0pt] at (0,-6.2) - {\includegraphics[width=\linewidth,trim=0 0cm 0 1cm]{sumprod_04.pdf}}; - \node[inner sep=0pt] at (0,-9.2) - {\includegraphics[width=\linewidth,trim=0 1cm 0 1cm]{sumprod_05.pdf}}; -\end{tikzpicture} -\end{document} diff --git a/docs/images/011/splitnets_libfile.tex b/docs/images/011/splitnets_libfile.tex deleted file mode 100644 index 9669ef841b0..00000000000 --- a/docs/images/011/splitnets_libfile.tex +++ /dev/null @@ -1,15 +0,0 @@ -\documentclass[12pt,tikz]{standalone} -\pdfinfoomitdate 1 -\pdfsuppressptexinfo 1 -\pdftrailerid{} -\usepackage[utf8]{inputenc} -\pagestyle{empty} - -\begin{document} -\begin{tikzpicture} - \node[inner sep=0pt] at (0,0) - {\includegraphics[height=\linewidth]{cmos_00.pdf}}; - \node[inner sep=0pt] at (2,-8) - {\includegraphics[width=\linewidth]{cmos_01.pdf}}; -\end{tikzpicture} -\end{document} diff --git a/docs/images/011/submod_dots.tex b/docs/images/011/submod_dots.tex deleted file mode 100644 index 3d48b46e5a5..00000000000 --- a/docs/images/011/submod_dots.tex +++ /dev/null @@ -1,27 +0,0 @@ -\documentclass[12pt,tikz]{standalone} -\pdfinfoomitdate 1 -\pdfsuppressptexinfo 1 -\pdftrailerid{} -\usepackage[utf8]{inputenc} -\pagestyle{empty} - -\begin{document} -\begin{tikzpicture} - \node[inner sep=0pt] at (0,0) - {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_00.pdf}}; - \node at (0, -2.5) - {\tt memdemo}; - \node[inner sep=0pt] at (0,-5) - {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_01.pdf}}; - \node at (0, -7.5) - {\tt scramble}; - \node[inner sep=0pt] at (0, -11) - {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_02.pdf}}; - \node at (0, -14.8) - {\tt outstage}; - \node[inner sep=0pt] at (0,-16.6) - {\includegraphics[width=\linewidth,trim=0 1.3cm 0 0cm]{submod_03.pdf}}; - \node at (0, -19) - {\tt selstage}; -\end{tikzpicture} -\end{document} diff --git a/docs/images/Makefile b/docs/images/Makefile deleted file mode 100644 index a7216ec9010..00000000000 --- a/docs/images/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -all: dots tex svg tidy - -TEX_SOURCE:= $(wildcard *.tex) -DOT_LOC:= ../source/APPNOTE_011_Design_Investigation -DOT_SOURCE:= $(wildcard $(DOT_LOC)/*.dot) - -TEX_SOURCE+= 011/example_out.tex -011/example_out.pdf: 011/example_00.pdf 011/example_01.pdf 011/example_02.pdf -TEX_SOURCE+= 011/select_prod.tex -011/select_prod.pdf: 011/sumprod_02.pdf 011/sumprod_03.pdf 011/sumprod_04.pdf 011/sumprod_05.pdf -TEX_SOURCE+= 011/splitnets_libfile.tex -011/splitnets_libfile.pdf: 011/cmos_00.pdf 011/cmos_01.pdf -TEX_SOURCE+= 011/submod_dots.tex -011/submod_dots.pdf: 011/submod_00.pdf 011/submod_01.pdf 011/submod_02.pdf 011/submod_03.pdf - -TEX_PDF:= $(patsubst %.tex,%.pdf,$(TEX_SOURCE)) -DOT_PDF:= $(addprefix 011/,$(notdir $(patsubst %.dot,%.pdf,$(DOT_SOURCE)))) -SVG_OUTPUT:= $(patsubst %.pdf,%.svg,$(TEX_PDF) $(DOT_PDF)) - -dots: $(DOT_PDF) -tex: $(TEX_PDF) -svg: $(SVG_OUTPUT) - -011/%.pdf: $(DOT_LOC)/%.dot - faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< - -011/%.pdf: 011/%.tex - cd 011 && faketime -f '2022-01-01 00:00:00 x0,001' pdflatex $( c13:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c14 [ shape=record, label="{{ A| B| Y}|$g4\nNOR|{}}" ]; -x1 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x1:e -> c14:p8:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -x2 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x2:e -> c14:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -n1 [ shape=diamond, label="$n4" ]; -n1:e -> c10:p9:w [color="black", label=""]; -n1:e -> c14:p7:w [color="black", label=""]; -n2 [ shape=diamond, label="$n5" ]; -n2:e -> c11:p9:w [color="black", label=""]; -n2:e -> c13:p7:w [color="black", label=""]; -n3 [ shape=diamond, label="$n6_1" ]; -n3:e -> c12:p9:w [color="black", label=""]; -n3:e -> c13:p8:w [color="black", label=""]; -n4:e -> c10:p8:w [color="black", label=""]; -n4:e -> c12:p7:w [color="black", label=""]; -n5:e -> c10:p7:w [color="black", label=""]; -n5:e -> c11:p7:w [color="black", label=""]; -n6:e -> x0:s0:w [color="black", label=""]; -n6:e -> x1:s0:w [color="black", label=""]; -n6:e -> x2:s0:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot b/docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot deleted file mode 100644 index ea6f4403ca8..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot +++ /dev/null @@ -1,23 +0,0 @@ -digraph "cmos_demo" { -rankdir="LR"; -remincross=true; -n4 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="y[0]", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="y[1]", color="black", fontcolor="black" ]; -c11 [ shape=record, label="{{ A| B}|$g0\nNOR|{ Y}}" ]; -c12 [ shape=record, label="{{ A}|$g1\nNOT|{ Y}}" ]; -c13 [ shape=record, label="{{ A}|$g2\nNOT|{ Y}}" ]; -c14 [ shape=record, label="{{ A| B}|$g3\nNOR|{ Y}}" ]; -c15 [ shape=record, label="{{ A| B}|$g4\nNOR|{ Y}}" ]; -c11:p10:e -> c15:p8:w [color="black", label=""]; -c12:p10:e -> c14:p8:w [color="black", label=""]; -c13:p10:e -> c14:p9:w [color="black", label=""]; -n4:e -> c11:p9:w [color="black", label=""]; -n4:e -> c13:p8:w [color="black", label=""]; -n5:e -> c11:p8:w [color="black", label=""]; -n5:e -> c12:p8:w [color="black", label=""]; -c15:p10:e -> n6:w [color="black", label=""]; -c14:p10:e -> n7:w [color="black", label=""]; -n7:e -> c15:p9:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example.ys b/docs/source/APPNOTE_011_Design_Investigation/example.ys deleted file mode 100644 index b1e956088cc..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example.ys +++ /dev/null @@ -1,11 +0,0 @@ -read_verilog example.v -show -format dot -prefix example_00 -proc -show -format dot -prefix example_01 -opt -show -format dot -prefix example_02 - -cd example -select t:$add -show -format dot -prefix example_03 - diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_00.dot b/docs/source/APPNOTE_011_Design_Investigation/example_00.dot deleted file mode 100644 index 1e23ed0ead3..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_00.dot +++ /dev/null @@ -1,23 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -n4 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c12 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -v0 [ label="2'00" ]; -c14 [ shape=record, label="{{ A| B| S}|$3\n$mux|{ Y}}" ]; -p1 [shape=box, style=rounded, label="PROC $1\nexample.v:3"]; -c12:p11:e -> c14:p10:w [color="black", style="setlinewidth(3)", label=""]; -c14:p11:e -> p1:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c12:p9:w [color="black", label=""]; -n5:e -> c12:p10:w [color="black", label=""]; -n6:e -> c14:p13:w [color="black", label=""]; -n6:e -> p1:w [color="black", label=""]; -n7:e -> p1:w [color="black", label=""]; -p1:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -n8:e -> p1:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c14:p9:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_01.dot b/docs/source/APPNOTE_011_Design_Investigation/example_01.dot deleted file mode 100644 index e89292b51ac..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_01.dot +++ /dev/null @@ -1,33 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -n6 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n9 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n10 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c14 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -c18 [ shape=record, label="{{ CLK| D}|$7\n$dff|{ Q}}" ]; -c20 [ shape=record, label="{{ A| B| S}|$5\n$mux|{ Y}}" ]; -v0 [ label="2'00" ]; -c21 [ shape=record, label="{{ A| B| S}|$3\n$mux|{ Y}}" ]; -x1 [shape=box, style=rounded, label="BUF"]; -x2 [shape=box, style=rounded, label="BUF"]; -n1 [ shape=diamond, label="$0\\y[1:0]" ]; -x2:e:e -> n1:w [color="black", style="setlinewidth(3)", label=""]; -c18:p17:e -> n10:w [color="black", style="setlinewidth(3)", label=""]; -n10:e -> c20:p11:w [color="black", style="setlinewidth(3)", label=""]; -c14:p13:e -> c21:p12:w [color="black", style="setlinewidth(3)", label=""]; -n3 [ shape=point ]; -c20:p13:e -> n3:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c18:p16:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> x2:w:w [color="black", style="setlinewidth(3)", label=""]; -x1:e:e -> c20:p19:w [color="black", label=""]; -c21:p13:e -> c20:p12:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c14:p11:w [color="black", label=""]; -n7:e -> c14:p12:w [color="black", label=""]; -n8:e -> c21:p19:w [color="black", label=""]; -n8:e -> x1:w:w [color="black", label=""]; -n9:e -> c18:p15:w [color="black", label=""]; -v0:e -> c21:p11:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_02.dot b/docs/source/APPNOTE_011_Design_Investigation/example_02.dot deleted file mode 100644 index f950ed2ed2c..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_02.dot +++ /dev/null @@ -1,20 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -n3 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c11 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -c15 [ shape=record, label="{{ CLK| D}|$7\n$dff|{ Q}}" ]; -c17 [ shape=record, label="{{ A| B| S}|$5\n$mux|{ Y}}" ]; -c17:p10:e -> c15:p13:w [color="black", style="setlinewidth(3)", label=""]; -c11:p10:e -> c17:p9:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c11:p8:w [color="black", label=""]; -n4:e -> c11:p9:w [color="black", label=""]; -n5:e -> c17:p16:w [color="black", label=""]; -n6:e -> c15:p12:w [color="black", label=""]; -c15:p14:e -> n7:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c17:p8:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_03.dot b/docs/source/APPNOTE_011_Design_Investigation/example_03.dot deleted file mode 100644 index e19d24af78a..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_03.dot +++ /dev/null @@ -1,11 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -v0 [ label="a" ]; -v1 [ label="b" ]; -v2 [ label="$2_Y" ]; -c4 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -v0:e -> c4:p1:w [color="black", label=""]; -v1:e -> c4:p2:w [color="black", label=""]; -c4:p3:e -> v2:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/make.sh b/docs/source/APPNOTE_011_Design_Investigation/make.sh deleted file mode 100644 index 3845dac6b31..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/make.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -ex -if false; then - rm -f *.dot - ../../yosys example.ys - ../../yosys -p 'proc; opt; show -format dot -prefix splice' splice.v - ../../yosys -p 'techmap; abc -liberty ../../techlibs/cmos/cmos_cells.lib;; show -format dot -prefix cmos_00' cmos.v - ../../yosys -p 'techmap; splitnets -ports; abc -liberty ../../techlibs/cmos/cmos_cells.lib;; show -lib ../../techlibs/cmos/cmos_cells.v -format dot -prefix cmos_01' cmos.v - ../../yosys -p 'opt; cd sumprod; select a:sumstuff; show -format dot -prefix sumprod_00' sumprod.v - ../../yosys -p 'opt; cd sumprod; select a:sumstuff %x; show -format dot -prefix sumprod_01' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod; show -format dot -prefix sumprod_02' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod %ci; show -format dot -prefix sumprod_03' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod %ci2; show -format dot -prefix sumprod_04' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod %ci3; show -format dot -prefix sumprod_05' sumprod.v - ../../yosys -p 'proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_00' memdemo.v - ../../yosys -p 'proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_01 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff' memdemo.v - ../../yosys submod.ys - sed -i '/^label=/ d;' *.dot -fi -for dot_file in *.dot; do - pdf_file=${dot_file%.dot}.pdf - dot -Tpdf -o $pdf_file $dot_file -done diff --git a/docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot b/docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot deleted file mode 100644 index 0336a9aac2a..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot +++ /dev/null @@ -1,138 +0,0 @@ -digraph "memdemo" { -rankdir="LR"; -remincross=true; -n24 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n25 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n26 [ shape=diamond, label="mem[0]", color="black", fontcolor="black" ]; -n27 [ shape=diamond, label="mem[1]", color="black", fontcolor="black" ]; -n28 [ shape=diamond, label="mem[2]", color="black", fontcolor="black" ]; -n29 [ shape=diamond, label="mem[3]", color="black", fontcolor="black" ]; -n30 [ shape=diamond, label="s1", color="black", fontcolor="black" ]; -n31 [ shape=diamond, label="s2", color="black", fontcolor="black" ]; -n32 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c36 [ shape=record, label="{{ A| B}|$28\n$add|{ Y}}" ]; -c37 [ shape=record, label="{{ A| B}|$31\n$add|{ Y}}" ]; -c38 [ shape=record, label="{{ A| B}|$34\n$add|{ Y}}" ]; -c39 [ shape=record, label="{{ A| B}|$37\n$add|{ Y}}" ]; -c41 [ shape=record, label="{{ A| B| S}|$110\n$mux|{ Y}}" ]; -x0 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x0:e -> c41:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c42 [ shape=record, label="{{ A| B| S}|$113\n$mux|{ Y}}" ]; -x1 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x1:e -> c42:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c43 [ shape=record, label="{{ A| B| S}|$116\n$mux|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x2:e -> c43:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -v3 [ label="1'1" ]; -c44 [ shape=record, label="{{ A| B}|$145\n$and|{ Y}}" ]; -v4 [ label="1'1" ]; -c45 [ shape=record, label="{{ A| B}|$175\n$and|{ Y}}" ]; -v5 [ label="1'1" ]; -c46 [ shape=record, label="{{ A| B}|$205\n$and|{ Y}}" ]; -v6 [ label="1'1" ]; -c47 [ shape=record, label="{{ A| B}|$235\n$and|{ Y}}" ]; -v7 [ label="2'00" ]; -c48 [ shape=record, label="{{ A| B}|$143\n$eq|{ Y}}" ]; -v8 [ label="2'01" ]; -c49 [ shape=record, label="{{ A| B}|$173\n$eq|{ Y}}" ]; -v9 [ label="2'10" ]; -c50 [ shape=record, label="{{ A| B}|$203\n$eq|{ Y}}" ]; -v10 [ label="2'11" ]; -c51 [ shape=record, label="{{ A| B}|$233\n$eq|{ Y}}" ]; -c52 [ shape=record, label="{{ A| B| S}|$147\n$mux|{ Y}}" ]; -c53 [ shape=record, label="{{ A| B| S}|$177\n$mux|{ Y}}" ]; -c54 [ shape=record, label="{{ A| B| S}|$207\n$mux|{ Y}}" ]; -c55 [ shape=record, label="{{ A| B| S}|$237\n$mux|{ Y}}" ]; -c59 [ shape=record, label="{{ CLK| D}|$66\n$dff|{ Q}}" ]; -c60 [ shape=record, label="{{ CLK| D}|$68\n$dff|{ Q}}" ]; -c61 [ shape=record, label="{{ CLK| D}|$70\n$dff|{ Q}}" ]; -c62 [ shape=record, label="{{ CLK| D}|$72\n$dff|{ Q}}" ]; -c63 [ shape=record, label="{{ CLK| D}|$59\n$dff|{ Q}}" ]; -c64 [ shape=record, label="{{ CLK| D}|$63\n$dff|{ Q}}" ]; -c65 [ shape=record, label="{{ CLK| D}|$64\n$dff|{ Q}}" ]; -c66 [ shape=record, label="{{ A}|$39\n$reduce_bool|{ Y}}" ]; -v11 [ label="4'0000" ]; -c67 [ shape=record, label="{{ A| B| S}|$40\n$mux|{ Y}}" ]; -x12 [ shape=record, style=rounded, label=" 3:2 - 1:0 | 1:0 - 1:0 " ]; -c67:p35:e -> x12:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c68 [ shape=record, label="{{ A| B}|$38\n$xor|{ Y}}" ]; -x13 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x13:e -> c68:p33:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c36:p35:e -> c52:p33:w [color="black", style="setlinewidth(3)", label=""]; -c44:p35:e -> c52:p40:w [color="black", label=""]; -c45:p35:e -> c53:p40:w [color="black", label=""]; -c46:p35:e -> c54:p40:w [color="black", label=""]; -c47:p35:e -> c55:p40:w [color="black", label=""]; -c48:p35:e -> c44:p33:w [color="black", label=""]; -c49:p35:e -> c45:p33:w [color="black", label=""]; -c50:p35:e -> c46:p33:w [color="black", label=""]; -c51:p35:e -> c47:p33:w [color="black", label=""]; -c52:p35:e -> c59:p57:w [color="black", style="setlinewidth(3)", label=""]; -c53:p35:e -> c60:p57:w [color="black", style="setlinewidth(3)", label=""]; -c37:p35:e -> c53:p33:w [color="black", style="setlinewidth(3)", label=""]; -c54:p35:e -> c61:p57:w [color="black", style="setlinewidth(3)", label=""]; -c55:p35:e -> c62:p57:w [color="black", style="setlinewidth(3)", label=""]; -c66:p35:e -> c67:p40:w [color="black", label=""]; -c68:p35:e -> c67:p34:w [color="black", style="setlinewidth(3)", label=""]; -n24:e -> c59:p56:w [color="black", label=""]; -n24:e -> c60:p56:w [color="black", label=""]; -n24:e -> c61:p56:w [color="black", label=""]; -n24:e -> c62:p56:w [color="black", label=""]; -n24:e -> c63:p56:w [color="black", label=""]; -n24:e -> c64:p56:w [color="black", label=""]; -n24:e -> c65:p56:w [color="black", label=""]; -n25:e -> c52:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c53:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c54:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c55:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c66:p33:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c68:p34:w [color="black", style="setlinewidth(3)", label=""]; -c59:p58:e -> n26:w [color="black", style="setlinewidth(3)", label=""]; -n26:e -> c38:p34:w [color="black", style="setlinewidth(3)", label=""]; -n26:e -> c39:p33:w [color="black", style="setlinewidth(3)", label=""]; -n26:e -> c42:p33:w [color="black", style="setlinewidth(3)", label=""]; -c60:p58:e -> n27:w [color="black", style="setlinewidth(3)", label=""]; -n27:e -> c36:p33:w [color="black", style="setlinewidth(3)", label=""]; -n27:e -> c39:p34:w [color="black", style="setlinewidth(3)", label=""]; -n27:e -> c42:p34:w [color="black", style="setlinewidth(3)", label=""]; -c61:p58:e -> n28:w [color="black", style="setlinewidth(3)", label=""]; -n28:e -> c36:p34:w [color="black", style="setlinewidth(3)", label=""]; -n28:e -> c37:p33:w [color="black", style="setlinewidth(3)", label=""]; -n28:e -> c43:p33:w [color="black", style="setlinewidth(3)", label=""]; -c62:p58:e -> n29:w [color="black", style="setlinewidth(3)", label=""]; -n29:e -> c37:p34:w [color="black", style="setlinewidth(3)", label=""]; -n29:e -> c38:p33:w [color="black", style="setlinewidth(3)", label=""]; -n29:e -> c43:p34:w [color="black", style="setlinewidth(3)", label=""]; -c38:p35:e -> c54:p33:w [color="black", style="setlinewidth(3)", label=""]; -c63:p58:e -> n30:w [color="black", style="setlinewidth(3)", label=""]; -n30:e -> x13:s1:w [color="black", style="setlinewidth(3)", label=""]; -c64:p58:e -> n31:w [color="black", style="setlinewidth(3)", label=""]; -n31:e -> x13:s0:w [color="black", style="setlinewidth(3)", label=""]; -c65:p58:e -> n32:w [color="black", style="setlinewidth(3)", label=""]; -c39:p35:e -> c55:p33:w [color="black", style="setlinewidth(3)", label=""]; -n5 [ shape=point ]; -x12:s0:e -> n5:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c48:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c49:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c50:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c51:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c63:p57:w [color="black", style="setlinewidth(3)", label=""]; -n6 [ shape=point ]; -x12:s1:e -> n6:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c64:p57:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x0:s0:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x1:s0:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x2:s0:w [color="black", style="setlinewidth(3)", label=""]; -c41:p35:e -> c65:p57:w [color="black", style="setlinewidth(3)", label=""]; -c42:p35:e -> c41:p33:w [color="black", style="setlinewidth(3)", label=""]; -c43:p35:e -> c41:p34:w [color="black", style="setlinewidth(3)", label=""]; -v10:e -> c51:p33:w [color="black", style="setlinewidth(3)", label=""]; -v11:e -> c67:p33:w [color="black", style="setlinewidth(3)", label=""]; -v3:e -> c44:p34:w [color="black", label=""]; -v4:e -> c45:p34:w [color="black", label=""]; -v5:e -> c46:p34:w [color="black", label=""]; -v6:e -> c47:p34:w [color="black", label=""]; -v7:e -> c48:p33:w [color="black", style="setlinewidth(3)", label=""]; -v8:e -> c49:p33:w [color="black", style="setlinewidth(3)", label=""]; -v9:e -> c50:p33:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot b/docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot deleted file mode 100644 index 2ad92c78b2f..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot +++ /dev/null @@ -1,29 +0,0 @@ -digraph "memdemo" { -rankdir="LR"; -remincross=true; -n4 [ shape=diamond, label="mem[0]", color="black", fontcolor="black" ]; -n5 [ shape=diamond, label="mem[1]", color="black", fontcolor="black" ]; -n6 [ shape=diamond, label="mem[2]", color="black", fontcolor="black" ]; -n7 [ shape=diamond, label="mem[3]", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -v0 [ label="$0\\s2[1:0] [1]" ]; -c13 [ shape=record, label="{{ A| B| S}|$110\n$mux|{ Y}}" ]; -v1 [ label="$0\\s2[1:0] [0]" ]; -c14 [ shape=record, label="{{ A| B| S}|$113\n$mux|{ Y}}" ]; -v2 [ label="$0\\s2[1:0] [0]" ]; -c15 [ shape=record, label="{{ A| B| S}|$116\n$mux|{ Y}}" ]; -v3 [ label="clk" ]; -c19 [ shape=record, label="{{ CLK| D}|$64\n$dff|{ Q}}" ]; -c13:p12:e -> c19:p17:w [color="black", style="setlinewidth(3)", label=""]; -c14:p12:e -> c13:p9:w [color="black", style="setlinewidth(3)", label=""]; -c15:p12:e -> c13:p10:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c14:p9:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c14:p10:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c15:p9:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c15:p10:w [color="black", style="setlinewidth(3)", label=""]; -c19:p18:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c13:p11:w [color="black", label=""]; -v1:e -> c14:p11:w [color="black", label=""]; -v2:e -> c15:p11:w [color="black", label=""]; -v3:e -> c19:p16:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/splice.dot b/docs/source/APPNOTE_011_Design_Investigation/splice.dot deleted file mode 100644 index 4657feed116..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/splice.dot +++ /dev/null @@ -1,39 +0,0 @@ -digraph "splice_demo" { -rankdir="LR"; -remincross=true; -n1 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n2 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="e", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="f", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="x", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c11 [ shape=record, label="{{ A}|$2\n$neg|{ Y}}" ]; -x0 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x0:e -> c11:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -x1 [ shape=record, style=rounded, label=" 3:0 - 7:4 " ]; -c11:p10:e -> x1:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c12 [ shape=record, label="{{ A}|$1\n$not|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x2:e -> c12:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -x3 [ shape=record, style=rounded, label=" 3:2 - 1:0 | 1:0 - 3:2 " ]; -c12:p10:e -> x3:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -x4 [ shape=record, style=rounded, label=" 0:0 - 1:1 | 1:1 - 0:0 " ]; -x5 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x6 [ shape=record, style=rounded, label=" 3:0 - 11:8 " ]; -x5:e -> x6:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -n1:e -> x4:s0:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> x4:s1:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> x5:s1:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> x5:s0:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> x0:s1:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> x0:s0:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> x2:s1:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x2:s0:w [color="black", style="setlinewidth(3)", label=""]; -x4:e -> n7:w [color="black", style="setlinewidth(3)", label=""]; -x1:s0:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -x3:s0:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -x3:s1:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -x6:s0:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_00.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_00.dot deleted file mode 100644 index 2e55268ee10..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_00.dot +++ /dev/null @@ -1,45 +0,0 @@ -digraph "memdemo" { -rankdir="LR"; -remincross=true; -n5 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n7 [ shape=diamond, label="mem[0]", color="black", fontcolor="black" ]; -n8 [ shape=diamond, label="mem[1]", color="black", fontcolor="black" ]; -n9 [ shape=diamond, label="mem[2]", color="black", fontcolor="black" ]; -n10 [ shape=diamond, label="mem[3]", color="black", fontcolor="black" ]; -n11 [ shape=diamond, label="s1", color="black", fontcolor="black" ]; -n12 [ shape=diamond, label="s2", color="black", fontcolor="black" ]; -n13 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c17 [ shape=record, label="{{ CLK| D}|$59\n$dff|{ Q}}" ]; -c18 [ shape=record, label="{{ CLK| D}|$63\n$dff|{ Q}}" ]; -c20 [ shape=record, label="{{ clk| mem[0]| mem[1]| mem[2]| mem[3]| n1}|outstage\noutstage|{ y}}" ]; -c21 [ shape=record, label="{{ clk| d| n1}|scramble\nscramble|{ mem[0]| mem[1]| mem[2]| mem[3]}}" ]; -c23 [ shape=record, label="{{ d| s1| s2}|selstage\nselstage|{ n1| n2}}" ]; -n1 [ shape=point ]; -c23:p19:e -> n1:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> c17:p15:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> c21:p19:w [color="black", style="setlinewidth(3)", label=""]; -c21:p10:e -> n10:w [color="black", style="setlinewidth(3)", label=""]; -n10:e -> c20:p10:w [color="black", style="setlinewidth(3)", label=""]; -c17:p16:e -> n11:w [color="black", style="setlinewidth(3)", label=""]; -n11:e -> c23:p11:w [color="black", style="setlinewidth(3)", label=""]; -c18:p16:e -> n12:w [color="black", style="setlinewidth(3)", label=""]; -n12:e -> c23:p12:w [color="black", style="setlinewidth(3)", label=""]; -c20:p13:e -> n13:w [color="black", style="setlinewidth(3)", label=""]; -n2 [ shape=point ]; -c23:p22:e -> n2:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c18:p15:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c20:p19:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c17:p14:w [color="black", label=""]; -n5:e -> c18:p14:w [color="black", label=""]; -n5:e -> c20:p5:w [color="black", label=""]; -n5:e -> c21:p5:w [color="black", label=""]; -n6:e -> c21:p6:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c23:p6:w [color="black", style="setlinewidth(3)", label=""]; -c21:p7:e -> n7:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c20:p7:w [color="black", style="setlinewidth(3)", label=""]; -c21:p8:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -n8:e -> c20:p8:w [color="black", style="setlinewidth(3)", label=""]; -c21:p9:e -> n9:w [color="black", style="setlinewidth(3)", label=""]; -n9:e -> c20:p9:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_01.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_01.dot deleted file mode 100644 index f8f8c008ac6..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_01.dot +++ /dev/null @@ -1,87 +0,0 @@ -digraph "scramble" { -rankdir="LR"; -remincross=true; -n17 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n18 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n19 [ shape=octagon, label="mem[0]", color="black", fontcolor="black" ]; -n20 [ shape=octagon, label="mem[1]", color="black", fontcolor="black" ]; -n21 [ shape=octagon, label="mem[2]", color="black", fontcolor="black" ]; -n22 [ shape=octagon, label="mem[3]", color="black", fontcolor="black" ]; -n23 [ shape=octagon, label="n1", color="black", fontcolor="black" ]; -c27 [ shape=record, label="{{ A| B}|$28\n$add|{ Y}}" ]; -c28 [ shape=record, label="{{ A| B}|$31\n$add|{ Y}}" ]; -c29 [ shape=record, label="{{ A| B}|$34\n$add|{ Y}}" ]; -c30 [ shape=record, label="{{ A| B}|$37\n$add|{ Y}}" ]; -v0 [ label="1'1" ]; -c31 [ shape=record, label="{{ A| B}|$145\n$and|{ Y}}" ]; -v1 [ label="1'1" ]; -c32 [ shape=record, label="{{ A| B}|$175\n$and|{ Y}}" ]; -v2 [ label="1'1" ]; -c33 [ shape=record, label="{{ A| B}|$205\n$and|{ Y}}" ]; -v3 [ label="1'1" ]; -c34 [ shape=record, label="{{ A| B}|$235\n$and|{ Y}}" ]; -v4 [ label="2'00" ]; -c35 [ shape=record, label="{{ A| B}|$143\n$eq|{ Y}}" ]; -v5 [ label="2'01" ]; -c36 [ shape=record, label="{{ A| B}|$173\n$eq|{ Y}}" ]; -v6 [ label="2'10" ]; -c37 [ shape=record, label="{{ A| B}|$203\n$eq|{ Y}}" ]; -v7 [ label="2'11" ]; -c38 [ shape=record, label="{{ A| B}|$233\n$eq|{ Y}}" ]; -c40 [ shape=record, label="{{ A| B| S}|$147\n$mux|{ Y}}" ]; -c41 [ shape=record, label="{{ A| B| S}|$177\n$mux|{ Y}}" ]; -c42 [ shape=record, label="{{ A| B| S}|$207\n$mux|{ Y}}" ]; -c43 [ shape=record, label="{{ A| B| S}|$237\n$mux|{ Y}}" ]; -c47 [ shape=record, label="{{ CLK| D}|$66\n$dff|{ Q}}" ]; -c48 [ shape=record, label="{{ CLK| D}|$68\n$dff|{ Q}}" ]; -c49 [ shape=record, label="{{ CLK| D}|$70\n$dff|{ Q}}" ]; -c50 [ shape=record, label="{{ CLK| D}|$72\n$dff|{ Q}}" ]; -c27:p26:e -> c40:p24:w [color="black", style="setlinewidth(3)", label=""]; -c36:p26:e -> c32:p24:w [color="black", label=""]; -c37:p26:e -> c33:p24:w [color="black", label=""]; -c38:p26:e -> c34:p24:w [color="black", label=""]; -c40:p26:e -> c47:p45:w [color="black", style="setlinewidth(3)", label=""]; -c41:p26:e -> c48:p45:w [color="black", style="setlinewidth(3)", label=""]; -c42:p26:e -> c49:p45:w [color="black", style="setlinewidth(3)", label=""]; -c43:p26:e -> c50:p45:w [color="black", style="setlinewidth(3)", label=""]; -n17:e -> c47:p44:w [color="black", label=""]; -n17:e -> c48:p44:w [color="black", label=""]; -n17:e -> c49:p44:w [color="black", label=""]; -n17:e -> c50:p44:w [color="black", label=""]; -n18:e -> c40:p25:w [color="black", style="setlinewidth(3)", label=""]; -n18:e -> c41:p25:w [color="black", style="setlinewidth(3)", label=""]; -n18:e -> c42:p25:w [color="black", style="setlinewidth(3)", label=""]; -n18:e -> c43:p25:w [color="black", style="setlinewidth(3)", label=""]; -c47:p46:e -> n19:w [color="black", style="setlinewidth(3)", label=""]; -n19:e -> c29:p25:w [color="black", style="setlinewidth(3)", label=""]; -n19:e -> c30:p24:w [color="black", style="setlinewidth(3)", label=""]; -c28:p26:e -> c41:p24:w [color="black", style="setlinewidth(3)", label=""]; -c48:p46:e -> n20:w [color="black", style="setlinewidth(3)", label=""]; -n20:e -> c27:p24:w [color="black", style="setlinewidth(3)", label=""]; -n20:e -> c30:p25:w [color="black", style="setlinewidth(3)", label=""]; -c49:p46:e -> n21:w [color="black", style="setlinewidth(3)", label=""]; -n21:e -> c27:p25:w [color="black", style="setlinewidth(3)", label=""]; -n21:e -> c28:p24:w [color="black", style="setlinewidth(3)", label=""]; -c50:p46:e -> n22:w [color="black", style="setlinewidth(3)", label=""]; -n22:e -> c28:p25:w [color="black", style="setlinewidth(3)", label=""]; -n22:e -> c29:p24:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c35:p25:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c36:p25:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c37:p25:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c38:p25:w [color="black", style="setlinewidth(3)", label=""]; -c29:p26:e -> c42:p24:w [color="black", style="setlinewidth(3)", label=""]; -c30:p26:e -> c43:p24:w [color="black", style="setlinewidth(3)", label=""]; -c31:p26:e -> c40:p39:w [color="black", label=""]; -c32:p26:e -> c41:p39:w [color="black", label=""]; -c33:p26:e -> c42:p39:w [color="black", label=""]; -c34:p26:e -> c43:p39:w [color="black", label=""]; -c35:p26:e -> c31:p24:w [color="black", label=""]; -v0:e -> c31:p25:w [color="black", label=""]; -v1:e -> c32:p25:w [color="black", label=""]; -v2:e -> c33:p25:w [color="black", label=""]; -v3:e -> c34:p25:w [color="black", label=""]; -v4:e -> c35:p24:w [color="black", style="setlinewidth(3)", label=""]; -v5:e -> c36:p24:w [color="black", style="setlinewidth(3)", label=""]; -v6:e -> c37:p24:w [color="black", style="setlinewidth(3)", label=""]; -v7:e -> c38:p24:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_02.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_02.dot deleted file mode 100644 index 1a672c484f1..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_02.dot +++ /dev/null @@ -1,33 +0,0 @@ -digraph "outstage" { -rankdir="LR"; -remincross=true; -n4 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="mem[0]", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="mem[1]", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="mem[2]", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="mem[3]", color="black", fontcolor="black" ]; -n9 [ shape=octagon, label="n1", color="black", fontcolor="black" ]; -n10 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c15 [ shape=record, label="{{ A| B| S}|$110\n$mux|{ Y}}" ]; -x0 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x0:e -> c15:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c16 [ shape=record, label="{{ A| B| S}|$113\n$mux|{ Y}}" ]; -x1 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x1:e -> c16:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c17 [ shape=record, label="{{ A| B| S}|$116\n$mux|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x2:e -> c17:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c21 [ shape=record, label="{{ CLK| D}|$64\n$dff|{ Q}}" ]; -c15:p14:e -> c21:p19:w [color="black", style="setlinewidth(3)", label=""]; -c21:p20:e -> n10:w [color="black", style="setlinewidth(3)", label=""]; -c16:p14:e -> c15:p11:w [color="black", style="setlinewidth(3)", label=""]; -c17:p14:e -> c15:p12:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c21:p18:w [color="black", label=""]; -n5:e -> c16:p11:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c16:p12:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c17:p11:w [color="black", style="setlinewidth(3)", label=""]; -n8:e -> c17:p12:w [color="black", style="setlinewidth(3)", label=""]; -n9:e -> x0:s0:w [color="black", label=""]; -n9:e -> x1:s0:w [color="black", label=""]; -n9:e -> x2:s0:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_03.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_03.dot deleted file mode 100644 index 0dbbe3baa17..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_03.dot +++ /dev/null @@ -1,26 +0,0 @@ -digraph "selstage" { -rankdir="LR"; -remincross=true; -n3 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="n1", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="n2", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="s1", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="s2", color="black", fontcolor="black" ]; -c10 [ shape=record, label="{{ A}|$39\n$reduce_bool|{ Y}}" ]; -v0 [ label="4'0000" ]; -c13 [ shape=record, label="{{ A| B| S}|$40\n$mux|{ Y}}" ]; -x1 [ shape=record, style=rounded, label=" 3:2 - 1:0 | 1:0 - 1:0 " ]; -c13:p9:e -> x1:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c14 [ shape=record, label="{{ A| B}|$38\n$xor|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x2:e -> c14:p8:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c10:p9:e -> c13:p12:w [color="black", label=""]; -c14:p9:e -> c13:p11:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c10:p8:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c14:p11:w [color="black", style="setlinewidth(3)", label=""]; -x1:s0:e -> n4:w [color="black", style="setlinewidth(3)", label=""]; -x1:s1:e -> n5:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x2:s1:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> x2:s0:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c13:p8:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot deleted file mode 100644 index 06522dcc9ef..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot +++ /dev/null @@ -1,18 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -v0 [ label="a" ]; -v1 [ label="b" ]; -v2 [ label="$1_Y" ]; -c4 [ shape=record, label="{{ A| B}|$1\n$add|{ Y}}" ]; -v3 [ label="$1_Y" ]; -v4 [ label="c" ]; -v5 [ label="sum" ]; -c5 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -v0:e -> c4:p1:w [color="black", style="setlinewidth(3)", label=""]; -v1:e -> c4:p2:w [color="black", style="setlinewidth(3)", label=""]; -c4:p3:e -> v2:w [color="black", style="setlinewidth(3)", label=""]; -v3:e -> c5:p1:w [color="black", style="setlinewidth(3)", label=""]; -v4:e -> c5:p2:w [color="black", style="setlinewidth(3)", label=""]; -c5:p3:e -> v5:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot deleted file mode 100644 index aefe7a6da93..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot +++ /dev/null @@ -1,15 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n2 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="sum", color="black", fontcolor="black" ]; -c9 [ shape=record, label="{{ A| B}|$1\n$add|{ Y}}" ]; -c10 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -c9:p8:e -> c10:p6:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c9:p6:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c9:p7:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c10:p7:w [color="black", style="setlinewidth(3)", label=""]; -c10:p8:e -> n5:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot deleted file mode 100644 index 4646c994786..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot +++ /dev/null @@ -1,5 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n1 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot deleted file mode 100644 index dcfea2b5609..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot +++ /dev/null @@ -1,11 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n1 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -v0 [ label="$3_Y" ]; -v1 [ label="c" ]; -c5 [ shape=record, label="{{ A| B}|$4\n$mul|{ Y}}" ]; -c5:p4:e -> n1:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c5:p2:w [color="black", style="setlinewidth(3)", label=""]; -v1:e -> c5:p3:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot deleted file mode 100644 index e77c41aa2e1..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot +++ /dev/null @@ -1,11 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n2 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -c7 [ shape=record, label="{{ A| B}|$4\n$mul|{ Y}}" ]; -n1 [ shape=diamond, label="$3_Y" ]; -n1:e -> c7:p4:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c7:p5:w [color="black", style="setlinewidth(3)", label=""]; -c7:p6:e -> n3:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot deleted file mode 100644 index b544412909c..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot +++ /dev/null @@ -1,15 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n2 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -v0 [ label="a" ]; -v1 [ label="b" ]; -c7 [ shape=record, label="{{ A| B}|$3\n$mul|{ Y}}" ]; -c8 [ shape=record, label="{{ A| B}|$4\n$mul|{ Y}}" ]; -c7:p6:e -> c8:p4:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c8:p5:w [color="black", style="setlinewidth(3)", label=""]; -c8:p6:e -> n3:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c7:p4:w [color="black", style="setlinewidth(3)", label=""]; -v1:e -> c7:p5:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/CHAPTER_Approach.rst b/docs/source/CHAPTER_Approach.rst deleted file mode 100644 index 32980e788bf..00000000000 --- a/docs/source/CHAPTER_Approach.rst +++ /dev/null @@ -1,141 +0,0 @@ -.. _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 -`). - -.. figure:: ../images/approach_flow.* - :class: width-helper - :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 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:: yoscrypt - :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 -:ref:`cmd_ref`. - -.. [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 deleted file mode 100644 index 3d463d3f90b..00000000000 --- a/docs/source/CHAPTER_Eval.rst +++ /dev/null @@ -1,233 +0,0 @@ -.. _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. - -.. footbibliography:: diff --git a/docs/source/CHAPTER_Intro.rst b/docs/source/CHAPTER_Intro.rst deleted file mode 100644 index 90b001c2312..00000000000 --- a/docs/source/CHAPTER_Intro.rst +++ /dev/null @@ -1,96 +0,0 @@ -.. _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 deleted file mode 100644 index 53e0a67aa09..00000000000 --- a/docs/source/CHAPTER_Optimize.rst +++ /dev/null @@ -1,330 +0,0 @@ -.. _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 ``\unused_bits`` 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 -``\fsm_encoding = "auto"`` attribute. The fsm_extract extracts all FSMs marked -using the ``\fsm_encoding`` attribute (unless ``\fsm_encoding`` 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 ``\fsm_encoding -= "auto"`` attribute on any (multi-bit) wire that matches the following -description: - -- Does not already have the ``\fsm_encoding`` attribute. -- Is not an output of the containing module. -- Is driven by single $dff or $adff cell. -- The ``\D``-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 ``\fsm_encoding = "auto"`` on registers that should be considered FSM -state registers and setting ``\fsm_encoding = "none"`` on registers that match -the above criteria but should not be considered FSM state registers. - -Note however that marking state registers with ``\fsm_encoding`` 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 -(``\fsm_encoding != "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 - ``\unused_bits`` (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 deleted file mode 100644 index 10d2ce47840..00000000000 --- a/docs/source/CHAPTER_Overview.rst +++ /dev/null @@ -1,571 +0,0 @@ -.. _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`_, the -`openMSP430 CPU`_, the `OpenCores I2C master`_, and the `k68 CPU`_. - -.. _OpenRISC 1200 CPU: https://github.com/openrisc/or1200 - -.. _openMSP430 CPU: http://opencores.org/projects/openmsp430 - -.. _OpenCores I2C master: http://opencores.org/projects/i2c - -.. _k68 CPU: http://opencores.org/projects/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.* - :class: width-helper - :name: fig:Overview_flow - - Yosys simplified data flow (ellipses: data structures, rectangles: - program modules) - -The RTL Intermediate Language (RTLIL) -------------------------------------- - -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.* - :class: width-helper - :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: - -.. code:: RTLIL - :number-lines: - - 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: - -.. code:: RTLIL - :number-lines: - - 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: - -.. code:: RTLIL - :number-lines: - - 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 ``\MEMID`` 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. - -.. code:: yoscrypt - - dump */t:$add %x:+[A] \*/w:\* %i - -The selection mechanism is very powerful. For example the command above will -print all wires that are connected to the ``\A`` 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/CHAPTER_Prog.rst b/docs/source/CHAPTER_Prog.rst deleted file mode 100644 index 23aeed5a50c..00000000000 --- a/docs/source/CHAPTER_Prog.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _chapter:prog: - -Programming Yosys extensions -============================ - -This chapter contains some bits and pieces of information about -programming yosys extensions. Also consult the section on programming in -the "Yosys Presentation" (can be downloaded from the Yosys website as -PDF) and don't be afraid to ask questions on the YosysHQ Slack. - -Guidelines ----------- - -The guidelines directory contains notes on various aspects of Yosys -development. The files GettingStarted and CodingStyle may be of -particular interest, and are reproduced here. - -.. literalinclude:: temp/GettingStarted - :language: none - :caption: guidelines/GettingStarted - -.. literalinclude:: temp/CodingStyle - :language: none - :caption: guidelines/CodingStyle - -The "stubsnets" example module ------------------------------- - -The following is the complete code of the "stubsnets" example module. It -is included in the Yosys source distribution as -docs/source/CHAPTER_Prog/stubnets.cc. - -.. literalinclude:: CHAPTER_Prog/stubnets.cc - :language: c++ - :linenos: - :caption: docs/source/CHAPTER_Prog/stubnets.cc - -.. literalinclude:: CHAPTER_Prog/Makefile - :language: makefile - :linenos: - :caption: docs/source/CHAPTER_Prog/Makefile - -.. literalinclude:: CHAPTER_Prog/test.v - :language: verilog - :linenos: - :caption: docs/source/CHAPTER_Prog/test.v diff --git a/docs/source/CHAPTER_Verilog.rst b/docs/source/CHAPTER_Verilog.rst deleted file mode 100644 index 484844fba04..00000000000 --- a/docs/source/CHAPTER_Verilog.rst +++ /dev/null @@ -1,666 +0,0 @@ -.. _chapter:verilog: - -The Verilog and AST frontends -============================= - -This chapter provides an overview of the implementation of the Yosys Verilog and -AST frontends. The Verilog frontend reads Verilog-2005 code and creates an -abstract syntax tree (AST) representation of the input. This AST representation -is then passed to the AST frontend that converts it to RTLIL data, as -illustrated in :numref:`Fig. %s `. - -.. figure:: ../images/verilog_flow.* - :class: width-helper - :name: fig:Verilog_flow - - Simplified Verilog to RTLIL data flow - -Transforming Verilog to AST ---------------------------- - -The Verilog frontend converts the Verilog sources to an internal AST -representation that closely resembles the structure of the original -Verilog code. The Verilog frontend consists of three components, the -Preprocessor, the Lexer and the Parser. - -The source code to the Verilog frontend can be found in -frontends/verilog/ in the Yosys source tree. - -The Verilog preprocessor -~~~~~~~~~~~~~~~~~~~~~~~~ - -The Verilog preprocessor scans over the Verilog source code and -interprets some of the Verilog compiler directives such as -:literal:`\`include`, :literal:`\`define` and :literal:`\`ifdef`. - -It is implemented as a C++ function that is passed a file descriptor as -input and returns the pre-processed Verilog code as a ``std::string``. - -The source code to the Verilog Preprocessor can be found in -frontends/verilog/preproc.cc in the Yosys source tree. - -The Verilog lexer -~~~~~~~~~~~~~~~~~ - -The Verilog Lexer is written using the lexer generator flex . Its source -code can be found in frontends/verilog/verilog_lexer.l in the Yosys -source tree. The lexer does little more than identifying all keywords -and literals recognised by the Yosys Verilog frontend. - -The lexer keeps track of the current location in the Verilog source code -using some global variables. These variables are used by the constructor -of AST nodes to annotate each node with the source code location it -originated from. - -Finally the lexer identifies and handles special comments such as -"``// synopsys translate_off``" and "``// synopsys full_case``". (It is -recommended to use :literal:`\`ifdef` constructs instead of the -Synsopsys translate_on/off comments and attributes such as -``(* full_case *)`` over "``// synopsys full_case``" whenever possible.) - -The Verilog parser -~~~~~~~~~~~~~~~~~~ - -The Verilog Parser is written using the parser generator bison . Its -source code can be found in frontends/verilog/verilog_parser.y in the -Yosys source tree. - -It generates an AST using the ``AST::AstNode`` data structure defined in -frontends/ast/ast.h. An ``AST::AstNode`` object has the following -properties: - -.. list-table:: AST node types with their corresponding Verilog constructs. - :name: tab:Verilog_AstNodeType - :widths: 50 50 - - * - AST Node Type - - Corresponding Verilog Construct - * - AST_NONE - - This Node type should never be used. - * - AST_DESIGN - - This node type is used for the top node of the AST tree. It has no corresponding Verilog construct. - * - AST_MODULE, AST_TASK, AST_FUNCTION - - ``module``, ``task`` and ``function`` - * - AST_WIRE - - ``input``, ``output``, ``wire``, ``reg`` and ``integer`` - * - AST_MEMORY - - Verilog Arrays - * - AST_AUTOWIRE - - Created by the simplifier when an undeclared signal name is used. - * - AST_PARAMETER, AST_LOCALPARAM - - ``parameter`` and ``localparam`` - * - AST_PARASET - - Parameter set in cell instantiation - * - AST_ARGUMENT - - Port connection in cell instantiation - * - AST_RANGE - - Bit-Index in a signal or element index in array - * - AST_CONSTANT - - A literal value - * - AST_CELLTYPE - - The type of cell in cell instantiation - * - AST_IDENTIFIER - - An Identifier (signal name in expression or cell/task/etc. name in other contexts) - * - AST_PREFIX - - Construct an identifier in the form []. (used only in advanced generate constructs) - * - AST_FCALL, AST_TCALL - - Call to function or task - * - AST_TO_SIGNED, AST_TO_UNSIGNED - - The ``$signed()`` and ``$unsigned()`` functions - * - AST_CONCAT, AST_REPLICATE - - The ``{...}`` and ``{...{...}}`` operators - * - AST_BIT_NOT, AST_BIT_AND, AST_BIT_OR, AST_BIT_XOR, AST_BIT_XNOR - - The bitwise operators ``~``, ``&``, ``|``, ``^`` and ``~^`` - * - AST_REDUCE_AND, AST_REDUCE_OR, AST_REDUCE_XOR, AST_REDUCE_XNOR - - The unary reduction operators ``~``, ``&``, ``|``, ``^`` and ``~^`` - * - AST_REDUCE_BOOL - - Conversion from multi-bit value to boolean value (equivalent to AST_REDUCE_OR) - * - AST_SHIFT_LEFT, AST_SHIFT_RIGHT, AST_SHIFT_SLEFT, AST_SHIFT_SRIGHT - - The shift operators ``<<``, ``>>``, ``<<<`` and ``>>>`` - * - AST_LT, AST_LE, AST_EQ, AST_NE, AST_GE, AST_GT - - The relational operators ``<``, ``<=``, ``==``, ``!=``, ``>=`` and ``>`` - * - AST_ADD, AST_SUB, AST_MUL, AST_DIV, AST_MOD, AST_POW - - The binary operators ``+``, ``-``, ``*``, ``/``, ``%`` and ``**`` - * - AST_POS, AST_NEG - - The prefix operators ``+`` and ``-`` - * - AST_LOGIC_AND, AST_LOGIC_OR, AST_LOGIC_NOT - - The logic operators ``&&``, ``||`` and ``!`` - * - AST_TERNARY - - The ternary ``?:``-operator - * - AST_MEMRD AST_MEMWR - - Read and write memories. These nodes are generated by the AST simplifier for writes/reads to/from Verilog arrays. - * - AST_ASSIGN - - An ``assign`` statement - * - AST_CELL - - A cell instantiation - * - AST_PRIMITIVE - - A primitive cell (``and``, ``nand``, ``or``, etc.) - * - AST_ALWAYS, AST_INITIAL - - Verilog ``always``- and ``initial``-blocks - * - AST_BLOCK - - A ``begin``-``end``-block - * - AST_ASSIGN_EQ. AST_ASSIGN_LE - - Blocking (``=``) and nonblocking (``<=``) assignments within an ``always``- or ``initial``-block - * - AST_CASE. AST_COND, AST_DEFAULT - - The ``case`` (``if``) statements, conditions within a case and the default case respectively - * - AST_FOR - - A ``for``-loop with an ``always``- or ``initial``-block - * - AST_GENVAR, AST_GENBLOCK, AST_GENFOR, AST_GENIF - - The ``genvar`` and ``generate`` keywords and ``for`` and ``if`` within a generate block. - * - AST_POSEDGE, AST_NEGEDGE, AST_EDGE - - Event conditions for ``always`` blocks. - -- | The node type - | This enum (``AST::AstNodeType``) specifies the role of the node. - :numref:`Table %s ` - contains a list of all node types. - -- | The child nodes - | This is a list of pointers to all children in the abstract syntax - tree. - -- | Attributes - | As almost every AST node might have Verilog attributes assigned to - it, the ``AST::AstNode`` has direct support for attributes. Note - that the attribute values are again AST nodes. - -- | Node content - | Each node might have additional content data. A series of member - variables exist to hold such data. For example the member - ``std::string str`` can hold a string value and is used e.g. in the - AST_IDENTIFIER node type to store the identifier name. - -- | Source code location - | Each ``AST::AstNode`` is automatically annotated with the current - source code location by the ``AST::AstNode`` constructor. It is - stored in the ``std::string filename`` and ``int linenum`` member - variables. - -The ``AST::AstNode`` constructor can be called with up to two child -nodes that are automatically added to the list of child nodes for the -new object. This simplifies the creation of AST nodes for simple -expressions a bit. For example the bison code for parsing -multiplications: - -.. code:: none - :number-lines: - - basic_expr '*' attr basic_expr { - $$ = new AstNode(AST_MUL, $1, $4); - append_attr($$, $3); - } | - -The generated AST data structure is then passed directly to the AST -frontend that performs the actual conversion to RTLIL. - -Note that the Yosys command ``read_verilog`` provides the options ``-yydebug`` -and ``-dump_ast`` that can be used to print the parse tree or abstract -syntax tree respectively. - -Transforming AST to RTLIL -------------------------- - -The AST Frontend converts a set of modules in AST representation to -modules in RTLIL representation and adds them to the current design. -This is done in two steps: simplification and RTLIL generation. - -The source code to the AST frontend can be found in ``frontends/ast/`` in -the Yosys source tree. - -AST simplification -~~~~~~~~~~~~~~~~~~ - -A full-featured AST is too complex to be transformed into RTLIL -directly. Therefore it must first be brought into a simpler form. This -is done by calling the ``AST::AstNode::simplify()`` method of all -AST_MODULE nodes in the AST. This initiates a recursive process that -performs the following transformations on the AST data structure: - -- Inline all task and function calls. - -- Evaluate all ``generate``-statements and unroll all ``for``-loops. - -- Perform const folding where it is necessary (e.g. in the value part - of AST_PARAMETER, AST_LOCALPARAM, AST_PARASET and AST_RANGE nodes). - -- Replace AST_PRIMITIVE nodes with appropriate AST_ASSIGN nodes. - -- Replace dynamic bit ranges in the left-hand-side of assignments with - AST_CASE nodes with AST_COND children for each possible case. - -- Detect array access patterns that are too complicated for the - RTLIL::Memory abstraction and replace them with a set of signals and - cases for all reads and/or writes. - -- Otherwise replace array accesses with AST_MEMRD and AST_MEMWR nodes. - -In addition to these transformations, the simplifier also annotates the -AST with additional information that is needed for the RTLIL generator, -namely: - -- All ranges (width of signals and bit selections) are not only const - folded but (when a constant value is found) are also written to - member variables in the AST_RANGE node. - -- All identifiers are resolved and all AST_IDENTIFIER nodes are - annotated with a pointer to the AST node that contains the - declaration of the identifier. If no declaration has been found, an - AST_AUTOWIRE node is created and used for the annotation. - -This produces an AST that is fairly easy to convert to the RTLIL format. - -Generating RTLIL -~~~~~~~~~~~~~~~~ - -After AST simplification, the ``AST::AstNode::genRTLIL()`` method of -each AST_MODULE node in the AST is called. This initiates a recursive -process that generates equivalent RTLIL data for the AST data. - -The ``AST::AstNode::genRTLIL()`` method returns an ``RTLIL::SigSpec`` -structure. For nodes that represent expressions (operators, constants, -signals, etc.), the cells needed to implement the calculation described -by the expression are created and the resulting signal is returned. That -way it is easy to generate the circuits for large expressions using -depth-first recursion. For nodes that do not represent an expression -(such as AST_CELL), the corresponding circuit is generated and an empty -``RTLIL::SigSpec`` is returned. - -Synthesizing Verilog always blocks --------------------------------------- - -For behavioural Verilog code (code utilizing ``always``- and -``initial``-blocks) it is necessary to also generate ``RTLIL::Process`` -objects. This is done in the following way: - -Whenever ``AST::AstNode::genRTLIL()`` encounters an ``always``- or -``initial``-block, it creates an instance of -``AST_INTERNAL::ProcessGenerator``. This object then generates the -``RTLIL::Process`` object for the block. It also calls -``AST::AstNode::genRTLIL()`` for all right-hand-side expressions -contained within the block. - -First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all -signals assigned within the block. It then creates a set of temporary -signals using the naming scheme $\ \\\ for each -of the assigned signals. - -Then an ``RTLIL::Process`` is created that assigns all intermediate -values for each left-hand-side signal to the temporary signal in its -``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree. - -Finally a ``RTLIL::SyncRule`` is created for the ``RTLIL::Process`` that -assigns the temporary signals for the final values to the actual -signals. - -A process may also contain memory writes. A ``RTLIL::MemWriteAction`` is -created for each of them. - -Calls to ``AST::AstNode::genRTLIL()`` are generated for right hand sides -as needed. When blocking assignments are used, -``AST::AstNode::genRTLIL()`` is configured using global variables to use -the temporary signals that hold the correct intermediate values whenever -one of the previously assigned signals is used in an expression. - -Unfortunately the generation of a correct -``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree for behavioural code is a -non-trivial task. The AST frontend solves the problem using the approach -described on the following pages. The following example illustrates what -the algorithm is supposed to do. Consider the following Verilog code: - -.. code:: verilog - :number-lines: - - always @(posedge clock) begin - out1 = in1; - if (in2) - out1 = !out1; - out2 <= out1; - if (in3) - out2 <= out2; - if (in4) - if (in5) - out3 <= in6; - else - out3 <= in7; - out1 = out1 ^ out2; - end - -This is translated by the Verilog and AST frontends into the following -RTLIL code (attributes, cell parameters and wire declarations not -included): - -.. code:: RTLIL - :number-lines: - - cell $logic_not $logic_not$:4$2 - connect \A \in1 - connect \Y $logic_not$:4$2_Y - end - cell $xor $xor$:13$3 - connect \A $1\out1[0:0] - connect \B \out2 - connect \Y $xor$:13$3_Y - end - process $proc$:1$1 - assign $0\out3[0:0] \out3 - assign $0\out2[0:0] $1\out1[0:0] - assign $0\out1[0:0] $xor$:13$3_Y - switch \in2 - case 1'1 - assign $1\out1[0:0] $logic_not$:4$2_Y - case - assign $1\out1[0:0] \in1 - end - switch \in3 - case 1'1 - assign $0\out2[0:0] \out2 - case - end - switch \in4 - case 1'1 - switch \in5 - case 1'1 - assign $0\out3[0:0] \in6 - case - assign $0\out3[0:0] \in7 - end - case - end - sync posedge \clock - update \out1 $0\out1[0:0] - update \out2 $0\out2[0:0] - update \out3 $0\out3[0:0] - end - -Note that the two operators are translated into separate cells outside -the generated process. The signal ``out1`` is assigned using blocking -assignments and therefore ``out1`` has been replaced with a different -signal in all expressions after the initial assignment. The signal -``out2`` is assigned using nonblocking assignments and therefore is not -substituted on the right-hand-side expressions. - -The ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree must be interpreted -the following way: - -- On each case level (the body of the process is the root case), first - the actions on this level are evaluated and then the switches within - the case are evaluated. (Note that the last assignment on line 13 of - the Verilog code has been moved to the beginning of the RTLIL process - to line 13 of the RTLIL listing.) - - I.e. the special cases deeper in the switch hierarchy override the - defaults on the upper levels. The assignments in lines 12 and 22 of - the RTLIL code serve as an example for this. - - Note that in contrast to this, the order within the - ``RTLIL::SwitchRule`` objects within a ``RTLIL::CaseRule`` is - preserved with respect to the original AST and Verilog code. - -- The whole ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree describes an - asynchronous circuit. I.e. the decision tree formed by the switches - can be seen independently for each assigned signal. Whenever one - assigned signal changes, all signals that depend on the changed - signals are to be updated. For example the assignments in lines 16 - and 18 in the RTLIL code in fact influence the assignment in line 12, - even though they are in the "wrong order". - -The only synchronous part of the process is in the ``RTLIL::SyncRule`` -object generated at line 35 in the RTLIL code. The sync rule is the only -part of the process where the original signals are assigned. The -synchronization event from the original Verilog code has been translated -into the synchronization type (posedge) and signal (\\clock) for the -``RTLIL::SyncRule`` object. In the case of this simple example the -``RTLIL::SyncRule`` object is later simply transformed into a set of -d-type flip-flops and the ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree -to a decision tree using multiplexers. - -In more complex examples (e.g. asynchronous resets) the part of the -``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree that describes the -asynchronous reset must first be transformed to the correct -``RTLIL::SyncRule`` objects. This is done by the proc_adff pass. - -The ProcessGenerator algorithm -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``AST_INTERNAL::ProcessGenerator`` uses the following internal state -variables: - -- | ``subst_rvalue_from`` and ``subst_rvalue_to`` - | These two variables hold the replacement pattern that should be - used by ``AST::AstNode::genRTLIL()`` for signals with blocking - assignments. After initialization of - ``AST_INTERNAL::ProcessGenerator`` these two variables are empty. - -- | ``subst_lvalue_from`` and ``subst_lvalue_to`` - | These two variables contain the mapping from left-hand-side signals - (\\\ ) to the current temporary signal for the same thing - (initially $0\\\ ). - -- | ``current_case`` - | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the - root case of the generated ``RTLIL::Process``. - -As the algorithm runs these variables are continuously modified as well -as pushed to the stack and later restored to their earlier values by -popping from the stack. - -On startup the ProcessGenerator generates a new ``RTLIL::Process`` -object with an empty root case and initializes its state variables as -described above. Then the ``RTLIL::SyncRule`` objects are created using -the synchronization events from the AST_ALWAYS node and the initial -values of ``subst_lvalue_from`` and ``subst_lvalue_to``. Then the AST -for this process is evaluated recursively. - -During this recursive evaluation, three different relevant types of AST -nodes can be discovered: AST_ASSIGN_LE (nonblocking assignments), -AST_ASSIGN_EQ (blocking assignments) and AST_CASE (``if`` or ``case`` -statement). - -Handling of nonblocking assignments -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When an AST_ASSIGN_LE node is discovered, the following actions are -performed by the ProcessGenerator: - -- The left-hand-side is evaluated using ``AST::AstNode::genRTLIL()`` - and mapped to a temporary signal name using ``subst_lvalue_from`` and - ``subst_lvalue_to``. - -- The right-hand-side is evaluated using ``AST::AstNode::genRTLIL()``. - For this call, the values of ``subst_rvalue_from`` and - ``subst_rvalue_to`` are used to map blocking-assigned signals - correctly. - -- Remove all assignments to the same left-hand-side as this assignment - from the ``current_case`` and all cases within it. - -- Add the new assignment to the ``current_case``. - -Handling of blocking assignments -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When an AST_ASSIGN_EQ node is discovered, the following actions are -performed by the ProcessGenerator: - -- Perform all the steps that would be performed for a nonblocking - assignment (see above). - -- Remove the found left-hand-side (before lvalue mapping) from - ``subst_rvalue_from`` and also remove the respective bits from - ``subst_rvalue_to``. - -- Append the found left-hand-side (before lvalue mapping) to - ``subst_rvalue_from`` and append the found right-hand-side to - ``subst_rvalue_to``. - -Handling of cases and if-statements -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When an AST_CASE node is discovered, the following actions are performed -by the ProcessGenerator: - -- The values of ``subst_rvalue_from``, ``subst_rvalue_to``, - ``subst_lvalue_from`` and ``subst_lvalue_to`` are pushed to the - stack. - -- A new ``RTLIL::SwitchRule`` object is generated, the selection - expression is evaluated using ``AST::AstNode::genRTLIL()`` (with the - use of ``subst_rvalue_from`` and ``subst_rvalue_to``) and added to - the ``RTLIL::SwitchRule`` object and the object is added to the - ``current_case``. - -- All lvalues assigned to within the AST_CASE node using blocking - assignments are collected and saved in the local variable - ``this_case_eq_lvalue``. - -- New temporary signals are generated for all signals in - ``this_case_eq_lvalue`` and stored in ``this_case_eq_ltemp``. - -- The signals in ``this_case_eq_lvalue`` are mapped using - ``subst_rvalue_from`` and ``subst_rvalue_to`` and the resulting set - of signals is stored in ``this_case_eq_rvalue``. - -Then the following steps are performed for each AST_COND node within the -AST_CASE node: - -- Set ``subst_rvalue_from``, ``subst_rvalue_to``, ``subst_lvalue_from`` - and ``subst_lvalue_to`` to the values that have been pushed to the - stack. - -- Remove ``this_case_eq_lvalue`` from - ``subst_lvalue_from``/``subst_lvalue_to``. - -- Append ``this_case_eq_lvalue`` to ``subst_lvalue_from`` and append - ``this_case_eq_ltemp`` to ``subst_lvalue_to``. - -- Push the value of ``current_case``. - -- Create a new ``RTLIL::CaseRule``. Set ``current_case`` to the new - object and add the new object to the ``RTLIL::SwitchRule`` created - above. - -- Add an assignment from ``this_case_eq_rvalue`` to - ``this_case_eq_ltemp`` to the new ``current_case``. - -- Evaluate the compare value for this case using - ``AST::AstNode::genRTLIL()`` (with the use of ``subst_rvalue_from`` - and ``subst_rvalue_to``) modify the new ``current_case`` accordingly. - -- Recursion into the children of the AST_COND node. - -- Restore ``current_case`` by popping the old value from the stack. - -Finally the following steps are performed: - -- The values of ``subst_rvalue_from``, ``subst_rvalue_to``, - ``subst_lvalue_from`` and ``subst_lvalue_to`` are popped from the - stack. - -- The signals from ``this_case_eq_lvalue`` are removed from the - ``subst_rvalue_from``/``subst_rvalue_to``-pair. - -- The value of ``this_case_eq_lvalue`` is appended to - ``subst_rvalue_from`` and the value of ``this_case_eq_ltemp`` is - appended to ``subst_rvalue_to``. - -- Map the signals in ``this_case_eq_lvalue`` using - ``subst_lvalue_from``/``subst_lvalue_to``. - -- Remove all assignments to signals in ``this_case_eq_lvalue`` in - ``current_case`` and all cases within it. - -- Add an assignment from ``this_case_eq_ltemp`` to - ``this_case_eq_lvalue`` to ``current_case``. - -Further analysis of the algorithm for cases and if-statements -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -With respect to nonblocking assignments the algorithm is easy: later -assignments invalidate earlier assignments. For each signal assigned -using nonblocking assignments exactly one temporary variable is -generated (with the $0-prefix) and this variable is used for all -assignments of the variable. - -Note how all the ``_eq_``-variables become empty when no blocking -assignments are used and many of the steps in the algorithm can then be -ignored as a result of this. - -For a variable with blocking assignments the algorithm shows the -following behaviour: First a new temporary variable is created. This new -temporary variable is then registered as the assignment target for all -assignments for this variable within the cases for this AST_CASE node. -Then for each case the new temporary variable is first assigned the old -temporary variable. This assignment is overwritten if the variable is -actually assigned in this case and is kept as a default value otherwise. - -This yields an ``RTLIL::CaseRule`` that assigns the new temporary -variable in all branches. So when all cases have been processed a final -assignment is added to the containing block that assigns the new -temporary variable to the old one. Note how this step always overrides a -previous assignment to the old temporary variable. Other than -nonblocking assignments, the old assignment could still have an effect -somewhere in the design, as there have been calls to -``AST::AstNode::genRTLIL()`` with a -``subst_rvalue_from``/``subst_rvalue_to``-tuple that contained the -right-hand-side of the old assignment. - -The proc pass -~~~~~~~~~~~~~ - -The ProcessGenerator converts a behavioural model in AST representation -to a behavioural model in ``RTLIL::Process`` representation. The actual -conversion from a behavioural model to an RTL representation is -performed by the proc pass and the passes it launches: - -- | proc_clean and proc_rmdead - | These two passes just clean up the ``RTLIL::Process`` structure. - The proc_clean pass removes empty parts (eg. empty assignments) - from the process and proc_rmdead detects and removes unreachable - branches from the process's decision trees. - -- | proc_arst - | This pass detects processes that describe d-type flip-flops with - asynchronous resets and rewrites the process to better reflect what - they are modelling: Before this pass, an asynchronous reset has two - edge-sensitive sync rules and one top-level for the reset path. - After this pass the sync rule for the reset is level-sensitive and - the top-level has been removed. - -- | proc_mux - | This pass converts the /-tree to a tree of multiplexers per written - signal. After this, the structure only contains the s that describe - the output registers. - -- | proc_dff - | This pass replaces the s to d-type flip-flops (with asynchronous - resets if necessary). - -- | proc_dff - | This pass replaces the s with $memwr cells. - -- | proc_clean - | A final call to proc_clean removes the now empty objects. - -Performing these last processing steps in passes instead of in the -Verilog frontend has two important benefits: - -First it improves the transparency of the process. Everything that -happens in a separate pass is easier to debug, as the RTLIL data -structures can be easily investigated before and after each of the -steps. - -Second it improves flexibility. This scheme can easily be extended to -support other types of storage-elements, such as sr-latches or -d-latches, without having to extend the actual Verilog frontend. - -Synthesizing Verilog arrays ---------------------------- - -Add some information on the generation of $memrd and $memwr cells and -how they are processed in the memory pass. - -Synthesizing parametric designs -------------------------------- - -Add some information on the ``RTLIL::Module::derive()`` method and how -it is used to synthesize parametric modules via the hierarchy pass. diff --git a/docs/source/_downloads/APPNOTE_010_Verilog_to_BLIF.pdf b/docs/source/_downloads/APPNOTE_010_Verilog_to_BLIF.pdf new file mode 100644 index 00000000000..91fc1aac8e8 Binary files /dev/null and b/docs/source/_downloads/APPNOTE_010_Verilog_to_BLIF.pdf differ diff --git a/docs/source/_downloads/APPNOTE_012_Verilog_to_BTOR.pdf b/docs/source/_downloads/APPNOTE_012_Verilog_to_BTOR.pdf new file mode 100644 index 00000000000..f3ffd6f308d Binary files /dev/null and b/docs/source/_downloads/APPNOTE_012_Verilog_to_BTOR.pdf differ diff --git a/docs/source/_images/Makefile b/docs/source/_images/Makefile new file mode 100644 index 00000000000..955805f9c58 --- /dev/null +++ b/docs/source/_images/Makefile @@ -0,0 +1,46 @@ +all: examples all_tex tidy + +# set a fake time in pdf generation to prevent unnecessary differences in output +FAKETIME := TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' + +# find all code example makefiles +.PHONY: examples +CODE_EXAMPLES := ../code_examples/*/Makefile +examples: $(CODE_EXAMPLES) + +# target to convert specified dot file(s) +.PHONY: convert +TARG_DOT ?= +convert: $(TARG_DOT:.dot=.pdf) $(TARG_DOT:.dot=.svg) + +# use empty FORCE target because .PHONY ignores % expansion, using find allows +# us to generate everything in one pass, since we don't know all of the possible +# outputs until the sub-makes run +FORCE: +../%/Makefile: FORCE + @make -C $(@D) dots + @mkdir -p $* + @find $(@D) -name *.dot -exec cp -u {} -t $* \; + @find $* -name *.dot -printf "%p " | xargs -i make --no-print-directory convert TARG_DOT="{}" + +# find and build all tex files +.PHONY: all_tex +TEX_FILES := $(wildcard **/*.tex) +all_tex: $(TEX_FILES:.tex=.pdf) $(TEX_FILES:.tex=.svg) + +%.pdf: %.dot + $(FAKETIME) dot -Tpdf -o $@ $< + +%.pdf: %.tex + cd $(@D) && $(FAKETIME) pdflatex $(] (sysx) -- node[right] {System Design} (hlx); + \draw[|->|] (hlx) -- node[right] {High Level Synthesis (HLS)} (behx); + \draw[->|] (behx) -- node[right] {Behavioral Synthesis} (rtlx); + \draw[->|] (rtlx) -- node[right] {RTL Synthesis} (lgx); + \draw[->|] (lgx) -- node[right] {Logic Synthesis} (pgx); + \draw[gray,->|] (pgx) -- node[right] {Cell Library} (swx); + + \draw[dotted] (behx) -- ++(4,0) coordinate (a); + \draw[dotted] (pgx) -- ++(4,0) coordinate (b); + \draw[|->|] (a) -- node[right] {Yosys} (b); +\end{tikzpicture} +\end{document} diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 00000000000..b08194c0521 --- /dev/null +++ b/docs/source/_static/custom.css @@ -0,0 +1,20 @@ +/* Reduce whitespace in cmd def pages */ +.cmd.def .highlight-yoscrypt, .cmd.def .highlight pre { + padding: 0%; + margin: 0%; +} + +.cmd.def .highlight-none, .cmd.def .highlight pre { + padding-top: 0%; + margin-top: 0%; +} + +/* Make images full width */ +.width-helper { + max-width: 100%; +} + +/* Prevent code block caption text from bunching into the caption number */ +.literal-block-wrapper .code-block-caption .caption-number { + padding-right: 0.5em +} diff --git a/docs/static/favico.png b/docs/source/_static/favico.png similarity index 100% rename from docs/static/favico.png rename to docs/source/_static/favico.png diff --git a/docs/static/logo.png b/docs/source/_static/logo.png similarity index 100% rename from docs/static/logo.png rename to docs/source/_static/logo.png diff --git a/docs/source/_static/yosyshq.css b/docs/source/_static/yosyshq.css new file mode 100644 index 00000000000..57ae8f87a5f --- /dev/null +++ b/docs/source/_static/yosyshq.css @@ -0,0 +1,26 @@ +/* Don't hide the right sidebar as we're placing our fixed links there */ +aside.no-toc { + display: block !important; +} + +/* Colorful headings */ +h1 { + color: var(--color-brand-primary); + } + +h2, h3, h4, h5, h6 { + color: var(--color-brand-content); +} + +/* Use a different color for external links */ +a.external { + color: var(--color-brand-primary) !important; +} + +.wy-table-responsive table td { + white-space: normal; +} + +th { + text-align: left; +} diff --git a/docs/source/_templates/page.html b/docs/source/_templates/page.html new file mode 100644 index 00000000000..d830124c176 --- /dev/null +++ b/docs/source/_templates/page.html @@ -0,0 +1,44 @@ +{# + +See https://github.com/pradyunsg/furo/blob/main/src/furo/theme/furo/page.html for the original +block this is overwriting. + +The part that is customized is between the "begin of custom part" and "end of custom part" +comments below. It uses the same styles as the existing right sidebar code. + +#} +{% extends "furo/page.html" %} +{% block right_sidebar %} +
+ {# begin of custom part #} +
+ + YosysHQ + +
+ + {# end of custom part #} + {% if not furo_hide_toc %} +
+ + {{ _("On this page") }} + +
+
+
+ {{ toc }} +
+
+ {% endif %} +
+{% endblock %} + \ No newline at end of file diff --git a/docs/source/appendix.rst b/docs/source/appendix.rst new file mode 100644 index 00000000000..0b0a2d15b5d --- /dev/null +++ b/docs/source/appendix.rst @@ -0,0 +1,18 @@ +Appendix +======== + +.. toctree:: + :maxdepth: 2 + :includehidden: + + appendix/primer + appendix/auxlibs + appendix/auxprogs + + bib + +.. toctree:: + :maxdepth: 1 + :includehidden: + + cmd_ref diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index a48401dcc18..ff404cb53d1 100644 --- a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst +++ b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst @@ -1,336 +1,363 @@ +:orphan: + ==================================== 010: Converting Verilog to BLIF page ==================================== -Installation -============ +Abstract +======== + +Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used +to easily create complex designs from small HDL code. It is the preferred method +of design entry for many designers. + +The Berkeley Logic Interchange Format (BLIF) is a simple file format for +exchanging sequential logic between programs. It is easy to generate and easy to +parse and is therefore the preferred method of design entry for many authors of +logic synthesis tools. + +Yosys is a feature-rich Open-Source Verilog synthesis tool that can be used to +bridge the gap between the two file formats. It implements most of Verilog-2005 +and thus can be used to import modern behavioral Verilog designs into BLIF-based +design flows without dependencies on proprietary synthesis tools. + +The scope of Yosys goes of course far beyond Verilog logic synthesis. But it is +a useful and important feature and this Application Note will focus on this +aspect of Yosys. + +Download +======== + +This document was originally published in April 2015: +:download:`Converting Verilog to BLIF PDF` + +.. + Installation + ============ -Yosys written in C++ (using features from C++11) and is tested on modern -Linux. It should compile fine on most UNIX systems with a C++11 -compiler. The README file contains useful information on building Yosys -and its prerequisites. + Yosys written in C++ (using features from C++11) and is tested on modern + Linux. It should compile fine on most UNIX systems with a C++11 + compiler. The README file contains useful information on building Yosys + and its prerequisites. -Yosys is a large and feature-rich program with a couple of dependencies. -It is, however, possible to deactivate some of the dependencies in the -Makefile, resulting in features in Yosys becoming unavailable. When -problems with building Yosys are encountered, a user who is only -interested in the features of Yosys that are discussed in this -Application Note may deactivate TCL, Qt and MiniSAT support in the -Makefile and may opt against building yosys-abc. + Yosys is a large and feature-rich program with a couple of dependencies. + It is, however, possible to deactivate some of the dependencies in the + Makefile, resulting in features in Yosys becoming unavailable. When + problems with building Yosys are encountered, a user who is only + interested in the features of Yosys that are discussed in this + Application Note may deactivate TCL, Qt and MiniSAT support in the + Makefile and may opt against building yosys-abc. -This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_ from 2013-11-23. -The Verilog sources used for the examples are taken from `yosys-bigsim`_, a -collection of real-world designs used for regression testing Yosys. + This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_ from 2013-11-23. + The Verilog sources used for the examples are taken from `yosys-bigsim`_, a + collection of real-world designs used for regression testing Yosys. -.. _Yosys GIT: https://github.com/YosysHQ/yosys + .. _Yosys GIT: https://github.com/YosysHQ/yosys -.. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e + .. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e -.. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim + .. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim -Getting started -=============== + Getting started + =============== -We start our tour with the Navré processor from yosys-bigsim. The `Navré -processor`_ is an Open Source AVR clone. It is a single module (softusb_navre) -in a single design file (softusb_navre.v). It also is using only features that -map nicely to the BLIF format, for example it only uses synchronous resets. + We start our tour with the Navré processor from yosys-bigsim. The `Navré + processor`_ is an Open Source AVR clone. It is a single module (softusb_navre) + in a single design file (softusb_navre.v). It also is using only features that + map nicely to the BLIF format, for example it only uses synchronous resets. -.. _Navré processor: http://opencores.org/projects/navre - -Converting softusb_navre.v to softusb_navre.blif could not be easier: + .. _Navré processor: http://opencores.org/projects/navre + + Converting softusb_navre.v to softusb_navre.blif could not be easier: -.. code:: sh + .. code:: sh - yosys -o softusb_navre.blif -S softusb_navre.v + yosys -o softusb_navre.blif -S softusb_navre.v -Behind the scenes Yosys is controlled by synthesis scripts that execute -commands that operate on Yosys' internal state. For example, the -o -softusb_navre.blif option just adds the command write_blif -softusb_navre.blif to the end of the script. Likewise a file on the -command line – softusb_navre.v in this case – adds the command -read_verilog softusb_navre.v to the beginning of the synthesis script. -In both cases the file type is detected from the file extension. + Behind the scenes Yosys is controlled by synthesis scripts that execute + commands that operate on Yosys' internal state. For example, the -o + softusb_navre.blif option just adds the command write_blif + softusb_navre.blif to the end of the script. Likewise a file on the + command line – softusb_navre.v in this case – adds the command + read_verilog softusb_navre.v to the beginning of the synthesis script. + In both cases the file type is detected from the file extension. -Finally the option -S instantiates a built-in default synthesis script. -Instead of using -S one could also specify the synthesis commands for -the script on the command line using the -p option, either using -individual options for each command or by passing one big command string -with a semicolon-separated list of commands. But in most cases it is -more convenient to use an actual script file. + Finally the option -S instantiates a built-in default synthesis script. + Instead of using -S one could also specify the synthesis commands for + the script on the command line using the -p option, either using + individual options for each command or by passing one big command string + with a semicolon-separated list of commands. But in most cases it is + more convenient to use an actual script file. -Using a synthesis script -======================== + Using a synthesis script + ======================== -With a script file we have better control over Yosys. The following -script file replicates what the command from the last section did: + With a script file we have better control over Yosys. The following + script file replicates what the command from the last section did: -.. code:: yoscrypt + .. code:: yoscrypt - read_verilog softusb_navre.v - hierarchy - proc; opt; memory; opt; techmap; opt - write_blif softusb_navre.blif - -The first and last line obviously read the Verilog file and write the -BLIF file. - -The 2nd line checks the design hierarchy and instantiates parametrized -versions of the modules in the design, if necessary. In the case of this -simple design this is a no-op. However, as a general rule a synthesis -script should always contain this command as first command after reading -the input files. - -The 3rd line does most of the actual work: - -- The command opt is the Yosys' built-in optimizer. It can perform some - simple optimizations such as const-folding and removing unconnected - parts of the design. It is common practice to call opt after each - major step in the synthesis procedure. In cases where too much - optimization is not appreciated (for example when analyzing a - design), it is recommended to call clean instead of opt. - -- The command proc converts processes (Yosys' internal representation - of Verilog always- and initial-blocks) to circuits of multiplexers - and storage elements (various types of flip-flops). - -- The command memory converts Yosys' internal representations of arrays - and array accesses to multi-port block memories, and then maps this - block memories to address decoders and flip-flops, unless the option - -nomap is used, in which case the multi-port block memories stay in - the design and can then be mapped to architecture-specific memory - primitives using other commands. - -- The command techmap turns a high-level circuit with coarse grain - cells such as wide adders and multipliers to a fine-grain circuit of - simple logic primitives and single-bit storage elements. The command - does that by substituting the complex cells by circuits of simpler - cells. It is possible to provide a custom set of rules for this - process in the form of a Verilog source file, as we will see in the - next section. - -Now Yosys can be run with the filename of the synthesis script as -argument: - -.. code:: sh - - yosys softusb_navre.ys - -Now that we are using a synthesis script we can easily modify how Yosys -synthesizes the design. The first thing we should customize is the call -to the hierarchy command: - -Whenever it is known that there are no implicit blackboxes in the -design, i.e. modules that are referenced but are not defined, the -hierarchy command should be called with the -check option. This will -then cause synthesis to fail when implicit blackboxes are found in the -design. - -The 2nd thing we can improve regarding the hierarchy command is that we -can tell it the name of the top level module of the design hierarchy. It -will then automatically remove all modules that are not referenced from -this top level module. - -For many designs it is also desired to optimize the encodings for the -finite state machines (FSMs) in the design. The fsm command finds FSMs, -extracts them, performs some basic optimizations and then generate a -circuit from the extracted and optimized description. It would also be -possible to tell the fsm command to leave the FSMs in their extracted -form, so they can be further processed using custom commands. But in -this case we don't want that. - -So now we have the final synthesis script for generating a BLIF file for -the Navré CPU: - -.. code:: yoscrypt - - read_verilog softusb_navre.v - hierarchy -check -top softusb_navre - proc; opt; memory; opt; fsm; opt; techmap; opt - write_blif softusb_navre.blif - -Advanced example: The Amber23 ARMv2a CPU -======================================== - -Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on -the Verilog code that is included in `yosys-bigsim`_. - -.. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber - -.. code-block:: yoscrypt - :caption: `amber23.ys` - :name: amber23.ys - - read_verilog a23_alu.v - read_verilog a23_barrel_shift_fpga.v - read_verilog a23_barrel_shift.v - read_verilog a23_cache.v - read_verilog a23_coprocessor.v - read_verilog a23_core.v - read_verilog a23_decode.v - read_verilog a23_execute.v - read_verilog a23_fetch.v - read_verilog a23_multiply.v - read_verilog a23_ram_register_bank.v - read_verilog a23_register_bank.v - read_verilog a23_wishbone.v - read_verilog generic_sram_byte_en.v - read_verilog generic_sram_line_en.v - hierarchy -check -top a23_core - add -global_input globrst 1 - proc -global_arst globrst - techmap -map adff2dff.v - opt; memory; opt; fsm; opt; techmap - write_blif amber23.blif - -The problem with this core is that it contains no dedicated reset logic. Instead -the coding techniques shown in :numref:`glob_arst` are used to define reset -values for the global asynchronous reset in an FPGA implementation. This design -can not be expressed in BLIF as it is. Instead we need to use a synthesis script -that transforms this form to synchronous resets that can be expressed in BLIF. - -(Note that there is no problem if this coding techniques are used to -model ROM, where the register is initialized using this syntax but is -never updated otherwise.) - -:numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17 -the add command is used to add a 1-bit wide global input signal with the name -globrst. That means that an input with that name is added to each module in the -design hierarchy and then all module instantiations are altered so that this new -signal is connected throughout the whole design hierarchy. - -.. code-block:: verilog - :caption: Implicit coding of global asynchronous resets - :name: glob_arst - - reg [7:0] a = 13, b; - initial b = 37; - -.. code-block:: verilog - :caption: `adff2dff.v` - :name: adff2dff.v - - (* techmap_celltype = "$adff" *) - module adff2dff (CLK, ARST, D, Q); - - parameter WIDTH = 1; - parameter CLK_POLARITY = 1; - parameter ARST_POLARITY = 1; - parameter ARST_VALUE = 0; - - input CLK, ARST; - input [WIDTH-1:0] D; - output reg [WIDTH-1:0] Q; - - wire [1023:0] _TECHMAP_DO_ = "proc"; - - wire _TECHMAP_FAIL_ = - !CLK_POLARITY || !ARST_POLARITY; - - always @(posedge CLK) - if (ARST) - Q <= ARST_VALUE; - else - Q <= D; - - endmodule - -In line 18 the proc command is called. But in this script the signal -name globrst is passed to the command as a global reset signal for -resetting the registers to their assigned initial values. - -Finally in line 19 the techmap command is used to replace all instances of -flip-flops with asynchronous resets with flip-flops with synchronous resets. The -map file used for this is shown in :numref:`adff2dff.v`. Note how the -techmap_celltype attribute is used in line 1 to tell the techmap command which -cells to replace in the design, how the \_TECHMAP_FAIL\_ wire in lines 15 and 16 -(which evaluates to a constant value) determines if the parameter set is -compatible with this replacement circuit, and how the \_TECHMAP_DO\_ wire in -line 13 provides a mini synthesis-script to be used to process this cell. - -.. code-block:: c - :caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled - using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a - -mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx`` - set and booted with a custom setup routine written in ARM assembler. - :name: sieve - - #include - #include - - #define BITMAP_SIZE 64 - #define OUTPORT 0x10000000 - - static uint32_t bitmap[BITMAP_SIZE/32]; - - static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); } - static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; } - static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; } - - int main() { - uint32_t i, j, k; - output(2); - for (i = 0; i < BITMAP_SIZE; i++) { - if (bitmap_get(i)) continue; - output(3+2*i); - for (j = 2*(3+2*i);; j += 3+2*i) { - if (j%2 == 0) continue; - k = (j-3)/2; - if (k >= BITMAP_SIZE) break; - bitmap_set(k); - } - } - output(0); - return 0; - } - -Verification of the Amber23 CPU -=============================== - -The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and -:numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled -with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It -successfully executed the program shown in :numref:`sieve` in the test-bench. - -For simulation the BLIF file was converted back to Verilog using `ABC`_. So this -test includes the successful transformation of the BLIF file into ABC's internal -format as well. - -.. _ABC: https://github.com/berkeley-abc/abc - -The only thing left to write about the simulation itself is that it -probably was one of the most energy inefficient and time consuming ways -of successfully calculating the first 31 primes the author has ever -conducted. - -Limitations -=========== - -At the time of this writing Yosys does not support multi-dimensional -memories, does not support writing to individual bits of array elements, -does not support initialization of arrays with $readmemb and $readmemh, -and has only limited support for tristate logic, to name just a few -limitations. - -That being said, Yosys can synthesize an overwhelming majority of -real-world Verilog RTL code. The remaining cases can usually be modified -to be compatible with Yosys quite easily. - -The various designs in yosys-bigsim are a good place to look for -examples of what is within the capabilities of Yosys. - -Conclusion -========== - -Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, -but one is to provide an easy gateway from high-level Verilog code to -low-level logic circuits. - -The command line option -S can be used to quickly synthesize Verilog -code to BLIF files without a hassle. - -With custom synthesis scripts it becomes possible to easily perform -high-level optimizations, such as re-encoding FSMs. In some extreme -cases, such as the Amber23 ARMv2 CPU, the more advanced Yosys features -can be used to change a design to fit a certain need without actually -touching the RTL code. + read_verilog softusb_navre.v + hierarchy + proc; opt; memory; opt; techmap; opt + write_blif softusb_navre.blif + + The first and last line obviously read the Verilog file and write the + BLIF file. + + The 2nd line checks the design hierarchy and instantiates parametrized + versions of the modules in the design, if necessary. In the case of this + simple design this is a no-op. However, as a general rule a synthesis + script should always contain this command as first command after reading + the input files. + + The 3rd line does most of the actual work: + + - The command opt is the Yosys' built-in optimizer. It can perform some + simple optimizations such as const-folding and removing unconnected + parts of the design. It is common practice to call opt after each + major step in the synthesis procedure. In cases where too much + optimization is not appreciated (for example when analyzing a + design), it is recommended to call clean instead of opt. + + - The command proc converts processes (Yosys' internal representation + of Verilog always- and initial-blocks) to circuits of multiplexers + and storage elements (various types of flip-flops). + + - The command memory converts Yosys' internal representations of arrays + and array accesses to multi-port block memories, and then maps this + block memories to address decoders and flip-flops, unless the option + -nomap is used, in which case the multi-port block memories stay in + the design and can then be mapped to architecture-specific memory + primitives using other commands. + + - The command techmap turns a high-level circuit with coarse grain + cells such as wide adders and multipliers to a fine-grain circuit of + simple logic primitives and single-bit storage elements. The command + does that by substituting the complex cells by circuits of simpler + cells. It is possible to provide a custom set of rules for this + process in the form of a Verilog source file, as we will see in the + next section. + + Now Yosys can be run with the filename of the synthesis script as + argument: + + .. code:: sh + + yosys softusb_navre.ys + + Now that we are using a synthesis script we can easily modify how Yosys + synthesizes the design. The first thing we should customize is the call + to the hierarchy command: + + Whenever it is known that there are no implicit blackboxes in the + design, i.e. modules that are referenced but are not defined, the + hierarchy command should be called with the -check option. This will + then cause synthesis to fail when implicit blackboxes are found in the + design. + + The 2nd thing we can improve regarding the hierarchy command is that we + can tell it the name of the top level module of the design hierarchy. It + will then automatically remove all modules that are not referenced from + this top level module. + + For many designs it is also desired to optimize the encodings for the + finite state machines (FSMs) in the design. The fsm command finds FSMs, + extracts them, performs some basic optimizations and then generate a + circuit from the extracted and optimized description. It would also be + possible to tell the fsm command to leave the FSMs in their extracted + form, so they can be further processed using custom commands. But in + this case we don't want that. + + So now we have the final synthesis script for generating a BLIF file for + the Navré CPU: + + .. code:: yoscrypt + + read_verilog softusb_navre.v + hierarchy -check -top softusb_navre + proc; opt; memory; opt; fsm; opt; techmap; opt + write_blif softusb_navre.blif + + Advanced example: The Amber23 ARMv2a CPU + ======================================== + + Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on + the Verilog code that is included in `yosys-bigsim`_. + + .. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber + + .. code-block:: yoscrypt + :caption: `amber23.ys` + :name: amber23.ys + + read_verilog a23_alu.v + read_verilog a23_barrel_shift_fpga.v + read_verilog a23_barrel_shift.v + read_verilog a23_cache.v + read_verilog a23_coprocessor.v + read_verilog a23_core.v + read_verilog a23_decode.v + read_verilog a23_execute.v + read_verilog a23_fetch.v + read_verilog a23_multiply.v + read_verilog a23_ram_register_bank.v + read_verilog a23_register_bank.v + read_verilog a23_wishbone.v + read_verilog generic_sram_byte_en.v + read_verilog generic_sram_line_en.v + hierarchy -check -top a23_core + add -global_input globrst 1 + proc -global_arst globrst + techmap -map adff2dff.v + opt; memory; opt; fsm; opt; techmap + write_blif amber23.blif + + The problem with this core is that it contains no dedicated reset logic. Instead + the coding techniques shown in :numref:`glob_arst` are used to define reset + values for the global asynchronous reset in an FPGA implementation. This design + can not be expressed in BLIF as it is. Instead we need to use a synthesis script + that transforms this form to synchronous resets that can be expressed in BLIF. + + (Note that there is no problem if this coding techniques are used to model ROM, + where the register is initialized using this syntax but is never updated + otherwise.) + + :numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17 + the add command is used to add a 1-bit wide global input signal with the name + ``globrst``. That means that an input with that name is added to each module in the + design hierarchy and then all module instantiations are altered so that this new + signal is connected throughout the whole design hierarchy. + + .. code-block:: verilog + :caption: Implicit coding of global asynchronous resets + :name: glob_arst + + reg [7:0] a = 13, b; + initial b = 37; + + .. code-block:: verilog + :caption: `adff2dff.v` + :name: adff2dff.v + + (* techmap_celltype = "$adff" *) + module adff2dff (CLK, ARST, D, Q); + + parameter WIDTH = 1; + parameter CLK_POLARITY = 1; + parameter ARST_POLARITY = 1; + parameter ARST_VALUE = 0; + + input CLK, ARST; + input [WIDTH-1:0] D; + output reg [WIDTH-1:0] Q; + + wire [1023:0] _TECHMAP_DO_ = "proc"; + + wire _TECHMAP_FAIL_ = + !CLK_POLARITY || !ARST_POLARITY; + + always @(posedge CLK) + if (ARST) + Q <= ARST_VALUE; + else + Q <= D; + + endmodule + + In line 18 the :cmd:ref:`proc` command is called. But in this script the signal + name globrst is passed to the command as a global reset signal for resetting the + registers to their assigned initial values. + + Finally in line 19 the techmap command is used to replace all instances of + flip-flops with asynchronous resets with flip-flops with synchronous resets. The + map file used for this is shown in :numref:`adff2dff.v`. Note how the + ``techmap_celltype`` attribute is used in line 1 to tell the techmap command + which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines + 15 and 16 (which evaluates to a constant value) determines if the parameter set + is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire + in line 13 provides a mini synthesis-script to be used to process this cell. + + .. code-block:: c + :caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled + using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a + -mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx`` + set and booted with a custom setup routine written in ARM assembler. + :name: sieve + + #include + #include + + #define BITMAP_SIZE 64 + #define OUTPORT 0x10000000 + + static uint32_t bitmap[BITMAP_SIZE/32]; + + static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); } + static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; } + static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; } + + int main() { + uint32_t i, j, k; + output(2); + for (i = 0; i < BITMAP_SIZE; i++) { + if (bitmap_get(i)) continue; + output(3+2*i); + for (j = 2*(3+2*i);; j += 3+2*i) { + if (j%2 == 0) continue; + k = (j-3)/2; + if (k >= BITMAP_SIZE) break; + bitmap_set(k); + } + } + output(0); + return 0; + } + + Verification of the Amber23 CPU + =============================== + + The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and + :numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled + with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It + successfully executed the program shown in :numref:`sieve` in the test-bench. + + For simulation the BLIF file was converted back to Verilog using `ABC`_. So this + test includes the successful transformation of the BLIF file into ABC's internal + format as well. + + .. _ABC: https://github.com/berkeley-abc/abc + + The only thing left to write about the simulation itself is that it probably was + one of the most energy inefficient and time consuming ways of successfully + calculating the first 31 primes the author has ever conducted. + + Limitations + =========== + + At the time of this writing Yosys does not support multi-dimensional memories, + does not support writing to individual bits of array elements, does not support + initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only + limited support for tristate logic, to name just a few limitations. + + That being said, Yosys can synthesize an overwhelming majority of real-world + Verilog RTL code. The remaining cases can usually be modified to be compatible + with Yosys quite easily. + + The various designs in yosys-bigsim are a good place to look for examples of + what is within the capabilities of Yosys. + + Conclusion + ========== + + Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one + is to provide an easy gateway from high-level Verilog code to low-level logic + circuits. + + The command line option ``-S`` can be used to quickly synthesize Verilog code to + BLIF files without a hassle. + + With custom synthesis scripts it becomes possible to easily perform high-level + optimizations, such as re-encoding FSMs. In some extreme cases, such as the + Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a + design to fit a certain need without actually touching the RTL code. diff --git a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst deleted file mode 100644 index 44819e28332..00000000000 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ /dev/null @@ -1,965 +0,0 @@ -========================================== -011: Interactive design investigation page -========================================== - -Installation and prerequisites -============================== - -This Application Note is based on the `Yosys GIT`_ `Rev. 2b90ba1`_ from -2013-12-08. The README file covers how to install Yosys. The ``show`` command -requires a working installation of `GraphViz`_ and `xdot` for generating the -actual circuit diagrams. - -.. _Yosys GIT: https://github.com/YosysHQ/yosys - -.. _Rev. 2b90ba1: https://github.com/YosysHQ/yosys/tree/2b90ba1 - -.. _GraphViz: http://www.graphviz.org/ - -.. _xdot: https://github.com/jrfonseca/xdot.py - -Overview -======== - -This application note is structured as follows: - -:ref:`intro_show` introduces the ``show`` command and explains the symbols used -in the circuit diagrams generated by it. - -:ref:`navigate` introduces additional commands used to navigate in the design, -select portions of the design, and print additional information on the elements -in the design that are not contained in the circuit diagrams. - -:ref:`poke` introduces commands to evaluate the design and solve SAT problems -within the design. - -:ref:`conclusion` concludes the document and summarizes the key points. - -.. _intro_show: - -Introduction to the show command -================================ - -.. code-block:: console - :caption: Yosys script with ``show`` commands and example design - :name: example_src - - $ cat example.ys - read_verilog example.v - show -pause - proc - show -pause - opt - show -pause - - $ cat example.v - module example(input clk, a, b, c, - output reg [1:0] y); - always @(posedge clk) - if (c) - y <= c ? a + b : 2'd0; - endmodule - -.. figure:: ../../images/011/example_out.* - :class: width-helper - :name: example_out - - Output of the three ``show`` commands from :numref:`example_src` - -The ``show`` command generates a circuit diagram for the design in its current -state. Various options can be used to change the appearance of the circuit -diagram, set the name and format for the output file, and so forth. When called -without any special options, it saves the circuit diagram in a temporary file -and launches ``xdot`` to display the diagram. Subsequent calls to show re-use the -``xdot`` instance (if still running). - -A simple circuit ----------------- - -:numref:`example_src` shows a simple synthesis script and a Verilog file that -demonstrate the usage of show in a simple setting. Note that ``show`` is called with -the ``-pause`` option, that halts execution of the Yosys script until the user -presses the Enter key. The ``show -pause`` command also allows the user to enter -an interactive shell to further investigate the circuit before continuing -synthesis. - -So this script, when executed, will show the design after each of the three -synthesis commands. The generated circuit diagrams are shown in -:numref:`example_out`. - -The first diagram (from top to bottom) shows the design directly after being -read by the Verilog front-end. Input and output ports are displayed as octagonal -shapes. Cells are displayed as rectangles with inputs on the left and outputs on -the right side. The cell labels are two lines long: The first line contains a -unique identifier for the cell and the second line contains the cell type. -Internal cell types are prefixed with a dollar sign. The Yosys manual contains a -chapter on the internal cell library used in Yosys. - -Constants are shown as ellipses with the constant value as label. The syntax -``'`` is used for for constants that are not 32-bit wide and/or -contain bits that are not 0 or 1 (i.e. ``x`` or ``z``). Ordinary 32-bit -constants are written using decimal numbers. - -Single-bit signals are shown as thin arrows pointing from the driver to the -load. Signals that are multiple bits wide are shown as think arrows. - -Finally *processes* are shown in boxes with round corners. Processes are Yosys' -internal representation of the decision-trees and synchronization events -modelled in a Verilog ``always``-block. The label reads ``PROC`` followed by a -unique identifier in the first line and contains the source code location of the -original ``always``-block in the 2nd line. Note how the multiplexer from the -``?:``-expression is represented as a ``$mux`` cell but the multiplexer from the -``if``-statement is yet still hidden within the process. - -The ``proc`` command transforms the process from the first diagram into a -multiplexer and a d-type flip-flip, which brings us to the 2nd diagram. - -The Rhombus shape to the right is a dangling wire. (Wire nodes are only shown if -they are dangling or have "public" names, for example names assigned from the -Verilog input.) Also note that the design now contains two instances of a -``BUF``-node. This are artefacts left behind by the ``proc``-command. It is -quite usual to see such artefacts after calling commands that perform changes in -the design, as most commands only care about doing the transformation in the -least complicated way, not about cleaning up after them. The next call to -``clean`` (or ``opt``, which includes ``clean`` as one of its operations) will -clean up this artefacts. This operation is so common in Yosys scripts that it -can simply be abbreviated with the ``;;`` token, which doubles as separator for -commands. Unless one wants to specifically analyze this artefacts left behind -some operations, it is therefore recommended to always call ``clean`` before -calling ``show``. - -In this script we directly call ``opt`` as next step, which finally leads us to -the 3rd diagram in :numref:`example_out`. Here we see that the ``opt`` command -not only has removed the artifacts left behind by ``proc``, but also determined -correctly that it can remove the first ``$mux`` cell without changing the -behavior of the circuit. - -.. figure:: ../../images/011/splice.* - :class: width-helper - :name: splice_dia - - Output of ``yosys -p 'proc; opt; show' splice.v`` - -.. literalinclude:: ../APPNOTE_011_Design_Investigation/splice.v - :caption: ``splice.v`` - :name: splice_src - -.. figure:: ../../images/011/splitnets_libfile.* - :class: width-helper - :name: splitnets_libfile - - Effects of ``splitnets`` command and of providing a cell library. (The - circuit is a half-adder built from simple CMOS gates.) - -Break-out boxes for signal vectors ----------------------------------- - -As has been indicated by the last example, Yosys is can manage signal vectors -(aka. multi-bit wires or buses) as native objects. This provides great -advantages when analyzing circuits that operate on wide integers. But it also -introduces some additional complexity when the individual bits of of a signal -vector are accessed. The example ``show`` in :numref:`splice_src` demonstrates -how such circuits are visualized by the ``show`` command. - -The key elements in understanding this circuit diagram are of course the boxes -with round corners and rows labeled ``: - -:``. Each of this boxes has one signal per row on one side -and a common signal for all rows on the other side. The ``:`` tuples -specify which bits of the signals are broken out and connected. So the top row -of the box connecting the signals ``a`` and ``x`` indicates that the bit 0 (i.e. -the range 0:0) from signal ``a`` is connected to bit 1 (i.e. the range 1:1) of -signal ``x``. - -Lines connecting such boxes together and lines connecting such boxes to -cell ports have a slightly different look to emphasise that they are not -actual signal wires but a necessity of the graphical representation. -This distinction seems like a technicality, until one wants to debug a -problem related to the way Yosys internally represents signal vectors, -for example when writing custom Yosys commands. - -Gate level netlists -------------------- - -Finally :numref:`splitnets_libfile` shows two common pitfalls when working with -designs mapped to a cell library. The top figure has two problems: First Yosys -did not have access to the cell library when this diagram was generated, -resulting in all cell ports defaulting to being inputs. This is why all ports -are drawn on the left side the cells are awkwardly arranged in a large column. -Secondly the two-bit vector ``y`` requires breakout-boxes for its individual -bits, resulting in an unnecessary complex diagram. - -For the 2nd diagram Yosys has been given a description of the cell library as -Verilog file containing blackbox modules. There are two ways to load cell -descriptions into Yosys: First the Verilog file for the cell library can be -passed directly to the ``show`` command using the ``-lib `` option. -Secondly it is possible to load cell libraries into the design with the -``read_verilog -lib `` command. The 2nd method has the great advantage -that the library only needs to be loaded once and can then be used in all -subsequent calls to the ``show`` command. - -In addition to that, the 2nd diagram was generated after ``splitnet -ports`` was -run on the design. This command splits all signal vectors into individual signal -bits, which is often desirable when looking at gate-level circuits. The -``-ports`` option is required to also split module ports. Per default the -command only operates on interior signals. - -Miscellaneous notes -------------------- - -Per default the ``show`` command outputs a temporary dot file and launches -``xdot`` to display it. The options ``-format``, ``-viewer`` and ``-prefix`` can -be used to change format, viewer and filename prefix. Note that the ``pdf`` and -``ps`` format are the only formats that support plotting multiple modules in one -run. - -In densely connected circuits it is sometimes hard to keep track of the -individual signal wires. For this cases it can be useful to call ``show`` with -the ``-colors `` argument, which randomly assigns colors to the nets. -The integer (> 0) is used as seed value for the random color assignments. -Sometimes it is necessary it try some values to find an assignment of colors -that looks good. - -The command ``help show`` prints a complete listing of all options supported by -the ``show`` command. - -.. _navigate: - -Navigating the design -===================== - -Plotting circuit diagrams for entire modules in the design brings us -only helps in simple cases. For complex modules the generated circuit -diagrams are just stupidly big and are no help at all. In such cases one -first has to select the relevant portions of the circuit. - -In addition to *what* to display one also needs to carefully decide *when* -to display it, with respect to the synthesis flow. In general it is a -good idea to troubleshoot a circuit in the earliest state in which a -problem can be reproduced. So if, for example, the internal state before -calling the ``techmap`` command already fails to verify, it is better to -troubleshoot the coarse-grain version of the circuit before ``techmap`` than -the gate-level circuit after ``techmap``. - -.. Note:: It is generally recommended to verify the internal state of a - design by writing it to a Verilog file using ``write_verilog -noexpr`` - and using the simulation models from ``simlib.v`` and ``simcells.v`` - from the Yosys data directory (as printed by ``yosys-config --datdir``). - -Interactive navigation ----------------------- - -.. code-block:: none - :caption: Demonstration of ``ls`` and ``cd`` using ``example.v`` from :numref:`example_src` - :name: lscd - - yosys> ls - - 1 modules: - example - - yosys> cd example - - yosys [example]> ls - - 7 wires: - $0\y[1:0] - $add$example.v:5$2_Y - a - b - c - clk - y - - 3 cells: - $add$example.v:5$2 - $procdff$7 - $procmux$5 - -.. code-block:: RTLIL - :caption: Output of ``dump \$2`` using the design from :numref:`example_src` - and :numref:`example_out` - :name: dump2 - - attribute \src "example.v:5" - cell $add $add$example.v:5$2 - parameter \A_SIGNED 0 - parameter \A_WIDTH 1 - parameter \B_SIGNED 0 - parameter \B_WIDTH 1 - parameter \Y_WIDTH 2 - connect \A \a - connect \B \b - connect \Y $add$example.v:5$2_Y - end - -Once the right state within the synthesis flow for debugging the circuit has -been identified, it is recommended to simply add the ``shell`` command to the -matching place in the synthesis script. This command will stop the synthesis at -the specified moment and go to shell mode, where the user can interactively -enter commands. - -For most cases, the shell will start with the whole design selected (i.e. when -the synthesis script does not already narrow the selection). The command ``ls`` -can now be used to create a list of all modules. The command ``cd`` can be used -to switch to one of the modules (type ``cd ..`` to switch back). Now the `ls` -command lists the objects within that module. :numref:`lscd` demonstrates this -using the design from :numref:`example_src`. - -There is a thing to note in :numref:`lscd`: We can see that the cell names from -:numref:`example_out` are just abbreviations of the actual cell names, namely -the part after the last dollar-sign. Most auto-generated names (the ones -starting with a dollar sign) are rather long and contains some additional -information on the origin of the named object. But in most cases those names can -simply be abbreviated using the last part. - -Usually all interactive work is done with one module selected using the ``cd`` -command. But it is also possible to work from the design-context (``cd ..``). In -this case all object names must be prefixed with ``/``. For example -``a*/b\*`` would refer to all objects whose names start with ``b`` from all -modules whose names start with ``a``. - -The ``dump`` command can be used to print all information about an object. For -example ``dump $2`` will print :numref:`dump2`. This can for example be useful -to determine the names of nets connected to cells, as the net-names are usually -suppressed in the circuit diagram if they are auto-generated. - -For the remainder of this document we will assume that the commands are -run from module-context and not design-context. - -Working with selections ------------------------ - -.. figure:: ../../images/011/example_03.* - :class: width-helper - :name: seladd - - Output of ``show`` after ``select $2`` or ``select t:$add`` (see also - :numref:`example_out`) - -When a module is selected using the ``cd`` command, all commands (with a few -exceptions, such as the ``read_`` and ``write_`` commands) operate only on the -selected module. This can also be useful for synthesis scripts where different -synthesis strategies should be applied to different modules in the design. - -But for most interactive work we want to further narrow the set of -selected objects. This can be done using the ``select`` command. - -For example, if the command ``select $2`` is executed, a subsequent ``show`` -command will yield the diagram shown in :numref:`seladd`. Note that the nets are -now displayed in ellipses. This indicates that they are not selected, but only -shown because the diagram contains a cell that is connected to the net. This of -course makes no difference for the circuit that is shown, but it can be a useful -information when manipulating selections. - -Objects can not only be selected by their name but also by other properties. For -example ``select t:$add`` will select all cells of type ``$add``. In this case -this is also yields the diagram shown in :numref:`seladd`. - -.. literalinclude:: ../APPNOTE_011_Design_Investigation/foobaraddsub.v - :caption: Test module for operations on selections - :name: foobaraddsub - :language: verilog - -The output of ``help select`` contains a complete syntax reference for -matching different properties. - -Many commands can operate on explicit selections. For example the command ``dump -t:$add`` will print information on all ``$add`` cells in the active module. -Whenever a command has ``[selection]`` as last argument in its usage help, this -means that it will use the engine behind the ``select`` command to evaluate -additional arguments and use the resulting selection instead of the selection -created by the last ``select`` command. - -Normally the ``select`` command overwrites a previous selection. The commands -``select -add`` and ``select -del`` can be used to add or remove objects from -the current selection. - -The command ``select -clear`` can be used to reset the selection to the default, -which is a complete selection of everything in the current module. - -Operations on selections ------------------------- - -.. literalinclude:: ../APPNOTE_011_Design_Investigation/sumprod.v - :caption: Another test module for operations on selections - :name: sumprod - :language: verilog - -.. figure:: ../../images/011/sumprod_00.* - :class: width-helper - :name: sumprod_00 - - Output of ``show a:sumstuff`` on :numref:`sumprod` - -The ``select`` command is actually much more powerful than it might seem on the -first glimpse. When it is called with multiple arguments, each argument is -evaluated and pushed separately on a stack. After all arguments have been -processed it simply creates the union of all elements on the stack. So the -following command will select all ``$add`` cells and all objects with the -``foo`` attribute set: - -.. code-block:: yoscrypt - - select t:$add a:foo - -(Try this with the design shown in :numref:`foobaraddsub`. Use the ``select --list`` command to list the current selection.) - -In many cases simply adding more and more stuff to the selection is an -ineffective way of selecting the interesting part of the design. Special -arguments can be used to combine the elements on the stack. For example -the ``%i`` arguments pops the last two elements from the stack, intersects -them, and pushes the result back on the stack. So the following command -will select all ``$add ``cells that have the ``foo`` attribute set: - -.. code-block:: yoscrypt - - select t:$add a:foo %i - -The listing in :numref:`sumprod` uses the Yosys non-standard ``{... \*}`` syntax -to set the attribute ``sumstuff`` on all cells generated by the first assign -statement. (This works on arbitrary large blocks of Verilog code an can be used -to mark portions of code for analysis.) - -Selecting ``a:sumstuff`` in this module will yield the circuit diagram shown in -:numref:`sumprod_00`. As only the cells themselves are selected, but not the -temporary wire ``$1_Y``, the two adders are shown as two disjunct parts. This -can be very useful for global signals like clock and reset signals: just -unselect them using a command such as ``select -del clk rst`` and each cell -using them will get its own net label. - -In this case however we would like to see the cells connected properly. This can -be achieved using the ``%x`` action, that broadens the selection, i.e. for each -selected wire it selects all cells connected to the wire and vice versa. So -``show a:sumstuff %x`` yields the diagram shown in :numref:`sumprod_01`. - -.. figure:: ../../images/011/sumprod_01.* - :class: width-helper - :name: sumprod_01 - - Output of ``show a:sumstuff %x`` on :numref:`sumprod` - -Selecting logic cones ---------------------- - -:numref:`sumprod_01` shows what is called the ``input cone`` of ``sum``, i.e. -all cells and signals that are used to generate the signal ``sum``. The ``%ci`` -action can be used to select the input cones of all object in the top selection -in the stack maintained by the ``select`` command. - -As the ``%x`` action, this commands broadens the selection by one "step". -But this time the operation only works against the direction of data -flow. That means, wires only select cells via output ports and cells -only select wires via input ports. - -:numref:`select_prod` show the sequence of diagrams generated by the following -commands: - -.. code-block:: yoscrypt - - show prod - show prod %ci - show prod %ci %ci - show prod %ci %ci %ci - -When selecting many levels of logic, repeating ``%ci`` over and over again can -be a bit dull. So there is a shortcut for that: the number of iterations can be -appended to the action. So for example the action ``%ci3`` is identical to -performing the ``%ci`` action three times. - -The action ``%ci\*`` performs the ``%ci`` action over and over again until it -has no effect anymore. - -.. figure:: ../../images/011/select_prod.* - :class: width-helper - :name: select_prod - - Objects selected by ``select prod \%ci...`` - -In most cases there are certain cell types and/or ports that should not be -considered for the ``%ci`` action, or we only want to follow certain cell types -and/or ports. This can be achieved using additional patterns that can be -appended to the ``%ci`` action. - -Lets consider the design from :numref:`memdemo_src`. It serves no purpose other -than being a non-trivial circuit for demonstrating some of the advanced Yosys -features. We synthesize the circuit using ``proc; opt; memory; opt`` and change -to the ``memdemo`` module with ``cd memdemo``. If we type ``show`` now we see -the diagram shown in :numref:`memdemo_00`. - -.. literalinclude:: ../APPNOTE_011_Design_Investigation/memdemo.v - :caption: Demo circuit for demonstrating some advanced Yosys features - :name: memdemo_src - :language: verilog - -.. figure:: ../../images/011/memdemo_00.* - :class: width-helper - :name: memdemo_00 - - Complete circuit diagram for the design shown in :numref:`memdemo_src` - -But maybe we are only interested in the tree of multiplexers that select the -output value. In order to get there, we would start by just showing the output -signal and its immediate predecessors: - -.. code-block:: yoscrypt - - show y %ci2 - -From this we would learn that ``y`` is driven by a ``$dff cell``, that ``y`` is -connected to the output port ``Q``, that the ``clk`` signal goes into the -``CLK`` input port of the cell, and that the data comes from a auto-generated -wire into the input ``D`` of the flip-flop cell. - -As we are not interested in the clock signal we add an additional pattern to the -``%ci`` action, that tells it to only follow ports ``Q`` and ``D`` of ``$dff`` -cells: - -.. code-block:: yoscrypt - - show y %ci2:+$dff[Q,D] - -To add a pattern we add a colon followed by the pattern to the ``%ci`` action. -The pattern it self starts with ``-`` or ``+``, indicating if it is an include -or exclude pattern, followed by an optional comma separated list of cell types, -followed by an optional comma separated list of port names in square brackets. - -Since we know that the only cell considered in this case is a ``$dff`` cell, -we could as well only specify the port names: - -.. code-block:: yoscrypt - - show y %ci2:+[Q,D] - -Or we could decide to tell the ``%ci`` action to not follow the ``CLK`` input: - -.. code-block:: yoscrypt - - show y %ci2:-[CLK] - -.. figure:: ../../images/011/memdemo_01.* - :class: width-helper - :name: memdemo_01 - - Output of ``show y \%ci2:+\$dff[Q,D] \%ci*:-\$mux[S]:-\$dff`` - -Next we would investigate the next logic level by adding another ``%ci2`` to -the command: - -.. code-block:: yoscrypt - - show y %ci2:-[CLK] %ci2 - -From this we would learn that the next cell is a ``$mux`` cell and we would -add additional pattern to narrow the selection on the path we are -interested. In the end we would end up with a command such as - -.. code-block:: yoscrypt - - show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff - -in which the first ``%ci`` jumps over the initial d-type flip-flop and the 2nd -action selects the entire input cone without going over multiplexer select -inputs and flip-flop cells. The diagram produces by this command is shown in -:numref:`memdemo_01`. - -Similar to ``%ci`` exists an action ``%co`` to select output cones that accepts -the same syntax for pattern and repetition. The ``%x`` action mentioned -previously also accepts this advanced syntax. - -This actions for traversing the circuit graph, combined with the actions for -boolean operations such as intersection (``%i``) and difference (``%d``) are -powerful tools for extracting the relevant portions of the circuit under -investigation. - -See ``help select`` for a complete list of actions available in selections. - -Storing and recalling selections --------------------------------- - -The current selection can be stored in memory with the command ``select -set -``. It can later be recalled using ``select @``. In fact, the -``@`` expression pushes the stored selection on the stack maintained by -the ``select`` command. So for example - -.. code-block:: yoscrypt - - select @foo @bar %i - -will select the intersection between the stored selections ``foo`` and ``bar``. - -In larger investigation efforts it is highly recommended to maintain a -script that sets up relevant selections, so they can easily be recalled, -for example when Yosys needs to be re-run after a design or source code -change. - -The ``history`` command can be used to list all recent interactive commands. -This feature can be useful for creating such a script from the commands -used in an interactive session. - -.. _poke: - -Advanced investigation techniques -================================= - -When working with very large modules, it is often not enough to just select the -interesting part of the module. Instead it can be useful to extract the -interesting part of the circuit into a separate module. This can for example be -useful if one wants to run a series of synthesis commands on the critical part -of the module and wants to carefully read all the debug output created by the -commands in order to spot a problem. This kind of troubleshooting is much easier -if the circuit under investigation is encapsulated in a separate module. - -:numref:`submod` shows how the ``submod`` command can be used to split the -circuit from :numref:`memdemo_src` and :numref:`memdemo_00` into its components. -The ``-name`` option is used to specify the name of the new module and also the -name of the new cell in the current module. - -.. figure:: ../../images/011/submod_dots.* - :class: width-helper - :name: submod_dots - -.. code-block:: yoscrypt - :caption: The circuit from :numref:`memdemo_src` and :numref:`memdemo_00` - broken up using ``submod`` - :name: submod - - select -set outstage y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff - select -set selstage y %ci2:+$dff[Q,D] %ci*:-$dff @outstage %d - select -set scramble mem* %ci2 %ci*:-$dff mem* %d @selstage %d - submod -name scramble @scramble - submod -name outstage @outstage - submod -name selstage @selstage - -Evaluation of combinatorial circuits ------------------------------------- - -The ``eval`` command can be used to evaluate combinatorial circuits. For example -(see :numref:`submod` for the circuit diagram of ``selstage``): - -:: - - yosys [selstage]> eval -set s2,s1 4'b1001 -set d 4'hc -show n2 -show n1 - - 1. Executing EVAL pass (evaluate the circuit given an input). - Full command line: eval -set s2,s1 4'b1001 -set d 4'hc -show n2 -show n1 - Eval result: \n2 = 2'10. - Eval result: \n1 = 2'10. - -So the ``-set`` option is used to set input values and the ``-show`` option is -used to specify the nets to evaluate. If no ``-show`` option is specified, all -selected output ports are used per default. - -If a necessary input value is not given, an error is produced. The option -``-set-undef`` can be used to instead set all unspecified input nets to undef -(``x``). - -The ``-table`` option can be used to create a truth table. For example: - -:: - - yosys [selstage]> eval -set-undef -set d[3:1] 0 -table s1,d[0] - - 10. Executing EVAL pass (evaluate the circuit given an input). - Full command line: eval -set-undef -set d[3:1] 0 -table s1,d[0] - - \s1 \d [0] | \n1 \n2 - ---- ------ | ---- ---- - 2'00 1'0 | 2'00 2'00 - 2'00 1'1 | 2'xx 2'00 - 2'01 1'0 | 2'00 2'00 - 2'01 1'1 | 2'xx 2'01 - 2'10 1'0 | 2'00 2'00 - 2'10 1'1 | 2'xx 2'10 - 2'11 1'0 | 2'00 2'00 - 2'11 1'1 | 2'xx 2'11 - - Assumed undef (x) value for the following signals: \s2 - -Note that the ``eval`` command (as well as the ``sat`` command discussed in the -next sections) does only operate on flattened modules. It can not analyze -signals that are passed through design hierarchy levels. So the ``flatten`` -command must be used on modules that instantiate other modules before this -commands can be applied. - -Solving combinatorial SAT problems ----------------------------------- - -.. literalinclude:: ../APPNOTE_011_Design_Investigation/primetest.v - :language: verilog - :caption: A simple miter circuit for testing if a number is prime. But it has - a problem (see main text and :numref:`primesat`). - :name: primetest - -.. code-block:: - :caption: Experiments with the miter circuit from :numref:`primetest`. - The first attempt of proving that 31 is prime failed because the - SAT solver found a creative way of factorizing 31 using integer - overflow. - :name: primesat - - yosys [primetest]> sat -prove ok 1 -set p 31 - - 8. Executing SAT pass (solving SAT problems in the circuit). - Full command line: sat -prove ok 1 -set p 31 - - Setting up SAT problem: - Import set-constraint: \p = 16'0000000000011111 - Final constraint equation: \p = 16'0000000000011111 - Imported 6 cells to SAT database. - Import proof-constraint: \ok = 1'1 - Final proof equation: \ok = 1'1 - - Solving problem with 2790 variables and 8241 clauses.. - SAT proof finished - model found: FAIL! - - ______ ___ ___ _ _ _ _ - (_____ \ / __) / __) (_) | | | | - _____) )___ ___ ___ _| |__ _| |__ _____ _| | _____ __| | | - | ____/ ___) _ \ / _ (_ __) (_ __|____ | | || ___ |/ _ |_| - | | | | | |_| | |_| || | | | / ___ | | || ____( (_| |_ - |_| |_| \___/ \___/ |_| |_| \_____|_|\_)_____)\____|_| - - - Signal Name Dec Hex Bin - -------------------- ---------- ---------- --------------------- - \a 15029 3ab5 0011101010110101 - \b 4099 1003 0001000000000011 - \ok 0 0 0 - \p 31 1f 0000000000011111 - - yosys [primetest]> sat -prove ok 1 -set p 31 -set a[15:8],b[15:8] 0 - - 9. Executing SAT pass (solving SAT problems in the circuit). - Full command line: sat -prove ok 1 -set p 31 -set a[15:8],b[15:8] 0 - - Setting up SAT problem: - Import set-constraint: \p = 16'0000000000011111 - Import set-constraint: { \a [15:8] \b [15:8] } = 16'0000000000000000 - Final constraint equation: { \a [15:8] \b [15:8] \p } = { 16'0000000000000000 16'0000000000011111 } - Imported 6 cells to SAT database. - Import proof-constraint: \ok = 1'1 - Final proof equation: \ok = 1'1 - - Solving problem with 2790 variables and 8257 clauses.. - SAT proof finished - no model found: SUCCESS! - - /$$$$$$ /$$$$$$$$ /$$$$$$$ - /$$__ $$ | $$_____/ | $$__ $$ - | $$ \ $$ | $$ | $$ \ $$ - | $$ | $$ | $$$$$ | $$ | $$ - | $$ | $$ | $$__/ | $$ | $$ - | $$/$$ $$ | $$ | $$ | $$ - | $$$$$$/ /$$| $$$$$$$$ /$$| $$$$$$$//$$ - \____ $$$|__/|________/|__/|_______/|__/ - \__/ - -Often the opposite of the ``eval`` command is needed, i.e. the circuits output -is given and we want to find the matching input signals. For small circuits with -only a few input bits this can be accomplished by trying all possible input -combinations, as it is done by the ``eval -table`` command. For larger circuits -however, Yosys provides the ``sat`` command that uses a `SAT`_ solver, -`MiniSAT`_, to solve this kind of problems. - -.. _SAT: http://en.wikipedia.org/wiki/Circuit_satisfiability - -.. _MiniSAT: http://minisat.se/ - -The ``sat`` command works very similar to the ``eval`` command. The main -difference is that it is now also possible to set output values and find the -corresponding input values. For Example: - -:: - - yosys [selstage]> sat -show s1,s2,d -set s1 s2 -set n2,n1 4'b1001 - - 11. Executing SAT pass (solving SAT problems in the circuit). - Full command line: sat -show s1,s2,d -set s1 s2 -set n2,n1 4'b1001 - - Setting up SAT problem: - Import set-constraint: \s1 = \s2 - Import set-constraint: { \n2 \n1 } = 4'1001 - Final constraint equation: { \n2 \n1 \s1 } = { 4'1001 \s2 } - Imported 3 cells to SAT database. - Import show expression: { \s1 \s2 \d } - - Solving problem with 81 variables and 207 clauses.. - SAT solving finished - model found: - - Signal Name Dec Hex Bin - -------------------- ---------- ---------- --------------- - \d 9 9 1001 - \s1 0 0 00 - \s2 0 0 00 - -Note that the ``sat`` command supports signal names in both arguments to the -``-set`` option. In the above example we used ``-set s1 s2`` to constraint -``s1`` and ``s2`` to be equal. When more complex constraints are needed, a -wrapper circuit must be constructed that checks the constraints and signals if -the constraint was met using an extra output port, which then can be forced to a -value using the ``-set`` option. (Such a circuit that contains the circuit under -test plus additional constraint checking circuitry is called a ``miter`` -circuit.) - -:numref:`primetest` shows a miter circuit that is supposed to be used as a prime -number test. If ``ok`` is 1 for all input values ``a`` and ``b`` for a given -``p``, then ``p`` is prime, or at least that is the idea. - -The Yosys shell session shown in :numref:`primesat` demonstrates that SAT -solvers can even find the unexpected solutions to a problem: Using integer -overflow there actually is a way of "factorizing" 31. The clean solution would -of course be to perform the test in 32 bits, for example by replacing ``p != -a*b`` in the miter with ``p != {16'd0,a}b``, or by using a temporary variable -for the 32 bit product ``a*b``. But as 31 fits well into 8 bits (and as the -purpose of this document is to show off Yosys features) we can also simply force -the upper 8 bits of ``a`` and ``b`` to zero for the ``sat`` call, as is done in -the second command in :numref:`primesat` (line 31). - -The ``-prove`` option used in this example works similar to ``-set``, but tries -to find a case in which the two arguments are not equal. If such a case is not -found, the property is proven to hold for all inputs that satisfy the other -constraints. - -It might be worth noting, that SAT solvers are not particularly efficient at -factorizing large numbers. But if a small factorization problem occurs as part -of a larger circuit problem, the Yosys SAT solver is perfectly capable of -solving it. - -Solving sequential SAT problems -------------------------------- - -.. code-block:: - :caption: Solving a sequential SAT problem in the ``memdemo`` module from :numref:`memdemo_src`. - :name: memdemo_sat - - yosys [memdemo]> sat -seq 6 -show y -show d -set-init-undef \ - -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3 - - 6. Executing SAT pass (solving SAT problems in the circuit). - Full command line: sat -seq 6 -show y -show d -set-init-undef - -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3 - - Setting up time step 1: - Final constraint equation: { } = { } - Imported 29 cells to SAT database. - - Setting up time step 2: - Final constraint equation: { } = { } - Imported 29 cells to SAT database. - - Setting up time step 3: - Final constraint equation: { } = { } - Imported 29 cells to SAT database. - - Setting up time step 4: - Import set-constraint for timestep: \y = 4'0001 - Final constraint equation: \y = 4'0001 - Imported 29 cells to SAT database. - - Setting up time step 5: - Import set-constraint for timestep: \y = 4'0010 - Final constraint equation: \y = 4'0010 - Imported 29 cells to SAT database. - - Setting up time step 6: - Import set-constraint for timestep: \y = 4'0011 - Final constraint equation: \y = 4'0011 - Imported 29 cells to SAT database. - - Setting up initial state: - Final constraint equation: { \y \s2 \s1 \mem[3] \mem[2] \mem[1] - \mem[0] } = 24'xxxxxxxxxxxxxxxxxxxxxxxx - - Import show expression: \y - Import show expression: \d - - Solving problem with 10322 variables and 27881 clauses.. - SAT model found. maximizing number of undefs. - SAT solving finished - model found: - - Time Signal Name Dec Hex Bin - ---- -------------------- ---------- ---------- --------------- - init \mem[0] -- -- xxxx - init \mem[1] -- -- xxxx - init \mem[2] -- -- xxxx - init \mem[3] -- -- xxxx - init \s1 -- -- xx - init \s2 -- -- xx - init \y -- -- xxxx - ---- -------------------- ---------- ---------- --------------- - 1 \d 0 0 0000 - 1 \y -- -- xxxx - ---- -------------------- ---------- ---------- --------------- - 2 \d 1 1 0001 - 2 \y -- -- xxxx - ---- -------------------- ---------- ---------- --------------- - 3 \d 2 2 0010 - 3 \y 0 0 0000 - ---- -------------------- ---------- ---------- --------------- - 4 \d 3 3 0011 - 4 \y 1 1 0001 - ---- -------------------- ---------- ---------- --------------- - 5 \d -- -- 001x - 5 \y 2 2 0010 - ---- -------------------- ---------- ---------- --------------- - 6 \d -- -- xxxx - 6 \y 3 3 0011 - -The SAT solver functionality in Yosys can not only be used to solve -combinatorial problems, but can also solve sequential problems. Let's consider -the entire memdemo module from :numref:`memdemo_src` and suppose we want to know -which sequence of input values for ``d`` will cause the output y to produce the -sequence 1, 2, 3 from any initial state. :numref:`memdemo_sat` show the solution -to this question, as produced by the following command: - -.. code-block:: yoscrypt - - sat -seq 6 -show y -show d -set-init-undef \ - -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3 - -The ``-seq 6`` option instructs the ``sat`` command to solve a sequential -problem in 6 time steps. (Experiments with lower number of steps have show that -at least 3 cycles are necessary to bring the circuit in a state from which the -sequence 1, 2, 3 can be produced.) - -The ``-set-init-undef`` option tells the ``sat`` command to initialize all -registers to the undef (``x``) state. The way the ``x`` state is treated in -Verilog will ensure that the solution will work for any initial state. - -The ``-max_undef`` option instructs the ``sat`` command to find a solution with -a maximum number of undefs. This way we can see clearly which inputs bits are -relevant to the solution. - -Finally the three ``-set-at`` options add constraints for the ``y`` signal to -play the 1, 2, 3 sequence, starting with time step 4. - -It is not surprising that the solution sets ``d = 0`` in the first step, as this -is the only way of setting the ``s1`` and ``s2`` registers to a known value. The -input values for the other steps are a bit harder to work out manually, but the -SAT solver finds the correct solution in an instant. - -There is much more to write about the ``sat`` command. For example, there is a -set of options that can be used to performs sequential proofs using temporal -induction :cite:p:`een2003temporal`. The command ``help sat`` can be used to -print a list of all options with short descriptions of their functions. - -.. _conclusion: - -Conclusion -========== - -Yosys provides a wide range of functions to analyze and investigate -designs. For many cases it is sufficient to simply display circuit -diagrams, maybe use some additional commands to narrow the scope of the -circuit diagrams to the interesting parts of the circuit. But some cases -require more than that. For this applications Yosys provides commands -that can be used to further inspect the behavior of the circuit, either -by evaluating which output values are generated from certain input -values (``eval``) or by evaluation which input values and initial conditions -can result in a certain behavior at the outputs (``sat``). The SAT command -can even be used to prove (or disprove) theorems regarding the circuit, -in more advanced cases with the additional help of a miter circuit. - -This features can be powerful tools for the circuit designer using Yosys -as a utility for building circuits and the software developer using -Yosys as a framework for new algorithms alike. diff --git a/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst index e9e44d1cd11..1874b014813 100644 --- a/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst +++ b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst @@ -1,333 +1,353 @@ +:orphan: + ==================================== 012: Converting Verilog to BTOR page ==================================== -Installation -============ +Abstract +======== + +Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used +to easily create complex designs from small HDL code. BTOR is a bit-precise +word-level format for model checking. It is a simple format and easy to parse. +It allows to model the model checking problem over the theory of bit-vectors +with one-dimensional arrays, thus enabling to model Verilog designs with +registers and memories. Yosys is an Open-Source Verilog synthesis tool that can +be used to convert Verilog designs with simple assertions to BTOR format. + +Download +======== + +This document was originally published in November 2013: +:download:`Converting Verilog to BTOR PDF` + +.. + Installation + ============ -Yosys written in C++ (using features from C++11) and is tested on modern Linux. -It should compile fine on most UNIX systems with a C++11 compiler. The README -file contains useful information on building Yosys and its prerequisites. + Yosys written in C++ (using features from C++11) and is tested on modern Linux. + It should compile fine on most UNIX systems with a C++11 compiler. The README + file contains useful information on building Yosys and its prerequisites. -Yosys is a large and feature-rich program with some dependencies. For this work, -we may deactivate other extra features such as TCL and ABC support in the -Makefile. + Yosys is a large and feature-rich program with some dependencies. For this work, + we may deactivate other extra features such as TCL and ABC support in the + Makefile. -This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04. + This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04. -.. _Yosys GIT: https://github.com/YosysHQ/yosys + .. _Yosys GIT: https://github.com/YosysHQ/yosys -.. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f + .. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f -Quick start -=========== + Quick start + =========== -We assume that the Verilog design is synthesizable and we also assume that the -design does not have multi-dimensional memories. As BTOR implicitly initializes -registers to zero value and memories stay uninitialized, we assume that the -Verilog design does not contain initial blocks. For more details about the BTOR -format, please refer to :cite:p:`btor`. + We assume that the Verilog design is synthesizable and we also assume that the + design does not have multi-dimensional memories. As BTOR implicitly initializes + registers to zero value and memories stay uninitialized, we assume that the + Verilog design does not contain initial blocks. For more details about the BTOR + format, please refer to :cite:p:`btor`. -We provide a shell script ``verilog2btor.sh`` which can be used to convert a -Verilog design to BTOR. The script can be found in the ``backends/btor`` -directory. The following example shows its usage: + We provide a shell script ``verilog2btor.sh`` which can be used to convert a + Verilog design to BTOR. The script can be found in the ``backends/btor`` + directory. The following example shows its usage: -.. code:: sh + .. code:: sh - verilog2btor.sh fsm.v fsm.btor test + verilog2btor.sh fsm.v fsm.btor test -The script ``verilog2btor.sh`` takes three parameters. In the above example, the -first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor`` -is the file name of BTOR output, and the third parameter ``test`` is the name of -top module in the design. + The script ``verilog2btor.sh`` takes three parameters. In the above example, the + first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor`` + is the file name of BTOR output, and the third parameter ``test`` is the name of + top module in the design. -To specify the properties (that need to be checked), we have two -options: + To specify the properties (that need to be checked), we have two + options: -- We can use the Verilog ``assert`` statement in the procedural block or module - body of the Verilog design, as shown in :numref:`specifying_property_assert`. - This is the preferred option. + - We can use the Verilog ``assert`` statement in the procedural block or module + body of the Verilog design, as shown in :numref:`specifying_property_assert`. + This is the preferred option. -- We can use a single-bit output wire, whose name starts with ``safety``. The - value of this output wire needs to be driven low when the property is met, - i.e. the solver will try to find a model that makes the safety pin go high. - This is demonstrated in :numref:`specifying_property_output`. + - We can use a single-bit output wire, whose name starts with ``safety``. The + value of this output wire needs to be driven low when the property is met, + i.e. the solver will try to find a model that makes the safety pin go high. + This is demonstrated in :numref:`specifying_property_output`. -.. code-block:: verilog - :caption: Specifying property in Verilog design with ``assert`` - :name: specifying_property_assert + .. code-block:: verilog + :caption: Specifying property in Verilog design with ``assert`` + :name: specifying_property_assert - module test(input clk, input rst, output y); + module test(input clk, input rst, output y); - reg [2:0] state; + reg [2:0] state; - always @(posedge clk) begin - if (rst || state == 3) begin - state <= 0; - end else begin - assert(state < 3); - state <= state + 1; - end - end + always @(posedge clk) begin + if (rst || state == 3) begin + state <= 0; + end else begin + assert(state < 3); + state <= state + 1; + end + end - assign y = state[2]; + assign y = state[2]; - assert property (y !== 1'b1); + assert property (y !== 1'b1); - endmodule + endmodule -.. code-block:: verilog - :caption: Specifying property in Verilog design with output wire - :name: specifying_property_output + .. code-block:: verilog + :caption: Specifying property in Verilog design with output wire + :name: specifying_property_output - module test(input clk, input rst, - output y, output safety1); + module test(input clk, input rst, + output y, output safety1); - reg [2:0] state; + reg [2:0] state; - always @(posedge clk) begin - if (rst || state == 3) - state <= 0; - else - state <= state + 1; - end + always @(posedge clk) begin + if (rst || state == 3) + state <= 0; + else + state <= state + 1; + end - assign y = state[2]; + assign y = state[2]; - assign safety1 = !(y !== 1'b1); + assign safety1 = !(y !== 1'b1); - endmodule + endmodule -We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file: + We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file: -.. _Boolector: http://fmv.jku.at/boolector/ + .. _Boolector: http://fmv.jku.at/boolector/ -.. code:: sh + .. code:: sh - $ boolector fsm.btor - unsat + $ boolector fsm.btor + unsat -We can also use `nuXmv`_, but on BTOR designs it does not support memories yet. -With the next release of nuXmv, we will be also able to verify designs with -memories. + We can also use `nuXmv`_, but on BTOR designs it does not support memories yet. + With the next release of nuXmv, we will be also able to verify designs with + memories. -.. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php + .. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php -Detailed flow -============= + Detailed flow + ============= -Yosys is able to synthesize Verilog designs up to the gate level. We are -interested in keeping registers and memories when synthesizing the design. For -this purpose, we describe a customized Yosys synthesis flow, that is also -provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows -the Yosys commands that are executed by ``verilog2btor.sh``. + Yosys is able to synthesize Verilog designs up to the gate level. We are + interested in keeping registers and memories when synthesizing the design. For + this purpose, we describe a customized Yosys synthesis flow, that is also + provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows + the Yosys commands that are executed by ``verilog2btor.sh``. -.. code-block:: yoscrypt - :caption: Synthesis Flow for BTOR with memories - :name: btor_script_memory + .. code-block:: yoscrypt + :caption: Synthesis Flow for BTOR with memories + :name: btor_script_memory - read_verilog -sv $1; - hierarchy -top $3; hierarchy -libdir $DIR; - hierarchy -check; - proc; opt; - opt_expr -mux_undef; opt; - rename -hide;;; - splice; opt; - memory_dff -wr_only; memory_collect;; - flatten;; - memory_unpack; - splitnets -driver; - setundef -zero -undriven; - opt;;; - write_btor $2; + read_verilog -sv $1; + hierarchy -top $3; hierarchy -libdir $DIR; + hierarchy -check; + proc; opt; + opt_expr -mux_undef; opt; + rename -hide;;; + splice; opt; + memory_dff -wr_only; memory_collect;; + flatten;; + memory_unpack; + splitnets -driver; + setundef -zero -undriven; + opt;;; + write_btor $2; -Here is short description of what is happening in the script line by -line: + Here is short description of what is happening in the script line by + line: -#. Reading the input file. + #. Reading the input file. -#. Setting the top module in the hierarchy and trying to read automatically the - files which are given as ``include`` in the file read in first line. + #. Setting the top module in the hierarchy and trying to read automatically the + files which are given as ``include`` in the file read in first line. -#. Checking the design hierarchy. + #. Checking the design hierarchy. -#. Converting processes to multiplexers (muxs) and flip-flops. + #. Converting processes to multiplexers (muxs) and flip-flops. -#. Removing undef signals from muxs. + #. Removing undef signals from muxs. -#. Hiding all signal names that are not used as module ports. + #. Hiding all signal names that are not used as module ports. -#. Explicit type conversion, by introducing slice and concat cells in the - circuit. + #. Explicit type conversion, by introducing slice and concat cells in the + circuit. -#. Converting write memories to synchronous memories, and collecting the - memories to multi-port memories. + #. Converting write memories to synchronous memories, and collecting the + memories to multi-port memories. -#. Flattening the design to get only one module. + #. Flattening the design to get only one module. -#. Separating read and write memories. + #. Separating read and write memories. -#. Splitting the signals that are partially assigned + #. Splitting the signals that are partially assigned -#. Setting undef to zero value. + #. Setting undef to zero value. -#. Final optimization pass. + #. Final optimization pass. -#. Writing BTOR file. + #. Writing BTOR file. -For detailed description of the commands mentioned above, please refer -to the Yosys documentation, or run ``yosys -h ``. - -The script presented earlier can be easily modified to have a BTOR file that -does not contain memories. This is done by removing the line number 8 and 10, -and introduces a new command ``memory`` at line number 8. -:numref:`btor_script_without_memory` shows the modified Yosys script file: - -.. code-block:: sh - :caption: Synthesis Flow for BTOR without memories - :name: btor_script_without_memory - - read_verilog -sv $1; - hierarchy -top $3; hierarchy -libdir $DIR; - hierarchy -check; - proc; opt; - opt_expr -mux_undef; opt; - rename -hide;;; - splice; opt; - memory;; - flatten;; - splitnets -driver; - setundef -zero -undriven; - opt;;; - write_btor $2; - -Example -======= - -Here is an example Verilog design that we want to convert to BTOR: - -.. code-block:: verilog - :caption: Example - Verilog Design - :name: example_verilog - - module array(input clk); - - reg [7:0] counter; - reg [7:0] mem [7:0]; - - always @(posedge clk) begin - counter <= counter + 8'd1; - mem[counter] <= counter; - end - - assert property (!(counter > 8'd0) || - mem[counter - 8'd1] == counter - 8'd1); - - endmodule - -The generated BTOR file that contain memories, using the script shown in -:numref:`btor_memory`: - -.. code-block:: - :caption: Example - Converted BTOR with memory - :name: btor_memory - - 1 var 1 clk - 2 array 8 3 - 3 var 8 $auto$rename.cc:150:execute$20 - 4 const 8 00000001 - 5 sub 8 3 4 - 6 slice 3 5 2 0 - 7 read 8 2 6 - 8 slice 3 3 2 0 - 9 add 8 3 4 - 10 const 8 00000000 - 11 ugt 1 3 10 - 12 not 1 11 - 13 const 8 11111111 - 14 slice 1 13 0 0 - 15 one 1 - 16 eq 1 1 15 - 17 and 1 16 14 - 18 write 8 3 2 8 3 - 19 acond 8 3 17 18 2 - 20 anext 8 3 2 19 - 21 eq 1 7 5 - 22 or 1 12 21 - 23 const 1 1 - 24 one 1 - 25 eq 1 23 24 - 26 cond 1 25 22 24 - 27 root 1 -26 - 28 cond 8 1 9 3 - 29 next 8 3 28 - -And the BTOR file obtained by the script shown in -:numref:`btor_without_memory`, which expands the memory into individual -elements: - -.. code-block:: - :caption: Example - Converted BTOR with memory - :name: btor_without_memory - - 1 var 1 clk - 2 var 8 mem[0] - 3 var 8 $auto$rename.cc:150:execute$20 - 4 slice 3 3 2 0 - 5 slice 1 4 0 0 - 6 not 1 5 - 7 slice 1 4 1 1 - 8 not 1 7 - 9 slice 1 4 2 2 - 10 not 1 9 - 11 and 1 8 10 - 12 and 1 6 11 - 13 cond 8 12 3 2 - 14 cond 8 1 13 2 - 15 next 8 2 14 - 16 const 8 00000001 - 17 add 8 3 16 - 18 const 8 00000000 - 19 ugt 1 3 18 - 20 not 1 19 - 21 var 8 mem[2] - 22 and 1 7 10 - 23 and 1 6 22 - 24 cond 8 23 3 21 - 25 cond 8 1 24 21 - 26 next 8 21 25 - 27 sub 8 3 16 - - ... - - 54 cond 1 53 50 52 - 55 root 1 -54 - - ... - - 77 cond 8 76 3 44 - 78 cond 8 1 77 44 - 79 next 8 44 78 - -Limitations -=========== - -BTOR does not support initialization of memories and registers, i.e. they are -implicitly initialized to value zero, so the initial block for memories need to -be removed when converting to BTOR. It should also be kept in consideration that -BTOR does not support the ``x`` or ``z`` values of Verilog. - -Another thing to bear in mind is that Yosys will convert multi-dimensional -memories to one-dimensional memories and address decoders. Therefore -out-of-bounds memory accesses can yield unexpected results. - -Conclusion -========== - -Using the described flow, we can use Yosys to generate word-level verification -benchmarks with or without memories from Verilog designs. - -.. [1] - Newer version of Boolector do not support sequential models. - Boolector 1.4.1 can be built with picosat-951. Newer versions of - picosat have an incompatible API. + For detailed description of the commands mentioned above, please refer + to the Yosys documentation, or run ``yosys -h ``. + + The script presented earlier can be easily modified to have a BTOR file that + does not contain memories. This is done by removing the line number 8 and 10, + and introduces a new command :cmd:ref:`memory` at line number 8. + :numref:`btor_script_without_memory` shows the modified Yosys script file: + + .. code-block:: sh + :caption: Synthesis Flow for BTOR without memories + :name: btor_script_without_memory + + read_verilog -sv $1; + hierarchy -top $3; hierarchy -libdir $DIR; + hierarchy -check; + proc; opt; + opt_expr -mux_undef; opt; + rename -hide;;; + splice; opt; + memory;; + flatten;; + splitnets -driver; + setundef -zero -undriven; + opt;;; + write_btor $2; + + Example + ======= + + Here is an example Verilog design that we want to convert to BTOR: + + .. code-block:: verilog + :caption: Example - Verilog Design + :name: example_verilog + + module array(input clk); + + reg [7:0] counter; + reg [7:0] mem [7:0]; + + always @(posedge clk) begin + counter <= counter + 8'd1; + mem[counter] <= counter; + end + + assert property (!(counter > 8'd0) || + mem[counter - 8'd1] == counter - 8'd1); + + endmodule + + The generated BTOR file that contain memories, using the script shown in + :numref:`btor_memory`: + + .. code-block:: + :caption: Example - Converted BTOR with memory + :name: btor_memory + + 1 var 1 clk + 2 array 8 3 + 3 var 8 $auto$rename.cc:150:execute$20 + 4 const 8 00000001 + 5 sub 8 3 4 + 6 slice 3 5 2 0 + 7 read 8 2 6 + 8 slice 3 3 2 0 + 9 add 8 3 4 + 10 const 8 00000000 + 11 ugt 1 3 10 + 12 not 1 11 + 13 const 8 11111111 + 14 slice 1 13 0 0 + 15 one 1 + 16 eq 1 1 15 + 17 and 1 16 14 + 18 write 8 3 2 8 3 + 19 acond 8 3 17 18 2 + 20 anext 8 3 2 19 + 21 eq 1 7 5 + 22 or 1 12 21 + 23 const 1 1 + 24 one 1 + 25 eq 1 23 24 + 26 cond 1 25 22 24 + 27 root 1 -26 + 28 cond 8 1 9 3 + 29 next 8 3 28 + + And the BTOR file obtained by the script shown in + :numref:`btor_without_memory`, which expands the memory into individual + elements: + + .. code-block:: + :caption: Example - Converted BTOR with memory + :name: btor_without_memory + + 1 var 1 clk + 2 var 8 mem[0] + 3 var 8 $auto$rename.cc:150:execute$20 + 4 slice 3 3 2 0 + 5 slice 1 4 0 0 + 6 not 1 5 + 7 slice 1 4 1 1 + 8 not 1 7 + 9 slice 1 4 2 2 + 10 not 1 9 + 11 and 1 8 10 + 12 and 1 6 11 + 13 cond 8 12 3 2 + 14 cond 8 1 13 2 + 15 next 8 2 14 + 16 const 8 00000001 + 17 add 8 3 16 + 18 const 8 00000000 + 19 ugt 1 3 18 + 20 not 1 19 + 21 var 8 mem[2] + 22 and 1 7 10 + 23 and 1 6 22 + 24 cond 8 23 3 21 + 25 cond 8 1 24 21 + 26 next 8 21 25 + 27 sub 8 3 16 + + ... + + 54 cond 1 53 50 52 + 55 root 1 -54 + + ... + + 77 cond 8 76 3 44 + 78 cond 8 1 77 44 + 79 next 8 44 78 + + Limitations + =========== + + BTOR does not support initialization of memories and registers, i.e. they are + implicitly initialized to value zero, so the initial block for memories need to + be removed when converting to BTOR. It should also be kept in consideration that + BTOR does not support the ``x`` or ``z`` values of Verilog. + + Another thing to bear in mind is that Yosys will convert multi-dimensional + memories to one-dimensional memories and address decoders. Therefore + out-of-bounds memory accesses can yield unexpected results. + + Conclusion + ========== + + Using the described flow, we can use Yosys to generate word-level verification + benchmarks with or without memories from Verilog designs. + + .. [1] + Newer version of Boolector do not support sequential models. + Boolector 1.4.1 can be built with picosat-951. Newer versions of + picosat have an incompatible API. diff --git a/docs/source/appendix/CHAPTER_Auxlibs.rst b/docs/source/appendix/CHAPTER_Auxlibs.rst deleted file mode 100644 index 361f00e025b..00000000000 --- a/docs/source/appendix/CHAPTER_Auxlibs.rst +++ /dev/null @@ -1,42 +0,0 @@ -Auxiliary libraries -=================== - -The Yosys source distribution contains some auxiliary libraries that are bundled -with Yosys. - -SHA1 ----- - -The files in ``libs/sha1/`` provide a public domain SHA1 implementation written -by Steve Reid, Bruce Guenter, and Volker Grabsch. It is used for generating -unique names when specializing parameterized modules. - -BigInt ------- - -The files in ``libs/bigint/`` provide a library for performing arithmetic with -arbitrary length integers. It is written by Matt McCutchen. - -The BigInt library is used for evaluating constant expressions, e.g. using the -ConstEval class provided in kernel/consteval.h. - -See also: http://mattmccutchen.net/bigint/ - -.. _sec:SubCircuit: - -SubCircuit ----------- - -The files in ``libs/subcircuit`` provide a library for solving the subcircuit -isomorphism problem. It is written by C. Wolf and based on the Ullmann Subgraph -Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the -extract pass (see :doc:`../cmd/extract`). - -ezSAT ------ - -The files in ``libs/ezsat`` provide a library for simplifying generating CNF -formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT -library is written by C. Wolf. It is used by the sat pass (see -:doc:`../cmd/sat`). - diff --git a/docs/source/appendix/CHAPTER_Auxprogs.rst b/docs/source/appendix/CHAPTER_Auxprogs.rst deleted file mode 100644 index e4f6f62cfb6..00000000000 --- a/docs/source/appendix/CHAPTER_Auxprogs.rst +++ /dev/null @@ -1,29 +0,0 @@ -Auxiliary programs -================== - -Besides the main yosys executable, the Yosys distribution contains a set of -additional helper programs. - -yosys-config ------------- - -The yosys-config tool (an auto-generated shell-script) can be used to query -compiler options and other information needed for building loadable modules for -Yosys. See Sec. \ :numref:`chapter:prog` for details. - -.. _sec:filterlib: - -yosys-filterlib ---------------- - -The yosys-filterlib tool is a small utility that can be used to strip or extract -information from a Liberty file. See :numref:`Sec. %s ` for -details. - -yosys-abc ---------- - -This is a fork of ABC with a small set of custom modifications that have not yet -been accepted upstream. Not all versions of Yosys work with all versions of ABC. -So Yosys comes with its own yosys-abc to avoid compatibility issues between the -two. diff --git a/docs/source/appendix/CHAPTER_StateOfTheArt.rst b/docs/source/appendix/CHAPTER_StateOfTheArt.rst deleted file mode 100644 index 894d0fbbe2b..00000000000 --- a/docs/source/appendix/CHAPTER_StateOfTheArt.rst +++ /dev/null @@ -1,410 +0,0 @@ -.. _chapter:sota: - -Evaluation of other OSS Verilog Synthesis Tools -=============================================== - -In this appendix [1]_ the existing FOSS Verilog synthesis tools [2]_ are -evaluated. Extremely limited or application specific tools (e.g. pure -Verilog Netlist parsers) as well as Verilog simulators are not included. -These existing solutions are tested using a set of representative -Verilog code snippets. It is shown that no existing FOSS tool implements -even close to a sufficient subset of Verilog to be usable as synthesis -tool for a wide range existing Verilog code. - -The packages evaluated are: - -- Icarus Verilog [3]_ - -- Verilog-to-Routing (VTR) / Odin-II - :cite:p:`vtr2012}`:raw-latex:`\cite{Odin` - -- HDL Analyzer and Netlist Architect (HANA) - -- Verilog front-end to VIS (vl2mv) :cite:p:`Cheng93vl2mv:a` - -In each of the following sections Verilog modules that test a certain -Verilog language feature are presented and the support for these -features is tested in all the tools mentioned above. It is evaluated -whether the tools under test successfully generate netlists for the -Verilog input and whether these netlists match the simulation behavior -of the designs using testbenches. - -All test cases are verified to be synthesizeable using Xilinx XST from -the Xilinx WebPACK suite. - -Trivial features such as support for simple structural Verilog are not -explicitly tested. - -Vl2mv and Odin-II generate output in the BLIF (Berkeley Logic -Interchange Format) and BLIF-MV (an extended version of BLIF) formats -respectively. ABC is used to convert this output to Verilog for -verification using testbenches. - -Icarus Verilog generates EDIF (Electronic Design Interchange Format) -output utilizing LPM (Library of Parameterized Modules) cells. The EDIF -files are converted to Verilog using edif2ngd and netgen from Xilinx -WebPACK. A hand-written implementation of the LPM cells utilized by the -generated netlists is used for verification. - -Following these functional tests, a quick analysis of the extensibility -of the tools under test is provided in a separate section. - -The last section of this chapter finally concludes these series of -evaluations with a summary of the results. - -.. code:: verilog - :number-lines: - - module uut_always01(clock, - reset, count); - - input clock, reset; - output [3:0] count; - reg [3:0] count; - - always @(posedge clock) - count <= reset ? - 0 : count + 1; - - - - endmodule - -.. code:: verilog - - module uut_always02(clock, - reset, count); - - input clock, reset; - output [3:0] count; - reg [3:0] count; - - always @(posedge clock) begin - count <= count + 1; - if (reset) - count <= 0; - end - - endmodule - -[fig:StateOfTheArt_always12] - -.. code:: verilog - :number-lines: - - module uut_always03(clock, in1, in2, in3, in4, in5, in6, in7, - out1, out2, out3); - - input clock, in1, in2, in3, in4, in5, in6, in7; - output out1, out2, out3; - reg out1, out2, out3; - - always @(posedge clock) begin - out1 = in1; - if (in2) - out1 = !out1; - out2 <= out1; - if (in3) - out2 <= out2; - if (in4) - if (in5) - out3 <= in6; - else - out3 <= in7; - out1 = out1 ^ out2; - end - - endmodule - -[fig:StateOfTheArt_always3] - -.. _sec:blocking_nonblocking: - -Always blocks and blocking vs. nonblocking assignments ------------------------------------------------------- - -The "always"-block is one of the most fundamental non-trivial Verilog -language features. It can be used to model a combinatorial path (with -optional registers on the outputs) in a way that mimics a regular -programming language. - -Within an always block, if- and case-statements can be used to model -multiplexers. Blocking assignments (:math:`=`) and nonblocking -assignments (:math:`<=`) are used to populate the leaf-nodes of these -multiplexer trees. Unassigned leaf-nodes default to feedback paths that -cause the output register to hold the previous value. More advanced -synthesis tools often convert these feedback paths to register enable -signals or even generate circuits with clock gating. - -Registers assigned with nonblocking assignments (:math:`<=`) behave -differently from variables in regular programming languages: In a -simulation they are not updated immediately after being assigned. -Instead the right-hand sides are evaluated and the results stored in -temporary memory locations. After all pending updates have been prepared -in this way they are executed, thus yielding semi-parallel execution of -all nonblocking assignments. - -For synthesis this means that every occurrence of that register in an -expression addresses the output port of the corresponding register -regardless of the question whether the register has been assigned a new -value in an earlier command in the same always block. Therefore with -nonblocking assignments the order of the assignments has no effect on -the resulting circuit as long as the left-hand sides of the assignments -are unique. - -The three example codes in -:numref:`Fig. %s ` -and :numref:`Fig. %s ` -use all these features and can thus be used to test the synthesis tools -capabilities to synthesize always blocks correctly. - -The first example is only using the most fundamental Verilog features. -All tools under test were able to successfully synthesize this design. - -.. code:: verilog - :number-lines: - - module uut_arrays01(clock, we, addr, wr_data, rd_data); - - input clock, we; - input [3:0] addr, wr_data; - output [3:0] rd_data; - reg [3:0] rd_data; - - reg [3:0] memory [15:0]; - - always @(posedge clock) begin - if (we) - memory[addr] <= wr_data; - rd_data <= memory[addr]; - end - - endmodule - -[fig:StateOfTheArt_arrays] - -The 2nd example is functionally identical to the 1st one but is using an -if-statement inside the always block. Odin-II fails to synthesize it and -instead produces the following error message: - -:: - - ERROR: (File: always02.v) (Line number: 13) - You've defined the driver "count~0" twice - -Vl2mv does not produce an error message but outputs an invalid synthesis -result that is not using the reset input at all. - -Icarus Verilog also doesn't produce an error message but generates an -invalid output for this 2nd example. The code generated by Icarus -Verilog only implements the reset path for the count register, -effectively setting the output to constant 0. - -So of all tools under test only HANA was able to create correct -synthesis results for the 2nd example. - -The 3rd example is using blocking and nonblocking assignments and many -if statements. Odin also fails to synthesize this example: - -:: - - ERROR: (File: always03.v) (Line number: 8) - ODIN doesn't handle blocking statements in Sequential blocks - -HANA, Icarus Verilog and vl2mv create invalid synthesis results for the -3rd example. - -So unfortunately none of the tools under test provide a complete and -correct implementation of blocking and nonblocking assignments. - -Arrays for memory modelling ---------------------------- - -Verilog arrays are part of the synthesizeable subset of Verilog and are -commonly used to model addressable memory. The Verilog code in -:numref:`Fig. %s ` -demonstrates this by implementing a single port memory. - -For this design HANA, vl2m and ODIN-II generate error messages -indicating that arrays are not supported. - -.. code:: verilog - :number-lines: - - module uut_forgen01(a, y); - - input [4:0] a; - output y; - - integer i, j; - reg [31:0] lut; - - initial begin - for (i = 0; i < 32; i = i+1) begin - lut[i] = i > 1; - for (j = 2; j*j <= i; j = j+1) - if (i % j == 0) - lut[i] = 0; - end - end - - assign y = lut[a]; - - endmodule - -[fig:StateOfTheArt_for] - -Icarus Verilog produces an invalid output that is using the address only -for reads. Instead of using the address input for writes, the generated -design simply loads the data to all memory locations whenever the -write-enable input is active, effectively turning the design into a -single 4-bit D-Flip-Flop with enable input. - -As all tools under test already fail this simple test, there is nothing -to gain by continuing tests on this aspect of Verilog synthesis such as -synthesis of dual port memories, correct handling of write collisions, -and so forth. - -.. code:: verilog - :number-lines: - - module uut_forgen02(a, b, cin, y, cout); - - parameter WIDTH = 8; - - input [WIDTH-1:0] a, b; - input cin; - - output [WIDTH-1:0] y; - output cout; - - genvar i; - wire [WIDTH-1:0] carry; - - generate - for (i = 0; i < WIDTH; i=i+1) begin:adder - wire [2:0] D; - assign D[1:0] = { a[i], b[i] }; - if (i == 0) begin:chain - assign D[2] = cin; - end else begin:chain - assign D[2] = carry[i-1]; - end - assign y[i] = ^D; - assign carry[i] = &D[1:0] | (^D[1:0] & D[2]); - end - endgenerate - - assign cout = carry[WIDTH-1]; - - endmodule - -[fig:StateOfTheArt_gen] - -For-loops and generate blocks ------------------------------ - -For-loops and generate blocks are more advanced Verilog features. These -features allow the circuit designer to add program code to her design -that is evaluated during synthesis to generate (parts of) the circuits -description; something that could only be done using a code generator -otherwise. - -For-loops are only allowed in synthesizeable Verilog if they can be -completely unrolled. Then they can be a powerful tool to generate array -logic or static lookup tables. The code in -:numref:`Fig. %s ` generates a -circuit that tests a 5 bit value for being a prime number using a static -lookup table. - -Generate blocks can be used to model array logic in complex parametric -designs. The code in -:numref:`Fig. %s ` implements a -ripple-carry adder with parametric width from simple assign-statements -and logic operations using a Verilog generate block. - -All tools under test failed to synthesize both test cases. HANA creates -invalid output in both cases. Icarus Verilog creates invalid output for -the first test and fails with an error for the second case. The other -two tools fail with error messages for both tests. - -Extensibility -------------- - -This section briefly discusses the extensibility of the tools under test -and their internal data- and control-flow. As all tools under test -already failed to synthesize simple Verilog always-blocks correctly, not -much resources have been spent on evaluating the extensibility of these -tools and therefore only a very brief discussion of the topic is -provided here. - -HANA synthesizes for a built-in library of standard cells using two -passes over an AST representation of the Verilog input. This approach -executes fast but limits the extensibility as everything happens in only -two comparable complex AST walks and there is no universal intermediate -representation that is flexible enough to be used in arbitrary -optimizations. - -Odin-II and vl2m are both front ends to existing synthesis flows. As -such they only try to quickly convert the Verilog input into the -internal representation of their respective flows (BLIF). So -extensibility is less of an issue here as potential extensions would -likely be implemented in other components of the flow. - -Icarus Verilog is clearly designed to be a simulation tool rather than a -synthesis tool. The synthesis part of Icarus Verilog is an ad-hoc add-on -to Icarus Verilog that aims at converting an internal representation -that is meant for generation of a virtual machine based simulation code -to netlists. - -Summary and Outlook -------------------- - -Table \ :numref:`tab:StateOfTheArt_sum` summarizes -the tests performed. Clearly none of the tools under test make a serious -attempt at providing a feature-complete implementation of Verilog. It -can be argued that Odin-II performed best in the test as it never -generated incorrect code but instead produced error messages indicating -that unsupported Verilog features where used in the Verilog input. - -In conclusion, to the best knowledge of the author, there is no FOSS -Verilog synthesis tool other than Yosys that is anywhere near feature -completeness and therefore there is no other candidate for a generic -Verilog front end and/or synthesis framework to be used as a basis for -custom synthesis tools. - -Yosys could also replace vl2m and/or Odin-II in their respective flows -or function as a pre-compiler that can translate full-featured Verilog -code to the simple subset of Verilog that is understood by vl2m and -Odin-II. - -Yosys is designed for extensibility. It can be used as-is to synthesize -Verilog code to netlists, but its main purpose is to be used as basis -for custom tools. Yosys is structured in a language dependent Verilog -front end and language independent synthesis code (which is in itself -structured in independent passes). This architecture will simplify -implementing additional HDL front ends and/or additional synthesis -passes. - -Chapter \ :numref:`` contains a more detailed -evaluation of Yosys using real-world designs that are far out of reach -for any of the other tools discussed in this appendix. - -…passed 2em …produced error 2em :math:`\skull` …incorrect output - -[tab:StateOfTheArt_sum] - -.. [1] - This appendix is an updated version of an unpublished student - research paper. :cite:p:`VerilogFossEval` - -.. [2] - To the author's best knowledge, all relevant tools that existed at - the time of this writing are included. But as there is no formal - channel through which such tools are published it is hard to give any - guarantees in that matter. - -.. [3] - Icarus Verilog is mainly a simulation tool but also supported - synthesis up to version 0.8. Therefore version 0.8.7 is used for this - evaluation.) diff --git a/docs/source/appendix/auxlibs.rst b/docs/source/appendix/auxlibs.rst new file mode 100644 index 00000000000..321cb52c4d1 --- /dev/null +++ b/docs/source/appendix/auxlibs.rst @@ -0,0 +1,81 @@ +Auxiliary libraries +=================== + +The Yosys source distribution contains some auxiliary libraries that are +compiled into Yosys and can be used in plugins. + +BigInt +------ + +The files in ``libs/bigint/`` provide a library for performing arithmetic with +arbitrary length integers. It is written by Matt McCutchen. + +The BigInt library is used for evaluating constant expressions, e.g. using the +ConstEval class provided in kernel/consteval.h. + +See also: http://mattmccutchen.net/bigint/ + +dlfcn-win32 +----------- + +The ``dlfcn`` library enables runtime loading of plugins without requiring +recompilation of Yosys. The files in ``libs/dlfcn-win32`` provide an +implementation of ``dlfcn`` for Windows. + +See also: https://github.com/dlfcn-win32/dlfcn-win32 + +ezSAT +----- + +The files in ``libs/ezsat`` provide a library for simplifying generating CNF +formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT +library is written by C. Wolf. It is used by the :cmd:ref:`sat` pass (see +:doc:`/cmd/sat`). + +fst +--- + +``libfst`` files from `gtkwave`_ are included in ``libs/fst`` to support +reading/writing signal traces from/to the GTKWave developed FST format. This is +primarily used in the :cmd:ref:`sim` command. + +.. _gtkwave: https://github.com/gtkwave/gtkwave + +json11 +------ + +For reading/writing designs from/to JSON, :cmd:ref:`read_json` and +:cmd:ref:`write_json` should be used. For everything else there is the `json11 +library`_: + + json11 is a tiny JSON library for C++11, providing JSON parsing and + serialization. + +This library is used for outputting machine-readable statistics (:cmd:ref:`stat` +with ``-json`` flag), using the RPC frontend (:cmd:ref:`connect_rpc`), and the +yosys-witness ``yw`` format. + +.. _json11 library: https://github.com/dropbox/json11 + +MiniSAT +------- + +The files in ``libs/minisat`` provide a high-performance SAT solver, used by the +:cmd:ref:`sat` command. + +SHA1 +---- + +The files in ``libs/sha1/`` provide a public domain SHA1 implementation written +by Steve Reid, Bruce Guenter, and Volker Grabsch. It is used for generating +unique names when specializing parameterized modules. + +.. _sec:SubCircuit: + +SubCircuit +---------- + +The files in ``libs/subcircuit`` provide a library for solving the subcircuit +isomorphism problem. It is written by C. Wolf and based on the Ullmann Subgraph +Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the +extract pass (see :doc:`../cmd/extract`). diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst new file mode 100644 index 00000000000..b6defbe802e --- /dev/null +++ b/docs/source/appendix/auxprogs.rst @@ -0,0 +1,63 @@ +Auxiliary programs +================== + +Besides the main yosys executable, the Yosys distribution contains a set of +additional helper programs. + +yosys-config +------------ + +The ``yosys-config`` tool (an auto-generated shell-script) can be used to query +compiler options and other information needed for building loadable modules for +Yosys. See :doc:`/yosys_internals/extending_yosys/extensions` for details. + +.. literalinclude:: /temp/yosys-config + :start-at: Usage + +.. _sec:filterlib: + +yosys-filterlib +--------------- + +.. todo:: how does a filterlib rules-file work? + +The ``yosys-filterlib`` tool is a small utility that can be used to strip or +extract information from a Liberty file. This can be useful for removing +sensitive or proprietary information such as timing or other trade secrets. + +.. literalinclude:: /temp/yosys-filterlib + :start-at: Usage + +yosys-abc +--------- + +This is a fork of ABC with a small set of custom modifications that have not yet +been accepted upstream. Not all versions of Yosys work with all versions of ABC. +So Yosys comes with its own yosys-abc to avoid compatibility issues between the +two. + +.. literalinclude:: /temp/yosys-abc + :start-at: usage + :end-before: UC Berkeley + +yosys-smtbmc +------------ + +The ``yosys-smtbmc`` tool is a utility used by SBY for interacting with smt +solvers. + +.. literalinclude:: /temp/yosys-smtbmc + +yosys-witness +------------- + +``yosys-witness`` is a new tool to inspect and convert yosys witness traces. +This is used in SBY and SCY for producing traces in a consistent format +independent of the solver. + +.. literalinclude:: /temp/yosys-witness + :start-at: Usage + +.. note:: ``yosys-witness`` requires `click`_ Python package for use. + +.. _click: https://pypi.org/project/click/ diff --git a/docs/source/appendix/env_vars.rst b/docs/source/appendix/env_vars.rst new file mode 100644 index 00000000000..26cc37c8133 --- /dev/null +++ b/docs/source/appendix/env_vars.rst @@ -0,0 +1,31 @@ +Yosys environment variables +=========================== + +``HOME`` + Yosys command history is stored in :file:`$HOME/.yosys_history`. Graphics + (from :cmd:ref:`show` and :cmd:ref:`viz` commands) will output to this + directory by default. This environment variable is also used in some cases + for resolving filenames with :file:`~`. + +``PATH`` + May be used in OpenBSD builds for finding the location of Yosys executable. + +``TMPDIR`` + Used for storing temporary files. + +``ABC`` + When compiling Yosys with out-of-tree ABC using :makevar:`ABCEXTERNAL`, this + variable can be used to override the external ABC executable. + +``YOSYS_NOVERIFIC`` + If Yosys was built with Verific, this environment variable can be used to + temporarily disable Verific support. + +``YOSYS_COVER_DIR`` and ``YOSYS_COVER_FILE`` + When using code coverage, these environment variables control the output file + name/location. + +``YOSYS_ABORT_ON_LOG_ERROR`` + Can be used for debugging Yosys internals. Setting it to 1 causes abort() to + be called when Yosys terminates with an error message. + diff --git a/docs/source/CHAPTER_Basics.rst b/docs/source/appendix/primer.rst similarity index 97% rename from docs/source/CHAPTER_Basics.rst rename to docs/source/appendix/primer.rst index 31230101a17..101723e32cb 100644 --- a/docs/source/CHAPTER_Basics.rst +++ b/docs/source/appendix/primer.rst @@ -3,8 +3,8 @@ .. _chapter:basics: -Basic principles -================ +A primer on digital circuit synthesis +===================================== This chapter contains a short introduction to the basic principles of digital circuit synthesis. @@ -23,7 +23,7 @@ circuit to a functionally equivalent low-level representation of a circuit. :numref:`Figure %s ` lists the different levels of abstraction and how they relate to different kinds of synthesis. -.. figure:: ../images/basics_abstractions.* +.. figure:: /_images/primer/basics_abstractions.* :class: width-helper :name: fig:Basics_abstractions @@ -161,7 +161,7 @@ At the logical gate level the design is represented by a netlist that uses only cells from a small number of single-bit cells, such as basic logic gates (AND, OR, NOT, XOR, etc.) and registers (usually D-Type Flip-flops). -A number of netlist formats exists that can be used on this level, e.g. the +A number of netlist formats exists that can be used on this level, e.g. the Electronic Design Interchange Format (EDIF), but for ease of simulation often a HDL netlist is used. The latter is a HDL file (Verilog or VHDL) that only uses the most basic language constructs for instantiation and connecting of cells. @@ -172,7 +172,7 @@ good) mapping of the logic gate netlist to an equivalent netlist of physically available gate types. The simplest approach to logic synthesis is two-level logic synthesis, where a -logic function is converted into a sum-of-products representation, e.g. using a +logic function is converted into a sum-of-products representation, e.g. using a Karnaugh map. This is a simple approach, but has exponential worst-case effort and cannot make efficient use of physical gates other than AND/NAND-, OR/NOR- and NOT-Gates. @@ -196,7 +196,7 @@ Physical gate level On the physical gate level only gates are used that are physically available on the target architecture. In some cases this may only be NAND, NOR and NOT gates as well as D-Type registers. In other cases this might include cells that are -more complex than the cells used at the logical gate level (e.g. complete +more complex than the cells used at the logical gate level (e.g. complete half-adders). In the case of an FPGA-based design the physical gate level representation is a netlist of LUTs with optional output registers, as these are the basic building blocks of FPGA logic cells. @@ -345,7 +345,7 @@ covered by the Verilog synthesis standard and when writing new designs one should limit herself or himself to these cases. In behavioural modelling, blocking assignments (=) and non-blocking assignments -(<=) can be used. The concept of blocking vs. non-blocking assignment is one of +(<=) can be used. The concept of blocking vs. non-blocking assignment is one of the most misunderstood constructs in Verilog :cite:p:`Cummings00`. The blocking assignment behaves exactly like an assignment in any imperative @@ -498,7 +498,7 @@ Then the synthesizable description is transformed to lower-level representations using a series of tools and the results are again verified using simulation. This process is illustrated in :numref:`Fig. %s `. -.. figure:: ../images/basics_flow.* +.. figure:: /_images/primer/basics_flow.* :class: width-helper :name: fig:Basics_flow @@ -515,8 +515,8 @@ Gate-Level Model are verified and the design process is finished. However, in any real-world design effort there will be multiple iterations for this design process. The reason for this can be the late change of a design requirement or the fact that the analysis of a low-abstraction model -(e.g. gate-level timing analysis) revealed that a design change is required in -order to meet the design requirements (e.g. maximum possible clock speed). +(e.g. gate-level timing analysis) revealed that a design change is required in +order to meet the design requirements (e.g. maximum possible clock speed). Whenever the behavioural model or the system level model is changed their equivalence must be re-verified by re-running the simulations and comparing the @@ -572,7 +572,7 @@ of lexical tokens given in :numref:`Tab. %s `. TOK_SEMICOLON \- ============== =============== -The lexer is usually generated by a lexer generator (e.g. flex ) from a +The lexer is usually generated by a lexer generator (e.g. flex ) from a description file that is using regular expressions to specify the text pattern that should match the individual tokens. @@ -586,7 +586,7 @@ use the Token-Type to make a decision on the grammatical role of a token. The parser then transforms the list of tokens into a parse tree that closely resembles the productions from the computer languages grammar. As the lexer, the -parser is also typically generated by a code generator (e.g. bison ) from a +parser is also typically generated by a code generator (e.g. bison) from a grammar description in Backus-Naur Form (BNF). Let's consider the following BNF (in Bison syntax): @@ -597,7 +597,7 @@ Let's consider the following BNF (in Bison syntax): assign_stmt: TOK_ASSIGN TOK_IDENTIFIER TOK_EQ expr TOK_SEMICOLON; expr: TOK_IDENTIFIER | TOK_NUMBER | expr TOK_PLUS expr; -.. figure:: ../images/basics_parsetree.* +.. figure:: /_images/primer/basics_parsetree.* :class: width-helper :name: fig:Basics_parsetree @@ -610,7 +610,7 @@ whole as data structure in memory. Instead the parser calls user-specified code snippets (so-called reduce-functions) for all inner nodes of the parse tree in depth-first order. -In some very simple applications (e.g. code generation for stack machines) it is +In some very simple applications (e.g. code generation for stack machines) it is possible to perform the task at hand directly in the reduce functions. But usually the reduce functions are only used to build an in-memory data structure with the relevant information from the parse tree. This data structure is called @@ -626,7 +626,7 @@ Usually the AST is then converted into yet another representation that is more suitable for further processing. In compilers this is often an assembler-like three-address-code intermediate representation. :cite:p:`Dragonbook` -.. figure:: ../images/basics_ast.* +.. figure:: /_images/primer/basics_ast.* :class: width-helper :name: fig:Basics_ast diff --git a/docs/source/bib.rst b/docs/source/bib.rst index 21f85a869e2..2675cec16cb 100644 --- a/docs/source/bib.rst +++ b/docs/source/bib.rst @@ -7,3 +7,4 @@ .. bibliography:: literature.bib +.. todo:: see if we can get the two hanging appnotes as lit references diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst index 4b9dc91f3e1..f0c4eaaf927 100644 --- a/docs/source/cmd_ref.rst +++ b/docs/source/cmd_ref.rst @@ -3,9 +3,14 @@ ================================================================================ Command line reference ================================================================================ + +.. literalinclude:: /temp/yosys + :start-at: Usage + .. toctree:: :caption: Command reference :maxdepth: 1 :glob: - cmd/* + /appendix/env_vars + /cmd/* diff --git a/manual/PRESENTATION_ExAdv/.gitignore b/docs/source/code_examples/.gitignore similarity index 50% rename from manual/PRESENTATION_ExAdv/.gitignore rename to docs/source/code_examples/.gitignore index cf658897d52..b4a858a0134 100644 --- a/manual/PRESENTATION_ExAdv/.gitignore +++ b/docs/source/code_examples/.gitignore @@ -1 +1,2 @@ *.dot +*.pdf diff --git a/manual/PRESENTATION_ExOth/axis_master.v b/docs/source/code_examples/axis/axis_master.v similarity index 100% rename from manual/PRESENTATION_ExOth/axis_master.v rename to docs/source/code_examples/axis/axis_master.v diff --git a/manual/PRESENTATION_ExOth/axis_test.v b/docs/source/code_examples/axis/axis_test.v similarity index 100% rename from manual/PRESENTATION_ExOth/axis_test.v rename to docs/source/code_examples/axis/axis_test.v diff --git a/manual/PRESENTATION_ExOth/axis_test.ys b/docs/source/code_examples/axis/axis_test.ys similarity index 70% rename from manual/PRESENTATION_ExOth/axis_test.ys rename to docs/source/code_examples/axis/axis_test.ys index 19663ac7733..a55d017d9d6 100644 --- a/manual/PRESENTATION_ExOth/axis_test.ys +++ b/docs/source/code_examples/axis/axis_test.ys @@ -2,4 +2,4 @@ read_verilog -sv axis_master.v axis_test.v hierarchy -top axis_test proc; flatten;; -sat -falsify -seq 50 -prove-asserts +sat -seq 50 -prove-asserts diff --git a/manual/PRESENTATION_Prog/.gitignore b/docs/source/code_examples/extensions/.gitignore similarity index 100% rename from manual/PRESENTATION_Prog/.gitignore rename to docs/source/code_examples/extensions/.gitignore diff --git a/docs/source/code_examples/extensions/Makefile b/docs/source/code_examples/extensions/Makefile new file mode 100644 index 00000000000..288983ed356 --- /dev/null +++ b/docs/source/code_examples/extensions/Makefile @@ -0,0 +1,32 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +.PHONY: all dots +all: dots test0.log test1.log test2.log +dots: test1.dot + +CXXFLAGS=$(shell $(YOSYS)-config --cxxflags) +DATDIR=$(shell $(YOSYS)-config --datdir) + +my_cmd.so: my_cmd.cc + $(YOSYS)-config --exec --cxx $(subst $(DATDIR),../../../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs + +test0.log: my_cmd.so + $(YOSYS) -Ql test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + mv test0.log_new test0.log + +test1.log: my_cmd.so + $(YOSYS) -Ql test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + mv test1.log_new test1.log + +test1.dot: my_cmd.so + $(YOSYS) -m ./my_cmd.so -p 'test1; show -format dot -prefix test1' + +test2.log: my_cmd.so + $(YOSYS) -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v + mv test2.log_new test2.log + +.PHONY: clean +clean: + rm -f *.d *.so *.dot diff --git a/manual/PRESENTATION_Prog/absval_ref.v b/docs/source/code_examples/extensions/absval_ref.v similarity index 69% rename from manual/PRESENTATION_Prog/absval_ref.v rename to docs/source/code_examples/extensions/absval_ref.v index ca0a115a0a7..3f547b50b28 100644 --- a/manual/PRESENTATION_Prog/absval_ref.v +++ b/docs/source/code_examples/extensions/absval_ref.v @@ -1,3 +1,3 @@ module absval_ref(input signed [3:0] a, output [3:0] y); - assign y = a[3] ? -a : a; + assign y = a[3] ? -a : a; endmodule diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc similarity index 97% rename from manual/PRESENTATION_Prog/my_cmd.cc rename to docs/source/code_examples/extensions/my_cmd.cc index 9cb4b8e38b1..36ddbe1758f 100644 --- a/manual/PRESENTATION_Prog/my_cmd.cc +++ b/docs/source/code_examples/extensions/my_cmd.cc @@ -14,7 +14,7 @@ struct MyPass : public Pass { log("Modules in current design:\n"); for (auto mod : design->modules()) - log(" %s (%zd wires, %zd cells)\n", log_id(mod), + log(" %s (%d wires, %d cells)\n", log_id(mod), GetSize(mod->wires()), GetSize(mod->cells())); } } MyPass; diff --git a/manual/PRESENTATION_Prog/sigmap_test.v b/docs/source/code_examples/extensions/sigmap_test.v similarity index 67% rename from manual/PRESENTATION_Prog/sigmap_test.v rename to docs/source/code_examples/extensions/sigmap_test.v index 18dcf5eb78e..8d0b4383689 100644 --- a/manual/PRESENTATION_Prog/sigmap_test.v +++ b/docs/source/code_examples/extensions/sigmap_test.v @@ -1,3 +1,3 @@ module test(input a, output x, y); -assign x = a, y = a; + assign x = a, y = a; endmodule diff --git a/docs/source/code_examples/fifo/Makefile b/docs/source/code_examples/fifo/Makefile new file mode 100644 index 00000000000..0a1186a62d4 --- /dev/null +++ b/docs/source/code_examples/fifo/Makefile @@ -0,0 +1,24 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOT_NAMES = addr_gen_hier addr_gen_proc addr_gen_clean +DOT_NAMES += rdata_proc rdata_flat rdata_adffe rdata_memrdv2 rdata_alumacc rdata_coarse +MAPDOT_NAMES = rdata_map_ram rdata_map_ffram rdata_map_gates +MAPDOT_NAMES += rdata_map_ffs rdata_map_luts rdata_map_cells + +DOTS := $(addsuffix .dot,$(DOT_NAMES)) +MAPDOTS := $(addsuffix .dot,$(MAPDOT_NAMES)) + +all: dots fifo.out fifo.stat +dots: $(DOTS) $(MAPDOTS) + +$(DOTS) fifo.out: fifo.v fifo.ys + $(YOSYS) fifo.ys -l fifo.out -Q -T + +$(MAPDOTS) fifo.stat: fifo.v fifo_map.ys + $(YOSYS) fifo_map.ys + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/code_examples/fifo/fifo.libmap b/docs/source/code_examples/fifo/fifo.libmap new file mode 100644 index 00000000000..5889b7cfd43 --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.libmap @@ -0,0 +1,65 @@ + +yosys> debug memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt -no-auto-huge + +yosys> memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt -no-auto-huge + +4. Executing MEMORY_LIBMAP pass (mapping memories to cells). +Memory fifo.data mapping candidates (post-geometry): +- logic fallback + - cost: 2048.000000 +- $__ICE40_RAM4K_: + - option HAS_BE 0 + - emulation score: 7 + - replicates (for ports): 1 + - replicates (for data): 1 + - mux score: 0 + - demux score: 0 + - cost: 78.000000 + - abits 11 dbits 2 4 8 16 + - chosen base width 8 + - swizzle 0 1 2 3 4 5 6 7 + - emulate read-first behavior + - write port 0: port group W + - widths 2 4 8 + - read port 0: port group R + - widths 2 4 8 16 + - emulate transparency with write port 0 +- $__ICE40_RAM4K_: + - option HAS_BE 1 + - emulation score: 7 + - replicates (for ports): 1 + - replicates (for data): 1 + - mux score: 0 + - demux score: 0 + - cost: 78.000000 + - abits 11 dbits 2 4 8 16 + - byte width 1 + - chosen base width 8 + - swizzle 0 1 2 3 4 5 6 7 + - emulate read-first behavior + - write port 0: port group W + - widths 16 + - read port 0: port group R + - widths 2 4 8 16 + - emulate transparency with write port 0 +Memory fifo.data mapping candidates (after post-geometry prune): +- logic fallback + - cost: 2048.000000 +- $__ICE40_RAM4K_: + - option HAS_BE 0 + - emulation score: 7 + - replicates (for ports): 1 + - replicates (for data): 1 + - mux score: 0 + - demux score: 0 + - cost: 78.000000 + - abits 11 dbits 2 4 8 16 + - chosen base width 8 + - swizzle 0 1 2 3 4 5 6 7 + - emulate read-first behavior + - write port 0: port group W + - widths 2 4 8 + - read port 0: port group R + - widths 2 4 8 16 + - emulate transparency with write port 0 +mapping memory fifo.data via $__ICE40_RAM4K_ diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out new file mode 100644 index 00000000000..ac132ee6c3d --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.out @@ -0,0 +1,425 @@ + +-- Executing script file `fifo.ys' -- +$ yosys fifo.v + +-- Parsing `fifo.v' using frontend ` -vlog2k' -- + +1. Executing Verilog-2005 frontend: fifo.v +Parsing Verilog input from `fifo.v' to AST representation. +Storing AST representation for module `$abstract\addr_gen'. +Storing AST representation for module `$abstract\fifo'. +Successfully finished Verilog frontend. +echo on + +yosys> hierarchy -top addr_gen + +2. Executing HIERARCHY pass (managing design hierarchy). + +3. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +Generating RTLIL representation for module `\addr_gen'. + +3.1. Analyzing design hierarchy.. +Top module: \addr_gen + +3.2. Analyzing design hierarchy.. +Top module: \addr_gen +Removing unused module `$abstract\fifo'. +Removing unused module `$abstract\addr_gen'. +Removed 2 unused modules. + +yosys> select -module addr_gen + +yosys [addr_gen]> select -list +addr_gen +addr_gen/$1\addr[7:0] +addr_gen/$add$fifo.v:19$3_Y +addr_gen/$eq$fifo.v:16$2_Y +addr_gen/$0\addr[7:0] +addr_gen/addr +addr_gen/rst +addr_gen/clk +addr_gen/en +addr_gen/$add$fifo.v:19$3 +addr_gen/$eq$fifo.v:16$2 +addr_gen/$proc$fifo.v:0$4 +addr_gen/$proc$fifo.v:12$1 + +yosys [addr_gen]> select t:* + +yosys [addr_gen]*> select -list +addr_gen/$add$fifo.v:19$3 +addr_gen/$eq$fifo.v:16$2 + +yosys [addr_gen]*> select -set new_cells % + +yosys [addr_gen]*> select -clear + +yosys> show -format dot -prefix addr_gen_show addr_gen + +4. Generating Graphviz representation of design. +Writing dot description to `addr_gen_show.dot'. +Dumping module addr_gen to page 1. + +yosys> show -format dot -prefix new_cells_show -notitle @new_cells + +5. Generating Graphviz representation of design. +Writing dot description to `new_cells_show.dot'. +Dumping selected parts of module addr_gen to page 1. + +yosys> show -color maroon3 @new_cells -color cornflowerblue p:* -notitle -format dot -prefix addr_gen_hier + +6. Generating Graphviz representation of design. +Writing dot description to `addr_gen_hier.dot'. +Dumping module addr_gen to page 1. + +yosys> proc -noopt + +7. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +7.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +7.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 2 switch rules as full_case in process $proc$fifo.v:12$1 in module addr_gen. +Removed a total of 0 dead cases. + +yosys> proc_prune + +7.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 1 assignment to connection. + +yosys> proc_init + +7.4. Executing PROC_INIT pass (extract init attributes). +Found init rule in `\addr_gen.$proc$fifo.v:0$4'. + Set init value: \addr = 8'00000000 + +yosys> proc_arst + +7.5. Executing PROC_ARST pass (detect async resets in processes). +Found async reset \rst in `\addr_gen.$proc$fifo.v:12$1'. + +yosys> proc_rom + +7.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. + + +yosys> proc_mux + +7.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\addr_gen.$proc$fifo.v:0$4'. +Creating decoders for process `\addr_gen.$proc$fifo.v:12$1'. + 1/1: $0\addr[7:0] + +yosys> proc_dlatch + +7.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +7.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\addr_gen.\addr' using process `\addr_gen.$proc$fifo.v:12$1'. + created $adff cell `$procdff$10' with positive edge clock and positive level reset. + +yosys> proc_memwr + +7.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +7.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Removing empty process `addr_gen.$proc$fifo.v:0$4'. +Found and cleaned up 2 empty switches in `\addr_gen.$proc$fifo.v:12$1'. +Removing empty process `addr_gen.$proc$fifo.v:12$1'. +Cleaned up 2 empty switches. + +yosys> select -set new_cells t:$mux t:*dff + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc + +8. Generating Graphviz representation of design. +Writing dot description to `addr_gen_proc.dot'. +Dumping module addr_gen to page 1. + +yosys> opt_expr + +9. Executing OPT_EXPR pass (perform const folding). +Optimizing module addr_gen. + +yosys> clean +Removed 0 unused cells and 4 unused wires. + +yosys> select -set new_cells t:$eq + +yosys> show -color cornflowerblue @new_cells -notitle -format dot -prefix addr_gen_clean + +10. Generating Graphviz representation of design. +Writing dot description to `addr_gen_clean.dot'. +Dumping module addr_gen to page 1. + +yosys> design -reset + +yosys> read_verilog fifo.v + +11. Executing Verilog-2005 frontend: fifo.v +Parsing Verilog input from `fifo.v' to AST representation. +Generating RTLIL representation for module `\addr_gen'. +Generating RTLIL representation for module `\fifo'. +Successfully finished Verilog frontend. + +yosys> hierarchy -check -top fifo + +12. Executing HIERARCHY pass (managing design hierarchy). + +12.1. Analyzing design hierarchy.. +Top module: \fifo +Used module: \addr_gen +Parameter \MAX_DATA = 256 + +12.2. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +Parameter \MAX_DATA = 256 +Generating RTLIL representation for module `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000'. +Parameter \MAX_DATA = 256 +Found cached RTLIL representation for module `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000'. + +12.3. Analyzing design hierarchy.. +Top module: \fifo +Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 + +12.4. Analyzing design hierarchy.. +Top module: \fifo +Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 +Removing unused module `\addr_gen'. +Removed 1 unused modules. + +yosys> proc + +13. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +13.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +13.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 2 switch rules as full_case in process $proc$fifo.v:62$24 in module fifo. +Marked 1 switch rules as full_case in process $proc$fifo.v:36$16 in module fifo. +Marked 2 switch rules as full_case in process $proc$fifo.v:12$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +Removed a total of 0 dead cases. + +yosys> proc_prune + +13.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 6 assignments to connections. + +yosys> proc_init + +13.4. Executing PROC_INIT pass (extract init attributes). +Found init rule in `\fifo.$proc$fifo.v:0$31'. + Set init value: \count = 9'000000000 +Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$35'. + Set init value: \addr = 8'00000000 + +yosys> proc_arst + +13.5. Executing PROC_ARST pass (detect async resets in processes). +Found async reset \rst in `\fifo.$proc$fifo.v:62$24'. +Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:12$32'. + +yosys> proc_rom + +13.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. + + +yosys> proc_mux + +13.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\fifo.$proc$fifo.v:0$31'. +Creating decoders for process `\fifo.$proc$fifo.v:62$24'. + 1/1: $0\count[8:0] +Creating decoders for process `\fifo.$proc$fifo.v:36$16'. + 1/3: $1$memwr$\data$fifo.v:38$15_EN[7:0]$22 + 2/3: $1$memwr$\data$fifo.v:38$15_DATA[7:0]$21 + 3/3: $1$memwr$\data$fifo.v:38$15_ADDR[7:0]$20 +Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$35'. +Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:12$32'. + 1/1: $0\addr[7:0] + +yosys> proc_dlatch + +13.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +13.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:62$24'. + created $adff cell `$procdff$55' with positive edge clock and positive level reset. +Creating register for signal `\fifo.\rdata' using process `\fifo.$proc$fifo.v:36$16'. + created $dff cell `$procdff$56' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:38$15_ADDR' using process `\fifo.$proc$fifo.v:36$16'. + created $dff cell `$procdff$57' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:38$15_DATA' using process `\fifo.$proc$fifo.v:36$16'. + created $dff cell `$procdff$58' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:38$15_EN' using process `\fifo.$proc$fifo.v:36$16'. + created $dff cell `$procdff$59' with positive edge clock. +Creating register for signal `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.\addr' using process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:12$32'. + created $adff cell `$procdff$60' with positive edge clock and positive level reset. + +yosys> proc_memwr + +13.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +13.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Removing empty process `fifo.$proc$fifo.v:0$31'. +Found and cleaned up 2 empty switches in `\fifo.$proc$fifo.v:62$24'. +Removing empty process `fifo.$proc$fifo.v:62$24'. +Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:36$16'. +Removing empty process `fifo.$proc$fifo.v:36$16'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$35'. +Found and cleaned up 2 empty switches in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:12$32'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:12$32'. +Cleaned up 5 empty switches. + +yosys> opt_expr -keepdc + +13.12. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. + +yosys> select -set new_cells t:$memrd + +yosys> show -color maroon3 c:fifo_reader -color cornflowerblue @new_cells -notitle -format dot -prefix rdata_proc o:rdata %ci* + +14. Generating Graphviz representation of design. +Writing dot description to `rdata_proc.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> flatten + +15. Executing FLATTEN pass (flatten design). +Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. + + +yosys> clean +Removed 3 unused cells and 25 unused wires. + +yosys> select -set rdata_path o:rdata %ci* + +yosys> select -set new_cells @rdata_path o:rdata %ci3 %d i:* %d + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_flat @rdata_path + +16. Generating Graphviz representation of design. +Writing dot description to `rdata_flat.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> opt_dff + +17. Executing OPT_DFF pass (perform DFF optimizations). +Adding EN signal on $procdff$55 ($adff) from module fifo (D = $0\count[8:0], Q = \count). +Adding EN signal on $flatten\fifo_writer.$procdff$60 ($adff) from module fifo (D = $flatten\fifo_writer.$procmux$51_Y, Q = \fifo_writer.addr). +Adding EN signal on $flatten\fifo_reader.$procdff$60 ($adff) from module fifo (D = $flatten\fifo_reader.$procmux$51_Y, Q = \fifo_reader.addr). + +yosys> select -set new_cells t:$adffe + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* + +18. Generating Graphviz representation of design. +Writing dot description to `rdata_adffe.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> wreduce + +19. Executing WREDUCE pass (reducing word size of cells). +Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:66$27 ($add). +Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:66$27 ($add). +Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:68$30 ($sub). +Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:68$30 ($sub). +Removed top 1 bits (of 2) from port B of cell fifo.$auto$opt_dff.cc:195:make_patterns_logic$66 ($ne). +Removed cell fifo.$flatten\fifo_writer.$procmux$53 ($mux). +Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_writer.$add$fifo.v:19$34 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:19$34 ($add). +Removed cell fifo.$flatten\fifo_reader.$procmux$53 ($mux). +Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_reader.$add$fifo.v:19$34 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:19$34 ($add). +Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:66$27_Y. +Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_reader.$add$fifo.v:19$34_Y. + +yosys> show -notitle -format dot -prefix rdata_wreduce o:rdata %ci* + +20. Generating Graphviz representation of design. +Writing dot description to `rdata_wreduce.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> opt_clean + +21. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 0 unused cells and 4 unused wires. + + +yosys> memory_dff + +22. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +Checking read port `\data'[0] in module `\fifo': merging output FF to cell. + Write port 0: non-transparent. + +yosys> select -set new_cells t:$memrd_v2 + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdata %ci* + +23. Generating Graphviz representation of design. +Writing dot description to `rdata_memrdv2.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> alumacc + +24. Executing ALUMACC pass (create $alu and $macc cells). +Extracting $alu and $macc cells in module fifo: + creating $macc model for $add$fifo.v:66$27 ($add). + creating $macc model for $flatten\fifo_reader.$add$fifo.v:19$34 ($add). + creating $macc model for $flatten\fifo_writer.$add$fifo.v:19$34 ($add). + creating $macc model for $sub$fifo.v:68$30 ($sub). + creating $alu model for $macc $sub$fifo.v:68$30. + creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:19$34. + creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:19$34. + creating $alu model for $macc $add$fifo.v:66$27. + creating $alu cell for $add$fifo.v:66$27: $auto$alumacc.cc:485:replace_alu$80 + creating $alu cell for $flatten\fifo_reader.$add$fifo.v:19$34: $auto$alumacc.cc:485:replace_alu$83 + creating $alu cell for $flatten\fifo_writer.$add$fifo.v:19$34: $auto$alumacc.cc:485:replace_alu$86 + creating $alu cell for $sub$fifo.v:68$30: $auto$alumacc.cc:485:replace_alu$89 + created 4 $alu and 0 $macc cells. + +yosys> select -set new_cells t:$alu t:$macc + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdata %ci* + +25. Generating Graphviz representation of design. +Writing dot description to `rdata_alumacc.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> memory_collect + +26. Executing MEMORY_COLLECT pass (generating $mem cells). + +yosys> select -set new_cells t:$mem_v2 + +yosys> select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @new_cells %co* %% + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path + +27. Generating Graphviz representation of design. +Writing dot description to `rdata_coarse.dot'. +Dumping selected parts of module fifo to page 1. diff --git a/docs/source/code_examples/fifo/fifo.stat b/docs/source/code_examples/fifo/fifo.stat new file mode 100644 index 00000000000..263c618e326 --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.stat @@ -0,0 +1,57 @@ + +yosys> stat + +2. Printing statistics. + +=== fifo === + + Number of wires: 28 + Number of wire bits: 219 + Number of public wires: 9 + Number of public wire bits: 45 + Number of memories: 1 + Number of memory bits: 2048 + Number of processes: 3 + Number of cells: 9 + $add 1 + $logic_and 2 + $logic_not 2 + $memrd 1 + $sub 1 + addr_gen 2 + +=== addr_gen === + + Number of wires: 8 + Number of wire bits: 60 + Number of public wires: 4 + Number of public wire bits: 11 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 2 + Number of cells: 2 + $add 1 + $eq 1 + + +yosys> stat -top fifo + +17. Printing statistics. + +=== fifo === + + Number of wires: 94 + Number of wire bits: 260 + Number of public wires: 94 + Number of public wire bits: 260 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 138 + $scopeinfo 2 + SB_CARRY 26 + SB_DFF 26 + SB_DFFER 25 + SB_LUT4 58 + SB_RAM40_4K 1 + diff --git a/docs/source/code_examples/fifo/fifo.v b/docs/source/code_examples/fifo/fifo.v new file mode 100644 index 00000000000..769dfafd4c9 --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.v @@ -0,0 +1,71 @@ +// address generator/counter +module addr_gen +#( parameter MAX_DATA=256, + localparam AWIDTH = $clog2(MAX_DATA) +) ( input en, clk, rst, + output reg [AWIDTH-1:0] addr +); + initial addr <= 0; + + // async reset + // increment address when enabled + always @(posedge clk or posedge rst) + if (rst) + addr <= 0; + else if (en) begin + if (addr == MAX_DATA-1) + addr <= 0; + else + addr <= addr + 1; + end +endmodule //addr_gen + +// Define our top level fifo entity +module fifo +#( parameter MAX_DATA=256, + localparam AWIDTH = $clog2(MAX_DATA) +) ( input wen, ren, clk, rst, + input [7:0] wdata, + output reg [7:0] rdata, + output reg [AWIDTH:0] count +); + // fifo storage + // sync read before write + wire [AWIDTH-1:0] waddr, raddr; + reg [7:0] data [MAX_DATA-1:0]; + always @(posedge clk) begin + if (wen) + data[waddr] <= wdata; + rdata <= data[raddr]; + end // storage + + // addr_gen for both write and read addresses + addr_gen #(.MAX_DATA(MAX_DATA)) + fifo_writer ( + .en (wen), + .clk (clk), + .rst (rst), + .addr (waddr) + ); + + addr_gen #(.MAX_DATA(MAX_DATA)) + fifo_reader ( + .en (ren), + .clk (clk), + .rst (rst), + .addr (raddr) + ); + + // status signals + initial count <= 0; + + always @(posedge clk or posedge rst) begin + if (rst) + count <= 0; + else if (wen && !ren) + count <= count + 1; + else if (ren && !wen) + count <= count - 1; + end + +endmodule diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys new file mode 100644 index 00000000000..57a28e63e8e --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.ys @@ -0,0 +1,82 @@ +# ======================================================== +# throw in some extra text to match what we expect if we were opening an +# interactive terminal +log $ yosys fifo.v +log +log -- Parsing `fifo.v' using frontend ` -vlog2k' -- +read_verilog -defer fifo.v + +# turn command echoes on to use the log output as a console session +echo on +hierarchy -top addr_gen +select -module addr_gen +select -list +select t:* +select -list +select -set new_cells % +select -clear +show -format dot -prefix addr_gen_show addr_gen +show -format dot -prefix new_cells_show -notitle @new_cells +show -color maroon3 @new_cells -color cornflowerblue p:* -notitle -format dot -prefix addr_gen_hier + +# ======================================================== +proc -noopt +select -set new_cells t:$mux t:*dff +show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc + +# ======================================================== +opt_expr; clean +select -set new_cells t:$eq +show -color cornflowerblue @new_cells -notitle -format dot -prefix addr_gen_clean + +# ======================================================== +design -reset +read_verilog fifo.v +hierarchy -check -top fifo +proc +select -set new_cells t:$memrd +show -color maroon3 c:fifo_reader -color cornflowerblue @new_cells -notitle -format dot -prefix rdata_proc o:rdata %ci* + +# ======================================================== + +flatten;; +select -set rdata_path o:rdata %ci* +select -set new_cells @rdata_path o:rdata %ci3 %d i:* %d +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_flat @rdata_path + +# ======================================================== + +opt_dff +select -set new_cells t:$adffe +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* + +# ======================================================== + +wreduce +show -notitle -format dot -prefix rdata_wreduce o:rdata %ci* + +# unclear if this is necessary or only because of bug(s) +opt_clean + +# ======================================================== + +memory_dff +select -set new_cells t:$memrd_v2 +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdata %ci* + +# ======================================================== + +alumacc +select -set new_cells t:$alu t:$macc +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdata %ci* + +# ======================================================== + +memory_collect +# or use the following commands: +# design -reset +# read_verilog fifo.v +# synth_ice40 -top fifo -run begin:map_ram +select -set new_cells t:$mem_v2 +select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path diff --git a/docs/source/code_examples/fifo/fifo_map.ys b/docs/source/code_examples/fifo/fifo_map.ys new file mode 100644 index 00000000000..f5a3edeb485 --- /dev/null +++ b/docs/source/code_examples/fifo/fifo_map.ys @@ -0,0 +1,57 @@ +read_verilog fifo.v +echo on +tee -o fifo.stat stat +echo off +synth_ice40 -top fifo -run begin:map_ram +# this point should be the same as rdata_coarse + +# ======================================================== + +echo on +tee -o fifo.libmap debug memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt -no-auto-huge +echo off +synth_ice40 -top fifo -run map_ram:map_ffram +select -set mem t:SB_RAM40_4K +select -set remap @mem %ci:+SB_RAM40_4K[RADDR] @mem %co %% +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ram @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_ffram:map_gates +select -set mem t:SB_RAM40_4K +select -set remap @mem %co @mem %d +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 @mem -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ffram @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_gates:map_ffs +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +select -set multibit t:$_MUX_ t:$_DFFE_*_ +select -set alu t:$_OR_ t:$_NOT_ t:$lut %% %ci %% w:fifo_reader.addr %d i:* %d +show -color maroon3 @multibit -color cornflowerblue @alu -notitle -format dot -prefix rdata_map_gates @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_ffs:map_luts +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +select -set dff t:SB_DFFER +select -set primitives t:$_AND_ %ci i:* %d +show -color maroon3 @dff -color cornflowerblue @primitives -notitle -format dot -prefix rdata_map_ffs @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_luts:map_cells +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 t:SB_CARRY -color cornflowerblue t:$lut -notitle -format dot -prefix rdata_map_luts @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_cells: +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 t:SB_LUT* -notitle -format dot -prefix rdata_map_cells @rdata_path + +echo on +tee -a fifo.stat stat -top fifo +echo off diff --git a/docs/source/code_examples/intro/.gitignore b/docs/source/code_examples/intro/.gitignore new file mode 100644 index 00000000000..9f8173c6d17 --- /dev/null +++ b/docs/source/code_examples/intro/.gitignore @@ -0,0 +1 @@ +synth.v diff --git a/docs/source/code_examples/intro/Makefile b/docs/source/code_examples/intro/Makefile new file mode 100644 index 00000000000..009c82c6219 --- /dev/null +++ b/docs/source/code_examples/intro/Makefile @@ -0,0 +1,15 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOTS = counter_00.dot counter_01.dot counter_02.dot counter_03.dot + +all: dots +dots: $(DOTS) + +$(DOTS): counter.v counter.ys mycells.lib + $(YOSYS) counter.ys + +.PHONY: clean +clean: + rm -f *.dot diff --git a/manual/PRESENTATION_Intro/counter.v b/docs/source/code_examples/intro/counter.v similarity index 100% rename from manual/PRESENTATION_Intro/counter.v rename to docs/source/code_examples/intro/counter.v diff --git a/docs/source/code_examples/intro/counter.ys b/docs/source/code_examples/intro/counter.ys new file mode 100644 index 00000000000..e327a6f6b81 --- /dev/null +++ b/docs/source/code_examples/intro/counter.ys @@ -0,0 +1,31 @@ +# read design +read_verilog counter.v +hierarchy -check -top counter + +show -notitle -format dot -prefix counter_00 + +# the high-level stuff +proc; opt +memory; opt +fsm; opt + +show -notitle -format dot -prefix counter_01 + +# mapping to internal cell library +techmap; opt + +splitnets -ports;; show -notitle -format dot -prefix counter_02 + +# mapping flip-flops to mycells.lib +dfflibmap -liberty mycells.lib + +# mapping logic to mycells.lib +abc -liberty mycells.lib + +# cleanup +clean + +show -notitle -lib mycells.v -format dot -prefix counter_03 + +# write synthesized design +write_verilog synth.v diff --git a/manual/PRESENTATION_Intro/mycells.lib b/docs/source/code_examples/intro/mycells.lib similarity index 100% rename from manual/PRESENTATION_Intro/mycells.lib rename to docs/source/code_examples/intro/mycells.lib diff --git a/manual/PRESENTATION_Intro/mycells.v b/docs/source/code_examples/intro/mycells.v similarity index 100% rename from manual/PRESENTATION_Intro/mycells.v rename to docs/source/code_examples/intro/mycells.v diff --git a/docs/source/code_examples/macc/Makefile b/docs/source/code_examples/macc/Makefile new file mode 100644 index 00000000000..e93fe065734 --- /dev/null +++ b/docs/source/code_examples/macc/Makefile @@ -0,0 +1,19 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOTS = macc_simple_xmap.dot macc_xilinx_xmap.dot + +all: dots +dots: $(DOTS) + +macc_simple_xmap.dot: macc_simple_*.v macc_simple_test.ys + $(YOSYS) macc_simple_test.ys + +macc_xilinx_xmap.dot: macc_xilinx_*.v macc_xilinx_test.ys + $(YOSYS) macc_xilinx_test.ys + +.PHONY: clean +clean: + rm -f *.dot + diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.v b/docs/source/code_examples/macc/macc_simple_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test.v rename to docs/source/code_examples/macc/macc_simple_test.v diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.ys b/docs/source/code_examples/macc/macc_simple_test.ys similarity index 60% rename from manual/PRESENTATION_ExAdv/macc_simple_test.ys rename to docs/source/code_examples/macc/macc_simple_test.ys index 8d106a28c9d..70496c05769 100644 --- a/manual/PRESENTATION_ExAdv/macc_simple_test.ys +++ b/docs/source/code_examples/macc/macc_simple_test.ys @@ -1,10 +1,10 @@ read_verilog macc_simple_test.v hierarchy -check -top test;; -show -prefix macc_simple_test_00a -format pdf -notitle -lib macc_simple_xmap.v +show -prefix macc_simple_test_00a -format dot -notitle -lib macc_simple_xmap.v extract -constports -map macc_simple_xmap.v;; -show -prefix macc_simple_test_00b -format pdf -notitle -lib macc_simple_xmap.v +show -prefix macc_simple_test_00b -format dot -notitle -lib macc_simple_xmap.v ################################################# @@ -12,10 +12,10 @@ design -reset read_verilog macc_simple_test_01.v hierarchy -check -top test;; -show -prefix macc_simple_test_01a -format pdf -notitle -lib macc_simple_xmap.v +show -prefix macc_simple_test_01a -format dot -notitle -lib macc_simple_xmap.v extract -map macc_simple_xmap.v;; -show -prefix macc_simple_test_01b -format pdf -notitle -lib macc_simple_xmap.v +show -prefix macc_simple_test_01b -format dot -notitle -lib macc_simple_xmap.v ################################################# @@ -23,10 +23,10 @@ design -reset read_verilog macc_simple_test_02.v hierarchy -check -top test;; -show -prefix macc_simple_test_02a -format pdf -notitle -lib macc_simple_xmap.v +show -prefix macc_simple_test_02a -format dot -notitle -lib macc_simple_xmap.v extract -map macc_simple_xmap.v;; -show -prefix macc_simple_test_02b -format pdf -notitle -lib macc_simple_xmap.v +show -prefix macc_simple_test_02b -format dot -notitle -lib macc_simple_xmap.v ################################################# @@ -34,4 +34,4 @@ design -reset read_verilog macc_simple_xmap.v hierarchy -check -top macc_16_16_32;; -show -prefix macc_simple_xmap -format pdf -notitle +show -prefix macc_simple_xmap -format dot -notitle diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test_01.v b/docs/source/code_examples/macc/macc_simple_test_01.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test_01.v rename to docs/source/code_examples/macc/macc_simple_test_01.v diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test_02.v b/docs/source/code_examples/macc/macc_simple_test_02.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test_02.v rename to docs/source/code_examples/macc/macc_simple_test_02.v diff --git a/manual/PRESENTATION_ExAdv/macc_simple_xmap.v b/docs/source/code_examples/macc/macc_simple_xmap.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_xmap.v rename to docs/source/code_examples/macc/macc_simple_xmap.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v b/docs/source/code_examples/macc/macc_xilinx_swap_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v rename to docs/source/code_examples/macc/macc_xilinx_swap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v b/docs/source/code_examples/macc/macc_xilinx_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_test.v rename to docs/source/code_examples/macc/macc_xilinx_test.v diff --git a/docs/source/code_examples/macc/macc_xilinx_test.ys b/docs/source/code_examples/macc/macc_xilinx_test.ys new file mode 100644 index 00000000000..47bf399b20a --- /dev/null +++ b/docs/source/code_examples/macc/macc_xilinx_test.ys @@ -0,0 +1,53 @@ +# ============================================================================ +# part a +read_verilog macc_xilinx_test.v +read_verilog -lib -icells macc_xilinx_unwrap_map.v +read_verilog -lib -icells macc_xilinx_xmap.v +hierarchy -check ;; +# end part a +show -prefix macc_xilinx_test1a -format dot -notitle test1 +show -prefix macc_xilinx_test2a -format dot -notitle test2 + +# ============================================================================ +# part b +techmap -map macc_xilinx_swap_map.v;; +# end part b +show -prefix macc_xilinx_test1b -format dot -notitle test1 +show -prefix macc_xilinx_test2b -format dot -notitle test2 + +# ============================================================================ +# part c +techmap -map macc_xilinx_wrap_map.v + +connwrappers -unsigned $__mul_wrapper Y Y_WIDTH \ + -unsigned $__add_wrapper Y Y_WIDTH;; +# end part c +show -prefix macc_xilinx_test1c -format dot -notitle test1 +show -prefix macc_xilinx_test2c -format dot -notitle test2 + +# ============================================================================ +# part d +design -push +read_verilog macc_xilinx_xmap.v +techmap -map macc_xilinx_swap_map.v +techmap -map macc_xilinx_wrap_map.v;; +design -save __macc_xilinx_xmap +design -pop + +extract -constports -ignore_parameters \ + -map %__macc_xilinx_xmap \ + -swap $__add_wrapper A,B ;; +# end part d +show -prefix macc_xilinx_test1d -format dot -notitle test1 +show -prefix macc_xilinx_test2d -format dot -notitle test2 + +# ============================================================================ +# part e +techmap -map macc_xilinx_unwrap_map.v;; +# end part e +show -prefix macc_xilinx_test1e -format dot -notitle test1 +show -prefix macc_xilinx_test2e -format dot -notitle test2 + +design -load __macc_xilinx_xmap +show -prefix macc_xilinx_xmap -format dot -notitle + diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v b/docs/source/code_examples/macc/macc_xilinx_unwrap_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v rename to docs/source/code_examples/macc/macc_xilinx_unwrap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v b/docs/source/code_examples/macc/macc_xilinx_wrap_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v rename to docs/source/code_examples/macc/macc_xilinx_wrap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v b/docs/source/code_examples/macc/macc_xilinx_xmap.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v rename to docs/source/code_examples/macc/macc_xilinx_xmap.v diff --git a/docs/source/code_examples/macro_commands/fsm.ys b/docs/source/code_examples/macro_commands/fsm.ys new file mode 100644 index 00000000000..627df1209ae --- /dev/null +++ b/docs/source/code_examples/macro_commands/fsm.ys @@ -0,0 +1,27 @@ +#start:It also calls opt_clean as needed: +#end:Options: +# 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 diff --git a/docs/source/code_examples/macro_commands/memory.ys b/docs/source/code_examples/macro_commands/memory.ys new file mode 100644 index 00000000000..ea4800a1cc1 --- /dev/null +++ b/docs/source/code_examples/macro_commands/memory.ys @@ -0,0 +1,15 @@ +#start:passes in a useful order: +#end:This converts memories to word-wide DFFs and address decoders +opt_mem +opt_mem_priority +opt_mem_feedback +memory_bmux2rom +memory_dff +opt_clean +memory_share +opt_mem_widen +memory_memx (when called with -memx) +opt_clean +memory_collect +memory_bram -rules (when called with -bram) +memory_map (skipped if called with -nomap) diff --git a/docs/source/code_examples/macro_commands/opt.ys b/docs/source/code_examples/macro_commands/opt.ys new file mode 100644 index 00000000000..cb883bc589a --- /dev/null +++ b/docs/source/code_examples/macro_commands/opt.ys @@ -0,0 +1,14 @@ +#start: passes in the following order: +#end: When called with -fast +opt_expr +opt_merge -nomux + +do + opt_muxtree + opt_reduce + opt_merge + opt_share (-full only) + opt_dff (except when called with -noff) + opt_clean + opt_expr +while diff --git a/docs/source/code_examples/macro_commands/proc.ys b/docs/source/code_examples/macro_commands/proc.ys new file mode 100644 index 00000000000..7a78ce0c6b8 --- /dev/null +++ b/docs/source/code_examples/macro_commands/proc.ys @@ -0,0 +1,14 @@ +#start: passes in the most common order. +#end: This replaces the processes +proc_clean # removes empty branches and processes +proc_rmdead # removes unreachable branches +proc_prune +proc_init # special handling of “initial” blocks +proc_arst # identifies modeling of async resets +proc_rom +proc_mux # converts decision trees to multiplexer networks +proc_dlatch +proc_dff # extracts registers from processes +proc_memwr +proc_clean # this should remove all the processes, provided all went fine +opt_expr -keepdc diff --git a/docs/source/code_examples/macro_commands/synth_ice40.ys b/docs/source/code_examples/macro_commands/synth_ice40.ys new file mode 100644 index 00000000000..443b8e0b026 --- /dev/null +++ b/docs/source/code_examples/macro_commands/synth_ice40.ys @@ -0,0 +1,90 @@ +#start:The following commands are executed by this synthesis command: +#end:blif: +begin: + read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v + hierarchy -check -top + proc + +flatten: + flatten + tribuf -logic + deminout + +coarse: + opt_expr + opt_clean + check + opt -nodffe -nosdff + fsm + opt + wreduce + peepopt + opt_clean + share + techmap + opt_expr + opt_clean + memory_dff + wreduce t:$mul + techmap + select a:mul2dsp + setattr -unset mul2dsp + opt_expr -fine + wreduce + select -clear + ice40_dsp + chtype -set $mul t:$__soft_mul + alumacc + opt + memory -nomap [-no-rw-check] + opt_clean + +map_ram: + memory_libmap + techmap + ice40_braminit + +map_ffram: + opt -fast -mux_undef -undriven -fine + memory_map + opt -undriven -fine + +map_gates: + ice40_wrapcarry + techmap + opt -fast + abc -dff -D 1 + ice40_opt + +map_ffs: + dfflegalize + techmap + opt_expr -mux_undef + simplemap + ice40_opt -full + +map_luts: + abc + ice40_opt + techmap + simplemap + techmap + flowmap + read_verilog + abc9 + ice40_wrapcarry -unwrap + techmap + clean + opt_lut -tech ice40 + +map_cells: + techmap + clean + +check: + autoname + hierarchy -check + stat + check -noinit + blackbox =A:whitebox + \ No newline at end of file diff --git a/docs/source/code_examples/opt/Makefile b/docs/source/code_examples/opt/Makefile new file mode 100644 index 00000000000..4cb51e90bec --- /dev/null +++ b/docs/source/code_examples/opt/Makefile @@ -0,0 +1,20 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOT_NAMES = opt_share opt_muxtree opt_merge opt_expr + +DOTS := $(addsuffix .dot,$(DOT_NAMES)) + +all: dots +dots: $(DOTS) + +%_full.dot: %.ys + $(YOSYS) $< + +%.dot: %_full.dot + gvpack -u $*_full.dot -o $@ + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/code_examples/opt/opt_expr.ys b/docs/source/code_examples/opt/opt_expr.ys new file mode 100644 index 00000000000..e87da339ed8 --- /dev/null +++ b/docs/source/code_examples/opt/opt_expr.ys @@ -0,0 +1,17 @@ +read_verilog < ls + +1 modules: + example + +yosys> cd example + +yosys [example]> ls + +8 wires: + $0\y[1:0] + $add$example.v:5$2_Y + $ternary$example.v:5$3_Y + a + b + c + clk + y + +2 cells: + $add$example.v:5$2 + $ternary$example.v:5$3 + +1 processes: + $proc$example.v:3$1 + +yosys [example]> dump $2 + + + attribute \src "example.v:5.22-5.27" + cell $add $add$example.v:5$2 + parameter \Y_WIDTH 2 + parameter \B_WIDTH 1 + parameter \A_WIDTH 1 + parameter \B_SIGNED 0 + parameter \A_SIGNED 0 + connect \Y $add$example.v:5$2_Y + connect \B \b + connect \A \a + end + +yosys [example]> cd .. + +yosys> echo off +echo off diff --git a/docs/source/APPNOTE_011_Design_Investigation/example.v b/docs/source/code_examples/show/example.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/example.v rename to docs/source/code_examples/show/example.v diff --git a/docs/source/code_examples/show/example.ys b/docs/source/code_examples/show/example.ys new file mode 100644 index 00000000000..a5332f13486 --- /dev/null +++ b/docs/source/code_examples/show/example.ys @@ -0,0 +1,6 @@ +read_verilog example.v +show -format dot -prefix example_first +proc +show -format dot -prefix example_second +opt +show -format dot -prefix example_third diff --git a/docs/source/code_examples/show/example_lscd.ys b/docs/source/code_examples/show/example_lscd.ys new file mode 100644 index 00000000000..de24842285a --- /dev/null +++ b/docs/source/code_examples/show/example_lscd.ys @@ -0,0 +1,8 @@ +read_verilog example.v +echo on +ls +cd example +ls +dump $2 +cd .. +echo off diff --git a/docs/source/code_examples/show/example_show.ys b/docs/source/code_examples/show/example_show.ys new file mode 100644 index 00000000000..711af84d9f2 --- /dev/null +++ b/docs/source/code_examples/show/example_show.ys @@ -0,0 +1,6 @@ +read_verilog example.v +show -pause # first +proc +show -pause # second +opt +show -pause # third diff --git a/docs/source/APPNOTE_011_Design_Investigation/splice.v b/docs/source/code_examples/show/splice.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/splice.v rename to docs/source/code_examples/show/splice.v diff --git a/docs/source/CHAPTER_Prog/.gitignore b/docs/source/code_examples/stubnets/.gitignore similarity index 100% rename from docs/source/CHAPTER_Prog/.gitignore rename to docs/source/code_examples/stubnets/.gitignore diff --git a/docs/source/CHAPTER_Prog/Makefile b/docs/source/code_examples/stubnets/Makefile similarity index 87% rename from docs/source/CHAPTER_Prog/Makefile rename to docs/source/code_examples/stubnets/Makefile index 8e326bdc266..ec501f006ca 100644 --- a/docs/source/CHAPTER_Prog/Makefile +++ b/docs/source/code_examples/stubnets/Makefile @@ -1,3 +1,8 @@ +.PHONY: all dots +all: dots +dots: + +.PHONY: test test: stubnets.so yosys -ql test1.log -m ./stubnets.so test.v -p "stubnets" yosys -ql test2.log -m ./stubnets.so test.v -p "opt; stubnets" @@ -7,6 +12,7 @@ test: stubnets.so stubnets.so: stubnets.cc yosys-config --exec --cxx --cxxflags --ldflags -o $@ -shared $^ --ldlibs +.PHONY: clean clean: rm -f test1.log test2.log test3.log rm -f stubnets.so stubnets.d diff --git a/docs/source/CHAPTER_Prog/stubnets.cc b/docs/source/code_examples/stubnets/stubnets.cc similarity index 100% rename from docs/source/CHAPTER_Prog/stubnets.cc rename to docs/source/code_examples/stubnets/stubnets.cc diff --git a/docs/source/CHAPTER_Prog/test.v b/docs/source/code_examples/stubnets/test.v similarity index 100% rename from docs/source/CHAPTER_Prog/test.v rename to docs/source/code_examples/stubnets/test.v diff --git a/docs/source/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile new file mode 100644 index 00000000000..cc5a34b26b5 --- /dev/null +++ b/docs/source/code_examples/synth_flow/Makefile @@ -0,0 +1,22 @@ + +TARGETS += proc_01 proc_02 proc_03 +TARGETS += memory_01 memory_02 +TARGETS += techmap_01 + +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOTS = $(addsuffix .dot,$(TARGETS)) + +.PHONY: all dots +all: dots +dots: $(DOTS) + +%.dot: %.v %.ys + $(YOSYS) -p 'script $*.ys; show -notitle -prefix $* -format dot' + +.PHONY: clean +clean: + rm -f *.dot + diff --git a/manual/PRESENTATION_ExSyn/memory_01.v b/docs/source/code_examples/synth_flow/memory_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_01.v rename to docs/source/code_examples/synth_flow/memory_01.v diff --git a/manual/PRESENTATION_ExSyn/memory_01.ys b/docs/source/code_examples/synth_flow/memory_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_01.ys rename to docs/source/code_examples/synth_flow/memory_01.ys diff --git a/manual/PRESENTATION_ExSyn/memory_02.v b/docs/source/code_examples/synth_flow/memory_02.v similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_02.v rename to docs/source/code_examples/synth_flow/memory_02.v diff --git a/manual/PRESENTATION_ExSyn/memory_02.ys b/docs/source/code_examples/synth_flow/memory_02.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_02.ys rename to docs/source/code_examples/synth_flow/memory_02.ys diff --git a/manual/PRESENTATION_ExSyn/proc_01.v b/docs/source/code_examples/synth_flow/proc_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_01.v rename to docs/source/code_examples/synth_flow/proc_01.v diff --git a/manual/PRESENTATION_ExSyn/proc_01.ys b/docs/source/code_examples/synth_flow/proc_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_01.ys rename to docs/source/code_examples/synth_flow/proc_01.ys diff --git a/manual/PRESENTATION_ExSyn/proc_02.v b/docs/source/code_examples/synth_flow/proc_02.v similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_02.v rename to docs/source/code_examples/synth_flow/proc_02.v diff --git a/manual/PRESENTATION_ExSyn/proc_02.ys b/docs/source/code_examples/synth_flow/proc_02.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_02.ys rename to docs/source/code_examples/synth_flow/proc_02.ys diff --git a/manual/PRESENTATION_ExSyn/proc_03.v b/docs/source/code_examples/synth_flow/proc_03.v similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_03.v rename to docs/source/code_examples/synth_flow/proc_03.v diff --git a/manual/PRESENTATION_ExSyn/proc_03.ys b/docs/source/code_examples/synth_flow/proc_03.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_03.ys rename to docs/source/code_examples/synth_flow/proc_03.ys diff --git a/manual/PRESENTATION_ExSyn/techmap_01.v b/docs/source/code_examples/synth_flow/techmap_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/techmap_01.v rename to docs/source/code_examples/synth_flow/techmap_01.v diff --git a/manual/PRESENTATION_ExSyn/techmap_01.ys b/docs/source/code_examples/synth_flow/techmap_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/techmap_01.ys rename to docs/source/code_examples/synth_flow/techmap_01.ys diff --git a/manual/PRESENTATION_ExSyn/techmap_01_map.v b/docs/source/code_examples/synth_flow/techmap_01_map.v similarity index 100% rename from manual/PRESENTATION_ExSyn/techmap_01_map.v rename to docs/source/code_examples/synth_flow/techmap_01_map.v diff --git a/docs/source/code_examples/techmap/Makefile b/docs/source/code_examples/techmap/Makefile new file mode 100644 index 00000000000..e900fea4c5f --- /dev/null +++ b/docs/source/code_examples/techmap/Makefile @@ -0,0 +1,26 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +.PHONY: all dots +all: dots +dots: red_or3x1.dot sym_mul.dot mymul.dot mulshift.dot addshift.dot + +red_or3x1.dot: red_or3x1_* + $(YOSYS) red_or3x1_test.ys + +sym_mul.dot: sym_mul_* + $(YOSYS) sym_mul_test.ys + +mymul.dot: mymul_* + $(YOSYS) mymul_test.ys + +mulshift.dot: mulshift_* + $(YOSYS) mulshift_test.ys + +addshift.dot: addshift_* + $(YOSYS) addshift_test.ys + +.PHONY: clean +clean: + rm -f *.dot diff --git a/manual/PRESENTATION_ExAdv/addshift_map.v b/docs/source/code_examples/techmap/addshift_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/addshift_map.v rename to docs/source/code_examples/techmap/addshift_map.v diff --git a/manual/PRESENTATION_ExAdv/addshift_test.v b/docs/source/code_examples/techmap/addshift_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/addshift_test.v rename to docs/source/code_examples/techmap/addshift_test.v diff --git a/manual/PRESENTATION_ExAdv/addshift_test.ys b/docs/source/code_examples/techmap/addshift_test.ys similarity index 67% rename from manual/PRESENTATION_ExAdv/addshift_test.ys rename to docs/source/code_examples/techmap/addshift_test.ys index c08f1106a25..c15691b3353 100644 --- a/manual/PRESENTATION_ExAdv/addshift_test.ys +++ b/docs/source/code_examples/techmap/addshift_test.ys @@ -3,4 +3,4 @@ hierarchy -check -top test techmap -map addshift_map.v;; -show -prefix addshift -format pdf -notitle +show -prefix addshift -format dot -notitle diff --git a/manual/PRESENTATION_ExAdv/mulshift_map.v b/docs/source/code_examples/techmap/mulshift_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mulshift_map.v rename to docs/source/code_examples/techmap/mulshift_map.v diff --git a/manual/PRESENTATION_ExAdv/mulshift_test.v b/docs/source/code_examples/techmap/mulshift_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mulshift_test.v rename to docs/source/code_examples/techmap/mulshift_test.v diff --git a/manual/PRESENTATION_ExAdv/mulshift_test.ys b/docs/source/code_examples/techmap/mulshift_test.ys similarity index 64% rename from manual/PRESENTATION_ExAdv/mulshift_test.ys rename to docs/source/code_examples/techmap/mulshift_test.ys index c5dac49eb9b..79daaf0c429 100644 --- a/manual/PRESENTATION_ExAdv/mulshift_test.ys +++ b/docs/source/code_examples/techmap/mulshift_test.ys @@ -4,4 +4,4 @@ hierarchy -check -top test techmap -map sym_mul_map.v \ -map mulshift_map.v;; -show -prefix mulshift -format pdf -notitle -lib sym_mul_cells.v +show -prefix mulshift -format dot -notitle -lib sym_mul_cells.v diff --git a/manual/PRESENTATION_ExAdv/mymul_map.v b/docs/source/code_examples/techmap/mymul_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mymul_map.v rename to docs/source/code_examples/techmap/mymul_map.v diff --git a/manual/PRESENTATION_ExAdv/mymul_test.v b/docs/source/code_examples/techmap/mymul_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mymul_test.v rename to docs/source/code_examples/techmap/mymul_test.v diff --git a/manual/PRESENTATION_ExAdv/mymul_test.ys b/docs/source/code_examples/techmap/mymul_test.ys similarity index 84% rename from manual/PRESENTATION_ExAdv/mymul_test.ys rename to docs/source/code_examples/techmap/mymul_test.ys index 48203e31992..b7176fdc49a 100644 --- a/manual/PRESENTATION_ExAdv/mymul_test.ys +++ b/docs/source/code_examples/techmap/mymul_test.ys @@ -12,4 +12,4 @@ flatten miter sat -verify -prove trigger 0 miter splitnets -ports test_mapped/A -show -prefix mymul -format pdf -notitle test_mapped +show -prefix mymul -format dot -notitle test_mapped diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_cells.v b/docs/source/code_examples/techmap/red_or3x1_cells.v similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_cells.v rename to docs/source/code_examples/techmap/red_or3x1_cells.v diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_map.v b/docs/source/code_examples/techmap/red_or3x1_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_map.v rename to docs/source/code_examples/techmap/red_or3x1_map.v diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_test.v b/docs/source/code_examples/techmap/red_or3x1_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_test.v rename to docs/source/code_examples/techmap/red_or3x1_test.v diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_test.ys b/docs/source/code_examples/techmap/red_or3x1_test.ys similarity index 63% rename from manual/PRESENTATION_ExAdv/red_or3x1_test.ys rename to docs/source/code_examples/techmap/red_or3x1_test.ys index b9234603494..891b8177b89 100644 --- a/manual/PRESENTATION_ExAdv/red_or3x1_test.ys +++ b/docs/source/code_examples/techmap/red_or3x1_test.ys @@ -4,4 +4,4 @@ hierarchy -check -top test techmap -map red_or3x1_map.v;; splitnets -ports -show -prefix red_or3x1 -format pdf -notitle -lib red_or3x1_cells.v +show -prefix red_or3x1 -format dot -notitle -lib red_or3x1_cells.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_cells.v b/docs/source/code_examples/techmap/sym_mul_cells.v similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_cells.v rename to docs/source/code_examples/techmap/sym_mul_cells.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_map.v b/docs/source/code_examples/techmap/sym_mul_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_map.v rename to docs/source/code_examples/techmap/sym_mul_map.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_test.v b/docs/source/code_examples/techmap/sym_mul_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_test.v rename to docs/source/code_examples/techmap/sym_mul_test.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_test.ys b/docs/source/code_examples/techmap/sym_mul_test.ys similarity index 57% rename from manual/PRESENTATION_ExAdv/sym_mul_test.ys rename to docs/source/code_examples/techmap/sym_mul_test.ys index 0c07e7e877c..f19bee64a95 100644 --- a/manual/PRESENTATION_ExAdv/sym_mul_test.ys +++ b/docs/source/code_examples/techmap/sym_mul_test.ys @@ -3,4 +3,4 @@ hierarchy -check -top test techmap -map sym_mul_map.v;; -show -prefix sym_mul -format pdf -notitle -lib sym_mul_cells.v +show -prefix sym_mul -format dot -notitle -lib sym_mul_cells.v diff --git a/docs/source/conf.py b/docs/source/conf.py index ab9618c8b47..29d36d9c45f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -7,27 +7,39 @@ copyright ='2022 YosysHQ GmbH' # select HTML theme -html_theme = 'press' -html_logo = '../static/logo.png' -html_favicon = '../static/favico.png' +html_theme = 'furo' +templates_path = ["_templates"] +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']} + +html_theme_options = { + "sidebar_hide_name": True, + + "light_css_variables": { + "color-brand-primary": "#d6368f", + "color-brand-content": "#4b72b8", + "color-api-name": "#8857a3", + "color-api-pre-name": "#4b72b8", + "color-link": "#8857a3", + }, + + "dark_css_variables": { + "color-brand-primary": "#e488bb", + "color-brand-content": "#98bdff", + "color-api-name": "#8857a3", + "color-api-pre-name": "#4b72b8", + "color-link": "#be95d5", + }, +} # These folders are copied to the documentation's HTML output -html_static_path = ['../static', "../images"] +html_static_path = ['_static', "_images"] # code blocks style pygments_style = 'colorful' highlight_language = 'none' -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', 'sphinxcontrib.bibtex'] # Ensure that autosectionlabel will produce unique names @@ -39,12 +51,6 @@ bibtex_bibfiles = ['literature.bib'] -# unused docs -exclude_patterns = [ - "CHAPTER_Eval.rst", - "appendix/CHAPTER_StateOfTheArt.rst" -] - latex_elements = { 'preamble': r''' \usepackage{lmodern} @@ -53,10 +59,17 @@ ''' } +# include todos during rewrite +extensions.append('sphinx.ext.todo') +todo_include_todos = False + +# custom cmd-ref parsing/linking +sys.path += [os.path.dirname(__file__) + "/../"] +extensions.append('util.cmdref') + def setup(sphinx): - sys.path += [os.path.dirname(__file__) + "/../util"] - from RtlilLexer import RtlilLexer + from util.RtlilLexer import RtlilLexer sphinx.add_lexer("RTLIL", RtlilLexer) - from YoscryptLexer import YoscryptLexer + from util.YoscryptLexer import YoscryptLexer sphinx.add_lexer("yoscrypt", YoscryptLexer) \ No newline at end of file diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst new file mode 100644 index 00000000000..799b4ec48b4 --- /dev/null +++ b/docs/source/getting_started/example_synth.rst @@ -0,0 +1,855 @@ +Synthesis starter +----------------- + +This page will be a guided walkthrough of the prepackaged iCE40 FPGA synthesis +script - :cmd:ref:`synth_ice40`. We will take a simple design through each +step, looking at the commands being called and what they do to the design. While +:cmd:ref:`synth_ice40` is specific to the iCE40 platform, most of the operations +we will be discussing are common across the majority of FPGA synthesis scripts. +Thus, this document will provide a good foundational understanding of how +synthesis in Yosys is performed, regardless of the actual architecture being +used. + +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/synth` + +Demo design +~~~~~~~~~~~ + +.. role:: yoscrypt(code) + :language: yoscrypt + +First, let's quickly look at the design we'll be synthesizing: + +.. todo:: reconsider including the whole (~77 line) design like this + +.. literalinclude:: /code_examples/fifo/fifo.v + :language: Verilog + :linenos: + :caption: :file:`fifo.v` + :name: fifo-v + +.. todo:: fifo.v description + +Loading the design +~~~~~~~~~~~~~~~~~~ + +Let's load the design into Yosys. From the command line, we can call ``yosys +fifo.v``. This will open an interactive Yosys shell session and immediately +parse the code from :ref:`fifo-v` and convert it into an Abstract Syntax Tree +(AST). If you are interested in how this happens, there is more information in +the document, :doc:`/yosys_internals/flow/verilog_frontend`. For now, suffice +it to say that we do this to simplify further processing of the design. You +should see something like the following: + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: console + :start-at: $ yosys fifo.v + :end-before: echo on + +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/more_scripting/load_design` + +Elaboration +~~~~~~~~~~~ + +Now that we are in the interactive shell, we can call Yosys commands directly. +Our overall goal is to call :yoscrypt:`synth_ice40 -top fifo`, but for now we +can run each of the commands individually for a better sense of how each part +contributes to the flow. We will also start with just a single module; +``addr_gen``. + +At the bottom of the :cmd:ref:`help` output for +:cmd:ref:`synth_ice40` is the complete list of commands called by this script. +Let's start with the section labeled ``begin``: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: begin: + :end-before: flatten: + :dedent: + :caption: ``begin`` section + :name: synth_begin + +:yoscrypt:`read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v` loads the +iCE40 cell models which allows us to include platform specific IP blocks in our +design. PLLs are a common example of this, where we might need to reference +``SB_PLL40_CORE`` directly rather than being able to rely on mapping passes +later. Since our simple design doesn't use any of these IP blocks, we can skip +this command for now. Because these cell models will also be needed once we +start mapping to hardware we will still need to load them later. + +.. note:: + + ``+/`` is a dynamic reference to the Yosys ``share`` directory. By default, + this is ``/usr/local/share/yosys``. If using a locally built version of + Yosys from the source directory, this will be the ``share`` folder in the + same directory. + +.. _addr_gen_example: + +The addr_gen module +^^^^^^^^^^^^^^^^^^^ + +Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy +-top addr_gen`. This command declares that the top level module is +``addr_gen``, and everything else can be discarded. + +.. literalinclude:: /code_examples/fifo/fifo.v + :language: Verilog + :start-at: module addr_gen + :end-at: endmodule //addr_gen + :lineno-match: + :caption: ``addr_gen`` module source + :name: addr_gen-v + +.. note:: + + :cmd:ref:`hierarchy` should always be the first command after the design has + been read. By specifying the top module, :cmd:ref:`hierarchy` will also set + the ``(* top *)`` attribute on it. This is used by other commands that need + to know which module is the top. + +.. use doscon for a console-like display that supports the `yosys> [command]` format. + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> hierarchy -top addr_gen + :end-before: yosys> select + :caption: :yoscrypt:`hierarchy -top addr_gen` output + :name: hierarchy_output + +Our ``addr_gen`` circuit now looks like this: + +.. figure:: /_images/code_examples/fifo/addr_gen_hier.* + :class: width-helper + :name: addr_gen_hier + + ``addr_gen`` module after :cmd:ref:`hierarchy` + +Simple operations like ``addr + 1`` and ``addr == MAX_DATA-1`` can be extracted +from our ``always @`` block in :ref:`addr_gen-v`. This gives us the highlighted +``$add`` and ``$eq`` cells we see. But control logic (like the ``if .. else``) +and memory elements (like the ``addr <= 0``) are not so straightforward. These +get put into "processes", shown in the schematic as ``PROC``. Note how the +second line refers to the line numbers of the start/end of the corresponding +``always @`` block. In the case of an ``initial`` block, we instead see the +``PROC`` referring to line 0. + +To handle these, let us now introduce the next command: :doc:`/cmd/proc`. +:cmd:ref:`proc` is a macro command like :cmd:ref:`synth_ice40`. Rather than +modifying the design directly, it instead calls a series of other commands. In +the case of :cmd:ref:`proc`, these sub-commands work to convert the behavioral +logic of processes into multiplexers and registers. Let's see what happens when +we run it. For now, we will call :yoscrypt:`proc -noopt` to prevent some +automatic optimizations which would normally happen. + +.. figure:: /_images/code_examples/fifo/addr_gen_proc.* + :class: width-helper + :name: addr_gen_proc + + ``addr_gen`` module after :yoscrypt:`proc -noopt` + +There are now a few new cells from our ``always @``, which have been +highlighted. The ``if`` statements are now modeled with ``$mux`` cells, while +the register uses an ``$adff`` cell. If we look at the terminal output we can +also see all of the different ``proc_*`` commands being called. We will look at +each of these in more detail in :doc:`/using_yosys/synthesis/proc`. + +Notice how in the top left of :ref:`addr_gen_proc` we have a floating wire, +generated from the initial assignment of 0 to the ``addr`` wire. However, this +initial assignment is not synthesizable, so this will need to be cleaned up +before we can generate the physical hardware. We can do this now by calling +:cmd:ref:`clean`. We're also going to call :cmd:ref:`opt_expr` now, which would +normally be called at the end of :cmd:ref:`proc`. We can call both commands at +the same time by separating them with a colon and space: :yoscrypt:`opt_expr; +clean`. + +.. figure:: /_images/code_examples/fifo/addr_gen_clean.* + :class: width-helper + :name: addr_gen_clean + + ``addr_gen`` module after :yoscrypt:`opt_expr; clean` + +You may also notice that the highlighted ``$eq`` cell input of ``255`` has +changed to ``8'11111111``. Constant values are presented in the format +``'``, with 32-bit values instead using the decimal number. +This indicates that the constant input has been reduced from 32-bit wide to +8-bit wide. This is a side-effect of running :cmd:ref:`opt_expr`, which +performs constant folding and simple expression rewriting. For more on why +this happens, refer to :doc:`/using_yosys/synthesis/opt` and the :ref:`section +on opt_expr `. + +.. note:: + + :doc:`/cmd/clean` can also be called with two semicolons after any command, + for example we could have called :yoscrypt:`opt_expr;;` instead of + :yoscrypt:`opt_expr; clean`. You may notice some scripts will end each line + with ``;;``. It is beneficial to run :cmd:ref:`clean` before inspecting + intermediate products to remove disconnected parts of the circuit which have + been left over, and in some cases can reduce the processing required in + subsequent commands. + +.. todo:: consider a brief glossary for terms like adff + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/proc` + - :doc:`/using_yosys/synthesis/opt` + +The full example +^^^^^^^^^^^^^^^^ + +Let's now go back and check on our full design by using :yoscrypt:`hierarchy +-check -top fifo`. By passing the ``-check`` option there we are also telling +the :cmd:ref:`hierarchy` command that if the design includes any non-blackbox +modules without an implementation it should return an error. + +Note that if we tried to run this command now then we would get an error. This +is because we already removed all of the modules other than ``addr_gen``. We +could restart our shell session, but instead let's use two new commands: + +- :doc:`/cmd/design`, and +- :doc:`/cmd/read_verilog`. + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: design -reset + :end-before: yosys> proc + :caption: reloading :file:`fifo.v` and running :yoscrypt:`hierarchy -check -top fifo` + +Notice how this time we didn't see any of those `$abstract` modules? That's +because when we ran ``yosys fifo.v``, the first command Yosys called was +:yoscrypt:`read_verilog -defer fifo.v`. The ``-defer`` option there tells +:cmd:ref:`read_verilog` only read the abstract syntax tree and defer actual +compilation to a later :cmd:ref:`hierarchy` command. This is useful in cases +where the default parameters of modules yield invalid code which is not +synthesizable. This is why Yosys defers compilation automatically and is one of +the reasons why hierarchy should always be the first command after loading the +design. If we know that our design won't run into this issue, we can skip the +``-defer``. + +.. todo:: :cmd:ref:`hierarchy` failure modes + +.. note:: + + The number before a command's output increments with each command run. Don't + worry if your numbers don't match ours! The output you are seeing comes from + the same script that was used to generate the images in this document, + included in the source as :file:`fifo.ys`. There are extra commands being run + which you don't see, but feel free to try them yourself, or play around with + different commands. You can always start over with a clean slate by calling + ``exit`` or hitting :kbd:`ctrl+d` (i.e. EOF) and re-launching the Yosys + interactive terminal. :kbd:`ctrl+c` (i.e. SIGINT) will also end the terminal + session but will return an error code rather than exiting gracefully. + +We can also run :cmd:ref:`proc` now to finish off the full :ref:`synth_begin`. +Because the design schematic is quite large, we will be showing just the data +path for the ``rdata`` output. If you would like to see the entire design for +yourself, you can do so with :doc:`/cmd/show`. Note that the :cmd:ref:`show` +command only works with a single module, so you may need to call it with +:yoscrypt:`show fifo`. :ref:`show_intro` section in +:doc:`/getting_started/scripting_intro` has more on how to use :cmd:ref:`show`. + +.. figure:: /_images/code_examples/fifo/rdata_proc.* + :class: width-helper + :name: rdata_proc + + ``rdata`` output after :cmd:ref:`proc` + +The highlighted ``fifo_reader`` block contains an instance of the +:ref:`addr_gen_proc` that we looked at earlier. Notice how the type is shown as +``$paramod\\addr_gen\\MAX_DATA=s32'...``. This is a "parametric module": an +instance of the ``addr_gen`` module with the ``MAX_DATA`` parameter set to the +given value. + +The other highlighted block is a ``$memrd`` cell. At this stage of synthesis we +don't yet know what type of memory is going to be implemented, but we *do* know +that ``rdata <= data[raddr];`` could be implemented as a read from memory. Note +that the ``$memrd`` cell here is asynchronous, with both the clock and enable +signal undefined; shown with the ``1'x`` inputs. + +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/proc` + +Flattening +~~~~~~~~~~ + +At this stage of a synthesis flow there are a few other commands we could run. +In :cmd:ref:`synth_ice40` we get these: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: flatten: + :end-before: coarse: + :dedent: + :name: synth_flatten + :caption: ``flatten`` section + +First off is :cmd:ref:`flatten`. Flattening the design like this can allow for +optimizations between modules which would otherwise be missed. Let's run +:yoscrypt:`flatten;;` on our design. + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> flatten + :end-before: yosys> select + :name: flat_clean + :caption: output of :yoscrypt:`flatten;;` + +.. figure:: /_images/code_examples/fifo/rdata_flat.* + :class: width-helper + :name: rdata_flat + + ``rdata`` output after :yoscrypt:`flatten;;` + +.. role:: yoterm(code) + :language: doscon + +The pieces have moved around a bit, but we can see :ref:`addr_gen_proc` from +earlier has replaced the ``fifo_reader`` block in :ref:`rdata_proc`. We can +also see that the ``addr`` output has been renamed to :file:`fifo_reader.addr` +and merged with the ``raddr`` wire feeding into the ``$memrd`` cell. This wire +merging happened during the call to :cmd:ref:`clean` which we can see in the +:ref:`flat_clean`. + +.. note:: + + :cmd:ref:`flatten` and :cmd:ref:`clean` would normally be combined into a + single :yoterm:`yosys> flatten;;` output, but they appear separately here as + a side effect of using :cmd:ref:`echo` for generating the terminal style + output. + +Depending on the target architecture, this stage of synthesis might also see +commands such as :cmd:ref:`tribuf` with the ``-logic`` option and +:cmd:ref:`deminout`. These remove tristate and inout constructs respectively, +replacing them with logic suitable for mapping to an FPGA. Since we do not have +any such constructs in our example running these commands does not change our +design. + +The coarse-grain representation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +At this stage, the design is in coarse-grain representation. It still looks +recognizable, and cells are word-level operators with parametrizable width. This +is the stage of synthesis where we do things like const propagation, expression +rewriting, and trimming unused parts of wires. + +This is also where we convert our FSMs and hard blocks like DSPs or memories. +Such elements have to be inferred from patterns in the design and there are +special passes for each. Detection of these patterns can also be affected by +optimizations and other transformations done previously. + +.. note:: + + While the iCE40 flow had a :ref:`synth_flatten` and put :cmd:ref:`proc` in + the :ref:`synth_begin`, some synthesis scripts will instead include these in + this section. + +Part 1 +^^^^^^ + +In the iCE40 flow, we start with the following commands: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: coarse: + :end-before: wreduce + :dedent: + :caption: ``coarse`` section (part 1) + :name: synth_coarse1 + +We've already come across :cmd:ref:`opt_expr`, and :cmd:ref:`opt_clean` is the +same as :cmd:ref:`clean` but with more verbose output. The :cmd:ref:`check` +pass identifies a few obvious problems which will cause errors later. Calling +it here lets us fail faster rather than wasting time on something we know is +impossible. + +Next up is :yoscrypt:`opt -nodffe -nosdff` performing a set of simple +optimizations on the design. This command also ensures that only a specific +subset of FF types are included, in preparation for the next command: +:doc:`/cmd/fsm`. Both :cmd:ref:`opt` and :cmd:ref:`fsm` are macro commands +which are explored in more detail in :doc:`/using_yosys/synthesis/opt` and +:doc:`/using_yosys/synthesis/fsm` respectively. + +Up until now, the data path for ``rdata`` has remained the same since +:ref:`rdata_flat`. However the next call to :cmd:ref:`opt` does cause a change. +Specifically, the call to :cmd:ref:`opt_dff` without the ``-nodffe -nosdff`` +options is able to fold one of the ``$mux`` cells into the ``$adff`` to form an +``$adffe`` cell; highlighted below: + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> opt_dff + :end-before: yosys> select + :caption: output of :cmd:ref:`opt_dff` + +.. figure:: /_images/code_examples/fifo/rdata_adffe.* + :class: width-helper + :name: rdata_adffe + + ``rdata`` output after :cmd:ref:`opt_dff` + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/fsm` + - :doc:`/using_yosys/synthesis/opt` + +Part 2 +^^^^^^ + +The next group of commands performs a series of optimizations: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-at: wreduce + :end-before: t:$mul + :dedent: + :caption: ``coarse`` section (part 2) + :name: synth_coarse2 + +First up is :doc:`/cmd/wreduce`. If we run this we get the following: + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> wreduce + :end-before: yosys> select + :caption: output of :cmd:ref:`wreduce` + +Looking at the data path for ``rdata``, the most relevant of these width +reductions are the ones affecting ``fifo.$flatten\fifo_reader.$add$fifo.v``. +That is the ``$add`` cell incrementing the fifo_reader address. We can look at +the schematic and see the output of that cell has now changed. + +.. todo:: pending bugfix in :cmd:ref:`wreduce` and/or :cmd:ref:`opt_clean` + +.. figure:: /_images/code_examples/fifo/rdata_wreduce.* + :class: width-helper + :name: rdata_wreduce + + ``rdata`` output after :cmd:ref:`wreduce` + +The next two (new) commands are :doc:`/cmd/peepopt` and :doc:`/cmd/share`. +Neither of these affect our design, and they're explored in more detail in +:doc:`/using_yosys/synthesis/opt`, so let's skip over them. :yoscrypt:`techmap +-map +/cmp2lut.v -D LUT_WIDTH=4` optimizes certain comparison operators by +converting them to LUTs instead. The usage of :cmd:ref:`techmap` is explored +more in :doc:`/using_yosys/synthesis/techmap_synth`. + +Our next command to run is +:doc:`/cmd/memory_dff`. + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> memory_dff + :end-before: yosys> select + :caption: output of :cmd:ref:`memory_dff` + +.. figure:: /_images/code_examples/fifo/rdata_memrdv2.* + :class: width-helper + :name: rdata_memrdv2 + + ``rdata`` output after :cmd:ref:`memory_dff` + +As the title suggests, :cmd:ref:`memory_dff` has merged the output ``$dff`` into +the ``$memrd`` cell and converted it to a ``$memrd_v2`` (highlighted). This has +also connected the ``CLK`` port to the ``clk`` input as it is now a synchronous +memory read with appropriate enable (``EN=1'1``) and reset (``ARST=1'0`` and +``SRST=1'0``) inputs. + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/opt` + - :doc:`/using_yosys/synthesis/techmap_synth` + - :doc:`/using_yosys/synthesis/memory` + +Part 3 +^^^^^^ + +The third part of the :cmd:ref:`synth_ice40` flow is a series of commands for +mapping to DSPs. By default, the iCE40 flow will not map to the hardware DSP +blocks and will only be performed if called with the ``-dsp`` flag: +:yoscrypt:`synth_ice40 -dsp`. While our example has nothing that could be +mapped to DSPs we can still take a quick look at the commands here and describe +what they do. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-at: t:$mul + :end-before: alumacc + :dedent: + :caption: ``coarse`` section (part 3) + :name: synth_coarse3 + +:yoscrypt:`wreduce t:$mul` performs width reduction again, this time targetting +only cells of type ``$mul``. :yoscrypt:`techmap -map +/mul2dsp.v -map ++/ice40/dsp_map.v ... -D DSP_NAME=$__MUL16X16` uses :cmd:ref:`techmap` to map +``$mul`` cells to ``$__MUL16X16`` which are, in turn, mapped to the iCE40 +``SB_MAC16``. Any multipliers which aren't compatible with conversion to +``$__MUL16X16`` are relabelled to ``$__soft_mul`` before :cmd:ref:`chtype` +changes them back to ``$mul``. + +During the mul2dsp conversion, some of the intermediate signals are marked with +the attribute ``mul2dsp``. By calling :yoscrypt:`select a:mul2dsp` we restrict +the following commands to only operate on the cells and wires used for these +signals. :cmd:ref:`setattr` removes the now unnecessary ``mul2dsp`` attribute. +:cmd:ref:`opt_expr` we've already come across for const folding and simple +expression rewriting, the ``-fine`` option just enables more fine-grain +optimizations. Then we perform width reduction a final time and clear the +selection. + +.. todo:: ``ice40_dsp`` is pmgen + +Finally we have :cmd:ref:`ice40_dsp`: similar to the :cmd:ref:`memory_dff` +command we saw in the previous section, this merges any surrounding registers +into the ``SB_MAC16`` cell. This includes not just the input/output registers, +but also pipeline registers and even a post-adder where applicable: turning a +multiply + add into a single multiply-accumulate. + +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/techmap_synth` + +Part 4 +^^^^^^ + +That brings us to the fourth and final part for the iCE40 synthesis flow: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-at: alumacc + :end-before: map_ram: + :dedent: + :caption: ``coarse`` section (part 4) + :name: synth_coarse4 + +Where before each type of arithmetic operation had its own cell, e.g. ``$add``, +we now want to extract these into ``$alu`` and ``$macc`` cells which can help +identify opportunities for reusing logic. We do this by running +:cmd:ref:`alumacc`, which we can see produce the following changes in our +example design: + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> alumacc + :end-before: yosys> select + :caption: output of :cmd:ref:`alumacc` + +.. figure:: /_images/code_examples/fifo/rdata_alumacc.* + :class: width-helper + :name: rdata_alumacc + + ``rdata`` output after :cmd:ref:`alumacc` + +Once these cells have been inserted, the call to :cmd:ref:`opt` can combine +cells which are now identical but may have been missed due to e.g. the +difference between ``$add`` and ``$sub``. + +The other new command in this part is :doc:`/cmd/memory`. :cmd:ref:`memory` is +another macro command which we examine in more detail in +:doc:`/using_yosys/synthesis/memory`. For this document, let us focus just on +the step most relevant to our example: :cmd:ref:`memory_collect`. Up until this +point, our memory reads and our memory writes have been totally disjoint cells; +operating on the same memory only in the abstract. :cmd:ref:`memory_collect` +combines all of the reads and writes for a memory block into a single cell. + +.. figure:: /_images/code_examples/fifo/rdata_coarse.* + :class: width-helper + :name: rdata_coarse + + ``rdata`` output after :cmd:ref:`memory_collect` + +Looking at the schematic after running :cmd:ref:`memory_collect` we see that our +``$memrd_v2`` cell has been replaced with a ``$mem_v2`` cell named ``data``, the +same name that we used in :ref:`fifo-v`. Where before we had a single set of +signals for address and enable, we now have one set for reading (``RD_*``) and +one for writing (``WR_*``), as well as both ``WR_DATA`` input and ``RD_DATA`` +output. + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/opt` + - :doc:`/using_yosys/synthesis/memory` + +Final note +^^^^^^^^^^ + +Having now reached the end of the the coarse-grain representation, we could also +have gotten here by running :yoscrypt:`synth_ice40 -top fifo -run :map_ram` +after loading the design. The :yoscrypt:`-run :` option +with an empty ```` starts from the :ref:`synth_begin`, while the +```` runs up to but including the :ref:`map_ram`. + +Hardware mapping +~~~~~~~~~~~~~~~~ + +The remaining sections each map a different type of hardware and are much more +architecture dependent than the previous sections. As such we will only be +looking at each section very briefly. + +If you skipped calling :yoscrypt:`read_verilog -D ICE40_HX -lib -specify ++/ice40/cells_sim.v` earlier, do it now. + +Memory blocks +^^^^^^^^^^^^^ + +Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap` and +:cmd:ref:`techmap`. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_ram: + :end-before: map_ffram: + :dedent: + :name: map_ram + :caption: ``map_ram`` section + +.. figure:: /_images/code_examples/fifo/rdata_map_ram.* + :class: width-helper + :name: rdata_map_ram + + ``rdata`` output after :ref:`map_ram` + +The :ref:`map_ram` converts the generic ``$mem_v2`` into the iCE40 +``SB_RAM40_4K`` (highlighted). We can also see the memory address has been +remapped, and the data bits have been reordered (or swizzled). There is also +now a ``$mux`` cell controlling the value of ``rdata``. In :ref:`fifo-v` we +wrote our memory as read-before-write, however the ``SB_RAM40_4K`` has undefined +behaviour when reading from and writing to the same address in the same cycle. +As a result, extra logic is added so that the generated circuit matches the +behaviour of the verilog. :ref:`no_rw_check` describes how we could change our +verilog to match our hardware instead. + +If we run :cmd:ref:`memory_libmap` under the :cmd:ref:`debug` command we can see +candidates which were identified for mapping, along with the costs of each and +what logic requires emulation. + +.. literalinclude:: /code_examples/fifo/fifo.libmap + :language: doscon + :lines: 2, 6- + +The ``$__ICE40_RAM4K_`` cell is defined in the file |techlibs/ice40/brams.txt|_, +with the mapping to ``SB_RAM40_4K`` done by :cmd:ref:`techmap` using +|techlibs/ice40/brams_map.v|_. Any leftover memory cells are then converted +into flip flops (the ``logic fallback``) with :cmd:ref:`memory_map`. + +.. |techlibs/ice40/brams.txt| replace:: :file:`techlibs/ice40/brams.txt` +.. _techlibs/ice40/brams.txt: https://github.com/YosysHQ/yosys/tree/master/techlibs/ice40/brams.txt +.. |techlibs/ice40/brams_map.v| replace:: :file:`techlibs/ice40/brams_map.v` +.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/master/techlibs/ice40/brams_map.v + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_ffram: + :end-before: map_gates: + :dedent: + :name: map_ffram + :caption: ``map_ffram`` section + +.. figure:: /_images/code_examples/fifo/rdata_map_ffram.* + :class: width-helper + :name: rdata_map_ffram + + ``rdata`` output after :ref:`map_ffram` + +.. note:: + + The visual clutter on the ``RDATA`` output port (highlighted) is an + unfortunate side effect of :cmd:ref:`opt_clean` on the swizzled data bits. In + connecting the ``$mux`` input port directly to ``RDATA`` to reduce the number + of wires, the ``$techmap579\data.0.0.RDATA`` wire becomes more visually + complex. + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/techmap_synth` + - :doc:`/using_yosys/synthesis/memory` + +Arithmetic +^^^^^^^^^^ + +Uses :cmd:ref:`techmap` to map basic arithmetic logic to hardware. This sees +somewhat of an explosion in cells as multi-bit ``$mux`` and ``$adffe`` are +replaced with single-bit ``$_MUX_`` and ``$_DFFE_PP0P_`` cells, while the +``$alu`` is replaced with primitive ``$_OR_`` and ``$_NOT_`` gates and a +``$lut`` cell. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_gates: + :end-before: map_ffs: + :dedent: + :name: map_gates + :caption: ``map_gates`` section + +.. figure:: /_images/code_examples/fifo/rdata_map_gates.* + :class: width-helper + :name: rdata_map_gates + + ``rdata`` output after :ref:`map_gates` + +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/techmap_synth` + +Flip-flops +^^^^^^^^^^ + +Convert FFs to the types supported in hardware with :cmd:ref:`dfflegalize`, and +then use :cmd:ref:`techmap` to map them. In our example, this converts the +``$_DFFE_PP0P_`` cells to ``SB_DFFER``. + +We also run :cmd:ref:`simplemap` here to convert any remaining cells which could +not be mapped to hardware into gate-level primitives. This includes optimizing +``$_MUX_`` cells where one of the inputs is a constant ``1'0``, replacing it +instead with an ``$_AND_`` cell. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_ffs: + :end-before: map_luts: + :dedent: + :name: map_ffs + :caption: ``map_ffs`` section + +.. figure:: /_images/code_examples/fifo/rdata_map_ffs.* + :class: width-helper + :name: rdata_map_ffs + + ``rdata`` output after :ref:`map_ffs` + +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/techmap_synth` + +LUTs +^^^^ + +:cmd:ref:`abc` and :cmd:ref:`techmap` are used to map LUTs; converting primitive +cell types to use ``$lut`` and ``SB_CARRY`` cells. Note that the iCE40 flow +uses :cmd:ref:`abc9` rather than :cmd:ref:`abc`. For more on what these do, and +what the difference between these two commands are, refer to +:doc:`/using_yosys/synthesis/abc`. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_luts: + :end-before: map_cells: + :dedent: + :name: map_luts + :caption: ``map_luts`` section + +.. figure:: /_images/code_examples/fifo/rdata_map_luts.* + :class: width-helper + :name: rdata_map_luts + + ``rdata`` output after :ref:`map_luts` + +Finally we use :cmd:ref:`techmap` to map the generic ``$lut`` cells to iCE40 +``SB_LUT4`` cells. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_cells: + :end-before: check: + :dedent: + :name: map_cells + :caption: ``map_cells`` section + +.. figure:: /_images/code_examples/fifo/rdata_map_cells.* + :class: width-helper + :name: rdata_map_cells + + ``rdata`` output after :ref:`map_cells` + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/techmap_synth` + - :doc:`/using_yosys/synthesis/abc` + +Other cells +^^^^^^^^^^^ + +The following commands may also be used for mapping other cells: + +:cmd:ref:`hilomap` + Some architectures require special driver cells for driving a constant hi or + lo value. This command replaces simple constants with instances of such + driver cells. + +:cmd:ref:`iopadmap` + Top-level input/outputs must usually be implemented using special I/O-pad + cells. This command inserts such cells to the design. + +These commands tend to either be in the :ref:`map_cells` or after the +:ref:`check` depending on the flow. + +Final steps +~~~~~~~~~~~~ + +The next section of the iCE40 synth flow performs some sanity checking and final +tidy up: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: check: + :end-before: blif: + :dedent: + :name: check + :caption: ``check`` section + +The new commands here are: + +- :doc:`/cmd/autoname`, +- :doc:`/cmd/stat`, and +- :doc:`/cmd/blackbox`. + +The output from :cmd:ref:`stat` is useful for checking resource utilization; +providing a list of cells used in the design and the number of each, as well as +the number of other resources used such as wires and processes. For this +design, the final call to :cmd:ref:`stat` should look something like the +following: + +.. literalinclude:: /code_examples/fifo/fifo.stat + :language: doscon + :start-at: yosys> stat -top fifo + +Note that the :yoscrypt:`-top fifo` here is optional. :cmd:ref:`stat` will +automatically use the module with the ``top`` attribute set, which ``fifo`` was +when we called :cmd:ref:`hierarchy`. If no module is marked ``top``, then stats +will be shown for each module selected. + +The :cmd:ref:`stat` output is also useful as a kind of sanity-check: Since we +have already run :cmd:ref:`proc`, we wouldn't expect there to be any processes. +We also expect ``data`` to use hard memory; if instead of an ``SB_RAM40_4K`` saw +a high number of flip-flops being used we might suspect something was wrong. + +If we instead called :cmd:ref:`stat` immediately after :yoscrypt:`read_verilog +fifo.v` we would see something very different: + +.. literalinclude:: /code_examples/fifo/fifo.stat + :language: doscon + :start-at: yosys> stat + :end-before: yosys> stat -top fifo + +Notice how ``fifo`` and ``addr_gen`` are listed separately, and the statistics +for ``fifo`` show 2 ``addr_gen`` modules. Because this is before the memory has +been mapped, we also see that there is 1 memory with 2048 memory bits; matching +our 8-bit wide ``data`` memory with 256 values (:math:`8*256=2048`). + +Synthesis output +^^^^^^^^^^^^^^^^ + +The iCE40 synthesis flow has the following output modes available: + +- :doc:`/cmd/write_blif`, +- :doc:`/cmd/write_edif`, and +- :doc:`/cmd/write_json`. + +As an example, if we called :yoscrypt:`synth_ice40 -top fifo -json fifo.json`, +our synthesized ``fifo`` design will be output as :file:`fifo.json`. We can +then read the design back into Yosys with :cmd:ref:`read_json`, but make sure +you use :yoscrypt:`design -reset` or open a new interactive terminal first. The +JSON output we get can also be loaded into `nextpnr`_ to do place and route; but +that is beyond the scope of this documentation. + +.. _nextpnr: https://github.com/YosysHQ/nextpnr + +.. seealso:: :doc:`/cmd/synth_ice40` diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst new file mode 100644 index 00000000000..7a92c212ae6 --- /dev/null +++ b/docs/source/getting_started/index.rst @@ -0,0 +1,13 @@ +Getting started with Yosys +========================== + +This section covers how to get started with Yosys, from installation to a guided +walkthrough of synthesizing a design for hardware, and finishing with an +introduction to writing re-usable Yosys scripts. + +.. toctree:: + :maxdepth: 3 + + installation + example_synth + scripting_intro diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst new file mode 100644 index 00000000000..4dd5244b912 --- /dev/null +++ b/docs/source/getting_started/installation.rst @@ -0,0 +1,216 @@ +Installation +------------ + +This document will guide you through the process of installing Yosys. + +CAD suite(s) +~~~~~~~~~~~~ + +Yosys is part of the `Tabby CAD Suite +`_ and the `OSS CAD Suite +`_! The easiest way to use yosys +is to install the binary software suite, which contains all required +dependencies and related tools. + +* `Contact YosysHQ `_ for a `Tabby CAD Suite + `_ Evaluation License and + download link +* OR go to https://github.com/YosysHQ/oss-cad-suite-build/releases to download + the free OSS CAD Suite +* Follow the `Install Instructions on GitHub + `_ + +Make sure to get a Tabby CAD Suite Evaluation License if you need features such +as industry-grade SystemVerilog and VHDL parsers! + +For more information about the difference between Tabby CAD Suite and the OSS +CAD Suite, please visit https://www.yosyshq.com/tabby-cad-datasheet + +Many Linux distributions also provide Yosys binaries, some more up to date than +others. Check with your package manager! + +Targeted architectures +^^^^^^^^^^^^^^^^^^^^^^ + +The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures: + +.. only:: html + + - linux-x64 |linux-x64| + - Most personal Linux based computers + + - darwin-x64 |darwin-x64| + - macOS 12 or later with Intel CPU + + - darwin-arm64 |darwin-arm64| + - macOS 12 or later with M1/M2 CPU + + - windows-x64 |windows-x64| + - Targeted for Windows 10 and 11 + + - linux-arm64 |linux-arm64| + +.. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build +.. _nightly builds: https://github.com/YosysHQ/oss-cad-suite-build/releases/latest + +.. |linux-x64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-x64.yml/badge.svg +.. |darwin-x64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/darwin-x64.yml/badge.svg +.. |darwin-arm64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/darwin-arm64.yml/badge.svg +.. |windows-x64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/windows-x64.yml/badge.svg +.. |linux-arm64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-arm64.yml/badge.svg + +Building from source +~~~~~~~~~~~~~~~~~~~~ + +Refer to the `readme`_ for the most up-to-date install instructions. + +.. _readme: https://github.com/YosysHQ/yosys#building-from-source + +Supported platforms +^^^^^^^^^^^^^^^^^^^ + +The following platforms are supported and regularly tested: + +- Linux +- macOS + +Other platforms which may work, but instructions may not be up to date and are +not regularly tested: + +- FreeBSD +- WSL +- Windows with (e.g.) Cygwin + +Build prerequisites +^^^^^^^^^^^^^^^^^^^ + +A C++ compiler with C++11 support is required as well as some standard tools +such as GNU Flex, GNU Bison, Make and Python. Some additional tools: readline, +libffi, Tcl and zlib; are optional but enabled by default (see +:makevar:`ENABLE_*` settings in Makefile). Graphviz and Xdot are used by the +:cmd:ref:`show` command to display schematics. + +Installing all prerequisites for Ubuntu 20.04: + +.. code:: console + + sudo sudo apt-get install build-essential clang bison flex \ + libreadline-dev gawk tcl-dev libffi-dev git make \ + graphviz xdot pkg-config python3 libboost-system-dev \ + libboost-python-dev libboost-filesystem-dev zlib1g-dev + +Installing all prerequisites for macOS 11 (with Homebrew): + +.. code:: console + + brew install bison flex gawk libffi git graphviz \ + pkg-config python3 tcl-tk xdot bash boost-python3 + +Running the build system +^^^^^^^^^^^^^^^^^^^^^^^^ + +From the root `yosys` directory, call the following commands: + +.. code:: console + + make + sudo make install + +This will build and then install Yosys, making it available on the command line +as `yosys`. Note that this also downloads, builds, and installs `ABC`_ (using +:program:`yosys-abc` as the executable name). + +.. _ABC: https://github.com/berkeley-abc/abc + +The default compiler is ``clang``, to change between ``clang`` and ``gcc``, use +one of the following: + +.. code:: console + + make config-clang + make config-gcc + +To use a compiler different than the default, use: + +.. code:: console + + make CXX="g++-11" + +.. seealso:: + + Refer to :doc:`/test_suites` for details on testing Yosys once compiled. + +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. + +``docs/`` + Contains the source for this documentation, including images and sample code. + +``examples/`` + Contains example code for using Yosys with some other tools including a demo + of the Yosys Python api, and synthesizing for various toolchains such as + Intel and Anlogic. + +``frontends/`` + This directory contains a subdirectory for each of the frontend modules. + +``guidelines/`` + Contains developer guidelines, including the code of conduct and coding style + guide. + +``kernel/`` + This directory contains all the core functionality of Yosys. This includes + the functions and definitions for working with the RTLIL data structures + (:file:`rtlil.{h|cc}`), the ``main()`` function (:file:`driver.cc`), the + internal framework for generating log messages (:file:`log.{h|cc}`), the + internal framework for registering and calling passes + (:file:`register.{h|cc}`), some core commands that are not really passes + (:file:`select.cc`, :file:`show.cc`, …) and a couple of other small utility + libraries. + +``libs/`` + Libraries packaged with Yosys builds are contained in this folder. See + :doc:`/appendix/auxlibs`. + +``misc/`` + Other miscellany which doesn't fit anywhere else. + +``passes/`` + This directory contains a subdirectory for each pass or group of passes. For + example as of this writing the directory :file:`passes/hierarchy/` contains the + code for three passes: :cmd:ref:`hierarchy`, :cmd:ref:`submod`, and + :cmd:ref:`uniquify`. + +``techlibs/`` + This directory contains simulation models and standard implementations for + the cells from the internal cell library. + +``tests/`` + This directory contains the suite of unit tests and regression tests used by + Yosys. See :doc:`/test_suites`. + +The top-level Makefile includes :file:`frontends/{*}/Makefile.inc`, +:file:`passes/{*}/Makefile.inc` and :file:`backends/{*}/Makefile.inc`. So when +extending Yosys it is enough to create a new directory in :file:`frontends/`, +:file:`passes/` or :file:`backends/` with your sources and a +:file:`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 :file:`passes/opt/opt_dff.cc` and :file:`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. diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst new file mode 100644 index 00000000000..63eca990125 --- /dev/null +++ b/docs/source/getting_started/scripting_intro.rst @@ -0,0 +1,197 @@ +Scripting in Yosys +------------------ + +On the previous page we went through a synthesis script, running each command in +the interactive Yosys shell. On this page, we will be introducing the script +file format and how you can make your own synthesis scripts. + +Yosys script files typically use the :file:`.ys` extension and contain a set of +commands for Yosys to run sequentially. These commands are the same ones we +were using on the previous page like :cmd:ref:`read_verilog` and +:cmd:ref:`hierarchy`. As with the interactive shell, each command consists of +the command name, and an optional whitespace separated list of arguments. +Commands are terminated with the newline character, or by a semicolon (;). Empty +lines, and lines starting with the hash sign (#), are ignored. + +The synthesis starter script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. role:: yoscrypt(code) + :language: yoscrypt + +All of the images and console output used in +:doc:`/getting_started/example_synth` were generated by Yosys, using Yosys +script files found in :file:`docs/source/code_examples/fifo`. If you haven't +already, let's take a look at some of those script files now. + +.. literalinclude:: /code_examples/fifo/fifo.ys + :language: yoscrypt + :lineno-match: + :start-at: echo on + :end-before: design -reset + :caption: A section of :file:`fifo.ys`, generating the images used for :ref:`addr_gen_example` + :name: fifo-ys + +The first command there, :yoscrypt:`echo on`, uses :cmd:ref:`echo` to enable +command echoes on. This is how we generated the code listing for +:ref:`hierarchy_output`. Turning command echoes on prints the ``yosys> +hierarchy -top addr_gen`` line, making the output look the same as if it were an +interactive terminal. :yoscrypt:`hierarchy -top addr_gen` is of course the +command we were demonstrating, including the output text and an image of the +design schematic after running it. + +We briefly touched on :cmd:ref:`select` when it came up in +:cmd:ref:`synth_ice40`, but let's look at it more now. + +.. _select_intro: + +Selections intro +^^^^^^^^^^^^^^^^ + +The :cmd:ref:`select` command is used to modify and view the list of selected +objects: + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> select + :end-before: yosys> show + +When we call :yoscrypt:`select -module addr_gen` we are changing the currently +active selection from the whole design, to just the ``addr_gen`` module. Notice +how this changes the ``yosys`` at the start of each command to ``yosys +[addr_gen]``? This indicates that any commands we run at this point will *only* +operate on the ``addr_gen`` module. When we then call :yoscrypt:`select -list` +we get a list of all objects in the ``addr_gen`` module, including the module +itself, as well as all of the wires, inputs, outputs, processes, and cells. + +Next we perform another selection, :yoscrypt:`select t:*`. The ``t:`` part +signifies we are matching on the *cell type*, and the ``*`` means to match +anything. For this (very simple) selection, we are trying to find all of the +cells, regardless of their type. The active selection is now shown as +``[addr_gen]*``, indicating some sub-selection of the ``addr_gen`` module. This +gives us the ``$add`` and ``$eq`` cells, which we want to highlight for the +:ref:`addr_gen_hier` image. + +.. _select_new_cells: + +We can assign a name to a selection with :yoscrypt:`select -set`. In our case +we are using the name ``new_cells``, and telling it to use the current +selection, indicated by the ``%`` symbol. We can then use this named selection +by referring to it as ``@new_cells``, which we will see later. Then we clear +the selection so that the following commands can operate on the full design. +While we split that out for this document, we could have done the same thing in +a single line by calling :yoscrypt:`select -set new_cells addr_gen/t:*`. If we +know we only have the one module in our design, we can even skip the `addr_gen/` +part. Looking further down :ref:`the fifo.ys code ` we can see this +with :yoscrypt:`select -set new_cells t:$mux t:*dff`. We can also see in that +command that selections don't have to be limited to a single statement. + +Many commands also support an optional ``[selection]`` argument which can be +used to override the currently selected objects. We could, for example, call +:yoscrypt:`clean addr_gen` to have :cmd:ref:`clean` operate on *just* the +``addr_gen`` module. + +Detailed documentation of the select framework can be found under +:doc:`/using_yosys/more_scripting/selections` or in the command reference at +:doc:`/cmd/select`. + +.. _show_intro: + +Displaying schematics +^^^^^^^^^^^^^^^^^^^^^ + +While the :cmd:ref:`select` command is very useful, sometimes nothing beats +being able to see a design for yourself. This is where :cmd:ref:`show` comes +in. Note that this document is just an introduction to the :cmd:ref:`show` +command, only covering the basics. For more information, including a guide on +what the different symbols represent, see :ref:`interactive_show` and the +:doc:`/using_yosys/more_scripting/interactive_investigation` page. + +.. figure:: /_images/code_examples/fifo/addr_gen_show.* + :class: width-helper + :name: addr_gen_show + + Calling :yoscrypt:`show addr_gen` after :cmd:ref:`hierarchy` + +.. note:: + + The :cmd:ref:`show` command requires a working installation of `GraphViz`_ + and `xdot`_ for displaying the actual circuit diagrams. + +.. _GraphViz: http://www.graphviz.org/ +.. _xdot: https://github.com/jrfonseca/xdot.py + +This is the first :yoscrypt:`show` command we called in :file:`fifo.ys`, +:ref:`as we saw above `. If we look at the log output for this image +we see the following: + +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: -prefix addr_gen_show + :end-before: yosys> show + +Calling :cmd:ref:`show` with :yoscrypt:`-format dot` tells it we want to output +a :file:`.dot` file rather than opening it for display. The :yoscrypt:`-prefix +addr_gen_show` option indicates we want the file to be called +:file:`addr_gen_show.{*}`. Remember, we do this in :file:`fifo.ys` because we +need to store the image for displaying in the documentation you're reading. But +if you just want to display the images locally you can skip these two options. +The ``-format`` option internally calls the ``dot`` command line program from +GraphViz to convert to formats other than :file:`.dot`. Check `GraphViz output +docs`_ for more on available formats. + +.. _GraphViz output docs: https://graphviz.org/docs/outputs/ + +.. note:: + + If you are using a POSIX based version of Yosys (such as for Mac or Linux), + xdot will be opened in the background and Yosys can continue to be used. If + it it still open, future calls to :yoscrypt:`show` will use the same xdot + instance. + +The ``addr_gen`` at the end tells it we only want the ``addr_gen`` module, just +like when we called :yoscrypt:`select -module addr_gen` in :ref:`select_intro`. +That last parameter doesn't have to be a module name, it can be any valid +selection string. Remember when we :ref:`assigned a name to a +selection` and called it ``new_cells``? We saw in the +:yoscrypt:`select -list` output that it contained two cells, an ``$add`` and an +``$eq``. We can call :cmd:ref:`show` on that selection just as easily: + +.. figure:: /_images/code_examples/fifo/new_cells_show.* + :class: width-helper + :name: new_cells_show + + Calling :yoscrypt:`show -notitle @new_cells` + +We could have gotten the same output with :yoscrypt:`show -notitle t:$add t:$eq` +if we didn't have the named selection. By adding the :yoscrypt:`-notitle` flag +there we can also get rid of the ``addr_gen`` title that would have been +automatically added. The last two images were both added for this introduction. +The next image is the first one we saw in :doc:`/getting_started/example_synth`: +showing the full ``addr_gen`` module while also highlighting ``@new_cells`` and +the two ``PROC`` blocks. To achieve this highlight, we make use of the +:yoscrypt:`-color` option: + +.. figure:: /_images/code_examples/fifo/addr_gen_hier.* + :class: width-helper + + Calling :yoscrypt:`show -color maroon3 @new_cells -color cornflowerblue p:* -notitle` + +As described in the the :cmd:ref:`help` output for :cmd:ref:`show` (or by +clicking on the :cmd:ref:`show` link), colors are specified as :yoscrypt:`-color + `. Color names for the ```` portion can be found on the +`GraphViz color docs`_. Unlike the final :cmd:ref:`show` parameter which can +have be any selection string, the ```` part must be a single selection +expression or named selection. That means while we can use ``@new_cells``, we +couldn't use ``t:$eq t:$add``. In general, if a command lists ``[selection]`` +as its final parameter it can be any selection string. Any selections that are +not the final parameter, such as those used in options, must be a single +expression instead. + +.. _GraphViz color docs: https://graphviz.org/doc/info/colors + +For all of the options available to :cmd:ref:`show`, check the command reference +at :doc:`/cmd/show`. + +.. seealso:: :ref:`interactive_show` on the + :doc:`/using_yosys/more_scripting/interactive_investigation` page. diff --git a/docs/source/index.rst b/docs/source/index.rst index 111aea873a4..582551f7486 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,73 +1,45 @@ -: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 +Yosys Open SYnthesis Suite ================================================================================ -.. toctree:: - :maxdepth: 2 - :caption: Manual - :numbered: +Yosys is an open source framework for RTL synthesis. To learn more about Yosys, +see :doc:`/introduction`. For a quick guide on how to get started using Yosys, +check out :doc:`/getting_started/index`. For the complete list of commands +available, go to :ref:`commandindex`. - CHAPTER_Intro - CHAPTER_Basics.rst - CHAPTER_Approach.rst - CHAPTER_Overview.rst - CHAPTER_CellLib.rst - CHAPTER_Prog.rst +.. note:: - CHAPTER_Verilog.rst - CHAPTER_Optimize.rst - CHAPTER_Techmap.rst - CHAPTER_Memorymap.rst - CHAPTER_Eval.rst + This documentation recently went through a major restructure. If you're + looking for something from the previous version and can't find it here, + please `let us know`_. Documentation from before the restructure can still + be found by switching to `version 0.36`_ or earlier. Note that the previous + theme does not include a version switcher. -.. raw:: latex +.. _let us know: https://github.com/YosysHQ/yosys/issues/new/choose +.. _version 0.36: https://yosyshq.readthedocs.io/projects/yosys/en/0.36/ - \appendix +.. todo:: look into command ref improvements -.. toctree:: - :maxdepth: 2 - :includehidden: - :caption: Appendix + - Search bar with live drop down suggestions for matching on title / + autocompleting commands + - Scroll the left sidebar to the current location on page load + - Also the formatting/linking in pdf is broken - appendix/CHAPTER_Auxlibs.rst - appendix/CHAPTER_Auxprogs.rst +.. todolist:: - appendix/CHAPTER_TextRtlil.rst - appendix/APPNOTE_010_Verilog_to_BLIF.rst - appendix/APPNOTE_011_Design_Investigation.rst - appendix/APPNOTE_012_Verilog_to_BTOR.rst - appendix/CHAPTER_StateOfTheArt.rst +.. only:: html - bib + Table of contents + ----------------- .. toctree:: - :maxdepth: 1 - :includehidden: + :maxdepth: 3 + :includehidden: - cmd_ref + introduction + getting_started/index + using_yosys/index + yosys_internals/index + test_suites + appendix diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst new file mode 100644 index 00000000000..936784d7411 --- /dev/null +++ b/docs/source/introduction.rst @@ -0,0 +1,248 @@ +What is Yosys +============= + +Yosys began as a BSc thesis project by Claire Wolf intended to support synthesis +for a CGRA (coarse-grained reconfigurable architecture). It then expanded into +more general infrastructure for research on synthesis. + +Modern Yosys has full support for the synthesizable subset of Verilog-2005 and +has been described as "the GCC of hardware synthesis." Freely available and +`open source`_, Yosys finds use across hobbyist and commercial applications as +well as academic. + +.. _open source: https://github.com/YosysHQ/yosys + +.. note:: Yosys is released under the ISC License: + + A permissive license lets people do anything with your code with proper + attribution and without warranty. The ISC license is functionally equivalent + to the BSD 2-Clause and MIT licenses, removing some language that is no + longer necessary. + +Together with the place and route tool `nextpnr`_, Yosys can be used to program +some FPGAs with a fully end-to-end open source flow (Lattice iCE40 and ECP5). It +also does the synthesis portion for the `OpenLane flow`_, targeting the SkyWater +130nm open source PDK for fully open source ASIC design. Yosys can also do +formal verification with backends for solver formats like `SMT2`_. + +.. _nextpnr: https://github.com/YosysHQ/nextpnr +.. _OpenLane flow: https://github.com/The-OpenROAD-Project/OpenLane +.. _SMT2: https://smtlib.cs.uiowa.edu/ + +Yosys, and the accompanying Open Source EDA ecosystem, is currently maintained +by `Yosys Headquarters`_, with many of the core developers employed by `YosysHQ +GmbH`_. A commercial extension, `Tabby CAD Suite`_, includes the Verific +frontend for industry-grade SystemVerilog and VHDL support, formal verification +with SVA, and formal apps. + +.. _Yosys Headquarters: https://github.com/YosysHQ +.. _YosysHQ GmbH: https://www.yosyshq.com/about +.. _Tabby CAD Suite: https://www.yosyshq.com/tabby-cad-datasheet + +.. figure:: /_static/logo.png + :class: width-helper + +What you can do with Yosys +-------------------------- + +- Read and process (most of) modern Verilog-2005 code +- Perform all kinds of operations on netlist (RTL, Logic, Gate) +- Perform logic optimizations and gate mapping with ABC + +Typical applications for Yosys +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Synthesis of final production designs +- Pre-production synthesis (trial runs before investing in other tools) +- Conversion of full-featured Verilog to simple Verilog +- Conversion of Verilog to other formats (BLIF, BTOR, etc) +- Demonstrating synthesis algorithms (e.g. for educational purposes) +- Framework for experimenting with new algorithms +- Framework for building custom flows (Not limited to synthesis but also formal + verification, reverse engineering, ...) + +Things you can't do +~~~~~~~~~~~~~~~~~~~ + +- Process high-level languages such as C/C++/SystemC +- Create physical layouts (place&route) + + - Check out `nextpnr`_ for that + +.. todo:: nextpnr for FPGAs, consider mentioning openlane, vpr, coriolis + +.. _nextpnr: https://github.com/YosysHQ/nextpnr + +The Yosys family +---------------- + +As mentioned above, `YosysHQ`_ maintains not just Yosys but an entire family of +tools built around it. In no particular order: + +.. _YosysHQ: https://github.com/YosysHQ + +SBY for formal verification + Yosys provides input parsing and conversion to the formats used by the solver + engines. Yosys also provides a unified witness framework for providing cover + traces and counter examples for engines which don't natively support this. + `SBY source`_ | `SBY docs`_ + +.. _SBY source: https://github.com/YosysHQ/sby +.. _SBY docs: https://yosyshq.readthedocs.io/projects/sby + +EQY for equivalence checking + In addition to input parsing and preparation, Yosys provides the plugin + support enabling EQY to operate on designs directly. `EQY source`_ | `EQY + docs`_ + +.. _EQY source: https://github.com/YosysHQ/eqy +.. _EQY docs: https://yosyshq.readthedocs.io/projects/eqy + +MCY for mutation coverage + Yosys is used to read the source design, generate a list of possible + mutations to maximise design coverage, and then perform selected mutations. + `MCY source`_ | `MCY docs`_ + +.. _MCY source: https://github.com/YosysHQ/mcy +.. _MCY docs: https://yosyshq.readthedocs.io/projects/mcy + +SCY for deep formal traces + Since SCY generates and runs SBY, Yosys provides the same utility for SCY as + it does for SBY. Yosys additionally provides the trace concatenation needed + for outputting the deep traces. `SCY source`_ + +.. _SCY source: https://github.com/YosysHQ/scy + +The original thesis abstract +---------------------------- + +The first version of the Yosys documentation was published as a bachelor thesis +at the Vienna University of Technology :cite:p:`BACC`. + +: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. + +Yosys is a Verilog HDL synthesis tool. This means that it takes a behavioural +design description as input and generates an RTL, logical gate or physical gate +level description of the design as output. Yosys' main strengths are behavioural +and RTL synthesis. A wide range of commands (synthesis passes) exist within +Yosys that can be used to perform a wide range of synthesis tasks within the +domain of behavioural, rtl and logic synthesis. Yosys is designed to be +extensible and therefore is a good basis for implementing custom synthesis tools +for specialised tasks. + +.. figure:: /_images/primer/levels_of_abstraction.* + :class: width-helper + :name: fig:Levels_of_abstraction + + Where Yosys exists in the layers of abstraction + +Benefits of open source HDL synthesis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Cost (also applies to ``free as in free beer`` solutions): + + Today the cost for a mask set in 180nm technology is far less than + the cost for the design tools needed to design the mask layouts. Open Source + ASIC flows are an important enabler for ASIC-level Open Source Hardware. + +- Availability and Reproducibility: + + If you are a researcher who is publishing, you want to use tools that everyone + else can also use. Even if most universities have access to all major + commercial tools, you usually do not have easy access to the version that was + used in a research project a couple of years ago. With Open Source tools you + can even release the source code of the tool you have used alongside your data. + +- Framework: + + Yosys is not only a tool. It is a framework that can be used as basis for other + developments, so researchers and hackers alike do not need to re-invent the + basic functionality. Extensibility was one of Yosys' design goals. + +- All-in-one: + + Because of the framework characteristics of Yosys, an increasing number of features + become available in one tool. Yosys not only can be used for circuit synthesis but + also for formal equivalence checking, SAT solving, and for circuit analysis, to + name just a few other application domains. With proprietary software one needs to + learn a new tool for each of these applications. + +- Educational Tool: + + Proprietary synthesis tools are at times very secretive about their inner + workings. They often are ``black boxes``. Yosys is very open about its + internals and it is easy to observe the different steps of synthesis. + +History of Yosys +~~~~~~~~~~~~~~~~ + +.. todo:: Consider a less academic version of the 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. + +.. [#] + A quick investigation into FOSS VHDL tools yielded similar grim results for + FOSS VHDL synthesis tools. diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt index d357a83b7cc..74c8dd090cb 100644 --- a/docs/source/requirements.txt +++ b/docs/source/requirements.txt @@ -1,2 +1,2 @@ -sphinx-press-theme +furo sphinxcontrib-bibtex diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst new file mode 100644 index 00000000000..2edb0e67d1a --- /dev/null +++ b/docs/source/test_suites.rst @@ -0,0 +1,25 @@ +Testing Yosys +============= + +.. todo:: more about the included test suite + +Automatic testing +----------------- + +.. only:: html + + The `Yosys Git repo`_ has automatic testing of builds and running of the + included test suite on the following platforms: + + - Ubuntu |test-linux| + - macOS |test-macos| + +.. _Yosys Git repo: https://github.com/YosysHQ/yosys + +.. |test-linux| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-linux.yml/badge.svg?branch=master +.. |test-macos| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-macos.yml/badge.svg?branch=master + +For up to date information, including OS versions, refer to `the git actions +page`_. + +.. _the git actions page: https://github.com/YosysHQ/yosys/actions diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst new file mode 100644 index 00000000000..55bd5c29151 --- /dev/null +++ b/docs/source/using_yosys/index.rst @@ -0,0 +1,17 @@ +Using Yosys (advanced) +====================== + +While much of Yosys is focused around synthesis, there are also a number of +other useful things that can be accomplished with Yosys scripts or in an +interactive shell. As such this section is broken into two parts: +:doc:`/using_yosys/synthesis/index` expands on the +:doc:`/getting_started/example_synth` and goes into further detail on the major +commands used in synthesis; :doc:`/using_yosys/more_scripting/index` covers the +ways Yosys can interact with designs for a deeper investigation. + +.. toctree:: + :maxdepth: 2 + :hidden: + + synthesis/index + more_scripting/index diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst new file mode 100644 index 00000000000..490a5a7ad8b --- /dev/null +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -0,0 +1,14 @@ +More scripting +-------------- + +.. todo:: brief overview for the more scripting index + +.. toctree:: + :maxdepth: 3 + + load_design + selections + interactive_investigation + model_checking + +.. troubleshooting diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst new file mode 100644 index 00000000000..223e09a1269 --- /dev/null +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -0,0 +1,813 @@ +Interactive design investigation +-------------------------------- + +.. todo:: interactive design opening text + +.. role:: yoscrypt(code) + :language: yoscrypt + +.. _interactive_show: + +A look at the show command +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. TODO:: merge into :doc:`/getting_started/scripting_intro` show section + +This section explores the :cmd:ref:`show` command and explains the symbols used +in the circuit diagrams generated by it. The code used is included in the Yosys +code base under |code_examples/show|_. + +.. |code_examples/show| replace:: :file:`docs/source/code_examples/show` +.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/show + +A simple circuit +^^^^^^^^^^^^^^^^ + +:ref:`example_v` below provides the Verilog code for a simple circuit which we +will use to demonstrate the usage of :cmd:ref:`show` in a simple setting. + +.. literalinclude:: /code_examples/show/example.v + :language: Verilog + :caption: :file:`example.v` + :name: example_v + +The Yosys synthesis script we will be running is included as +:numref:`example_ys`. Note that :cmd:ref:`show` is called with the ``-pause`` +option, that halts execution of the Yosys script until the user presses the +Enter key. Using :yoscrypt:`show -pause` also allows the user to enter an +interactive shell to further investigate the circuit before continuing +synthesis. + +.. literalinclude:: /code_examples/show/example_show.ys + :language: yoscrypt + :caption: :file:`example_show.ys` + :name: example_ys + +This script, when executed, will show the design after each of the three +synthesis commands. We will now look at each of these diagrams and explain what +is shown. + +.. note:: + + The images uses in this document are generated from the :file:`example.ys` + file, rather than :file:`example_show.ys`. :file:`example.ys` outputs the + schematics as :file:`.dot` files rather than displaying them directly. You + can view these images yourself by running :file:`yosys example.ys` and then + ``xdot example_first.dot`` etc. + +.. figure:: /_images/code_examples/show/example_first.* + :class: width-helper + + Output of the first :cmd:ref:`show` command in :numref:`example_ys` + +The first output shows the design directly after being read by the Verilog +front-end. Input and output ports are displayed as octagonal shapes. Cells are +displayed as rectangles with inputs on the left and outputs on the right side. +The cell labels are two lines long: The first line contains a unique identifier +for the cell and the second line contains the cell type. Internal cell types are +prefixed with a dollar sign. For more details on the internal cell library, see +:doc:`/yosys_internals/formats/cell_library`. + +Constants are shown as ellipses with the constant value as label. The syntax +``'`` is used for constants that are not 32-bit wide and/or +contain bits that are not 0 or 1 (i.e. ``x`` or ``z``). Ordinary 32-bit +constants are written using decimal numbers. + +Single-bit signals are shown as thin arrows pointing from the driver to the +load. Signals that are multiple bits wide are shown as think arrows. + +Finally *processes* are shown in boxes with round corners. Processes are Yosys' +internal representation of the decision-trees and synchronization events +modelled in a Verilog ``always``-block. The label reads ``PROC`` followed by a +unique identifier in the first line and contains the source code location of the +original ``always``-block in the second line. Note how the multiplexer from the +``?:``-expression is represented as a ``$mux`` cell but the multiplexer from the +``if``-statement is yet still hidden within the process. + +The :cmd:ref:`proc` command transforms the process from the first diagram into a +multiplexer and a d-type flip-flop, which brings us to the second diagram: + +.. figure:: /_images/code_examples/show/example_second.* + :class: width-helper + + Output of the second :cmd:ref:`show` command in :numref:`example_ys` + +The Rhombus shape to the right is a dangling wire. (Wire nodes are only shown if +they are dangling or have "public" names, for example names assigned from the +Verilog input.) Also note that the design now contains two instances of a +``BUF``-node. These are artefacts left behind by the :cmd:ref:`proc` command. It +is quite usual to see such artefacts after calling commands that perform changes +in the design, as most commands only care about doing the transformation in the +least complicated way, not about cleaning up after them. The next call to +:cmd:ref:`clean` (or :cmd:ref:`opt`, which includes :cmd:ref:`clean` as one of +its operations) will clean up these artefacts. This operation is so common in +Yosys scripts that it can simply be abbreviated with the ``;;`` token, which +doubles as separator for commands. Unless one wants to specifically analyze this +artefacts left behind some operations, it is therefore recommended to always +call :cmd:ref:`clean` before calling :cmd:ref:`show`. + +In this script we directly call :cmd:ref:`opt` as the next step, which finally +leads us to the third diagram: + +.. figure:: /_images/code_examples/show/example_third.* + :class: width-helper + :name: example_out + + Output of the third :cmd:ref:`show` command in :ref:`example_ys` + +Here we see that the :cmd:ref:`proc` command not only has removed the artifacts +left behind by :cmd:ref:`proc`, but also determined correctly that it can remove +the first ``$mux`` cell without changing the behavior of the circuit. + +Break-out boxes for signal vectors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The code listing below shows a simple circuit which uses a lot of spliced signal +accesses. + +.. literalinclude:: /code_examples/show/splice.v + :caption: :file:`splice.v` + :name: splice_src + +Notice how the output for this circuit from the :cmd:ref:`show` command +(:numref:`splice_dia`) appears quite complex. This is an unfortunate side effect +of the way Yosys handles signal vectors (aka. multi-bit wires or buses) as +native objects. While this provides great advantages when analyzing circuits +that operate on wide integers, it also introduces some additional complexity +when the individual bits of of a signal vector are accessed. + +.. figure:: /_images/code_examples/show/splice.* + :class: width-helper + :name: splice_dia + + Output of ``yosys -p 'prep -top splice_demo; show' splice.v`` + +The key elements in understanding this circuit diagram are of course the boxes +with round corners and rows labeled ``: - +:``. Each of these boxes have one signal per row on one +side and a common signal for all rows on the other side. The ``:`` +tuples specify which bits of the signals are broken out and connected. So the +top row of the box connecting the signals ``a`` and ``x`` indicates that the bit +0 (i.e. the range 0:0) from signal ``a`` is connected to bit 1 (i.e. the range +1:1) of signal ``x``. + +Lines connecting such boxes together and lines connecting such boxes to cell +ports have a slightly different look to emphasise that they are not actual +signal wires but a necessity of the graphical representation. This distinction +seems like a technicality, until one wants to debug a problem related to the way +Yosys internally represents signal vectors, for example when writing custom +Yosys commands. + +Gate level netlists +^^^^^^^^^^^^^^^^^^^ + +:numref:`first_pitfall` shows two common pitfalls when working with designs +mapped to a cell library: + +.. figure:: /_images/code_examples/show/cmos_00.* + :class: width-helper + :name: first_pitfall + + A half-adder built from simple CMOS gates, demonstrating common pitfalls when + using :cmd:ref:`show` + +.. literalinclude:: /code_examples/show/cmos.ys + :language: yoscrypt + :start-after: pitfall + :end-at: cmos_00 + :name: pitfall_code + :caption: Generating :numref:`first_pitfall` + +First, Yosys did not have access to the cell library when this diagram was +generated, resulting in all cell ports defaulting to being inputs. This is why +all ports are drawn on the left side the cells are awkwardly arranged in a large +column. Secondly the two-bit vector ``y`` requires breakout-boxes for its +individual bits, resulting in an unnecessary complex diagram. + +.. figure:: /_images/code_examples/show/cmos_01.* + :class: width-helper + :name: second_pitfall + + Effects of :cmd:ref:`splitnets` command and of providing a cell library on + design in :numref:`first_pitfall` + +.. literalinclude:: /code_examples/show/cmos.ys + :language: yoscrypt + :start-after: fixed + :end-at: cmos_01 + :name: pitfall_avoided + :caption: Generating :numref:`second_pitfall` + +For :numref:`second_pitfall`, Yosys has been given a description of the cell +library as Verilog file containing blackbox modules. There are two ways to load +cell descriptions into Yosys: First the Verilog file for the cell library can be +passed directly to the :cmd:ref:`show` command using the ``-lib `` +option. Secondly it is possible to load cell libraries into the design with the +:yoscrypt:`read_verilog -lib ` command. The second method has the +great advantage that the library only needs to be loaded once and can then be +used in all subsequent calls to the :cmd:ref:`show` command. + +In addition to that, :numref:`second_pitfall` was generated after +:yoscrypt:`splitnet -ports` was run on the design. This command splits all +signal vectors into individual signal bits, which is often desirable when +looking at gate-level circuits. The ``-ports`` option is required to also split +module ports. Per default the command only operates on interior signals. + +Miscellaneous notes +^^^^^^^^^^^^^^^^^^^ + +Per default the :cmd:ref:`show` command outputs a temporary dot file and +launches ``xdot`` to display it. The options ``-format``, ``-viewer`` and +``-prefix`` can be used to change format, viewer and filename prefix. Note that +the ``pdf`` and ``ps`` format are the only formats that support plotting +multiple modules in one run. The ``dot`` format can be used to output multiple +modules, however ``xdot`` will raise an error when trying to read them. + +In densely connected circuits it is sometimes hard to keep track of the +individual signal wires. For these cases it can be useful to call +:cmd:ref:`show` with the ``-colors `` argument, which randomly assigns +colors to the nets. The integer (> 0) is used as seed value for the random color +assignments. Sometimes it is necessary it try some values to find an assignment +of colors that looks good. + +The command :yoscrypt:`help show` prints a complete listing of all options +supported by the :cmd:ref:`show` command. + +Navigating the design +~~~~~~~~~~~~~~~~~~~~~ + +Plotting circuit diagrams for entire modules in the design brings us only helps +in simple cases. For complex modules the generated circuit diagrams are just +stupidly big and are no help at all. In such cases one first has to select the +relevant portions of the circuit. + +In addition to *what* to display one also needs to carefully decide *when* to +display it, with respect to the synthesis flow. In general it is a good idea to +troubleshoot a circuit in the earliest state in which a problem can be +reproduced. So if, for example, the internal state before calling the +:cmd:ref:`techmap` command already fails to verify, it is better to troubleshoot +the coarse-grain version of the circuit before :cmd:ref:`techmap` than the +gate-level circuit after :cmd:ref:`techmap`. + +.. Note:: + + It is generally recommended to verify the internal state of a design by + writing it to a Verilog file using :yoscrypt:`write_verilog -noexpr` and + using the simulation models from :file:`simlib.v` and :file:`simcells.v` from + the Yosys data directory (as printed by ``yosys-config --datdir``). + +Interactive navigation +^^^^^^^^^^^^^^^^^^^^^^ + +Once the right state within the synthesis flow for debugging the circuit has +been identified, it is recommended to simply add the :cmd:ref:`shell` command to +the matching place in the synthesis script. This command will stop the synthesis +at the specified moment and go to shell mode, where the user can interactively +enter commands. + +For most cases, the shell will start with the whole design selected (i.e. when +the synthesis script does not already narrow the selection). The command +:cmd:ref:`ls` can now be used to create a list of all modules. The command +:cmd:ref:`cd` can be used to switch to one of the modules (type ``cd ..`` to +switch back). Now the :cmd:ref:`ls` command lists the objects within that +module. This is demonstrated below using :file:`example.v` from `A simple +circuit`_: + +.. literalinclude:: /code_examples/show/example.out + :language: doscon + :start-at: yosys> ls + :end-before: yosys [example]> dump + :caption: Output of :cmd:ref:`ls` and :cmd:ref:`cd` after running :file:`yosys example.v` + :name: lscd + +When a module is selected using the :cmd:ref:`cd` command, all commands (with a +few exceptions, such as the ``read_`` and ``write_`` commands) operate only on +the selected module. This can also be useful for synthesis scripts where +different synthesis strategies should be applied to different modules in the +design. + +We can see that the cell names from :numref:`example_out` are just abbreviations +of the actual cell names, namely the part after the last dollar-sign. Most +auto-generated names (the ones starting with a dollar sign) are rather long and +contains some additional information on the origin of the named object. But in +most cases those names can simply be abbreviated using the last part. + +Usually all interactive work is done with one module selected using the +:cmd:ref:`cd` command. But it is also possible to work from the design-context +(``cd ..``). In this case all object names must be prefixed with +``/``. For example ``a*/b*`` would refer to all objects whose names +start with ``b`` from all modules whose names start with ``a``. + +The :cmd:ref:`dump` command can be used to print all information about an +object. For example, calling :yoscrypt:`dump $2` after the :yoscrypt:`cd +example` above: + +.. literalinclude:: /code_examples/show/example.out + :language: RTLIL + :start-after: yosys [example]> dump + :end-before: yosys [example]> cd + :dedent: + :caption: Output of :yoscrypt:`dump $2` after :numref:`lscd` + :name: dump2 + +This can for example be useful to determine the names of nets connected to +cells, as the net-names are usually suppressed in the circuit diagram if they +are auto-generated. Note that the output is in the RTLIL representation, +described in :doc:`/yosys_internals/formats/rtlil_rep`. + +Interactive Design Investigation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Yosys can also be used to investigate designs (or netlists created from other +tools). + +- The selection mechanism, especially patterns such as ``%ci`` and ``%co``, can + be used to figure out how parts of the design are connected. +- Commands such as :cmd:ref:`submod`, :cmd:ref:`expose`, and :cmd:ref:`splice` + can be used to transform the design into an equivalent design that is easier + to analyse. +- Commands such as :cmd:ref:`eval` and :cmd:ref:`sat` can be used to investigate + the behavior of the circuit. +- :doc:`/cmd/show`. +- :doc:`/cmd/dump`. +- :doc:`/cmd/add` and :doc:`/cmd/delete` can be used to modify and reorganize a + design dynamically. + +The code used is included in the Yosys code base under +|code_examples/scrambler|_. + +.. |code_examples/scrambler| replace:: :file:`docs/source/code_examples/scrambler` +.. _code_examples/scrambler: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/scrambler + +Changing design hierarchy +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Commands such as :cmd:ref:`flatten` and :cmd:ref:`submod` can be used to change +the design hierarchy, i.e. flatten the hierarchy or moving parts of a module to +a submodule. This has applications in synthesis scripts as well as in reverse +engineering and analysis. An example using :cmd:ref:`submod` is shown below for +reorganizing a module in Yosys and checking the resulting circuit. + +.. literalinclude:: /code_examples/scrambler/scrambler.v + :language: verilog + :caption: :file:`scrambler.v` + +.. literalinclude:: /code_examples/scrambler/scrambler.ys + :language: yoscrypt + :caption: :file:`scrambler.ys` + :end-before: cd .. + +.. figure:: /_images/code_examples/scrambler/scrambler_p01.* + :class: width-helper + +.. figure:: /_images/code_examples/scrambler/scrambler_p02.* + :class: width-helper + +Analyzing the resulting circuit with :doc:`/cmd/eval`: + +.. todo:: replace inline code + +.. code:: text + + > cd xorshift32 + > rename n2 in + > rename n1 out + + > eval -set in 1 -show out + Eval result: \out = 270369. + + > eval -set in 270369 -show out + Eval result: \out = 67634689. + + > sat -set out 632435482 + Signal Name Dec Hex Bin + -------------------- ---------- ---------- ------------------------------------- + \in 745495504 2c6f5bd0 00101100011011110101101111010000 + \out 632435482 25b2331a 00100101101100100011001100011010 + +Behavioral changes +^^^^^^^^^^^^^^^^^^ + +Commands such as :cmd:ref:`techmap` can be used to make behavioral changes to +the design, for example changing asynchronous resets to synchronous resets. This +has applications in design space exploration (evaluation of various +architectures for one circuit). + +The following techmap map file replaces all positive-edge async reset flip-flops +with positive-edge sync reset flip-flops. The code is taken from the example +Yosys script for ASIC synthesis of the Amber ARMv2 CPU. + +.. todo:: replace inline code + +.. code:: verilog + + (* techmap_celltype = "$adff" *) + module adff2dff (CLK, ARST, D, Q); + + parameter WIDTH = 1; + parameter CLK_POLARITY = 1; + parameter ARST_POLARITY = 1; + parameter ARST_VALUE = 0; + + input CLK, ARST; + input [WIDTH-1:0] D; + output reg [WIDTH-1:0] Q; + + wire [1023:0] _TECHMAP_DO_ = "proc"; + + wire _TECHMAP_FAIL_ = !CLK_POLARITY || !ARST_POLARITY; + + always @(posedge CLK) + if (ARST) + Q <= ARST_VALUE; + else + Q <= D; + + endmodule + +For more on the :cmd:ref:`techmap` command, see the page on +:doc:`/yosys_internals/techmap`. + +Advanced investigation techniques +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When working with very large modules, it is often not enough to just select the +interesting part of the module. Instead it can be useful to extract the +interesting part of the circuit into a separate module. This can for example be +useful if one wants to run a series of synthesis commands on the critical part +of the module and wants to carefully read all the debug output created by the +commands in order to spot a problem. This kind of troubleshooting is much easier +if the circuit under investigation is encapsulated in a separate module. + +Recall the ``memdemo`` design from :ref:`advanced_logic_cones`: + +.. figure:: /_images/code_examples/selections/memdemo_00.* + :class: width-helper + + ``memdemo`` + +Because this produces a rather large circuit, it can be useful to split it into +smaller parts for viewing and working with. :numref:`submod` does exactly that, +utilising the :cmd:ref:`submod` command to split the circuit into three +sections: ``outstage``, ``selstage``, and ``scramble``. + +.. literalinclude:: /code_examples/selections/submod.ys + :language: yoscrypt + :caption: Using :cmd:ref:`submod` to break up the circuit from :file:`memdemo.v` + :start-after: cd memdemo + :end-before: cd .. + :name: submod + +The ``-name`` option is used to specify the name of the new module and also the +name of the new cell in the current module. The resulting circuits are shown +below. + +.. figure:: /_images/code_examples/selections/submod_02.* + :class: width-helper + + ``outstage`` + +.. figure:: /_images/code_examples/selections/submod_03.* + :class: width-helper + :name: selstage + + ``selstage`` + +.. figure:: /_images/code_examples/selections/submod_01.* + :class: width-helper + + ``scramble`` + +Evaluation of combinatorial circuits +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :cmd:ref:`eval` command can be used to evaluate combinatorial circuits. As +an example, we will use the ``selstage`` subnet of ``memdemo`` which we found +above and is shown in :numref:`selstage`. + +.. todo:: replace inline code + +:: + + yosys [selstage]> eval -set s2,s1 4'b1001 -set d 4'hc -show n2 -show n1 + + 1. Executing EVAL pass (evaluate the circuit given an input). + Full command line: eval -set s2,s1 4'b1001 -set d 4'hc -show n2 -show n1 + Eval result: \n2 = 2'10. + Eval result: \n1 = 2'10. + +So the ``-set`` option is used to set input values and the ``-show`` option is +used to specify the nets to evaluate. If no ``-show`` option is specified, all +selected output ports are used per default. + +If a necessary input value is not given, an error is produced. The option +``-set-undef`` can be used to instead set all unspecified input nets to undef +(``x``). + +The ``-table`` option can be used to create a truth table. For example: + +:: + + yosys [selstage]> eval -set-undef -set d[3:1] 0 -table s1,d[0] + + 10. Executing EVAL pass (evaluate the circuit given an input). + Full command line: eval -set-undef -set d[3:1] 0 -table s1,d[0] + + \s1 \d [0] | \n1 \n2 + ---- ------ | ---- ---- + 2'00 1'0 | 2'00 2'00 + 2'00 1'1 | 2'xx 2'00 + 2'01 1'0 | 2'00 2'00 + 2'01 1'1 | 2'xx 2'01 + 2'10 1'0 | 2'00 2'00 + 2'10 1'1 | 2'xx 2'10 + 2'11 1'0 | 2'00 2'00 + 2'11 1'1 | 2'xx 2'11 + + Assumed undef (x) value for the following signals: \s2 + +Note that the :cmd:ref:`eval` command (as well as the :cmd:ref:`sat` command +discussed in the next sections) does only operate on flattened modules. It can +not analyze signals that are passed through design hierarchy levels. So the +:cmd:ref:`flatten` command must be used on modules that instantiate other +modules before these commands can be applied. + +Solving combinatorial SAT problems +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Often the opposite of the :cmd:ref:`eval` command is needed, i.e. the circuits +output is given and we want to find the matching input signals. For small +circuits with only a few input bits this can be accomplished by trying all +possible input combinations, as it is done by the ``eval -table`` command. For +larger circuits however, Yosys provides the :cmd:ref:`sat` command that uses a +`SAT`_ solver, `MiniSAT`_, to solve this kind of problems. + +.. _SAT: http://en.wikipedia.org/wiki/Circuit_satisfiability + +.. _MiniSAT: http://minisat.se/ + +.. note:: + + While it is possible to perform model checking directly in Yosys, it + is highly recommended to use SBY or EQY for formal hardware verification. + +The :cmd:ref:`sat` command works very similar to the :cmd:ref:`eval` command. +The main difference is that it is now also possible to set output values and +find the corresponding input values. For Example: + +.. todo:: replace inline code + +:: + + yosys [selstage]> sat -show s1,s2,d -set s1 s2 -set n2,n1 4'b1001 + + 11. Executing SAT pass (solving SAT problems in the circuit). + Full command line: sat -show s1,s2,d -set s1 s2 -set n2,n1 4'b1001 + + Setting up SAT problem: + Import set-constraint: \s1 = \s2 + Import set-constraint: { \n2 \n1 } = 4'1001 + Final constraint equation: { \n2 \n1 \s1 } = { 4'1001 \s2 } + Imported 3 cells to SAT database. + Import show expression: { \s1 \s2 \d } + + Solving problem with 81 variables and 207 clauses.. + SAT solving finished - model found: + + Signal Name Dec Hex Bin + -------------------- ---------- ---------- --------------- + \d 9 9 1001 + \s1 0 0 00 + \s2 0 0 00 + +Note that the :cmd:ref:`sat` command supports signal names in both arguments to +the ``-set`` option. In the above example we used ``-set s1 s2`` to constraint +``s1`` and ``s2`` to be equal. When more complex constraints are needed, a +wrapper circuit must be constructed that checks the constraints and signals if +the constraint was met using an extra output port, which then can be forced to a +value using the ``-set`` option. (Such a circuit that contains the circuit under +test plus additional constraint checking circuitry is called a ``miter`` +circuit.) + +.. literalinclude:: /code_examples/primetest.v + :language: verilog + :caption: :file:`primetest.v`, a simple miter circuit for testing if a number is + prime. But it has a problem. + :name: primetest + +:numref:`primetest` shows a miter circuit that is supposed to be used as a prime +number test. If ``ok`` is 1 for all input values ``a`` and ``b`` for a given +``p``, then ``p`` is prime, or at least that is the idea. + +.. todo:: replace inline code + +.. code-block:: + :caption: Experiments with the miter circuit from :file:`primetest.v`. + :name: prime_shell + + yosys [primetest]> sat -prove ok 1 -set p 31 + + 1. Executing SAT pass (solving SAT problems in the circuit). + Full command line: sat -prove ok 1 -set p 31 + + Setting up SAT problem: + Import set-constraint: \p = 16'0000000000011111 + Final constraint equation: \p = 16'0000000000011111 + Imported 6 cells to SAT database. + Import proof-constraint: \ok = 1'1 + Final proof equation: \ok = 1'1 + + Solving problem with 2790 variables and 8241 clauses.. + SAT proof finished - model found: FAIL! + + ______ ___ ___ _ _ _ _ + (_____ \ / __) / __) (_) | | | | + _____) )___ ___ ___ _| |__ _| |__ _____ _| | _____ __| | | + | ____/ ___) _ \ / _ (_ __) (_ __|____ | | || ___ |/ _ |_| + | | | | | |_| | |_| || | | | / ___ | | || ____( (_| |_ + |_| |_| \___/ \___/ |_| |_| \_____|_|\_)_____)\____|_| + + + Signal Name Dec Hex Bin + -------------------- ---------- ---------- --------------------- + \a 15029 3ab5 0011101010110101 + \b 4099 1003 0001000000000011 + \ok 0 0 0 + \p 31 1f 0000000000011111 + +The Yosys shell session shown in :numref:`prime_shell` demonstrates that SAT +solvers can even find the unexpected solutions to a problem: Using integer +overflow there actually is a way of "factorizing" 31. The clean solution would +of course be to perform the test in 32 bits, for example by replacing ``p != +a*b`` in the miter with ``p != {16'd0,a}b``, or by using a temporary variable +for the 32 bit product ``a*b``. But as 31 fits well into 8 bits (and as the +purpose of this document is to show off Yosys features) we can also simply force +the upper 8 bits of ``a`` and ``b`` to zero for the :cmd:ref:`sat` call, as is +done below. + +.. todo:: replace inline code + +.. code-block:: + :caption: Miter circuit from :file:`primetest.v`, with the upper 8 bits of ``a`` + and ``b`` constrained to prevent overflow. + :name: prime_fixed + + yosys [primetest]> sat -prove ok 1 -set p 31 -set a[15:8],b[15:8] 0 + + 1. Executing SAT pass (solving SAT problems in the circuit). + Full command line: sat -prove ok 1 -set p 31 -set a[15:8],b[15:8] 0 + + Setting up SAT problem: + Import set-constraint: \p = 16'0000000000011111 + Import set-constraint: { \a [15:8] \b [15:8] } = 16'0000000000000000 + Final constraint equation: { \a [15:8] \b [15:8] \p } = { 16'0000000000000000 16'0000000000011111 } + Imported 6 cells to SAT database. + Import proof-constraint: \ok = 1'1 + Final proof equation: \ok = 1'1 + + Solving problem with 2790 variables and 8257 clauses.. + SAT proof finished - no model found: SUCCESS! + + /$$$$$$ /$$$$$$$$ /$$$$$$$ + /$$__ $$ | $$_____/ | $$__ $$ + | $$ \ $$ | $$ | $$ \ $$ + | $$ | $$ | $$$$$ | $$ | $$ + | $$ | $$ | $$__/ | $$ | $$ + | $$/$$ $$ | $$ | $$ | $$ + | $$$$$$/ /$$| $$$$$$$$ /$$| $$$$$$$//$$ + \____ $$$|__/|________/|__/|_______/|__/ + \__/ + +The ``-prove`` option used in :numref:`prime_fixed` works similar to ``-set``, +but tries to find a case in which the two arguments are not equal. If such a +case is not found, the property is proven to hold for all inputs that satisfy +the other constraints. + +It might be worth noting, that SAT solvers are not particularly efficient at +factorizing large numbers. But if a small factorization problem occurs as part +of a larger circuit problem, the Yosys SAT solver is perfectly capable of +solving it. + +Solving sequential SAT problems +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The SAT solver functionality in Yosys can not only be used to solve +combinatorial problems, but can also solve sequential problems. Let's consider +the ``memdemo`` design from :ref:`advanced_logic_cones` again, and suppose we +want to know which sequence of input values for ``d`` will cause the output y to +produce the sequence 1, 2, 3 from any initial state. Let's use the following +command: + +.. todo:: replace inline code? + +.. code-block:: yoscrypt + + sat -seq 6 -show y -show d -set-init-undef \ + -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3 + +The ``-seq 6`` option instructs the :cmd:ref:`sat` command to solve a sequential +problem in 6 time steps. (Experiments with lower number of steps have show that +at least 3 cycles are necessary to bring the circuit in a state from which the +sequence 1, 2, 3 can be produced.) + +The ``-set-init-undef`` option tells the :cmd:ref:`sat` command to initialize +all registers to the undef (``x``) state. The way the ``x`` state is treated in +Verilog will ensure that the solution will work for any initial state. + +The ``-max_undef`` option instructs the :cmd:ref:`sat` command to find a +solution with a maximum number of undefs. This way we can see clearly which +inputs bits are relevant to the solution. + +Finally the three ``-set-at`` options add constraints for the ``y`` signal to +play the 1, 2, 3 sequence, starting with time step 4. + +This produces the following output: + +.. todo:: replace inline code + +.. code-block:: + :caption: Solving a sequential SAT problem in the ``memdemo`` module. + :name: memdemo_sat + + yosys [memdemo]> sat -seq 6 -show y -show d -set-init-undef \ + -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3 + + 1. Executing SAT pass (solving SAT problems in the circuit). + Full command line: sat -seq 6 -show y -show d -set-init-undef + -max_undef -set-at 4 y 1 -set-at 5 y 2 -set-at 6 y 3 + + Setting up time step 1: + Final constraint equation: { } = { } + Imported 29 cells to SAT database. + + Setting up time step 2: + Final constraint equation: { } = { } + Imported 29 cells to SAT database. + + Setting up time step 3: + Final constraint equation: { } = { } + Imported 29 cells to SAT database. + + Setting up time step 4: + Import set-constraint for timestep: \y = 4'0001 + Final constraint equation: \y = 4'0001 + Imported 29 cells to SAT database. + + Setting up time step 5: + Import set-constraint for timestep: \y = 4'0010 + Final constraint equation: \y = 4'0010 + Imported 29 cells to SAT database. + + Setting up time step 6: + Import set-constraint for timestep: \y = 4'0011 + Final constraint equation: \y = 4'0011 + Imported 29 cells to SAT database. + + Setting up initial state: + Final constraint equation: { \y \s2 \s1 \mem[3] \mem[2] \mem[1] + \mem[0] } = 24'xxxxxxxxxxxxxxxxxxxxxxxx + + Import show expression: \y + Import show expression: \d + + Solving problem with 10322 variables and 27881 clauses.. + SAT model found. maximizing number of undefs. + SAT solving finished - model found: + + Time Signal Name Dec Hex Bin + ---- -------------------- ---------- ---------- --------------- + init \mem[0] -- -- xxxx + init \mem[1] -- -- xxxx + init \mem[2] -- -- xxxx + init \mem[3] -- -- xxxx + init \s1 -- -- xx + init \s2 -- -- xx + init \y -- -- xxxx + ---- -------------------- ---------- ---------- --------------- + 1 \d 0 0 0000 + 1 \y -- -- xxxx + ---- -------------------- ---------- ---------- --------------- + 2 \d 1 1 0001 + 2 \y -- -- xxxx + ---- -------------------- ---------- ---------- --------------- + 3 \d 2 2 0010 + 3 \y 0 0 0000 + ---- -------------------- ---------- ---------- --------------- + 4 \d 3 3 0011 + 4 \y 1 1 0001 + ---- -------------------- ---------- ---------- --------------- + 5 \d -- -- 001x + 5 \y 2 2 0010 + ---- -------------------- ---------- ---------- --------------- + 6 \d -- -- xxxx + 6 \y 3 3 0011 + +It is not surprising that the solution sets ``d = 0`` in the first step, as this +is the only way of setting the ``s1`` and ``s2`` registers to a known value. The +input values for the other steps are a bit harder to work out manually, but the +SAT solver finds the correct solution in an instant. + +There is much more to write about the :cmd:ref:`sat` command. For example, there +is a set of options that can be used to performs sequential proofs using +temporal induction :cite:p:`een2003temporal`. The command ``help sat`` can be +used to print a list of all options with short descriptions of their functions. diff --git a/docs/source/using_yosys/more_scripting/load_design.rst b/docs/source/using_yosys/more_scripting/load_design.rst new file mode 100644 index 00000000000..d64c50959bd --- /dev/null +++ b/docs/source/using_yosys/more_scripting/load_design.rst @@ -0,0 +1,40 @@ +Loading a design +~~~~~~~~~~~~~~~~ + +keyword: Frontends + +- :doc:`/cmd/read_verilog` + +.. todo:: include ``read_verilog </`` prefix. For example: + +.. code:: yoscrypt + + cd foo # switch to module foo + delete bar # delete object foo/bar + + cd mycpu # switch to module mycpu + dump reg_* # print details on all objects whose names start with reg_ + + cd .. # switch back to design + +Note: Most synthesis scripts never switch to module context. But it is a very +powerful tool which we explore more in +:doc:`/using_yosys/more_scripting/interactive_investigation`. + +Selecting by object property or type +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Special patterns can be used to select by object property or type. For example: + +- select all wires whose names start with ``reg_``: :yoscrypt:`select w:reg_*` +- select all objects with the attribute ``foobar`` set: :yoscrypt:`select + a:foobar` +- select all objects with the attribute ``foobar`` set to 42: :yoscrypt:`select + a:foobar=42` +- select all modules with the attribute ``blabla`` set: :yoscrypt:`select + A:blabla` +- select all $add cells from the module foo: :yoscrypt:`select foo/t:$add` + +A complete list of pattern expressions can be found in :doc:`/cmd/select`. + +Operations on selections +~~~~~~~~~~~~~~~~~~~~~~~~ + +Combining selections +^^^^^^^^^^^^^^^^^^^^ + +The :cmd:ref:`select` command is actually much more powerful than it might seem +at first glance. When it is called with multiple arguments, each argument is +evaluated and pushed separately on a stack. After all arguments have been +processed it simply creates the union of all elements on the stack. So +:yoscrypt:`select t:$add a:foo` will select all ``$add`` cells and all objects +with the ``foo`` attribute set: + +.. literalinclude:: /code_examples/selections/foobaraddsub.v + :caption: Test module for operations on selections + :name: foobaraddsub + :language: verilog + +.. code-block:: + :caption: Output for command ``select t:$add a:foo -list`` on :numref:`foobaraddsub` + + yosys> select t:$add a:foo -list + foobaraddsub/$add$foobaraddsub.v:6$3 + foobaraddsub/$sub$foobaraddsub.v:5$2 + foobaraddsub/$add$foobaraddsub.v:4$1 + +In many cases simply adding more and more stuff to the selection is an +ineffective way of selecting the interesting part of the design. Special +arguments can be used to combine the elements on the stack. For example the +``%i`` arguments pops the last two elements from the stack, intersects them, and +pushes the result back on the stack. So :yoscrypt:`select t:$add a:foo %i` will +select all ``$add`` cells that have the ``foo`` attribute set: + +.. code-block:: + :caption: Output for command ``select t:$add a:foo %i -list`` on :numref:`foobaraddsub` + + yosys> select t:$add a:foo %i -list + foobaraddsub/$add$foobaraddsub.v:4$1 + +Some of the special ``%``-codes: + +- ``%u``: union of top two elements on stack -- pop 2, push 1 +- ``%d``: difference of top two elements on stack -- pop 2, push 1 +- ``%i``: intersection of top two elements on stack -- pop 2, push 1 +- ``%n``: inverse of top element on stack -- pop 1, push 1 + +See :doc:`/cmd/select` for the full list. + +Expanding selections +^^^^^^^^^^^^^^^^^^^^ + +:numref:`sumprod` uses the Yosys non-standard ``{... *}`` syntax to set the +attribute ``sumstuff`` on all cells generated by the first assign statement. +(This works on arbitrary large blocks of Verilog code and can be used to mark +portions of code for analysis.) + +.. literalinclude:: /code_examples/selections/sumprod.v + :caption: Another test module for operations on selections + :name: sumprod + :language: verilog + +Selecting ``a:sumstuff`` in this module will yield the following circuit +diagram: + +.. figure:: /_images/code_examples/selections/sumprod_00.* + :class: width-helper + :name: sumprod_00 + + Output of ``show a:sumstuff`` on :numref:`sumprod` + +As only the cells themselves are selected, but not the temporary wire ``$1_Y``, +the two adders are shown as two disjunct parts. This can be very useful for +global signals like clock and reset signals: just unselect them using a command +such as :yoscrypt:`select -del clk rst` and each cell using them will get its +own net label. + +In this case however we would like to see the cells connected properly. This can +be achieved using the ``%x`` action, that broadens the selection, i.e. for each +selected wire it selects all cells connected to the wire and vice versa. So +:yoscrypt:`show a:sumstuff %x` yields the diagram shown in :numref:`sumprod_01`: + +.. figure:: /_images/code_examples/selections/sumprod_01.* + :class: width-helper + :name: sumprod_01 + + Output of ``show a:sumstuff %x`` on :numref:`sumprod` + +.. _selecting_logic_cones: + +Selecting logic cones +^^^^^^^^^^^^^^^^^^^^^ + +:numref:`sumprod_01` shows what is called the ``input cone`` of ``sum``, i.e. +all cells and signals that are used to generate the signal ``sum``. The ``%ci`` +action can be used to select the input cones of all object in the top selection +in the stack maintained by the :cmd:ref:`select` command. + +As with the ``%x`` action, these commands broaden the selection by one "step". +But this time the operation only works against the direction of data flow. That +means, wires only select cells via output ports and cells only select wires via +input ports. + +The following sequence of diagrams demonstrates this step-wise expansion: + +.. figure:: /_images/code_examples/selections/sumprod_02.* + :class: width-helper + + Output of :yoscrypt:`show prod` on :numref:`sumprod` + +.. figure:: /_images/code_examples/selections/sumprod_03.* + :class: width-helper + + Output of :yoscrypt:`show prod %ci` on :numref:`sumprod` + +.. figure:: /_images/code_examples/selections/sumprod_04.* + :class: width-helper + + Output of :yoscrypt:`show prod %ci %ci` on :numref:`sumprod` + +.. figure:: /_images/code_examples/selections/sumprod_05.* + :class: width-helper + + Output of :yoscrypt:`show prod %ci %ci %ci` on :numref:`sumprod` + +Notice the subtle difference between :yoscrypt:`show prod %ci` and +:yoscrypt:`show prod %ci %ci`. Both images show the ``$mul`` cell driven by +some inputs ``$3_Y`` and ``c``. However it is not until the second image, +having called ``%ci`` the second time, that :cmd:ref:`show` is able to +distinguish between ``$3_Y`` being a wire and ``c`` being an input. We can see +this better with the :cmd:ref:`dump` command instead: + +.. literalinclude:: /code_examples/selections/sumprod.out + :language: RTLIL + :end-at: end + :caption: Output of :yoscrypt:`dump prod %ci` + +.. literalinclude:: /code_examples/selections/sumprod.out + :language: RTLIL + :start-after: end + :caption: Output of :yoscrypt:`dump prod %ci %ci` + +When selecting many levels of logic, repeating ``%ci`` over and over again can +be a bit dull. So there is a shortcut for that: the number of iterations can be +appended to the action. So for example the action ``%ci3`` is identical to +performing the ``%ci`` action three times. + +The action ``%ci*`` performs the ``%ci`` action over and over again until it +has no effect anymore. + +.. _advanced_logic_cones: + +Advanced logic cone selection +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In most cases there are certain cell types and/or ports that should not be +considered for the ``%ci`` action, or we only want to follow certain cell types +and/or ports. This can be achieved using additional patterns that can be +appended to the ``%ci`` action. + +Lets consider :numref:`memdemo_src`. It serves no purpose other than being a +non-trivial circuit for demonstrating some of the advanced Yosys features. This +code is available in ``docs/source/code_examples/selections`` of the Yosys +source repository. + +.. literalinclude:: /code_examples/selections/memdemo.v + :caption: :file:`memdemo.v` + :name: memdemo_src + :language: verilog + +The script :file:`memdemo.ys` is used to generate the images included here. Let's +look at the first section: + +.. literalinclude:: /code_examples/selections/memdemo.ys + :caption: Synthesizing :ref:`memdemo_src` + :name: memdemo_ys + :language: yoscrypt + :end-at: opt + +This loads :numref:`memdemo_src` and synthesizes the included module. Note that +this code can be copied and run directly in a Yosys command line session, +provided :file:`memdemo.v` is in the same directory. We can now change to the +``memdemo`` module with ``cd memdemo``, and call :cmd:ref:`show` to see the +diagram in :numref:`memdemo_00`. + +.. figure:: /_images/code_examples/selections/memdemo_00.* + :class: width-helper + :name: memdemo_00 + + Complete circuit diagram for the design shown in :numref:`memdemo_src` + +There's a lot going on there, but maybe we are only interested in the tree of +multiplexers that select the output value. Let's start by just showing the +output signal, ``y``, and its immediate predecessors. Remember `Selecting logic +cones`_ from above, we can use :yoscrypt:`show y %ci2`: + +.. figure:: /_images/code_examples/selections/memdemo_01.* + :class: width-helper + :name: memdemo_01 + + Output of :yoscrypt:`show y %ci2` + +From this we would learn that ``y`` is driven by a ``$dff cell``, that ``y`` is +connected to the output port ``Q``, that the ``clk`` signal goes into the +``CLK`` input port of the cell, and that the data comes from an auto-generated +wire into the input ``D`` of the flip-flop cell (indicated by the ``$`` at the +start of the name). Let's go a bit further now and try :yoscrypt:`show y %ci5`: + +.. figure:: /_images/code_examples/selections/memdemo_02.* + :class: width-helper + :name: memdemo_02 + + Output of :yoscrypt:`show y %ci5` + +That's starting to get a bit messy, so maybe we want to ignore the mux select +inputs. To add a pattern we add a colon followed by the pattern to the ``%ci`` +action. The pattern itself starts with ``-`` or ``+``, indicating if it is an +include or exclude pattern, followed by an optional comma separated list of cell +types, followed by an optional comma separated list of port names in square +brackets. In this case, we want to exclude the ``S`` port of the ``$mux`` cell +type with :yoscrypt:`show y %ci5:-$mux[S]`: + +.. figure:: /_images/code_examples/selections/memdemo_03.* + :class: width-helper + :name: memdemo_03 + + Output of :yoscrypt:`show y %ci5:-$mux[S]` + +We could use a command such as :yoscrypt:`show y %ci2:+$dff[Q,D] +%ci*:-$mux[S]:-$dff` in which the first ``%ci`` jumps over the initial d-type +flip-flop and the 2nd action selects the entire input cone without going over +multiplexer select inputs and flip-flop cells: + +.. figure:: /_images/code_examples/selections/memdemo_05.* + :class: width-helper + :name: memdemo_05 + + Output of ``show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff`` + +Or we could use :yoscrypt:`show y %ci*:-[CLK,S]:+$dff:+$mux` instead, following +the input cone all the way but only following ``$dff`` and ``$mux`` cells, and +ignoring any ports named ``CLK`` or ``S``: + +.. TODO:: pending discussion on whether rule ordering is a bug or a feature + +.. figure:: /_images/code_examples/selections/memdemo_04.* + :class: width-helper + :name: memdemo_04 + + Output of :yoscrypt:`show y %ci*:-[CLK,S]:+$dff,$mux` + +Similar to ``%ci`` exists an action ``%co`` to select output cones that accepts +the same syntax for pattern and repetition. The ``%x`` action mentioned +previously also accepts this advanced syntax. + +These actions for traversing the circuit graph, combined with the actions for +boolean operations such as intersection (``%i``) and difference (``%d``) are +powerful tools for extracting the relevant portions of the circuit under +investigation. + +Again, see :doc:`/cmd/select` for full documentation of these expressions. + +Incremental selection +^^^^^^^^^^^^^^^^^^^^^ + +Sometimes a selection can most easily be described by a series of add/delete +operations. As mentioned previously, the commands :yoscrypt:`select -add` and +:yoscrypt:`select -del` respectively add or remove objects from the current +selection instead of overwriting it. + +.. code:: yoscrypt + + select -none # start with an empty selection + select -add reg_* # select a bunch of objects + select -del reg_42 # but not this one + select -add state %ci # and add more stuff + +Within a select expression the token ``%`` can be used to push the previous selection +on the stack. + +.. code:: yoscrypt + + select t:$add t:$sub # select all $add and $sub cells + select % %ci % %d # select only the input wires to those cells + +Storing and recalling selections +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: reflow for not presentation + +The current selection can be stored in memory with the command ``select -set +``. It can later be recalled using ``select @``. In fact, the +``@`` expression pushes the stored selection on the stack maintained by +the :cmd:ref:`select` command. So for example :yoscrypt:`select @foo @bar %i` +will select the intersection between the stored selections ``foo`` and ``bar``. + +In larger investigation efforts it is highly recommended to maintain a script +that sets up relevant selections, so they can easily be recalled, for example +when Yosys needs to be re-run after a design or source code change. + +The :cmd:ref:`history` command can be used to list all recent interactive +commands. This feature can be useful for creating such a script from the +commands used in an interactive session. + +Remember that select expressions can also be used directly as arguments to most +commands. Some commands also accept a single select argument to some options. In +those cases selection variables must be used to capture more complex selections. + +Example code from |code_examples/selections|_: + +.. |code_examples/selections| replace:: :file:`docs/source/code_examples/selections` +.. _code_examples/selections: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/selections + +.. literalinclude:: /code_examples/selections/select.v + :language: verilog + :caption: :file:`select.v` + +.. literalinclude:: /code_examples/selections/select.ys + :language: yoscrypt + :caption: :file:`select.ys` + :name: select_ys + +.. figure:: /_images/code_examples/selections/select.* + :class: width-helper + + Circuit diagram produced by :numref:`select_ys` diff --git a/docs/source/using_yosys/more_scripting/troubleshooting.rst b/docs/source/using_yosys/more_scripting/troubleshooting.rst new file mode 100644 index 00000000000..a17a552d2e4 --- /dev/null +++ b/docs/source/using_yosys/more_scripting/troubleshooting.rst @@ -0,0 +1,6 @@ +Troubleshooting +~~~~~~~~~~~~~~~ + +.. todo:: troubleshooting document(?) + +See :doc:`/cmd/bugpoint` diff --git a/docs/source/using_yosys/synthesis/abc.rst b/docs/source/using_yosys/synthesis/abc.rst new file mode 100644 index 00000000000..928b320186d --- /dev/null +++ b/docs/source/using_yosys/synthesis/abc.rst @@ -0,0 +1,103 @@ +The ABC toolbox +--------------- + +.. role:: yoscrypt(code) + :language: yoscrypt + +ABC_, from the University of California, Berkeley, is a logic toolbox used for +fine-grained optimisation and LUT mapping. + +Yosys has two different commands, which both use this logic toolbox, but use it +in different ways. + +The :cmd:ref:`abc` pass can be used for both ASIC (e.g. :yoscrypt:`abc +-liberty`) and FPGA (:yoscrypt:`abc -lut`) mapping, but this page will focus on +FPGA mapping. + +The :cmd:ref:`abc9` pass generally provides superior mapping quality due to +being aware of combination boxes and DFF and LUT timings, giving it a more +global view of the mapping problem. + +.. _ABC: https://github.com/berkeley-abc/abc + +ABC: the unit delay model, simple and efficient +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :cmd:ref:`abc` pass uses a highly simplified view of an FPGA: + +- An FPGA is made up of a network of inputs that connect through LUTs to a + network of outputs. These inputs may actually be I/O pins, D flip-flops, + memory blocks or DSPs, but ABC is unaware of this. +- Each LUT has 1 unit of delay between an input and its output, and this applies + for all inputs of a LUT, and for all sizes of LUT up to the maximum LUT size + allowed; e.g. the delay between the input of a LUT2 and its output is the same + as the delay between the input of a LUT6 and its output. +- A LUT may take up a variable number of area units. This is constant for each + size of LUT; e.g. a LUT4 may take up 1 unit of area, but a LUT5 may take up 2 + units of area, but this applies for all LUT4s and LUT5s. + +This is known as the "unit delay model", because each LUT uses one unit of +delay. + +From this view, the problem ABC has to solve is finding a mapping of the network +to LUTs that has the lowest delay, and then optimising the mapping for size +while maintaining this delay. + +This approach has advantages: + +- It is simple and easy to implement. +- Working with unit delays is fast to manipulate. +- It reflects *some* FPGA families, for example, the iCE40HX/LP fits the + assumptions of the unit delay model quite well (almost all synchronous blocks, + except for adders). + +But this approach has drawbacks, too: + +- The network of inputs and outputs with only LUTs means that a lot of + combinational cells (multipliers and LUTRAM) are invisible to the unit delay + model, meaning the critical path it optimises for is not necessarily the + actual critical path. +- LUTs are implemented as multiplexer trees, so there is a delay caused by the + result propagating through the remaining multiplexers. This means the + assumption of delay being equal isn't true in physical hardware, and is + proportionally larger for larger LUTs. +- Even synchronous blocks have arrival times (propagation delay between clock + edge to output changing) and setup times (requirement for input to be stable + before clock edge) which affect the delay of a path. + +ABC9: the generalised delay model, realistic and flexible +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +ABC9 uses a more detailed and accurate model of an FPGA: + +- An FPGA is made up of a network of inputs that connect through LUTs and + combinational boxes to a network of outputs. These boxes have specified delays + between inputs and outputs, and may have an associated network ("white boxes") + or not ("black boxes"), but must be treated as a whole. +- Each LUT has a specified delay between an input and its output in arbitrary + delay units, and this varies for all inputs of a LUT and for all sizes of LUT, + but each size of LUT has the same associated delay; e.g. the delay between + input A and output is different between a LUT2 and a LUT6, but is constant for + all LUT6s. +- A LUT may take up a variable number of area units. This is constant for each + size of LUT; e.g. a LUT4 may take up 1 unit of area, but a LUT5 may take up 2 + units of area, but this applies for all LUT4s and LUT5s. + +This is known as the "generalised delay model", because it has been generalised +to arbitrary delay units. ABC9 doesn't actually care what units you use here, +but the Yosys convention is picoseconds. Note the introduction of boxes as a +concept. While the generalised delay model does not require boxes, they +naturally fit into it to represent combinational delays. Even synchronous delays +like arrival and setup can be emulated with combinational boxes that act as a +delay. This is further extended to white boxes, where the mapper is able to see +inside a box, and remove orphan boxes with no outputs, such as adders. + +Again, ABC9 finds a mapping of the network to LUTs that has the lowest delay, +and then minimises it to find the lowest area, but it has a lot more information +to work with about the network. + +The result here is that ABC9 can remove boxes (like adders) to reduce area, +optimise better around those boxes, and also permute inputs to give the critical +path the fastest inputs. + +.. todo:: more about logic minimization & register balancing et al with ABC diff --git a/docs/source/using_yosys/synthesis/cell_libs.rst b/docs/source/using_yosys/synthesis/cell_libs.rst new file mode 100644 index 00000000000..a2fac8dbf7f --- /dev/null +++ b/docs/source/using_yosys/synthesis/cell_libs.rst @@ -0,0 +1,125 @@ +Mapping to cell libraries +------------------------- + +.. role:: yoscrypt(code) + :language: yoscrypt + +While much of this documentation focuses on the use of Yosys with FPGAs, it is +also possible to map to cell libraries which can be used in designing ASICs. +This section will cover a brief `example project`_, available in the Yosys +source code under :file:`docs/source/code_examples/intro/`. The project +contains a simple ASIC synthesis script (:file:`counter.ys`), a digital design +written in Verilog (:file:`counter.v`), and a simple CMOS cell library +(:file:`mycells.lib`). Many of the early steps here are already covered in more +detail in the :doc:`/getting_started/example_synth` document. + +.. note:: + + The :file:`counter.ys` script includes the commands used to generate the + images in this document. Code snippets in this document skip these commands; + including line numbers to allow the reader to follow along with the source. + + To learn more about these commands, check out :ref:`interactive_show`. + +.. _example project: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/intro + +A simple counter +~~~~~~~~~~~~~~~~ + +First, let's quickly look at the design: + +.. literalinclude:: /code_examples/intro/counter.v + :language: Verilog + :linenos: + :name: counter-v + :caption: :file:`counter.v` + +This is a simple counter with reset and enable. If the reset signal, ``rst``, +is high then the counter will reset to 0. Otherwise, if the enable signal, +``en``, is high then the ``count`` register will increment by 1 each rising edge +of the clock, ``clk``. + +Loading the design +~~~~~~~~~~~~~~~~~~ + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 1-3 + :lineno-match: + :caption: :file:`counter.ys` - read design + +Our circuit now looks like this: + +.. figure:: /_images/code_examples/intro/counter_00.* + :class: width-helper + :name: counter-hierarchy + + ``counter`` after :cmd:ref:`hierarchy` + +Coarse-grain representation +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 7-10 + :lineno-match: + :caption: :file:`counter.ys` - the high-level stuff + +.. figure:: /_images/code_examples/intro/counter_01.* + :class: width-helper + + Coarse-grain representation of the ``counter`` module + +Logic gate mapping +~~~~~~~~~~~~~~~~~~ + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 14-15 + :lineno-match: + :caption: :file:`counter.ys` - mapping to internal cell library + +.. figure:: /_images/code_examples/intro/counter_02.* + :class: width-helper + + ``counter`` after :cmd:ref:`techmap` + +Mapping to hardware +~~~~~~~~~~~~~~~~~~~ + +For this example, we are using a Liberty file to describe a cell library which +our internal cell library will be mapped to: + +.. literalinclude:: /code_examples/intro/mycells.lib + :language: Liberty + :linenos: + :name: mycells-lib + :caption: :file:`mycells.lib` + +Recall that the Yosys built-in logic gate types are ``$_NOT_``, ``$_AND_``, +``$_OR_``, ``$_XOR_``, and ``$_MUX_`` with an assortment of dff memory types. +:ref:`mycells-lib` defines our target cells as ``BUF``, ``NOT``, ``NAND``, +``NOR``, and ``DFF``. Mapping between these is performed with the commands +:cmd:ref:`dfflibmap` and :cmd:ref:`abc` as follows: + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 20-27 + :lineno-match: + :caption: :file:`counter.ys` - mapping to hardware + +The final version of our ``counter`` module looks like this: + +.. figure:: /_images/code_examples/intro/counter_03.* + :class: width-helper + + ``counter`` after hardware cell mapping + +Before finally being output as a verilog file with :cmd:ref:`write_verilog`, +which can then be loaded into another tool: + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 30-31 + :lineno-match: + :caption: :file:`counter.ys` - write synthesized design diff --git a/docs/source/using_yosys/synthesis/extract.rst b/docs/source/using_yosys/synthesis/extract.rst new file mode 100644 index 00000000000..650354469b2 --- /dev/null +++ b/docs/source/using_yosys/synthesis/extract.rst @@ -0,0 +1,231 @@ +The extract pass +---------------- + +- Like the :cmd:ref:`techmap` pass, the :cmd:ref:`extract` pass is called with a + map file. It compares the circuits inside the modules of the map file with the + design and looks for sub-circuits in the design that match any of the modules + in the map file. +- If a match is found, the :cmd:ref:`extract` pass will replace the matching + subcircuit with an instance of the module from the map file. +- In a way the :cmd:ref:`extract` pass is the inverse of the techmap pass. + +.. todo:: add/expand supporting text, also mention custom pattern matching and + pmgen + +Example code can be found in |code_examples/macc|_. + +.. |code_examples/macc| replace:: :file:`docs/source/code_examples/macc` +.. _code_examples/macc: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/macc + + +.. literalinclude:: /code_examples/macc/macc_simple_test.ys + :language: yoscrypt + :lines: 1-2 + +.. figure:: /_images/code_examples/macc/macc_simple_test_00a.* + :class: width-helper + + before :cmd:ref:`extract` + +.. literalinclude:: /code_examples/macc/macc_simple_test.ys + :language: yoscrypt + :lines: 6 + +.. figure:: /_images/code_examples/macc/macc_simple_test_00b.* + :class: width-helper + + after :cmd:ref:`extract` + +.. literalinclude:: /code_examples/macc/macc_simple_test.v + :language: verilog + :caption: :file:`macc_simple_test.v` + +.. literalinclude:: /code_examples/macc/macc_simple_xmap.v + :language: verilog + :caption: :file:`macc_simple_xmap.v` + +.. literalinclude:: /code_examples/macc/macc_simple_test_01.v + :language: verilog + :caption: :file:`macc_simple_test_01.v` + +.. figure:: /_images/code_examples/macc/macc_simple_test_01a.* + :class: width-helper + +.. figure:: /_images/code_examples/macc/macc_simple_test_01b.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_simple_test_02.v + :language: verilog + :caption: :file:`macc_simple_test_02.v` + +.. figure:: /_images/code_examples/macc/macc_simple_test_02a.* + :class: width-helper + +.. figure:: /_images/code_examples/macc/macc_simple_test_02b.* + :class: width-helper + +The wrap-extract-unwrap method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Often a coarse-grain element has a constant bit-width, but can be used to +implement operations with a smaller bit-width. For example, a 18x25-bit multiplier +can also be used to implement 16x20-bit multiplication. + +A way of mapping such elements in coarse grain synthesis is the +wrap-extract-unwrap method: + +wrap + Identify candidate-cells in the circuit and wrap them in a cell with a + constant wider bit-width using :cmd:ref:`techmap`. The wrappers use the same + parameters as the original cell, so the information about the original width + of the ports is preserved. Then use the :cmd:ref:`connwrappers` command to + connect up the bit-extended in- and outputs of the wrapper cells. + +extract + Now all operations are encoded using the same bit-width as the coarse grain + element. The :cmd:ref:`extract` command can be used to replace circuits with + cells of the target architecture. + +unwrap + The remaining wrapper cell can be unwrapped using :cmd:ref:`techmap`. + +Example: DSP48_MACC +~~~~~~~~~~~~~~~~~~~ + +This section details an example that shows how to map MACC operations of +arbitrary size to MACC cells with a 18x25-bit multiplier and a 48-bit adder +(such as the Xilinx DSP48 cells). + +Preconditioning: :file:`macc_xilinx_swap_map.v` + +Make sure ``A`` is the smaller port on all multipliers + +.. todo:: add/expand supporting text + +.. literalinclude:: /code_examples/macc/macc_xilinx_swap_map.v + :language: verilog + :caption: :file:`macc_xilinx_swap_map.v` + +Wrapping multipliers: :file:`macc_xilinx_wrap_map.v` + +.. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v + :language: verilog + :lines: 1-46 + :caption: :file:`macc_xilinx_wrap_map.v` + +Wrapping adders: :file:`macc_xilinx_wrap_map.v` + +.. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v + :language: verilog + :lines: 48-89 + :caption: :file:`macc_xilinx_wrap_map.v` + +Extract: :file:`macc_xilinx_xmap.v` + +.. literalinclude:: /code_examples/macc/macc_xilinx_xmap.v + :language: verilog + :caption: :file:`macc_xilinx_xmap.v` + +... simply use the same wrapping commands on this module as on the design to +create a template for the :cmd:ref:`extract` command. + +Unwrapping multipliers: :file:`macc_xilinx_unwrap_map.v` + +.. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v + :language: verilog + :lines: 1-30 + :caption: ``$__mul_wrapper`` module in :file:`macc_xilinx_unwrap_map.v` + +Unwrapping adders: :file:`macc_xilinx_unwrap_map.v` + +.. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v + :language: verilog + :lines: 32-61 + :caption: ``$__add_wrapper`` module in :file:`macc_xilinx_unwrap_map.v` + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.v + :language: verilog + :lines: 1-6 + :caption: ``test1`` of :file:`macc_xilinx_test.v` + +.. figure:: /_images/code_examples/macc/macc_xilinx_test1a.* + :class: width-helper + +.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.v + :language: verilog + :lines: 8-13 + :caption: ``test2`` of :file:`macc_xilinx_test.v` + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2a.* + :class: width-helper + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.* + :class: width-helper + +Wrapping in ``test1``: + +.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys + :language: yoscrypt + :start-after: part c + :end-before: end part c + +.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.* + :class: width-helper + +Wrapping in ``test2``: + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys + :language: yoscrypt + :start-after: part c + :end-before: end part c + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.* + :class: width-helper + +Extract in ``test1``: + +.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys + :language: yoscrypt + :start-after: part d + :end-before: end part d + +.. figure:: /_images/code_examples/macc/macc_xilinx_test1d.* + :class: width-helper + +Extract in ``test2``: + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys + :language: yoscrypt + :start-after: part d + :end-before: end part d + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.* + :class: width-helper + +Unwrap in ``test2``: + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.* + :class: width-helper + +.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys + :language: yoscrypt + :start-after: part e + :end-before: end part e + +.. figure:: /_images/code_examples/macc/macc_xilinx_test2e.* + :class: width-helper \ No newline at end of file diff --git a/docs/source/using_yosys/synthesis/fsm.rst b/docs/source/using_yosys/synthesis/fsm.rst new file mode 100644 index 00000000000..e1ed5513397 --- /dev/null +++ b/docs/source/using_yosys/synthesis/fsm.rst @@ -0,0 +1,142 @@ +FSM handling +============ + +The :cmd:ref:`fsm` command identifies, extracts, optimizes (re-encodes), and +re-synthesizes finite state machines. It again is a macro that calls a series of +other commands: + +.. literalinclude:: /code_examples/macro_commands/fsm.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`fsm` + +See also :doc:`/cmd/fsm`. + +The algorithms used for FSM detection and extraction are influenced by a more +general reported technique :cite:p:`fsmextract`. + +FSM detection +~~~~~~~~~~~~~ + +The :cmd:ref:`fsm_detect` pass identifies FSM state registers. It sets the +``\fsm_encoding = "auto"`` attribute on any (multi-bit) wire that matches the +following description: + +- Does not already have the ``\fsm_encoding`` attribute. +- Is not an output of the containing module. +- Is driven by single ``$dff`` or ``$adff`` cell. +- The ``\D``-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 ``\fsm_encoding = "auto"`` on registers that should be considered FSM +state registers and setting ``\fsm_encoding = "none"`` on registers that match +the above criteria but should not be considered FSM state registers. + +Note however that marking state registers with ``\fsm_encoding`` that are not +suitable for FSM recoding can cause synthesis to fail or produce invalid +results. + +FSM extraction +~~~~~~~~~~~~~~ + +The :cmd:ref:`fsm_extract` pass operates on all state signals marked with the +(``\fsm_encoding != "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 :cmd:ref:`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 :cmd:ref:`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 + ``\unused_bits`` (that is usually set by the :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`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. diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst new file mode 100644 index 00000000000..c00a940daa6 --- /dev/null +++ b/docs/source/using_yosys/synthesis/index.rst @@ -0,0 +1,35 @@ +Synthesis in detail +------------------- + +Synthesis can generally be broken down into coarse-grain synthesis, and +fine-grain synthesis. We saw this in :doc:`/getting_started/example_synth` +where a design was loaded and elaborated and then went through a series of +coarse-grain optimizations before being mapped to hard blocks and fine-grain +cells. Most commands in Yosys will target either coarse-grain representation or +fine-grain representation, with only a select few compatible with both states. + +Commands such as :cmd:ref:`proc`, :cmd:ref:`fsm`, and :cmd:ref:`memory` rely on +the additional information in the coarse-grain representation, along with a +number of optimizations such as :cmd:ref:`wreduce`, :cmd:ref:`share`, and +:cmd:ref:`alumacc`. :cmd:ref:`opt` provides optimizations which are useful in +both states, while :cmd:ref:`techmap` is used to convert coarse-grain cells +to the corresponding fine-grain representation. + +Single-bit cells (logic gates, FFs) as well as LUTs, half-adders, and +full-adders make up the bulk of the fine-grain representation and are necessary +for commands such as :cmd:ref:`abc`\ /:cmd:ref:`abc9`, :cmd:ref:`simplemap`, +:cmd:ref:`dfflegalize`, and :cmd:ref:`memory_map`. + +.. toctree:: + :maxdepth: 3 + + synth + proc + fsm + memory + opt + techmap_synth + extract + abc + cell_libs + diff --git a/docs/source/CHAPTER_Memorymap.rst b/docs/source/using_yosys/synthesis/memory.rst similarity index 81% rename from docs/source/CHAPTER_Memorymap.rst rename to docs/source/using_yosys/synthesis/memory.rst index cdc381eed81..c04a21e53da 100644 --- a/docs/source/CHAPTER_Memorymap.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -1,19 +1,111 @@ -.. _chapter:memorymap: +Memory handling +=============== + +The :cmd:ref:`memory` command +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In the RTL netlist, memory reads and writes are individual cells. This makes +consolidating the number of ports for a memory easier. The :cmd:ref:`memory` +pass transforms memories to an implementation. Per default that is logic for +address decoders and registers. It also is a macro command that calls the other +common ``memory_*`` passes in a sensible order: + +.. literalinclude:: /code_examples/macro_commands/memory.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`memory` + +.. todo:: Make ``memory_*`` notes less quick + +Some quick notes: + +- :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. +- :cmd:ref:`memory_collect` collects all read and write cells for a memory and + transforms them into one multi-port memory cell. +- :cmd:ref:`memory_map` takes the multi-port memory cell and transforms it to + address decoder logic and registers. + +For more information about :cmd:ref:`memory`, such as disabling certain sub +commands, see :doc:`/cmd/memory`. + +Example +------- + +.. todo:: describe ``memory`` images + +|code_examples/synth_flow|_. + +.. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/synth_flow + +.. figure:: /_images/code_examples/synth_flow/memory_01.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/memory_01.ys + :language: yoscrypt + :caption: :file:`memory_01.ys` + +.. literalinclude:: /code_examples/synth_flow/memory_01.v + :language: verilog + :caption: :file:`memory_01.v` + +.. figure:: /_images/code_examples/synth_flow/memory_02.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/memory_02.v + :language: verilog + :caption: :file:`memory_02.v` + +.. literalinclude:: /code_examples/synth_flow/memory_02.ys + :language: yoscrypt + :caption: :file:`memory_02.ys` + +.. _memory_map: Memory mapping -============== +^^^^^^^^^^^^^^ + +Usually it is preferred to use architecture-specific RAM resources for memory. +For example: + +.. code-block:: yoscrypt + + memory -nomap + memory_libmap -lib my_memory_map.txt + techmap -map my_memory_map.v + memory_map + +:cmd:ref:`memory_libmap` attempts to convert memory cells (``$mem_v2`` etc) into +hardware supported memory using a provided library (:file:`my_memory_map.txt` in the +example above). Where necessary, emulation logic is added to ensure functional +equivalence before and after this conversion. :yoscrypt:`techmap -map +my_memory_map.v` then uses :cmd:ref:`techmap` to map to hardware primitives. Any +leftover memory cells unable to be converted are then picked up by +:cmd:ref:`memory_map` and mapped to DFFs and address decoders. -Documentation for the Yosys ``memory_libmap`` memory mapper. Note that not all supported patterns -are included in this document, of particular note is that combinations of multiple patterns should -generally work. For example, `Write port with byte enables`_ could be used in conjunction with any -of the simple dual port (SDP) models. In general if a hardware memory definition does not support a -given configuration, additional logic will be instantiated to guarantee behaviour is consistent with -simulation. +.. note:: -See also: `passes/memory/memlib.md `_ + More information about what mapping options are available and associated + costs of each can be found by enabling debug outputs. This can be done with + the :cmd:ref:`debug` command, or by using the ``-g`` flag when calling Yosys + to globally enable debug messages. -Additional notes ----------------- +For more on the lib format for :cmd:ref:`memory_libmap`, see +`passes/memory/memlib.md +`_ + +Supported memory patterns +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Note that not all supported patterns are included in this document, of +particular note is that combinations of multiple patterns should generally work. +For example, `wbe`_ could be used in conjunction with any of the simple dual +port (SDP) models. In general if a hardware memory definition does not support +a given configuration, additional logic will be instantiated to guarantee +behaviour is consistent with simulation. + +Notes +----- Memory kind selection ~~~~~~~~~~~~~~~~~~~~~ @@ -94,7 +186,9 @@ Initial data Most FPGA targets support initializing all kinds of memory to user-provided values. If explicit initialization is not used the initial memory value is undefined. Initial data can be provided by either initial statements writing memory cells one by one of ``$readmemh`` or ``$readmemb`` system -tasks. For an example pattern, see `Synchronous read port with initial value`_. +tasks. For an example pattern, see `sr_init`_. + +.. _wbe: Write port with byte enables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -127,6 +221,8 @@ Write port with byte enables Simple dual port (SDP) memory patterns -------------------------------------- +.. todo:: assorted enables, e.g. cen, wen+ren + Asynchronous-read SDP ~~~~~~~~~~~~~~~~~~~~~ @@ -180,6 +276,8 @@ Synchronous SDP read first read_data <= mem[read_addr]; end +.. _no_rw_check: + Synchronous SDP with undefined collision behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -197,8 +295,8 @@ Synchronous SDP with undefined collision behavior if (read_enable) begin read_data <= mem[read_addr]; - // 👇 this if block 👇 if (write_enable && read_addr == write_addr) + // this if block read_data <= 'x; end end @@ -218,6 +316,8 @@ Synchronous SDP with undefined collision behavior read_data <= mem[read_addr]; end +.. _sdp_wf: + Synchronous SDP with write-first behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -247,6 +347,7 @@ Synchronous SDP with write-first behavior (alternate pattern) .. code:: verilog + reg [ADDR_WIDTH - 1 : 0] read_addr_reg; reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; always @(posedge clk) begin @@ -333,6 +434,8 @@ Synchronous single-port RAM with write-first behavior read_data <= mem[addr]; end +.. _sr_init: + Synchronous read port with initial value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -373,7 +476,7 @@ Synchronous reset, reset priority over enable mem[write_addr] <= write_data; if (read_reset) - read_data <= {sval}; + read_data <= 'h1234; else if (read_enable) read_data <= mem[read_addr]; end @@ -407,8 +510,8 @@ Synchronous read port with asynchronous reset mem[write_addr] <= write_data; end - always @(posedge clk, posedge reset_read) begin - if (reset_read) + always @(posedge clk, posedge read_reset) begin + if (read_reset) read_data <= 'h1234; else if (read_enable) read_data <= mem[read_addr]; @@ -434,6 +537,8 @@ Asymmetric memory is supported on all targets, but may require emulation circuit natively supported. Note that when the memory is larger than the underlying block RAM primitive, hardware asymmetric memory support is likely not to be used even if present as it is more expensive. +.. _wide_sr: + Wide synchronous read port ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -589,14 +694,14 @@ TDP with multiple read ports assign read_data_b = mem[read_addr_b]; assign read_data_c = mem[read_addr_c]; -Not yet supported patterns --------------------------- +Patterns only supported with Verific +------------------------------------ Synchronous SDP with write-first behavior via blocking assignments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Would require modifications to the Yosys Verilog frontend. -- Use `Synchronous SDP with write-first behavior`_ instead +- Use `sdp_wf`_ for compatibility with Yosys + Verilog frontend. .. code:: verilog @@ -613,8 +718,8 @@ Synchronous SDP with write-first behavior via blocking assignments Asymmetric memories via part selection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Would require major changes to the Verilog frontend. -- Build wide ports out of narrow ports instead (see `Wide synchronous read port`_) +- Build wide ports out of narrow ports instead (see `wide_sr`_) for + compatibility with Yosys Verilog frontend. .. code:: verilog diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst new file mode 100644 index 00000000000..7861f66d4cd --- /dev/null +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -0,0 +1,230 @@ +Optimization passes +=================== + +Yosys employs a number of optimizations to generate better and cleaner results. +This chapter outlines these optimizations. + +.. todo:: "outlines these optimizations" or "outlines *some*.."? + +The :cmd:ref:`opt` macro command +-------------------------------- + +The Yosys pass :cmd:ref:`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. As listed in +:doc:`/cmd/opt`, this macro command calls the following ``opt_*`` commands: + +.. literalinclude:: /code_examples/macro_commands/opt.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`opt` + +.. _adv_opt_expr: + +Constant folding and simple expression rewriting - :cmd:ref:`opt_expr` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: unsure if this is too much detail and should be in :doc:`/yosys_internals/index` + +This pass performs constant folding on the internal combinational cell types +described in :doc:`/yosys_internals/formats/cell_library`. 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 :cmd:ref:`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` + ========= ========= =========== + +: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 :cmd:ref:`opt_expr` pass can replace 1-bit +wide ``$eq`` and ``$ne`` cells with buffers or not-gates if one input is +constant. Equality checks may also be reduced in size if there are redundant +bits in the arguments (i.e. bits which are constant on both inputs). This can, +for example, result in a 32-bit wide constant like ``255`` being reduced to the +8-bit value of ``8'11111111`` if the signal being compared is only 8-bit as in +:ref:`addr_gen_clean` of :doc:`/getting_started/example_synth`. + +The :cmd:ref:`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. + +.. literalinclude:: /code_examples/opt/opt_expr.ys + :language: Verilog + :start-after: read_verilog <`). In the second phase this netlist of internal gate +cells are mapped to an internal library of single-bit cells (see +:ref:`sec:celllib_gates`). In the second phase this netlist of internal gate types is transformed to a netlist of gates from the target technology library. When the target architecture provides coarse-grain cells (such as block ram or @@ -29,11 +29,11 @@ provided implementation. When no map file is provided, techmap uses a built-in map file that maps the Yosys RTL cell types to the internal gate library used by Yosys. The curious -reader may find this map file as techlibs/common/techmap.v in the Yosys source +reader may find this map file as `techlibs/common/techmap.v` in the Yosys source tree. Additional features have been added to techmap to allow for conditional mapping -of cells (see :doc:`cmd/techmap`). This can for example be useful if the target +of cells (see :doc:`/cmd/techmap`). This can for example be useful if the target architecture supports hardware multipliers for certain bit-widths but not for others. @@ -52,14 +52,14 @@ cell type but only combinations of cells. For these cases Yosys provides the extract pass that can match a given set of modules against a design and identify the portions of the design that are -identical (i.e. isomorphic subcircuits) to any of the given modules. These +identical (i.e. isomorphic subcircuits) to any of the given modules. These matched subcircuits are then replaced by instances of the given modules. The extract pass also finds basic variations of the given modules, such as swapped inputs on commutative cell types. In addition to this the extract pass also has limited support for frequent -subcircuit mining, i.e. the process of finding recurring subcircuits in the +subcircuit mining, i.e. the process of finding recurring subcircuits in the design. This has a few applications, including the design of new coarse-grain architectures :cite:p:`intersynthFdlBookChapter`. @@ -73,11 +73,13 @@ SubCircuit library that can also be used stand-alone without Yosys (see Gate-level technology mapping ----------------------------- +.. todo:: newer techmap libraries appear to be largely ``.v`` instead of ``.lib`` + On the gate-level the target architecture is usually described by a "Liberty file". The Liberty file format is an industry standard format that can be used to describe the behaviour and other properties of standard library cells . -Mapping a design utilizing the Yosys internal gate library (e.g. as a result of +Mapping a design utilizing the Yosys internal gate library (e.g. as a result of mapping it to this representation using the techmap pass) is performed in two phases. diff --git a/docs/source/yosys_internals/extending_yosys/abc_flow.rst b/docs/source/yosys_internals/extending_yosys/abc_flow.rst new file mode 100644 index 00000000000..86afd3336f6 --- /dev/null +++ b/docs/source/yosys_internals/extending_yosys/abc_flow.rst @@ -0,0 +1,76 @@ +Setting up a flow for ABC9 +-------------------------- + +Much of the configuration comes from attributes and ``specify`` blocks in +Verilog simulation models. + +``specify`` syntax +~~~~~~~~~~~~~~~~~~ + +Since ``specify`` is a relatively obscure part of the Verilog standard, a quick +guide to the syntax: + +.. code-block:: verilog + + specify // begins a specify block + (A => B) = 123; // simple combinational path from A to B with a delay of 123. + (A *> B) = 123; // simple combinational path from A to all bits of B with a delay of 123 for all. + if (FOO) (A => B) = 123; // paths may apply under specific conditions. + (posedge CLK => (Q : D)) = 123; // combinational path triggered on the positive edge of CLK; used for clock-to-Q arrival paths. + $setup(A, posedge CLK, 123); // setup constraint for an input relative to a clock. + endspecify // ends a specify block + +By convention, all delays in ``specify`` blocks are in integer picoseconds. +Files containing ``specify`` blocks should be read with the ``-specify`` option +to :cmd:ref:`read_verilog` so that they aren't skipped. + +LUTs +^^^^ + +LUTs need to be annotated with an ``(* abc9_lut=N *)`` attribute, where ``N`` is +the relative area of that LUT model. For example, if an architecture can combine +LUTs to produce larger LUTs, then the combined LUTs would have increasingly +larger ``N``. Conversely, if an architecture can split larger LUTs into smaller +LUTs, then the smaller LUTs would have smaller ``N``. + +LUTs are generally specified with simple combinational paths from the LUT inputs +to the LUT output. + +DFFs +^^^^ + +DFFs should be annotated with an ``(* abc9_flop *)`` attribute, however ABC9 has +some specific requirements for this to be valid: - the DFF must initialise to +zero (consider using :cmd:ref:`dfflegalize` to ensure this). - the DFF cannot +have any asynchronous resets/sets (see the simplification idiom and the Boxes +section for what to do here). + +It is worth noting that in pure ``abc9`` mode, only the setup and arrival times +are passed to ABC9 (specifically, they are modelled as buffers with the given +delay). In ``abc9 -dff``, the flop itself is passed to ABC9, permitting +sequential optimisations. + +Some vendors have universal DFF models which include async sets/resets even when +they're unused. Therefore *the simplification idiom* exists to handle this: by +using a ``techmap`` file to discover flops which have a constant driver to those +asynchronous controls, they can be mapped into an intermediate, simplified flop +which qualifies as an ``(* abc9_flop *)``, ran through :cmd:ref:`abc9`, and then +mapped back to the original flop. This is used in :cmd:ref:`synth_intel_alm` and +:cmd:ref:`synth_quicklogic` for the PolarPro3. + +DFFs are usually specified to have setup constraints against the clock on the +input signals, and an arrival time for the ``Q`` output. + +Boxes +^^^^^ + +A "box" is a purely-combinational piece of hard logic. If the logic is exposed +to ABC9, it's a "whitebox", otherwise it's a "blackbox". Carry chains would be +best implemented as whiteboxes, but a DSP would be best implemented as a +blackbox (multipliers are too complex to easily work with). LUT RAMs can be +implemented as whiteboxes too. + +Boxes are arguably the biggest advantage that ABC9 has over ABC: by being aware +of carry chains and DSPs, it avoids optimising for a path that isn't the actual +critical path, while the generally-longer paths result in ABC9 being able to +reduce design area by mapping other logic to larger-but-slower cells. diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst new file mode 100644 index 00000000000..902c1c66c7f --- /dev/null +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -0,0 +1,272 @@ +Writing extensions +================== + +.. role:: yoscrypt(code) + :language: yoscrypt + +.. todo:: check text is coherent + +.. todo:: update to use :file:`/code_examples/extensions/test*.log` + +This chapter contains some bits and pieces of information about programming +yosys extensions. Don't be afraid to ask questions on the YosysHQ Slack. + +The `guidelines/` directory of the Yosys source code contains notes on various +aspects of Yosys development. In particular, the files GettingStarted and +CodingStyle may be of interest. + +.. todo:: what's in guidelines/GettingStarted that's missing from the manual? + +Quick guide +----------- + +Code examples from this section are included in the +|code_examples/extensions|_ directory of the Yosys source code. + +.. |code_examples/extensions| replace:: :file:`docs/source/code_examples/extensions` +.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/extensions + + +Program components and data formats +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See :doc:`/yosys_internals/formats/rtlil_rep` document for more information +about the internal data storage format used in Yosys and the classes that it +provides. + +This document will focus on the much simpler version of RTLIL left after the +commands :cmd:ref:`proc` and :cmd:ref:`memory` (or :yoscrypt:`memory -nomap`): + +.. figure:: /_images/internals/simplified_rtlil.* + :class: width-helper + :name: fig:Simplified_RTLIL + + Simplified RTLIL entity-relationship diagram without memories and processes + +It is possible to only work on this simpler version: + +.. todo:: consider replacing inline code + +.. code:: c++ + + for (RTLIL::Module *module : design->selected_modules() { + if (module->has_memories_warn() || module->has_processes_warn()) + continue; + .... + } + +When trying to understand what a command does, creating a small test case to +look at the output of :cmd:ref:`dump` and :cmd:ref:`show` before and after the +command has been executed can be helpful. +:doc:`/using_yosys/more_scripting/selections` has more information on using +these commands. + +Creating a command +~~~~~~~~~~~~~~~~~~ + +.. todo:: add/expand supporting text + +Let's create a very simple test command which prints the arguments we called it +with, and lists off the current design's modules. + +.. literalinclude:: /code_examples/extensions/my_cmd.cc + :language: c++ + :lines: 1, 4, 6, 7-20 + :caption: Example command :yoscrypt:`my_cmd` from :file:`my_cmd.cc` + +Note that we are making a global instance of a class derived from +``Yosys::Pass``, which we get by including :file:`kernel/yosys.h`. + +Compiling to a plugin +~~~~~~~~~~~~~~~~~~~~~ + +Yosys can be extended by adding additional C++ code to the Yosys code base, or +by loading plugins into Yosys. For maintainability it is generally recommended +to create plugins. + +The following command compiles our example :yoscrypt:`my_cmd` to a Yosys plugin: + +.. todo:: replace inline code + +.. code:: shell + + yosys-config --exec --cxx --cxxflags --ldflags \ + -o my_cmd.so -shared my_cmd.cc --ldlibs + +Or shorter: + +.. code:: shell + + yosys-config --build my_cmd.so my_cmd.cc + +Running Yosys with the ``-m`` option allows the plugin to be used. Here's a +quick example that also uses the ``-p`` option to run :yoscrypt:`my_cmd foo +bar`. + +.. code:: shell-session + + $ yosys -m ./my_cmd.so -p 'my_cmd foo bar' + + -- Running command `my_cmd foo bar' -- + Arguments to my_cmd: + my_cmd + foo + bar + Modules in current design: + +Creating modules from scratch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's create the following module using the RTLIL API: + +.. literalinclude:: /code_examples/extensions/absval_ref.v + :language: Verilog + :caption: absval_ref.v + +We'll do the same as before and format it as a a ``Yosys::Pass``. + +.. literalinclude:: /code_examples/extensions/my_cmd.cc + :language: c++ + :lines: 23-47 + :caption: :yoscrypt:`test1` - creating the absval module, from :file:`my_cmd.cc` + +.. code:: shell-session + + $ yosys -m ./my_cmd.so -p 'test1' -Q + + -- Running command `test1' -- + Name of this module: absval + +And if we look at the schematic for this new module we see the following: + +.. figure:: /_images/code_examples/extensions/test1.* + :class: width-helper + + Output of ``yosys -m ./my_cmd.so -p 'test1; show'`` + +Modifying modules +~~~~~~~~~~~~~~~~~ + +Most commands modify existing modules, not create new ones. + +When modifying existing modules, stick to the following DOs and DON'Ts: + +- Do not remove wires. Simply disconnect them and let a successive + :cmd:ref:`clean` command worry about removing it. +- Use ``module->fixup_ports()`` after changing the ``port_*`` properties of + wires. +- You can safely remove cells or change the ``connections`` property of a cell, + but be careful when changing the size of the ``SigSpec`` connected to a cell + port. +- Use the ``SigMap`` helper class (see next section) when you need a unique + handle for each signal bit. + +Using the SigMap helper class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider the following module: + +.. literalinclude:: /code_examples/extensions/sigmap_test.v + :language: Verilog + :caption: :file:`sigmap_test.v` + +In this case ``a``, ``x``, and ``y`` are all different names for the same +signal. However: + +.. todo:: use my_cmd.cc literalincludes + +.. code:: C++ + + RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), + y(module->wire("\\y")); + log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" + +The ``SigMap`` helper class can be used to map all such aliasing signals to a +unique signal from the group (usually the wire that is directly driven by a cell +or port). + +.. code:: C++ + + SigMap sigmap(module); + log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y), + sigmap(y) == sigmap(a)); // will print "1 1 1" + +Printing log messages +~~~~~~~~~~~~~~~~~~~~~ + +The ``log()`` function is a ``printf()``-like function that can be used to +create log messages. + +Use ``log_signal()`` to create a C-string for a SigSpec object: + +.. code:: C++ + + log("Mapped signal x: %s\n", log_signal(sigmap(x))); + +The pointer returned by ``log_signal()`` is automatically freed by the log +framework at a later time. + +Use ``log_id()`` to create a C-string for an ``RTLIL::IdString``: + +.. code:: C++ + + log("Name of this module: %s\n", log_id(module->name)); + +Use ``log_header()`` and ``log_push()``/\ ``log_pop()`` to structure log +messages: + +.. todo:: replace inline code + +.. code:: C++ + + log_header(design, "Doing important stuff!\n"); + log_push(); + for (int i = 0; i < 10; i++) + log("Log message #%d.\n", i); + log_pop(); + +Error handling +~~~~~~~~~~~~~~ + +Use ``log_error()`` to report a non-recoverable error: + +.. todo:: replace inline code + +.. code:: C++ + + if (design->modules.count(module->name) != 0) + log_error("A module with the name %s already exists!\n", + RTLIL::id2cstr(module->name)); + +Use ``log_cmd_error()`` to report a recoverable error: + +.. code:: C++ + + if (design->selection_stack.back().empty()) + log_cmd_error("This command can't operator on an empty selection!\n"); + +Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``. + +The "stubnets" example module +------------------------------ + +The following is the complete code of the "stubnets" example module. It is +included in the Yosys source distribution under |code_examples/stubnets|_. + +.. |code_examples/stubnets| replace:: :file:`docs/source/code_examples/stubnets` +.. _code_examples/stubnets: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/stubnets + +.. literalinclude:: /code_examples/stubnets/stubnets.cc + :language: c++ + :linenos: + :caption: :file:`stubnets.cc` + +.. literalinclude:: /code_examples/stubnets/Makefile + :language: makefile + :linenos: + :caption: :file:`Makefile` + +.. literalinclude:: /code_examples/stubnets/test.v + :language: verilog + :linenos: + :caption: :file:`test.v` diff --git a/docs/source/yosys_internals/extending_yosys/index.rst b/docs/source/yosys_internals/extending_yosys/index.rst new file mode 100644 index 00000000000..c2dc6cd2b8b --- /dev/null +++ b/docs/source/yosys_internals/extending_yosys/index.rst @@ -0,0 +1,11 @@ +Extending Yosys +--------------- + +.. todo:: brief overview for the extending Yosys index + +.. toctree:: + :maxdepth: 3 + + extensions + abc_flow + diff --git a/docs/source/yosys_internals/flow/control_and_data.rst b/docs/source/yosys_internals/flow/control_and_data.rst new file mode 100644 index 00000000000..5dcbe073025 --- /dev/null +++ b/docs/source/yosys_internals/flow/control_and_data.rst @@ -0,0 +1,31 @@ +Control and data flow +===================== + +.. todo:: less academic + +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 +`). + +.. figure:: /_images/internals/approach_flow.* + :class: width-helper + :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 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. diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst new file mode 100644 index 00000000000..c7ab0ebccda --- /dev/null +++ b/docs/source/yosys_internals/flow/index.rst @@ -0,0 +1,19 @@ +Internal flow +============= + +A (usually short) synthesis script controls Yosys. + +These scripts contain three types of commands: + +- **Frontends**, that read input files (usually Verilog); +- **Passes**, that perform transformations on the design in memory; +- **Backends**, that write the design in memory to a file (various formats are + available: Verilog, BLIF, EDIF, SPICE, BTOR, . . .). + +.. toctree:: + :maxdepth: 3 + + overview + control_and_data + verilog_frontend + diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst new file mode 100644 index 00000000000..f7589df031f --- /dev/null +++ b/docs/source/yosys_internals/flow/overview.rst @@ -0,0 +1,49 @@ +Flow overview +============= + +.. todo:: less academic + +: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 :doc:`/yosys_internals/formats/rtlil_rep`. + +There is also a text representation of the RTLIL data structure that can be +parsed using the RTLIL Frontend which is described in +:doc:`/yosys_internals/formats/rtlil_text`. + +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/internals/overview_flow.* + :class: width-helper + :name: fig:Overview_flow + + Yosys simplified data flow (ellipses: data structures, rectangles: + program modules) diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst new file mode 100644 index 00000000000..127fa7be388 --- /dev/null +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -0,0 +1,656 @@ +.. _chapter:verilog: + +The Verilog and AST frontends +============================= + +This chapter provides an overview of the implementation of the Yosys Verilog and +AST frontends. The Verilog frontend reads Verilog-2005 code and creates an +abstract syntax tree (AST) representation of the input. This AST representation +is then passed to the AST frontend that converts it to RTLIL data, as +illustrated in :numref:`Fig. %s `. + +.. figure:: /_images/internals/verilog_flow.* + :class: width-helper + :name: fig:Verilog_flow + + Simplified Verilog to RTLIL data flow + +Transforming Verilog to AST +--------------------------- + +The Verilog frontend converts the Verilog sources to an internal AST +representation that closely resembles the structure of the original Verilog +code. The Verilog frontend consists of three components, the Preprocessor, the +Lexer and the Parser. + +The source code to the Verilog frontend can be found in +:file:`frontends/verilog/` in the Yosys source tree. + +The Verilog preprocessor +~~~~~~~~~~~~~~~~~~~~~~~~ + +The Verilog preprocessor scans over the Verilog source code and interprets some +of the Verilog compiler directives such as :literal:`\`include`, +:literal:`\`define` and :literal:`\`ifdef`. + +It is implemented as a C++ function that is passed a file descriptor as input +and returns the pre-processed Verilog code as a ``std::string``. + +The source code to the Verilog Preprocessor can be found in +:file:`frontends/verilog/preproc.cc` in the Yosys source tree. + +The Verilog lexer +~~~~~~~~~~~~~~~~~ + +The Verilog Lexer is written using the lexer generator flex. Its source code can +be found in :file:`frontends/verilog/verilog_lexer.l` in the Yosys source tree. +The lexer does little more than identifying all keywords and literals recognised +by the Yosys Verilog frontend. + +The lexer keeps track of the current location in the Verilog source code using +some global variables. These variables are used by the constructor of AST nodes +to annotate each node with the source code location it originated from. + +Finally the lexer identifies and handles special comments such as "``// synopsys +translate_off``" and "``// synopsys full_case``". (It is recommended to use +:literal:`\`ifdef` constructs instead of the Synsopsys translate_on/off comments +and attributes such as ``(* full_case *)`` over "``// synopsys full_case``" +whenever possible.) + +The Verilog parser +~~~~~~~~~~~~~~~~~~ + +The Verilog Parser is written using the parser generator bison. Its source code +can be found in :file:`frontends/verilog/verilog_parser.y` in the Yosys source +tree. + +It generates an AST using the ``AST::AstNode`` data structure defined in +:file:`frontends/ast/ast.h`. An ``AST::AstNode`` object has the following +properties: + +.. list-table:: AST node types with their corresponding Verilog constructs. + :name: tab:Verilog_AstNodeType + :widths: 50 50 + + * - AST Node Type + - Corresponding Verilog Construct + * - AST_NONE + - This Node type should never be used. + * - AST_DESIGN + - This node type is used for the top node of the AST tree. It has no + corresponding Verilog construct. + * - AST_MODULE, AST_TASK, AST_FUNCTION + - ``module``, ``task`` and ``function`` + * - AST_WIRE + - ``input``, ``output``, ``wire``, ``reg`` and ``integer`` + * - AST_MEMORY + - Verilog Arrays + * - AST_AUTOWIRE + - Created by the simplifier when an undeclared signal name is used. + * - AST_PARAMETER, AST_LOCALPARAM + - ``parameter`` and ``localparam`` + * - AST_PARASET + - Parameter set in cell instantiation + * - AST_ARGUMENT + - Port connection in cell instantiation + * - AST_RANGE + - Bit-Index in a signal or element index in array + * - AST_CONSTANT + - A literal value + * - AST_CELLTYPE + - The type of cell in cell instantiation + * - AST_IDENTIFIER + - An Identifier (signal name in expression or cell/task/etc. name in other + contexts) + * - AST_PREFIX + - Construct an identifier in the form []. (used + only in advanced generate constructs) + * - AST_FCALL, AST_TCALL + - Call to function or task + * - AST_TO_SIGNED, AST_TO_UNSIGNED + - The ``$signed()`` and ``$unsigned()`` functions + * - AST_CONCAT, AST_REPLICATE + - The ``{...}`` and ``{...{...}}`` operators + * - AST_BIT_NOT, AST_BIT_AND, AST_BIT_OR, AST_BIT_XOR, AST_BIT_XNOR + - The bitwise operators ``~``, ``&``, ``|``, ``^`` and ``~^`` + * - AST_REDUCE_AND, AST_REDUCE_OR, AST_REDUCE_XOR, AST_REDUCE_XNOR + - The unary reduction operators ``~``, ``&``, ``|``, ``^`` and ``~^`` + * - AST_REDUCE_BOOL + - Conversion from multi-bit value to boolean value (equivalent to + AST_REDUCE_OR) + * - AST_SHIFT_LEFT, AST_SHIFT_RIGHT, AST_SHIFT_SLEFT, AST_SHIFT_SRIGHT + - The shift operators ``<<``, ``>>``, ``<<<`` and ``>>>`` + * - AST_LT, AST_LE, AST_EQ, AST_NE, AST_GE, AST_GT + - The relational operators ``<``, ``<=``, ``==``, ``!=``, ``>=`` and ``>`` + * - AST_ADD, AST_SUB, AST_MUL, AST_DIV, AST_MOD, AST_POW + - The binary operators ``+``, ``-``, ``*``, ``/``, ``%`` and ``**`` + * - AST_POS, AST_NEG + - The prefix operators ``+`` and ``-`` + * - AST_LOGIC_AND, AST_LOGIC_OR, AST_LOGIC_NOT + - The logic operators ``&&``, ``||`` and ``!`` + * - AST_TERNARY + - The ternary ``?:``-operator + * - AST_MEMRD AST_MEMWR + - Read and write memories. These nodes are generated by the AST simplifier + for writes/reads to/from Verilog arrays. + * - AST_ASSIGN + - An ``assign`` statement + * - AST_CELL + - A cell instantiation + * - AST_PRIMITIVE + - A primitive cell (``and``, ``nand``, ``or``, etc.) + * - AST_ALWAYS, AST_INITIAL + - Verilog ``always``- and ``initial``-blocks + * - AST_BLOCK + - A ``begin``-``end``-block + * - AST_ASSIGN_EQ. AST_ASSIGN_LE + - Blocking (``=``) and nonblocking (``<=``) assignments within an + ``always``- or ``initial``-block + * - AST_CASE. AST_COND, AST_DEFAULT + - The ``case`` (``if``) statements, conditions within a case and the + default case respectively + * - AST_FOR + - A ``for``-loop with an ``always``- or ``initial``-block + * - AST_GENVAR, AST_GENBLOCK, AST_GENFOR, AST_GENIF + - The ``genvar`` and ``generate`` keywords and ``for`` and ``if`` within a + generate block. + * - AST_POSEDGE, AST_NEGEDGE, AST_EDGE + - Event conditions for ``always`` blocks. + +- | The node type + | This enum (``AST::AstNodeType``) specifies the role of the node. + :numref:`Table %s ` contains a list of all node + types. + +- | The child nodes + | This is a list of pointers to all children in the abstract syntax tree. + +- | Attributes + | As almost every AST node might have Verilog attributes assigned to it, the + ``AST::AstNode`` has direct support for attributes. Note that the attribute + values are again AST nodes. + +- | Node content + | Each node might have additional content data. A series of member variables + exist to hold such data. For example the member ``std::string str`` can + hold a string value and is used e.g. in the ``AST_IDENTIFIER`` node type to + store the identifier name. + +- | Source code location + | Each ``AST::AstNode`` is automatically annotated with the current source + code location by the ``AST::AstNode`` constructor. It is stored in the + ``std::string filename`` and ``int linenum`` member variables. + +The ``AST::AstNode`` constructor can be called with up to two child nodes that +are automatically added to the list of child nodes for the new object. This +simplifies the creation of AST nodes for simple expressions a bit. For example +the bison code for parsing multiplications: + +.. code:: none + :number-lines: + + basic_expr '*' attr basic_expr { + $$ = new AstNode(AST_MUL, $1, $4); + append_attr($$, $3); + } | + +The generated AST data structure is then passed directly to the AST frontend +that performs the actual conversion to RTLIL. + +Note that the Yosys command ``read_verilog`` provides the options ``-yydebug`` +and ``-dump_ast`` that can be used to print the parse tree or abstract syntax +tree respectively. + +Transforming AST to RTLIL +------------------------- + +The AST Frontend converts a set of modules in AST representation to modules in +RTLIL representation and adds them to the current design. This is done in two +steps: simplification and RTLIL generation. + +The source code to the AST frontend can be found in ``frontends/ast/`` in the +Yosys source tree. + +AST simplification +~~~~~~~~~~~~~~~~~~ + +A full-featured AST is too complex to be transformed into RTLIL directly. +Therefore it must first be brought into a simpler form. This is done by calling +the ``AST::AstNode::simplify()`` method of all ``AST_MODULE`` nodes in the AST. +This initiates a recursive process that performs the following transformations +on the AST data structure: + +- Inline all task and function calls. + +- Evaluate all ``generate``-statements and unroll all ``for``-loops. + +- Perform const folding where it is necessary (e.g. in the value part of + ``AST_PARAMETER``, ``AST_LOCALPARAM``, ``AST_PARASET`` and ``AST_RANGE`` + nodes). + +- Replace ``AST_PRIMITIVE`` nodes with appropriate ``AST_ASSIGN`` nodes. + +- Replace dynamic bit ranges in the left-hand-side of assignments with + ``AST_CASE`` nodes with ``AST_COND`` children for each possible case. + +- Detect array access patterns that are too complicated for the + ``RTLIL::Memory`` abstraction and replace them with a set of signals and + cases for all reads and/or writes. + +- Otherwise replace array accesses with ``AST_MEMRD`` and ``AST_MEMWR`` nodes. + +In addition to these transformations, the simplifier also annotates the +AST with additional information that is needed for the RTLIL generator, +namely: + +- All ranges (width of signals and bit selections) are not only const + folded but (when a constant value is found) are also written to + member variables in the AST_RANGE node. + +- All identifiers are resolved and all ``AST_IDENTIFIER`` nodes are annotated + with a pointer to the AST node that contains the declaration of the + identifier. If no declaration has been found, an ``AST_AUTOWIRE`` node is + created and used for the annotation. + +This produces an AST that is fairly easy to convert to the RTLIL format. + +Generating RTLIL +~~~~~~~~~~~~~~~~ + +After AST simplification, the ``AST::AstNode::genRTLIL()`` method of each +``AST_MODULE`` node in the AST is called. This initiates a recursive process +that generates equivalent RTLIL data for the AST data. + +The ``AST::AstNode::genRTLIL()`` method returns an ``RTLIL::SigSpec`` structure. +For nodes that represent expressions (operators, constants, signals, etc.), the +cells needed to implement the calculation described by the expression are +created and the resulting signal is returned. That way it is easy to generate +the circuits for large expressions using depth-first recursion. For nodes that +do not represent an expression (such as ``AST_CELL``), the corresponding circuit +is generated and an empty ``RTLIL::SigSpec`` is returned. + +Synthesizing Verilog always blocks +-------------------------------------- + +For behavioural Verilog code (code utilizing ``always``- and ``initial``-blocks) +it is necessary to also generate ``RTLIL::Process`` objects. This is done in the +following way: + +Whenever ``AST::AstNode::genRTLIL()`` encounters an ``always``- or +``initial``-block, it creates an instance of ``AST_INTERNAL::ProcessGenerator``. +This object then generates the ``RTLIL::Process`` object for the block. It also +calls ``AST::AstNode::genRTLIL()`` for all right-hand-side expressions contained +within the block. + +First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all signals +assigned within the block. It then creates a set of temporary signals using the +naming scheme ``$ \ `` for each of the assigned signals. + +Then an ``RTLIL::Process`` is created that assigns all intermediate values for +each left-hand-side signal to the temporary signal in its +``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree. + +Finally a ``RTLIL::SyncRule`` is created for the ``RTLIL::Process`` that assigns +the temporary signals for the final values to the actual signals. + +A process may also contain memory writes. A ``RTLIL::MemWriteAction`` is created +for each of them. + +Calls to ``AST::AstNode::genRTLIL()`` are generated for right hand sides as +needed. When blocking assignments are used, ``AST::AstNode::genRTLIL()`` is +configured using global variables to use the temporary signals that hold the +correct intermediate values whenever one of the previously assigned signals is +used in an expression. + +Unfortunately the generation of a correct +``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule`` tree for behavioural code is a +non-trivial task. The AST frontend solves the problem using the approach +described on the following pages. The following example illustrates what the +algorithm is supposed to do. Consider the following Verilog code: + +.. code:: verilog + :number-lines: + + always @(posedge clock) begin + out1 = in1; + if (in2) + out1 = !out1; + out2 <= out1; + if (in3) + out2 <= out2; + if (in4) + if (in5) + out3 <= in6; + else + out3 <= in7; + out1 = out1 ^ out2; + end + +This is translated by the Verilog and AST frontends into the following RTLIL +code (attributes, cell parameters and wire declarations not included): + +.. code:: RTLIL + :number-lines: + + cell $logic_not $logic_not$:4$2 + connect \A \in1 + connect \Y $logic_not$:4$2_Y + end + cell $xor $xor$:13$3 + connect \A $1\out1[0:0] + connect \B \out2 + connect \Y $xor$:13$3_Y + end + process $proc$:1$1 + assign $0\out3[0:0] \out3 + assign $0\out2[0:0] $1\out1[0:0] + assign $0\out1[0:0] $xor$:13$3_Y + switch \in2 + case 1'1 + assign $1\out1[0:0] $logic_not$:4$2_Y + case + assign $1\out1[0:0] \in1 + end + switch \in3 + case 1'1 + assign $0\out2[0:0] \out2 + case + end + switch \in4 + case 1'1 + switch \in5 + case 1'1 + assign $0\out3[0:0] \in6 + case + assign $0\out3[0:0] \in7 + end + case + end + sync posedge \clock + update \out1 $0\out1[0:0] + update \out2 $0\out2[0:0] + update \out3 $0\out3[0:0] + end + +Note that the two operators are translated into separate cells outside the +generated process. The signal ``out1`` is assigned using blocking assignments +and therefore ``out1`` has been replaced with a different signal in all +expressions after the initial assignment. The signal ``out2`` is assigned using +nonblocking assignments and therefore is not substituted on the right-hand-side +expressions. + +The ``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule`` tree must be interpreted the +following way: + +- On each case level (the body of the process is the root case), first the + actions on this level are evaluated and then the switches within the case are + evaluated. (Note that the last assignment on line 13 of the Verilog code has + been moved to the beginning of the RTLIL process to line 13 of the RTLIL + listing.) + + I.e. the special cases deeper in the switch hierarchy override the defaults + on the upper levels. The assignments in lines 12 and 22 of the RTLIL code + serve as an example for this. + + Note that in contrast to this, the order within the ``RTLIL::SwitchRule`` + objects within a ``RTLIL::CaseRule`` is preserved with respect to the + original AST and Verilog code. + +- The whole ``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule`` tree describes an + asynchronous circuit. I.e. the decision tree formed by the switches can be + seen independently for each assigned signal. Whenever one assigned signal + changes, all signals that depend on the changed signals are to be updated. + For example the assignments in lines 16 and 18 in the RTLIL code in fact + influence the assignment in line 12, even though they are in the "wrong + order". + +The only synchronous part of the process is in the ``RTLIL::SyncRule`` object +generated at line 35 in the RTLIL code. The sync rule is the only part of the +process where the original signals are assigned. The synchronization event from +the original Verilog code has been translated into the synchronization type +(posedge) and signal (``\clock``) for the ``RTLIL::SyncRule`` object. In the +case of this simple example the ``RTLIL::SyncRule`` object is later simply +transformed into a set of d-type flip-flops and the +``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule`` tree to a decision tree using +multiplexers. + +In more complex examples (e.g. asynchronous resets) the part of the +``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule`` tree that describes the asynchronous +reset must first be transformed to the correct ``RTLIL::SyncRule`` objects. This +is done by the ``proc_arst`` pass. + +The ProcessGenerator algorithm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``AST_INTERNAL::ProcessGenerator`` uses the following internal state +variables: + +- | ``subst_rvalue_from`` and ``subst_rvalue_to`` + | These two variables hold the replacement pattern that should be used by + ``AST::AstNode::genRTLIL()`` for signals with blocking assignments. After + initialization of ``AST_INTERNAL::ProcessGenerator`` these two variables are + empty. + +- | ``subst_lvalue_from`` and ``subst_lvalue_to`` + | These two variables contain the mapping from left-hand-side signals (``\ + ``) to the current temporary signal for the same thing (initially + ``$0\ ``). + +- | ``current_case`` + | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the root case + of the generated ``RTLIL::Process``. + +As the algorithm runs these variables are continuously modified as well as +pushed to the stack and later restored to their earlier values by popping from +the stack. + +On startup the ProcessGenerator generates a new ``RTLIL::Process`` object with +an empty root case and initializes its state variables as described above. Then +the ``RTLIL::SyncRule`` objects are created using the synchronization events +from the AST_ALWAYS node and the initial values of ``subst_lvalue_from`` and +``subst_lvalue_to``. Then the AST for this process is evaluated recursively. + +During this recursive evaluation, three different relevant types of AST nodes +can be discovered: ``AST_ASSIGN_LE`` (nonblocking assignments), +``AST_ASSIGN_EQ`` (blocking assignments) and ``AST_CASE`` (``if`` or ``case`` +statement). + +Handling of nonblocking assignments +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When an ``AST_ASSIGN_LE`` node is discovered, the following actions are +performed by the ProcessGenerator: + +- The left-hand-side is evaluated using ``AST::AstNode::genRTLIL()`` and mapped + to a temporary signal name using ``subst_lvalue_from`` and + ``subst_lvalue_to``. + +- The right-hand-side is evaluated using ``AST::AstNode::genRTLIL()``. For this + call, the values of ``subst_rvalue_from`` and ``subst_rvalue_to`` are used to + map blocking-assigned signals correctly. + +- Remove all assignments to the same left-hand-side as this assignment from the + ``current_case`` and all cases within it. + +- Add the new assignment to the ``current_case``. + +Handling of blocking assignments +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When an ``AST_ASSIGN_EQ`` node is discovered, the following actions are +performed by the ProcessGenerator: + +- Perform all the steps that would be performed for a nonblocking assignment + (see above). + +- Remove the found left-hand-side (before lvalue mapping) from + ``subst_rvalue_from`` and also remove the respective bits from + ``subst_rvalue_to``. + +- Append the found left-hand-side (before lvalue mapping) to + ``subst_rvalue_from`` and append the found right-hand-side to + ``subst_rvalue_to``. + +Handling of cases and if-statements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When an ``AST_CASE`` node is discovered, the following actions are performed by +the ProcessGenerator: + +- The values of ``subst_rvalue_from``, ``subst_rvalue_to``, + ``subst_lvalue_from`` and ``subst_lvalue_to`` are pushed to the stack. + +- A new ``RTLIL::SwitchRule`` object is generated, the selection expression is + evaluated using ``AST::AstNode::genRTLIL()`` (with the use of + ``subst_rvalue_from`` and ``subst_rvalue_to``) and added to the + ``RTLIL::SwitchRule`` object and the object is added to the ``current_case``. + +- All lvalues assigned to within the ``AST_CASE`` node using blocking + assignments are collected and saved in the local variable + ``this_case_eq_lvalue``. + +- New temporary signals are generated for all signals in + ``this_case_eq_lvalue`` and stored in ``this_case_eq_ltemp``. + +- The signals in ``this_case_eq_lvalue`` are mapped using ``subst_rvalue_from`` + and ``subst_rvalue_to`` and the resulting set of signals is stored in + ``this_case_eq_rvalue``. + +Then the following steps are performed for each ``AST_COND`` node within the +``AST_CASE`` node: + +- Set ``subst_rvalue_from``, ``subst_rvalue_to``, ``subst_lvalue_from`` and + ``subst_lvalue_to`` to the values that have been pushed to the stack. + +- Remove ``this_case_eq_lvalue`` from + ``subst_lvalue_from``/``subst_lvalue_to``. + +- Append ``this_case_eq_lvalue`` to ``subst_lvalue_from`` and append + ``this_case_eq_ltemp`` to ``subst_lvalue_to``. + +- Push the value of ``current_case``. + +- Create a new ``RTLIL::CaseRule``. Set ``current_case`` to the new object and + add the new object to the ``RTLIL::SwitchRule`` created above. + +- Add an assignment from ``this_case_eq_rvalue`` to ``this_case_eq_ltemp`` to + the new ``current_case``. + +- Evaluate the compare value for this case using + ``AST::AstNode::genRTLIL()`` (with the use of ``subst_rvalue_from`` + and ``subst_rvalue_to``) modify the new ``current_case`` accordingly. + +- Recursion into the children of the ``AST_COND`` node. + +- Restore ``current_case`` by popping the old value from the stack. + +Finally the following steps are performed: + +- The values of ``subst_rvalue_from``, ``subst_rvalue_to``, + ``subst_lvalue_from`` and ``subst_lvalue_to`` are popped from the stack. + +- The signals from ``this_case_eq_lvalue`` are removed from the + ``subst_rvalue_from``/``subst_rvalue_to``-pair. + +- The value of ``this_case_eq_lvalue`` is appended to ``subst_rvalue_from`` and + the value of ``this_case_eq_ltemp`` is appended to ``subst_rvalue_to``. + +- Map the signals in ``this_case_eq_lvalue`` using + ``subst_lvalue_from``/``subst_lvalue_to``. + +- Remove all assignments to signals in ``this_case_eq_lvalue`` in + ``current_case`` and all cases within it. + +- Add an assignment from ``this_case_eq_ltemp`` to ``this_case_eq_lvalue`` to + ``current_case``. + +Further analysis of the algorithm for cases and if-statements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With respect to nonblocking assignments the algorithm is easy: later assignments +invalidate earlier assignments. For each signal assigned using nonblocking +assignments exactly one temporary variable is generated (with the ``$0``-prefix) +and this variable is used for all assignments of the variable. + +Note how all the ``_eq_``-variables become empty when no blocking assignments +are used and many of the steps in the algorithm can then be ignored as a result +of this. + +For a variable with blocking assignments the algorithm shows the following +behaviour: First a new temporary variable is created. This new temporary +variable is then registered as the assignment target for all assignments for +this variable within the cases for this ``AST_CASE`` node. Then for each case +the new temporary variable is first assigned the old temporary variable. This +assignment is overwritten if the variable is actually assigned in this case and +is kept as a default value otherwise. + +This yields an ``RTLIL::CaseRule`` that assigns the new temporary variable in +all branches. So when all cases have been processed a final assignment is added +to the containing block that assigns the new temporary variable to the old one. +Note how this step always overrides a previous assignment to the old temporary +variable. Other than nonblocking assignments, the old assignment could still +have an effect somewhere in the design, as there have been calls to +``AST::AstNode::genRTLIL()`` with a +``subst_rvalue_from``/\ ``subst_rvalue_to``-tuple that contained the +right-hand-side of the old assignment. + +The proc pass +~~~~~~~~~~~~~ + +The ProcessGenerator converts a behavioural model in AST representation to a +behavioural model in ``RTLIL::Process`` representation. The actual conversion +from a behavioural model to an RTL representation is performed by the +:cmd:ref:`proc` pass and the passes it launches: + +- | :cmd:ref:`proc_clean` and :cmd:ref:`proc_rmdead` + | These two passes just clean up the ``RTLIL::Process`` structure. The + :cmd:ref:`proc_clean` pass removes empty parts (eg. empty assignments) from + the process and :cmd:ref:`proc_rmdead` detects and removes unreachable + branches from the process's decision trees. + +- | :cmd:ref:`proc_arst` + | This pass detects processes that describe d-type flip-flops with + asynchronous resets and rewrites the process to better reflect what they + are modelling: Before this pass, an asynchronous reset has two + edge-sensitive sync rules and one top-level ``RTLIL::SwitchRule`` for the + reset path. After this pass the sync rule for the reset is level-sensitive + and the top-level ``RTLIL::SwitchRule`` has been removed. + +- | :cmd:ref:`proc_mux` + | This pass converts the ``RTLIL::CaseRule``/\ ``RTLIL::SwitchRule``-tree to a + tree of multiplexers per written signal. After this, the ``RTLIL::Process`` + structure only contains the ``RTLIL::SyncRule`` s that describe the output + registers. + +- | :cmd:ref:`proc_dff` + | This pass replaces the ``RTLIL::SyncRule``\ s to d-type flip-flops (with + asynchronous resets if necessary). + +- | :cmd:ref:`proc_dff` + | This pass replaces the ``RTLIL::MemWriteAction``\ s with ``$memwr`` cells. + +- | :cmd:ref:`proc_clean` + | A final call to :cmd:ref:`proc_clean` removes the now empty + ``RTLIL::Process`` objects. + +Performing these last processing steps in passes instead of in the Verilog +frontend has two important benefits: + +First it improves the transparency of the process. Everything that happens in a +separate pass is easier to debug, as the RTLIL data structures can be easily +investigated before and after each of the steps. + +Second it improves flexibility. This scheme can easily be extended to support +other types of storage-elements, such as sr-latches or d-latches, without having +to extend the actual Verilog frontend. + +.. todo:: Synthesizing Verilog arrays + + Add some information on the generation of ``$memrd`` and ``$memwr`` cells and + how they are processed in the memory pass. + + +.. todo:: Synthesizing parametric designs + + Add some information on the ``RTLIL::Module::derive()`` method and how it is + used to synthesize parametric modules via the hierarchy pass. diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/yosys_internals/formats/cell_library.rst similarity index 91% rename from docs/source/CHAPTER_CellLib.rst rename to docs/source/yosys_internals/formats/cell_library.rst index 70a0e2150f7..c80b0740255 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -6,9 +6,14 @@ Internal cell library ===================== -Most of the passes in Yosys operate on netlists, i.e. they only care about the -RTLIL::Wire and RTLIL::Cell objects in an RTLIL::Module. This chapter discusses -the cell types used by Yosys to represent a behavioural design internally. +.. todo:: less academic, also check formatting consistency + +Most of the passes in Yosys operate on netlists, i.e. they only care about the +``RTLIL::Wire`` and ``RTLIL::Cell`` objects in an ``RTLIL::Module``. This +chapter discusses the cell types used by Yosys to represent a behavioural design +internally. + +.. TODO:: is this chapter split preserved This chapter is split in two parts. In the first part the internal RTL cells are covered. These cells are used to represent the design on a coarse grain level. @@ -31,7 +36,7 @@ parameters in sync with the size of the signals connected to the inputs and outputs. Simulation models for the RTL cells can be found in the file -``techlibs/common/simlib.v`` in the Yosys source tree. +:file:`techlibs/common/simlib.v` in the Yosys source tree. Unary operators ~~~~~~~~~~~~~~~ @@ -40,8 +45,8 @@ All unary RTL cells have one input port ``\A`` and one output port ``\Y``. They also have the following parameters: ``\A_SIGNED`` - Set to a non-zero value if the input ``\A`` is signed and therefore - should be sign-extended when needed. + Set to a non-zero value if the input ``\A`` is signed and therefore should be + sign-extended when needed. ``\A_WIDTH`` The width of the input port ``\A``. @@ -108,7 +113,7 @@ All binary RTL cells have two input ports ``\A`` and ``\B`` and one output port :name: tab:CellLib_binary ======================= ============= ======================= ========= - Verilog Cell Type Verilog Cell Type + Verilog Cell Type Verilog Cell Type ======================= ============= ======================= ========= :verilog:`Y = A & B` $and :verilog:`Y = A < B` $lt :verilog:`Y = A | B` $or :verilog:`Y = A <= B` $le @@ -122,7 +127,7 @@ All binary RTL cells have two input ports ``\A`` and ``\B`` and one output port :verilog:`Y = A || B` $logic_or :verilog:`Y = A / B` $div :verilog:`Y = A === B` $eqx :verilog:`Y = A % B` $mod :verilog:`Y = A !== B` $nex ``N/A`` $divfloor - :verilog:`Y = A ** B` $pow ``N/A`` $modfoor + :verilog:`Y = A ** B` $pow ``N/A`` $modfloor ======================= ============= ======================= ========= The ``$shl`` and ``$shr`` cells implement logical shifts, whereas the ``$sshl`` @@ -139,7 +144,7 @@ positions are filled with undef (x) bits, and corresponds to the Verilog indexed part-select expression. For the binary cells that output a logical value (``$logic_and``, ``$logic_or``, -``$eqx``, ``$nex``, ``$lt``, ``$le``, ``$eq``, ``$ne``, ``$ge``, ``$gt)``, when +``$eqx``, ``$nex``, ``$lt``, ``$le``, ``$eq``, ``$ne``, ``$ge``, ``$gt``), when the ``\Y_WIDTH`` parameter is greater than 1, the output is zero-extended, and only the least significant bit varies. @@ -205,7 +210,7 @@ Behavioural code with cascaded if-then-else- and case-statements usually results in trees of multiplexer cells. Many passes (from various optimizations to FSM extraction) heavily depend on these multiplexer trees to understand dependencies between signals. Therefore optimizations should not break these multiplexer -trees (e.g. by replacing a multiplexer between a calculated signal and a +trees (e.g. by replacing a multiplexer between a calculated signal and a constant zero with an ``$and`` gate). Registers @@ -253,8 +258,8 @@ additional two parameters: ``\ARST_VALUE`` The state of ``\Q`` will be set to this value when the reset is active. -Usually these cells are generated by the ``proc`` pass using the information in -the designs RTLIL::Process objects. +Usually these cells are generated by the :cmd:ref:`proc` pass using the +information in the designs RTLIL::Process objects. D-type flip-flops with synchronous reset are represented by ``$sdff`` cells. As the ``$dff`` cells they have ``\CLK``, ``\D`` and ``\Q`` ports. In addition they @@ -268,8 +273,8 @@ additional two parameters: ``\SRST_VALUE`` The state of ``\Q`` will be set to this value when the reset is active. -Note that the ``$adff`` and ``$sdff`` cells can only be used when the reset value is -constant. +Note that the ``$adff`` and ``$sdff`` cells can only be used when the reset +value is constant. D-type flip-flops with asynchronous load are represented by ``$aldff`` cells. As the ``$dff`` cells they have ``\CLK``, ``\D`` and ``\Q`` ports. In addition they @@ -332,11 +337,11 @@ cells. Memories ~~~~~~~~ -Memories are either represented using RTLIL::Memory objects, ``$memrd_v2``, +Memories are either represented using ``RTLIL::Memory`` objects, ``$memrd_v2``, ``$memwr_v2``, and ``$meminit_v2`` cells, or by ``$mem_v2`` cells alone. -In the first alternative the RTLIL::Memory objects hold the general metadata for -the memory (bit width, size in number of words, etc.) and for each port a +In the first alternative the ``RTLIL::Memory`` objects hold the general metadata +for the memory (bit width, size in number of words, etc.) and for each port a ``$memrd_v2`` (read port) or ``$memwr_v2`` (write port) cell is created. Having individual cells for read and write ports has the advantage that they can be consolidated using resource sharing passes. In some cases this drastically @@ -351,7 +356,7 @@ address input ``\ADDR``, a data output ``\DATA``, an asynchronous reset input parameters: ``\MEMID`` - The name of the RTLIL::Memory object that is associated with this read + The name of the ``RTLIL::Memory`` object that is associated with this read port. ``\ABITS`` @@ -411,7 +416,7 @@ The ``$memwr_v2`` cells have a clock input ``\CLK``, an enable input ``\EN`` ``\DATA``. They also have the following parameters: ``\MEMID`` - The name of the RTLIL::Memory object that is associated with this write + The name of the ``RTLIL::Memory`` object that is associated with this write port. ``\ABITS`` @@ -431,16 +436,17 @@ The ``$memwr_v2`` cells have a clock input ``\CLK``, an enable input ``\EN`` ``1'b1`` and on the negative edge if this parameter is ``1'b0``. ``\PORTID`` - An identifier for this write port, used to index write port bit mask parameters. + An identifier for this write port, used to index write port bit mask + parameters. ``\PRIORITY_MASK`` - This parameter is a bitmask of write ports that this write port has - priority over in case of writing to the same address. The bits of this - parameter are indexed by the other write port's ``\PORTID`` parameter. - Write ports can only have priority over write ports with lower port ID. - When two ports write to the same address and neither has priority over - the other, the result is undefined. Priority can only be set between - two synchronous ports sharing the same clock domain. + This parameter is a bitmask of write ports that this write port has priority + over in case of writing to the same address. The bits of this parameter are + indexed by the other write port's ``\PORTID`` parameter. Write ports can + only have priority over write ports with lower port ID. When two ports write + to the same address and neither has priority over the other, the result is + undefined. Priority can only be set between two synchronous ports sharing + the same clock domain. The ``$meminit_v2`` cells have an address input ``\ADDR``, a data input ``\DATA``, with the width of the ``\DATA`` port equal to ``\WIDTH`` parameter @@ -449,7 +455,7 @@ to ``\WIDTH`` parameter. All three of the inputs must resolve to a constant for synthesis to succeed. ``\MEMID`` - The name of the RTLIL::Memory object that is associated with this + The name of the ``RTLIL::Memory`` object that is associated with this initialization cell. ``\ABITS`` @@ -465,19 +471,19 @@ synthesis to succeed. The cell with the higher integer value in this parameter wins an initialization conflict. -The HDL frontend models a memory using RTLIL::Memory objects and asynchronous -``$memrd_v2`` and ``$memwr_v2`` cells. The ``memory`` pass (i.e.~its various -sub-passes) migrates ``$dff`` cells into the ``$memrd_v2`` and ``$memwr_v2`` -cells making them synchronous, then converts them to a single ``$mem_v2`` cell -and (optionally) maps this cell type to ``$dff`` cells for the individual words -and multiplexer-based address decoders for the read and write interfaces. When -the last step is disabled or not possible, a ``$mem_v2`` cell is left in the -design. +The HDL frontend models a memory using ``RTLIL::Memory`` objects and +asynchronous ``$memrd_v2`` and ``$memwr_v2`` cells. The :cmd:ref:`memory` pass +(i.e. its various sub-passes) migrates ``$dff`` cells into the ``$memrd_v2`` and +``$memwr_v2`` cells making them synchronous, then converts them to a single +``$mem_v2`` cell and (optionally) maps this cell type to ``$dff`` cells for the +individual words and multiplexer-based address decoders for the read and write +interfaces. When the last step is disabled or not possible, a ``$mem_v2`` cell +is left in the design. The ``$mem_v2`` cell provides the following parameters: ``\MEMID`` - The name of the original RTLIL::Memory object that became this + The name of the original ``RTLIL::Memory`` object that became this ``$mem_v2`` cell. ``\SIZE`` @@ -598,15 +604,15 @@ The ``$mem_v2`` cell has the following ports: This input is ``\WR_PORTS*\WIDTH`` bits wide, containing all data signals for the write ports. -The ``memory_collect`` pass can be used to convert discrete ``$memrd_v2``, -``$memwr_v2``, and ``$meminit_v2`` cells belonging to the same memory to a -single ``$mem_v2`` cell, whereas the ``memory_unpack`` pass performs the inverse -operation. The ``memory_dff`` pass can combine asynchronous memory ports that -are fed by or feeding registers into synchronous memory ports. The -``memory_bram`` pass can be used to recognize ``$mem_v2`` cells that can be -implemented with a block RAM resource on an FPGA. The ``memory_map`` pass can be -used to implement ``$mem_v2`` cells as basic logic: word-wide DFFs and address -decoders. +The :cmd:ref:`memory_collect` pass can be used to convert discrete +``$memrd_v2``, ``$memwr_v2``, and ``$meminit_v2`` cells belonging to the same +memory to a single ``$mem_v2`` cell, whereas the :cmd:ref:`memory_unpack` pass +performs the inverse operation. The :cmd:ref:`memory_dff` pass can combine +asynchronous memory ports that are fed by or feeding registers into synchronous +memory ports. The :cmd:ref:`memory_bram` pass can be used to recognize +``$mem_v2`` cells that can be implemented with a block RAM resource on an FPGA. +The :cmd:ref:`memory_map` pass can be used to implement ``$mem_v2`` cells as +basic logic: word-wide DFFs and address decoders. Finite state machines ~~~~~~~~~~~~~~~~~~~~~ @@ -943,17 +949,17 @@ techlibs/common/simcells.v in the Yosys source tree. ============== ============== ========= -Tables \ :numref:`%s `, :numref:`%s -`, :numref:`%s `, :numref:`%s -`, :numref:`%s `, :numref:`%s -`, :numref:`%s `, -:numref:`%s ` and :numref:`%s -` list all cell types used for gate level logic. The cell -types ``$_BUF_``, ``$_NOT_``, ``$_AND_``, ``$_NAND_``, ``$_ANDNOT_``, ``$_OR_``, -``$_NOR_``, ``$_ORNOT_``, ``$_XOR_``, ``$_XNOR_``, ``$_AOI3_``, ``$_OAI3_``, -``$_AOI4_``, ``$_OAI4_``, ``$_MUX_``, ``$_MUX4_``, ``$_MUX8_``, ``$_MUX16_`` and -``$_NMUX_`` are used to model combinatorial logic. The cell type ``$_TBUF_`` is -used to model tristate logic. +Tables :numref:`%s `, :numref:`%s `, +:numref:`%s `, :numref:`%s `, +:numref:`%s `, :numref:`%s `, +:numref:`%s `, :numref:`%s +` and :numref:`%s ` list all +cell types used for gate level logic. The cell types ``$_BUF_``, ``$_NOT_``, +``$_AND_``, ``$_NAND_``, ``$_ANDNOT_``, ``$_OR_``, ``$_NOR_``, ``$_ORNOT_``, +``$_XOR_``, ``$_XNOR_``, ``$_AOI3_``, ``$_OAI3_``, ``$_AOI4_``, ``$_OAI4_``, +``$_MUX_``, ``$_MUX4_``, ``$_MUX8_``, ``$_MUX16_`` and ``$_NMUX_`` are used to +model combinatorial logic. The cell type ``$_TBUF_`` is used to model tristate +logic. The ``$_MUX4_``, ``$_MUX8_`` and ``$_MUX16_`` cells are used to model wide muxes, and correspond to the following Verilog code: @@ -1142,8 +1148,8 @@ mapped to physical flip-flop cells from a Liberty file using the dfflibmap pass. The combinatorial logic cells can be mapped to physical cells from a Liberty file via ABC using the abc pass. -Add information about ``$slice`` and ``$concat`` cells. +.. todo:: Add information about ``$slice`` and ``$concat`` cells. -Add information about ``$lut`` and ``$sop`` cells. +.. todo:: Add information about ``$lut`` and ``$sop`` cells. -Add information about ``$alu``, ``$macc``, ``$fa``, and ``$lcu`` cells. +.. todo:: Add information about ``$alu``, ``$macc``, ``$fa``, and ``$lcu`` cells. diff --git a/docs/source/yosys_internals/formats/index.rst b/docs/source/yosys_internals/formats/index.rst new file mode 100644 index 00000000000..c187a8238a8 --- /dev/null +++ b/docs/source/yosys_internals/formats/index.rst @@ -0,0 +1,13 @@ +Internal formats +================ + +.. todo:: brief overview for the internal formats index + +.. toctree:: + :maxdepth: 3 + + overview + rtlil_rep + rtlil_text + cell_library + diff --git a/docs/source/yosys_internals/formats/overview.rst b/docs/source/yosys_internals/formats/overview.rst new file mode 100644 index 00000000000..cbf5369bc06 --- /dev/null +++ b/docs/source/yosys_internals/formats/overview.rst @@ -0,0 +1,53 @@ +Format overview +=============== + +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. + +.. [1] + In Yosys the term pass is only used to refer to commands that operate on the + RTLIL data structure. \ No newline at end of file diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst new file mode 100644 index 00000000000..5de3430f228 --- /dev/null +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -0,0 +1,416 @@ +The RTL Intermediate Language (RTLIL) +===================================== + +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/internals/overview_rtlil.* + :class: width-helper + :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, :cmd:ref:`opt_clean` 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. Note that this can be overridden + with the `-purge` option to also delete internal nets with user-provided + names. + +- 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 ``_123_``. + +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 :ref:`ER diagram ` above, +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 more than 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 more than 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: + +.. code:: RTLIL + :number-lines: + + 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 2..12 describe how ``$0\q[0:0]`` should be calculated. The +lines 13..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 2..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 3..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 6..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 13..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 :cmd:ref:`proc_arst` pass. This pass transforms the above example to the +following ``RTLIL::Process``: + +.. code:: RTLIL + :number-lines: + + 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: + +.. code:: RTLIL + :number-lines: + + 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 ``\MEMID`` +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 :ref:`sec:memcells` for details about the memory cell types. + +.. [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/appendix/CHAPTER_TextRtlil.rst b/docs/source/yosys_internals/formats/rtlil_text.rst similarity index 92% rename from docs/source/appendix/CHAPTER_TextRtlil.rst rename to docs/source/yosys_internals/formats/rtlil_text.rst index dc3d72230b9..8b5c1068120 100644 --- a/docs/source/appendix/CHAPTER_TextRtlil.rst +++ b/docs/source/yosys_internals/formats/rtlil_text.rst @@ -1,7 +1,7 @@ .. _chapter:textrtlil: RTLIL text representation -========================= +------------------------- This appendix documents the text representation of RTLIL in extended Backus-Naur form (EBNF). @@ -17,10 +17,10 @@ Finally, note that all statements (rules ending in ``-stmt``) terminate in an end-of-line. Because of this, a statement cannot be broken into multiple lines. Lexical elements ----------------- +~~~~~~~~~~~~~~~~ Characters -~~~~~~~~~~ +^^^^^^^^^^ An RTLIL file is a stream of bytes. Strictly speaking, a "character" in an RTLIL file is a single byte. The lexer treats multi-byte encoded characters as @@ -37,7 +37,7 @@ An ``eol`` is one or more consecutive ASCII newlines (10) and carriage returns (13). Identifiers -~~~~~~~~~~~ +^^^^^^^^^^^ There are two types of identifiers in RTLIL: @@ -51,7 +51,7 @@ There are two types of identifiers in RTLIL: ::= $ + Values -~~~~~~ +^^^^^^ A *value* consists of a width in bits and a bit representation, most significant bit first. Bits may be any of: @@ -76,7 +76,7 @@ error. ::= -? + Strings -~~~~~~~ +^^^^^^^ A string is a series of characters delimited by double-quote characters. Within a string, any character except ASCII NUL (0) may be used. In addition, certain @@ -94,13 +94,13 @@ character. Thus: - ``\r``: An 'r' character Comments -~~~~~~~~ +^^^^^^^^ A comment starts with a ``#`` character and proceeds to the end of the line. All comments are ignored. File ----- +~~~~ A file consists of an optional autoindex statement followed by zero or more modules. @@ -110,7 +110,7 @@ modules. ::= ? * Autoindex statements -~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^ The autoindex statement sets the global autoindex value used by Yosys when it needs to generate a unique name, e.g. ``flattenN``. The N part is filled with @@ -123,7 +123,7 @@ would have different properties than just running a pass on a warm design. ::= autoidx Modules -~~~~~~~ +^^^^^^^ Declares a module, with zero or more attributes, consisting of zero or more wires, memories, cells, processes, and connections. @@ -142,7 +142,7 @@ wires, memories, cells, processes, and connections. ::= end Attribute statements -~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^ Declares an attribute with the given identifier and value. @@ -151,7 +151,7 @@ Declares an attribute with the given identifier and value. ::= attribute Signal specifications -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^ A signal is anything that can be applied to a cell port, i.e. a constant value, all bits or a selection of bits from a wire, or concatenations of those. @@ -161,8 +161,7 @@ all bits or a selection of bits from a wire, or concatenations of those. ``32'11111111111111111111111111111111``, while a constant of :math:`1` is the same as ``32'1``. -See :numref:`Sec. %s ` for an overview of signal -specifications. +See :ref:`sec:rtlil_sigspec` for an overview of signal specifications. .. code:: BNF @@ -172,7 +171,7 @@ specifications. | { * } Connections -~~~~~~~~~~~ +^^^^^^^^^^^ Declares a connection between the given signals. @@ -181,12 +180,12 @@ Declares a connection between the given signals. ::= connect Wires -~~~~~ +^^^^^ Declares a wire, with zero or more attributes, with the given identifier and options in the enclosing module. -See :numref:`Sec. %s ` for an overview of wires. +See :ref:`sec:rtlil_cell_wire` for an overview of wires. .. code:: BNF @@ -202,13 +201,13 @@ See :numref:`Sec. %s ` for an overview of wires. | signed Memories -~~~~~~~~ +^^^^^^^^ Declares a memory, with zero or more attributes, with the given identifier and options in the enclosing module. -See :numref:`Sec. %s ` for an overview of memory cells, and -:numref:`Sec. %s ` for details about memory cell types. +See :ref:`sec:rtlil_memory` for an overview of memory cells, and +:ref:`sec:memcells` for details about memory cell types. .. code:: BNF @@ -219,13 +218,13 @@ See :numref:`Sec. %s ` for an overview of memory cells, and | offset Cells -~~~~~ +^^^^^ Declares a cell, with zero or more attributes, with the given identifier and type in the enclosing module. -Cells perform functions on input signals. See :numref:`Chap. %s -` for a detailed list of cell types. +Cells perform functions on input signals. See +:doc:`/yosys_internals/formats/cell_library` for a detailed list of cell types. .. code:: BNF @@ -239,13 +238,13 @@ Cells perform functions on input signals. See :numref:`Chap. %s Processes -~~~~~~~~~ +^^^^^^^^^ Declares a process, with zero or more attributes, with the given identifier in the enclosing module. The body of a process consists of zero or more assignments, exactly one switch, and zero or more syncs. -See :numref:`Sec. %s ` for an overview of processes. +See :ref:`sec:rtlil_process` for an overview of processes. .. code:: BNF @@ -258,7 +257,7 @@ See :numref:`Sec. %s ` for an overview of processes. ::= end Switches -~~~~~~~~ +^^^^^^^^ Switches test a signal for equality against a list of cases. Each case specifies a comma-separated list of signals to check against. If there are no signals in @@ -277,7 +276,7 @@ attributes. ::= end Syncs -~~~~~ +^^^^^ Syncs update signals with other signals when an event happens. Such an event may be: diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst new file mode 100644 index 00000000000..b04f136995d --- /dev/null +++ b/docs/source/yosys_internals/index.rst @@ -0,0 +1,40 @@ +.. _chapter:overview: + +Yosys internals +=============== + +.. todo:: less academic + +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`_, the +`openMSP430 CPU`_, the `OpenCores I2C master`_, and the `k68 CPU`_. + +.. todo:: add RISC-V core example + +.. _OpenRISC 1200 CPU: https://github.com/openrisc/or1200 + +.. _openMSP430 CPU: http://opencores.org/projects/openmsp430 + +.. _OpenCores I2C master: http://opencores.org/projects/i2c + +.. _k68 CPU: http://opencores.org/projects/k68 + +Yosys is written in C++, targeting C++11 at minimum. 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. + +.. toctree:: + :maxdepth: 3 + + flow/index + formats/index + extending_yosys/index + techmap diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst new file mode 100644 index 00000000000..8508e6280fb --- /dev/null +++ b/docs/source/yosys_internals/techmap.rst @@ -0,0 +1,191 @@ +Techmap by example +------------------ + +As a quick recap, the :cmd:ref:`techmap` command replaces cells in the design +with implementations given as Verilog code (called "map files"). It can replace +Yosys' internal cell types (such as ``$or``) as well as user-defined cell types. + +- Verilog parameters are used extensively to customize the internal cell types. +- Additional special parameters are used by techmap to communicate meta-data to + the map files. +- Special wires are used to instruct techmap how to handle a module in the map + file. +- Generate blocks and recursion are powerful tools for writing map files. + +Code examples used in this document are included in the Yosys code base under +|code_examples/techmap|_. + +.. |code_examples/techmap| replace:: :file:`docs/source/code_examples/techmap` +.. _code_examples/techmap: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/techmap + + +Mapping OR3X1 +~~~~~~~~~~~~~ + +.. todo:: add/expand supporting text + +.. note:: + + This is a simple example for demonstration only. Techmap shouldn't be used + to implement basic logic optimization. + +.. literalinclude:: /code_examples/techmap/red_or3x1_map.v + :language: verilog + :caption: :file:`red_or3x1_map.v` + +.. figure:: /_images/code_examples/techmap/red_or3x1.* + :class: width-helper + +.. literalinclude:: /code_examples/techmap/red_or3x1_test.ys + :language: yoscrypt + :caption: :file:`red_or3x1_test.ys` + +.. literalinclude:: /code_examples/techmap/red_or3x1_test.v + :language: verilog + :caption: :file:`red_or3x1_test.v` + +Conditional techmap +~~~~~~~~~~~~~~~~~~~ + +- In some cases only cells with certain properties should be substituted. +- The special wire ``_TECHMAP_FAIL_`` can be used to disable a module in the map + file for a certain set of parameters. +- The wire ``_TECHMAP_FAIL_`` must be set to a constant value. If it is non-zero + then the module is disabled for this set of parameters. +- Example use-cases: + + - coarse-grain cell types that only operate on certain bit widths + - memory resources for different memory geometries (width, depth, ports, + etc.) + +Example: + +.. figure:: /_images/code_examples/techmap/sym_mul.* + :class: width-helper + +.. literalinclude:: /code_examples/techmap/sym_mul_map.v + :language: verilog + :caption: :file:`sym_mul_map.v` + +.. literalinclude:: /code_examples/techmap/sym_mul_test.v + :language: verilog + :caption: :file:`sym_mul_test.v` + +.. literalinclude:: /code_examples/techmap/sym_mul_test.ys + :language: yoscrypt + :caption: :file:`sym_mul_test.ys` + + +Scripting in map modules +~~~~~~~~~~~~~~~~~~~~~~~~ + +- The special wires ``_TECHMAP_DO_*`` can be used to run Yosys scripts in the + context of the replacement module. +- The wire that comes first in alphabetical oder is interpreted as string (must + be connected to constants) that is executed as script. Then the wire is + removed. Repeat. +- You can even call techmap recursively! +- Example use-cases: + + - Using always blocks in map module: call :cmd:ref:`proc` + - Perform expensive optimizations (such as :cmd:ref:`freduce`) on cells + where this is known to work well. + - Interacting with custom commands. + +.. note:: PROTIP: + + Commands such as :cmd:ref:`shell`, ``show -pause``, and :cmd:ref:`dump` can + be used in the ``_TECHMAP_DO_*`` scripts for debugging map modules. + +Example: + +.. figure:: /_images/code_examples/techmap/mymul.* + :class: width-helper + +.. literalinclude:: /code_examples/techmap/mymul_map.v + :language: verilog + :caption: :file:`mymul_map.v` + +.. literalinclude:: /code_examples/techmap/mymul_test.v + :language: verilog + :caption: :file:`mymul_test.v` + +.. literalinclude:: /code_examples/techmap/mymul_test.ys + :language: yoscrypt + :caption: :file:`mymul_test.ys` + +Handling constant inputs +~~~~~~~~~~~~~~~~~~~~~~~~ + +- The special parameters ``_TECHMAP_CONSTMSK__`` and + ``_TECHMAP_CONSTVAL__`` can be used to handle constant input values + to cells. +- The former contains 1-bits for all constant input bits on the port. +- The latter contains the constant bits or undef (x) for non-constant bits. +- Example use-cases: + + - Converting arithmetic (for example multiply to shift). + - Identify constant addresses or enable bits in memory interfaces. + +Example: + +.. figure:: /_images/code_examples/techmap/mulshift.* + :class: width-helper + +.. literalinclude:: /code_examples/techmap/mulshift_map.v + :language: verilog + :caption: :file:`mulshift_map.v` + +.. literalinclude:: /code_examples/techmap/mulshift_test.v + :language: verilog + :caption: :file:`mulshift_test.v` + +.. literalinclude:: /code_examples/techmap/mulshift_test.ys + :language: yoscrypt + :caption: :file:`mulshift_test.ys` + +Handling shorted inputs +~~~~~~~~~~~~~~~~~~~~~~~ + +- The special parameters ``_TECHMAP_BITS_CONNMAP_`` and + ``_TECHMAP_CONNMAP__`` can be used to handle shorted inputs. +- Each bit of the port correlates to an ``_TECHMAP_BITS_CONNMAP_`` bits wide + number in ``_TECHMAP_CONNMAP__``. +- Each unique signal bit is assigned its own number. Identical fields in the + ``_TECHMAP_CONNMAP__`` parameters mean shorted signal bits. +- The numbers 0-3 are reserved for ``0``, ``1``, ``x``, and ``z`` respectively. +- Example use-cases: + + - Detecting shared clock or control signals in memory interfaces. + - In some cases this can be used for for optimization. + +Example: + +.. figure:: /_images/code_examples/techmap/addshift.* + :class: width-helper + +.. literalinclude:: /code_examples/techmap/addshift_map.v + :language: verilog + :caption: :file:`addshift_map.v` + +.. literalinclude:: /code_examples/techmap/addshift_test.v + :language: verilog + :caption: :file:`addshift_test.v` + +.. literalinclude:: /code_examples/techmap/addshift_test.ys + :language: yoscrypt + :caption: :file:`addshift_test.ys` + +Notes on using techmap +~~~~~~~~~~~~~~~~~~~~~~ + +- Don't use positional cell parameters in map modules. +- You can use the ``$__``-prefix for internal cell types to avoid collisions + with the user-namespace. But always use two underscores or the internal + consistency checker will trigger on these cells. +- Techmap has two major use cases: + + - Creating good logic-level representation of arithmetic functions. This + also means using dedicated hardware resources such as half- and full-adder + cells in ASICS or dedicated carry logic in FPGAs. + - Mapping of coarse-grain resources such as block memory or DSP cells. diff --git a/docs/static/custom.css b/docs/static/custom.css deleted file mode 100644 index 40a8c178f10..00000000000 --- a/docs/static/custom.css +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/docs/static/yosyshq.css b/docs/static/yosyshq.css deleted file mode 100644 index 0be7f77281d..00000000000 --- a/docs/static/yosyshq.css +++ /dev/null @@ -1,78 +0,0 @@ -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; -} - -.cmdref .highlight-yoscrypt .highlight pre { - padding: 0%; - margin: 0%; -} - -.cmdref .highlight-none .highlight pre { - padding-top: 0%; - margin-top: 0%; -} - -.width-helper { - max-width: 100%; -} diff --git a/docs/tests/macro_commands.py b/docs/tests/macro_commands.py new file mode 100755 index 00000000000..faf2baa530b --- /dev/null +++ b/docs/tests/macro_commands.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 + +import logging +from pathlib import Path +import re +import subprocess +import sys + +# basic logging setup +logging.basicConfig(level=logging.INFO) + +# expects __file__ = yosys/docs/tests/macro_commands.py +TESTS_DIR = Path(__file__).parent +ROOT_DIR = TESTS_DIR.parent.parent +THIS_FILE = (TESTS_DIR / "macro_commands.py").relative_to(ROOT_DIR) +MACRO_SOURCE = TESTS_DIR.parent / "source" / "code_examples" / "macro_commands" +assert MACRO_SOURCE.exists(), f"can't find macro_commands in {MACRO_SOURCE}" + +YOSYS = TESTS_DIR.parent.parent / "yosys" +assert YOSYS.exists(), f"can't find yosys executable in {YOSYS}" + +raise_error = False +# get all macro commands being used +for macro in MACRO_SOURCE.glob("*.ys"): + # log current test + relative_path = macro.relative_to(ROOT_DIR) + logging.log(logging.INFO, f"Checking {relative_path}") + # files in macros_commands should be named {command}.ys + command = macro.stem + # run `yosys -h {command}` to capture current sub-commands + proc = subprocess.run([YOSYS, "-QTh", command], capture_output=True, text=True) + with open(macro) as f: + # {command.ys} starts with two commented lines, the first is the text + # immediately prior to the macro body. The second is the text + # immediately after. + start = f.readline() + end = f.readline() + file_content = f.readlines() + expected_content = [] + for line in file_content: + line = line.split("#")[0].strip() + if line: + expected_content.append(line) + # parse {command.ys} + if "#start:" not in start or "#end:" not in end: + logging.error(f"Missing start and/or end string in {relative_path}, see {THIS_FILE}") + raise_error = True + continue + start = start.replace("#start:", "").strip() + end = end.replace("#end:", "").strip() + # attempt to find macro body in help output + match = re.fullmatch(f".*{start}(.*){end}.*", proc.stdout, re.DOTALL) + if not match: + logging.error(f"Couldn't find {start!r} and/or {end!r} in `yosys -h {command}` output") + raise_error = True + continue + match_content = match.group(1).strip().splitlines() + actual_content = [] + for line in match_content: + if line: + actual_content.append(line) + # iterate over and compare expected v actual + for (expected, actual) in zip(expected_content, actual_content): + expected = expected.strip() + actual = actual.strip() + # raw match + if expected == actual: + continue + + # rip apart formatting to match line parts + pattern = r"(?P\S+)(?P \[.*\])?(?P.*?)(?P\s+\(.*\))?" + try: + expected_dict = re.fullmatch(pattern, expected).groupdict() + except AttributeError: + logging.error(f"Bad formatting in {relative_path}: {expected!r}") + raise_error = True + continue + + try: + actual_dict = re.fullmatch(pattern, actual).groupdict() + except AttributeError: + logging.error(f"Unexpected formatting in `yosys -h {command}` output, {actual!r}") + raise_error = True + continue + + does_match = expected_dict["cmd"] == actual_dict["cmd"] + + #todo: check expected_dict["pass"] is a subset of actual_dict["pass"] + # only check opt and cond match if they're in {command}.ys + match_keys = ["opt", "cond"] + for key in match_keys: + if expected_dict[key] and expected_dict[key] != actual_dict[key]: + does_match = False + + # raise error on mismatch + if not does_match: + logging.error(f"Expected {expected!r}, got {actual!r}") + raise_error = True + +sys.exit(raise_error) diff --git a/docs/util/__init__.py b/docs/util/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/util/cmdref.py b/docs/util/cmdref.py new file mode 100644 index 00000000000..ec146e23173 --- /dev/null +++ b/docs/util/cmdref.py @@ -0,0 +1,246 @@ +# based on https://github.com/ofosos/sphinxrecipes/blob/master/sphinxrecipes/sphinxrecipes.py +# license: +# Copyright 2019 Mark Meyer +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import docutils +from docutils import nodes +import sphinx +from docutils.parsers import rst +from docutils.parsers.rst import directives +from sphinx.domains import Domain, Index +from sphinx.domains.std import StandardDomain +from sphinx.roles import XRefRole +from sphinx.directives import ObjectDescription +from sphinx.util.nodes import make_refnode +from sphinx import addnodes + +class CommandNode(ObjectDescription): + """A custom node that describes a command.""" + + required_arguments = 1 + + option_spec = { + 'title': directives.unchanged_required, + 'tags': directives.unchanged + } + + def handle_signature(self, sig, signode: addnodes.desc_signature): + signode += addnodes.desc_addname(text="yosys> help ") + signode += addnodes.desc_name(text=sig) + return sig + + def add_target_and_index(self, name_cls, sig, signode): + signode['ids'].append('cmd' + '-' + sig) + if 'noindex' not in self.options: + name = "{}.{}.{}".format('cmd', type(self).__name__, sig) + tagmap = self.env.domaindata['cmd']['obj2tag'] + tagmap[name] = list(self.options.get('tags', '').split(' ')) + title = self.options.get('title') + titlemap = self.env.domaindata['cmd']['obj2title'] + titlemap[name] = title + objs = self.env.domaindata['cmd']['objects'] + objs.append((name, + sig, + title, + self.env.docname, + 'cmd' + '-' + sig, + 0)) + +class TagIndex(Index): + """A custom directive that creates an tag matrix.""" + + name = 'tag' + localname = 'Tag Index' + shortname = 'Tag' + + def __init__(self, *args, **kwargs): + super(TagIndex, self).__init__(*args, **kwargs) + + def generate(self, docnames=None): + """Return entries for the index given by *name*. If *docnames* is + given, restrict to entries referring to these docnames. + The return value is a tuple of ``(content, collapse)``, where + * collapse* is a boolean that determines if sub-entries should + start collapsed (for output formats that support collapsing + sub-entries). + *content* is a sequence of ``(letter, entries)`` tuples, where *letter* + is the "heading" for the given *entries*, usually the starting letter. + *entries* is a sequence of single entries, where a single entry is a + sequence ``[name, subtype, docname, anchor, extra, qualifier, descr]``. + The items in this sequence have the following meaning: + - `name` -- the name of the index entry to be displayed + - `subtype` -- sub-entry related type: + 0 -- normal entry + 1 -- entry with sub-entries + 2 -- sub-entry + - `docname` -- docname where the entry is located + - `anchor` -- anchor for the entry within `docname` + - `extra` -- extra info for the entry + - `qualifier` -- qualifier for the description + - `descr` -- description for the entry + Qualifier and description are not rendered e.g. in LaTeX output. + """ + + content = {} + + objs = {name: (dispname, typ, docname, anchor) + for name, dispname, typ, docname, anchor, prio + in self.domain.get_objects()} + + tmap = {} + tags = self.domain.data['obj2tag'] + for name, tags in tags.items(): + for tag in tags: + tmap.setdefault(tag,[]) + tmap[tag].append(name) + + for tag in tmap.keys(): + lis = content.setdefault(tag, []) + objlis = tmap[tag] + for objname in objlis: + dispname, typ, docname, anchor = objs[objname] + lis.append(( + dispname, 0, docname, + anchor, + docname, '', typ + )) + re = [(k, v) for k, v in sorted(content.items())] + + return (re, True) + + +class CommandIndex(Index): + name = 'cmd' + localname = 'Command Reference' + shortname = 'Command' + + def __init__(self, *args, **kwargs): + super(CommandIndex, self).__init__(*args, **kwargs) + + def generate(self, docnames=None): + """Return entries for the index given by *name*. If *docnames* is + given, restrict to entries referring to these docnames. + The return value is a tuple of ``(content, collapse)``, where + * collapse* is a boolean that determines if sub-entries should + start collapsed (for output formats that support collapsing + sub-entries). + *content* is a sequence of ``(letter, entries)`` tuples, where *letter* + is the "heading" for the given *entries*, usually the starting letter. + *entries* is a sequence of single entries, where a single entry is a + sequence ``[name, subtype, docname, anchor, extra, qualifier, descr]``. + The items in this sequence have the following meaning: + - `name` -- the name of the index entry to be displayed + - `subtype` -- sub-entry related type: + 0 -- normal entry + 1 -- entry with sub-entries + 2 -- sub-entry + - `docname` -- docname where the entry is located + - `anchor` -- anchor for the entry within `docname` + - `extra` -- extra info for the entry + - `qualifier` -- qualifier for the description + - `descr` -- description for the entry + Qualifier and description are not rendered e.g. in LaTeX output. + """ + + content = {} + items = ((name, dispname, typ, docname, anchor) + for name, dispname, typ, docname, anchor, prio + in self.domain.get_objects()) + items = sorted(items, key=lambda item: item[0]) + for name, dispname, typ, docname, anchor in items: + lis = content.setdefault('Command', []) + lis.append(( + dispname, 0, docname, + anchor, + '', '', typ + )) + re = [(k, v) for k, v in sorted(content.items())] + + return (re, True) + + +class CommandDomain(Domain): + name = 'cmd' + label = 'Command Sample' + + roles = { + 'ref': XRefRole() + } + + directives = { + 'def': CommandNode, + } + + indices = { + CommandIndex, + TagIndex + } + + initial_data = { + 'objects': [], # object list + 'obj2tag': {}, # name -> tags + 'obj2title': {}, # name -> title + } + + def get_full_qualified_name(self, node): + """Return full qualified name for a given node""" + return "{}.{}.{}".format('cmd', + type(node).__name__, + node.arguments[0]) + + def get_objects(self): + for obj in self.data['objects']: + yield(obj) + + def resolve_xref(self, env, fromdocname, builder, typ, + target, node, contnode): + + match = [(docname, anchor, name) + for name, sig, typ, docname, anchor, prio + in self.get_objects() if sig == target] + + if match: + todocname = match[0][0] + targ = match[0][1] + qual_name = match[0][2] + title = self.data['obj2title'].get(qual_name, targ) + + return make_refnode(builder,fromdocname,todocname, + targ, contnode, title) + else: + print(f"Missing ref for {target} in {fromdocname} ") + return None + +def setup(app): + app.add_domain(CommandDomain) + + StandardDomain.initial_data['labels']['commandindex'] =\ + ('cmd-cmd', '', 'Command Reference') + StandardDomain.initial_data['labels']['tagindex'] =\ + ('cmd-tag', '', 'Tag Index') + + StandardDomain.initial_data['anonlabels']['commandindex'] =\ + ('cmd-cmd', '') + StandardDomain.initial_data['anonlabels']['tagindex'] =\ + ('cmd-tag', '') + + return {'version': '0.1'} diff --git a/guidelines/GettingStarted b/guidelines/GettingStarted index d27b285fce4..110f6318518 100644 --- a/guidelines/GettingStarted +++ b/guidelines/GettingStarted @@ -191,8 +191,8 @@ Example Code The following yosys commands are a good starting point if you are looking for examples of how to use the Yosys API: - docs/source/CHAPTER_Prog/stubnets.cc - manual/PRESENTATION_Prog/my_cmd.cc + docs/source/code_examples/stubnets/stubnets.cc + docs/resources/PRESENTATION_Prog/my_cmd.cc Script Passes diff --git a/kernel/register.cc b/kernel/register.cc index 3ccb5ee7848..80bc44901b2 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -784,9 +784,8 @@ struct HelpPass : public Pass { fprintf(f, ".. raw:: latex\n\n \\begin{comment}\n\n"); // render html - fprintf(f, ":code:`yosys> help %s`\n", cmd.c_str()); - fprintf(f, "--------------------------------------------------------------------------------\n\n"); - fprintf(f, ".. container:: cmdref\n"); + fprintf(f, ".. cmd:def:: %s\n", cmd.c_str()); + fprintf(f, " :title: %s\n\n", title.c_str()); std::stringstream ss; std::string textcp = text; ss << text; diff --git a/manual/.gitignore b/manual/.gitignore deleted file mode 100644 index 110f65b1900..00000000000 --- a/manual/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -*.aux -*.bbl -*.blg -*.idx -*.log -*.out -*.pdf -*.toc -*.snm -*.nav -*.vrb -*.ok diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex deleted file mode 100644 index 6a426ff2b1f..00000000000 --- a/manual/PRESENTATION_ExAdv.tex +++ /dev/null @@ -1,896 +0,0 @@ - -\section{Yosys by example -- Advanced Synthesis} - -\begin{frame} -\sectionpage -\end{frame} - -\begin{frame}{Overview} -This section contains 4 subsections: -\begin{itemize} -\item Using selections -\item Advanced uses of techmap -\item Coarse-grain synthesis -\item Automatic design changes -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Using selections} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Simple selections} - -\begin{frame}[fragile]{\subsubsecname} -Most Yosys commands make use of the ``selection framework'' of Yosys. It can be used -to apply commands only to part of the design. For example: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -delete # will delete the whole design, but - -delete foobar # will only delete the module foobar. -\end{lstlisting} - -\bigskip -The {\tt select} command can be used to create a selection for subsequent -commands. For example: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select foobar # select the module foobar -delete # delete selected objects -select -clear # reset selection (select whole design) -\end{lstlisting} -\end{frame} - -\subsubsection{Selection by object name} - -\begin{frame}[fragile]{\subsubsecname} -The easiest way to select objects is by object name. This is usually only done -in synthesis scripts that are hand-tailored for a specific design. - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select foobar # select module foobar -select foo* # select all modules whose names start with foo -select foo*/bar* # select all objects matching bar* from modules matching foo* -select */clk # select objects named clk from all modules -\end{lstlisting} -\end{frame} - -\subsubsection{Module and design context} - -\begin{frame}[fragile]{\subsubsecname} -Commands can be executed in {\it module\/} or {\it design\/} context. Until now all -commands have been executed in design context. The {\tt cd} command can be used -to switch to module context. - -\bigskip -In module context all commands only effect the active module. Objects in the module -are selected without the {\tt /} prefix. For example: - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -cd foo # switch to module foo -delete bar # delete object foo/bar - -cd mycpu # switch to module mycpu -dump reg_* # print details on all objects whose names start with reg_ - -cd .. # switch back to design -\end{lstlisting} - -\bigskip -Note: Most synthesis scripts never switch to module context. But it is a very powerful -tool for interactive design investigation. -\end{frame} - -\subsubsection{Selecting by object property or type} - -\begin{frame}[fragile]{\subsubsecname} -Special patterns can be used to select by object property or type. For example: - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select w:reg_* # select all wires whose names start with reg_ -select a:foobar # select all objects with the attribute foobar set -select a:foobar=42 # select all objects with the attribute foobar set to 42 -select A:blabla # select all modules with the attribute blabla set -select foo/t:$add # select all $add cells from the module foo -\end{lstlisting} - -\bigskip -A complete list of this pattern expressions can be found in the command -reference to the {\tt select} command. -\end{frame} - -\subsubsection{Combining selection} - -\begin{frame}[fragile]{\subsubsecname} -When more than one selection expression is used in one statement, then they are -pushed on a stack. The final elements on the stack are combined into a union: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select t:$dff r:WIDTH>1 # all cells of type $dff and/or with a parameter WIDTH > 1 -\end{lstlisting} - -\bigskip -Special \%-commands can be used to combine the elements on the stack: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select t:$dff r:WIDTH>1 %i # all cells of type $dff *AND* with a parameter WIDTH > 1 -\end{lstlisting} - -\medskip -\begin{block}{Examples for {\tt \%}-codes (see {\tt help select} for full list)} -{\tt \%u} \dotfill union of top two elements on stack -- pop 2, push 1 \\ -{\tt \%d} \dotfill difference of top two elements on stack -- pop 2, push 1 \\ -{\tt \%i} \dotfill intersection of top two elements on stack -- pop 2, push 1 \\ -{\tt \%n} \dotfill inverse of top element on stack -- pop 1, push 1 \\ -\end{block} -\end{frame} - -\subsubsection{Expanding selections} - -\begin{frame}[fragile]{\subsubsecname} -Selections of cells and wires can be expanded along connections using {\tt \%}-codes -for selecting input cones ({\tt \%ci}), output cones ({\tt \%co}), or both ({\tt \%x}). - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# select all wires that are inputs to $add cells -select t:$add %ci w:* %i -\end{lstlisting} - -\bigskip -Additional constraints such as port names can be specified. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# select all wires that connect a "Q" output with a "D" input -select c:* %co:+[Q] w:* %i c:* %ci:+[D] w:* %i %i - -# select the multiplexer tree that drives the signal 'state' -select state %ci*:+$mux,$pmux[A,B,Y] -\end{lstlisting} - -\bigskip -See {\tt help select} for full documentation of this expressions. -\end{frame} - -\subsubsection{Incremental selection} - -\begin{frame}[fragile]{\subsubsecname} -Sometimes a selection can most easily be described by a series of add/delete operations. -The commands {\tt select -add} and {\tt select -del} respectively add or remove objects -from the current selection instead of overwriting it. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select -none # start with an empty selection -select -add reg_* # select a bunch of objects -select -del reg_42 # but not this one -select -add state %ci # and add mor stuff -\end{lstlisting} - -\bigskip -Within a select expression the token {\tt \%} can be used to push the previous selection -on the stack. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select t:$add t:$sub # select all $add and $sub cells -select % %ci % %d # select only the input wires to those cells -\end{lstlisting} -\end{frame} - -\subsubsection{Creating selection variables} - -\begin{frame}[fragile]{\subsubsecname} -Selections can be stored under a name with the {\tt select -set } -command. The stored selections can be used in later select expressions -using the syntax {\tt @}. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select -set cone_a state_a %ci*:-$dff # set @cone_a to the input cone of state_a -select -set cone_b state_b %ci*:-$dff # set @cone_b to the input cone of state_b -select @cone_a @cone_b %i # select the objects that are in both cones -\end{lstlisting} - -\bigskip -Remember that select expressions can also be used directly as arguments to most -commands. Some commands also except a single select argument to some options. -In those cases selection variables must be used to capture more complex selections. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -dump @cone_a @cone_b - -select -set cone_ab @cone_a @cone_b %i -show -color red @cone_ab -color magenta @cone_a -color blue @cone_b -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- Example} -\begin{columns} -\column[t]{4cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/select.v} -\column[t]{7cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExAdv/select.ys} -\end{columns} -\hfil\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/select.pdf} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Advanced uses of techmap} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Introduction to techmap} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item -The {\tt techmap} command replaces cells in the design with implementations given -as Verilog code (called ``map files''). It can replace Yosys' internal cell -types (such as {\tt \$or}) as well as user-defined cell types. -\medskip\item -Verilog parameters are used extensively to customize the internal cell types. -\medskip\item -Additional special parameters are used by techmap to communicate meta-data to the -map files. -\medskip\item -Special wires are used to instruct techmap how to handle a module in the map file. -\medskip\item -Generate blocks and recursion are powerful tools for writing map files. -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example 1/2} -\vskip-0.2cm -To map the Verilog OR-reduction operator to 3-input OR gates: -\vskip-0.2cm -\begin{columns} -\column[t]{0.35\linewidth} -\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=24]{PRESENTATION_ExAdv/red_or3x1_map.v} -\column[t]{0.65\linewidth} -\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=25]{PRESENTATION_ExAdv/red_or3x1_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example 2/2} -\vbox to 0cm{ -\hfil\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/red_or3x1.pdf} -\vss -} -\begin{columns} -\column[t]{6cm} -\column[t]{4cm} -\vskip-0.6cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, firstline=4, lastline=4, frame=single]{PRESENTATION_ExAdv/red_or3x1_test.ys} -\vskip-0.2cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/red_or3x1_test.v} -\end{columns} -\end{frame} - -\subsubsection{Conditional techmap} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item In some cases only cells with certain properties should be substituted. -\medskip -\item The special wire {\tt \_TECHMAP\_FAIL\_} can be used to disable a module -in the map file for a certain set of parameters. -\medskip -\item The wire {\tt \_TECHMAP\_FAIL\_} must be set to a constant value. If it -is non-zero then the module is disabled for this set of parameters. -\medskip -\item Example use-cases: -\begin{itemize} -\item coarse-grain cell types that only operate on certain bit widths -\item memory resources for different memory geometries (width, depth, ports, etc.) -\end{itemize} -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip-0.5cm -\hfill\includegraphics[width=6cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/sym_mul.pdf} -\vss -} -\vskip-0.5cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/sym_mul_map.v} -\begin{columns} -\column[t]{6cm} -\vskip-0.5cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/sym_mul_test.v} -\column[t]{4cm} -\vskip-0.5cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=4]{PRESENTATION_ExAdv/sym_mul_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Scripting in map modules} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item The special wires {\tt \_TECHMAP\_DO\_*} can be used to run Yosys scripts -in the context of the replacement module. -\medskip -\item The wire that comes first in alphabetical oder is interpreted as string (must -be connected to constants) that is executed as script. Then the wire is removed. Repeat. -\medskip -\item You can even call techmap recursively! -\medskip -\item Example use-cases: -\begin{itemize} -\item Using always blocks in map module: call {\tt proc} -\item Perform expensive optimizations (such as {\tt freduce}) on cells where -this is known to work well. -\item Interacting with custom commands. -\end{itemize} -\end{itemize} - -\scriptsize -PROTIP: Commands such as {\tt shell}, {\tt show -pause}, and {\tt dump} can be use -in the {\tt \_TECHMAP\_DO\_*} scripts for debugging map modules. -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip4.2cm -\hskip0.5cm\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/mymul.pdf} -\vss -} -\vskip-0.6cm -\begin{columns} -\column[t]{6cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/mymul_map.v} -\column[t]{4.2cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/mymul_test.v} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/mymul_test.ys} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, frame=single, language=ys, firstline=7, lastline=12]{PRESENTATION_ExAdv/mymul_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Handling constant inputs} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item The special parameters {\tt \_TECHMAP\_CONSTMSK\_\it \tt \_} and -{\tt \_TECHMAP\_CONSTVAL\_\it \tt \_} can be used to handle constant -input values to cells. -\medskip -\item The former contains 1-bits for all constant input bits on the port. -\medskip -\item The latter contains the constant bits or undef (x) for non-constant bits. -\medskip -\item Example use-cases: -\begin{itemize} -\item Converting arithmetic (for example multiply to shift) -\item Identify constant addresses or enable bits in memory interfaces. -\end{itemize} -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip5.2cm -\hskip6.5cm\includegraphics[width=5cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/mulshift.pdf} -\vss -} -\vskip-0.6cm -\begin{columns} -\column[t]{6cm} -\vskip-0.4cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/mulshift_map.v} -\column[t]{4.2cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/mulshift_test.v} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/mulshift_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Handling shorted inputs} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item The special parameters {\tt \_TECHMAP\_BITS\_CONNMAP\_} and -{\tt \_TECHMAP\_CONNMAP\_\it \tt \_} can be used to handle shorted inputs. -\medskip -\item Each bit of the port correlates to an {\tt \_TECHMAP\_BITS\_CONNMAP\_} bits wide -number in {\tt \_TECHMAP\_CONNMAP\_\it \tt \_}. -\medskip -\item Each unique signal bit is assigned its own number. Identical fields in the {\tt -\_TECHMAP\_CONNMAP\_\it \tt \_} parameters mean shorted signal bits. -\medskip -\item The numbers 0-3 are reserved for {\tt 0}, {\tt 1}, {\tt x}, and {\tt z} respectively. -\medskip -\item Example use-cases: -\begin{itemize} -\item Detecting shared clock or control signals in memory interfaces. -\item In some cases this can be used for for optimization. -\end{itemize} -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip4.5cm -\hskip6.5cm\includegraphics[width=5cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/addshift.pdf} -\vss -} -\vskip-0.6cm -\begin{columns} -\column[t]{6cm} -\vskip-0.4cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/addshift_map.v} -\column[t]{4.2cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/addshift_test.v} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/addshift_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Notes on using techmap} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item Don't use positional cell parameters in map modules. -\medskip -\item Don't try to implement basic logic optimization with techmap. \\ -{\small (So the OR-reduce using OR3X1 cells map was actually a bad example.)} -\medskip -\item You can use the {\tt \$\_\,\_}-prefix for internal cell types to avoid -collisions with the user-namespace. But always use two underscores or the -internal consistency checker will trigger on this cells. -\medskip -\item Techmap has two major use cases: -\begin{itemize} -\item Creating good logic-level representation of arithmetic functions. \\ -This also means using dedicated hardware resources such as half- and full-adder -cells in ASICS or dedicated carry logic in FPGAs. -\smallskip -\item Mapping of coarse-grain resources such as block memory or DSP cells. -\end{itemize} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Coarse-grain synthesis} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Intro to coarse-grain synthesis} - -\begin{frame}[fragile]{\subsubsecname} -In coarse-grain synthesis the target architecture has cells of the same -complexity or larger complexity than the internal RTL representation. - -For example: -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog] - wire [15:0] a, b; - wire [31:0] c, y; - assign y = a * b + c; -\end{lstlisting} - -This circuit contains two cells in the RTL representation: one multiplier and -one adder. In some architectures this circuit can be implemented using -a single circuit element, for example an FPGA DSP core. Coarse grain synthesis -is this mapping of groups of circuit elements to larger components. - -\bigskip -Fine-grain synthesis would be matching the circuit elements to smaller -components, such as LUTs, gates, or half- and full-adders. -\end{frame} - -\subsubsection{The extract pass} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item Like the {\tt techmap} pass, the {\tt extract} pass is called with -a map file. It compares the circuits inside the modules of the map file -with the design and looks for sub-circuits in the design that match any -of the modules in the map file. -\bigskip -\item If a match is found, the {\tt extract} pass will replace the matching -subcircuit with an instance of the module from the map file. -\bigskip -\item In a way the {\tt extract} pass is the inverse of the techmap pass. -\end{itemize} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- Example 1/2} -\vbox to 0cm{ -\vskip2cm -\begin{tikzpicture} - \node at (0,0) {\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_00a.pdf}}; - \node at (3,-3) {\includegraphics[width=8cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_00b.pdf}}; - \draw[yshift=0.2cm,thick,-latex] (1,-1) -- (2,-2); -\end{tikzpicture} -\vss} -\vskip-1.2cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/macc_simple_xmap.v} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys] -read_verilog macc_simple_test.v -hierarchy -check -top test - -extract -map macc_simple_xmap.v;; -\end{lstlisting} -\end{columns} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- Example 2/2} -\hfil\begin{tabular}{cc} -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test_01.v}}} & -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test_02.v}}} \\ -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_01a.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_02a.pdf}} \\ -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_01b.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_02b.pdf}} \\ -\end{tabular} -\end{frame} - -\subsubsection{The wrap-extract-unwrap method} - -\begin{frame}{\subsubsecname} -\scriptsize -Often a coarse-grain element has a constant bit-width, but can be used to -implement operations with a smaller bit-width. For example, a 18x25-bit multiplier -can also be used to implement 16x20-bit multiplication. - -\bigskip -A way of mapping such elements in coarse grain synthesis is the wrap-extract-unwrap method: - -\begin{itemize} -\item {\bf wrap} \\ -Identify candidate-cells in the circuit and wrap them in a cell with a constant -wider bit-width using {\tt techmap}. The wrappers use the same parameters as the original cell, so -the information about the original width of the ports is preserved. \\ -Then use the {\tt connwrappers} command to connect up the bit-extended in- and -outputs of the wrapper cells. -\item {\bf extract} \\ -Now all operations are encoded using the same bit-width as the coarse grain element. The {\tt -extract} command can be used to replace circuits with cells of the target architecture. -\item {\bf unwrap} \\ -The remaining wrapper cell can be unwrapped using {\tt techmap}. -\end{itemize} - -\bigskip -The following sides detail an example that shows how to map MACC operations of -arbitrary size to MACC cells with a 18x25-bit multiplier and a 48-bit adder (such as -the Xilinx DSP48 cells). -\end{frame} - -\subsubsection{Example: DSP48\_MACC} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 1/13} -Preconditioning: {\tt macc\_xilinx\_swap\_map.v} \\ -Make sure {\tt A} is the smaller port on all multipliers - -\begin{columns} -\column{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=15]{PRESENTATION_ExAdv/macc_xilinx_swap_map.v} -\column{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=16]{PRESENTATION_ExAdv/macc_xilinx_swap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 2/13} -Wrapping multipliers: {\tt macc\_xilinx\_wrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=23]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=24, lastline=46]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 3/13} -Wrapping adders: {\tt macc\_xilinx\_wrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=48, lastline=67]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=68, lastline=89]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 4/13} -Extract: {\tt macc\_xilinx\_xmap.v} - -\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=1, lastline=17]{PRESENTATION_ExAdv/macc_xilinx_xmap.v} - -.. simply use the same wrapping commands on this module as on the design to create a template for the {\tt extract} command. -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 5/13} -Unwrapping multipliers: {\tt macc\_xilinx\_unwrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=1, lastline=17]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=18, lastline=30]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 6/13} -Unwrapping adders: {\tt macc\_xilinx\_unwrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=32, lastline=48]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=49, lastline=61]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- 7/13} -\hfil\begin{tabular}{cc} -{\tt test1} & {\tt test2} \\ -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=1, lastline=6, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} & -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=8, lastline=13, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} \\ -$\downarrow$ & $\downarrow$ \\ -\end{tabular} -\vskip-0.5cm -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - read_verilog macc_xilinx_test.v - hierarchy -check -\end{lstlisting} -\vskip-0.5cm -\hfil\begin{tabular}{cc} -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2a.pdf}} \\ -\end{tabular} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- 8/13} -\hfil\begin{tabular}{cc} -{\tt test1} & {\tt test2} \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2a.pdf}} \\ -$\downarrow$ & $\downarrow$ \\ -\end{tabular} -\vskip-0.2cm -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - techmap -map macc_xilinx_swap_map.v ;; -\end{lstlisting} -\vskip-0.2cm -\hfil\begin{tabular}{cc} -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1b.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2b.pdf}} \\ -\end{tabular} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 9/13} -Wrapping in {\tt test1}: -\begin{columns} -\column[t]{5cm} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1b.pdf}}\vss} -\column[t]{6cm} -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -techmap -map macc_xilinx_wrap_map.v - -connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; -\end{lstlisting} -\end{columns} - -\vskip1cm -\hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 10/13} -Wrapping in {\tt test2}: -\begin{columns} -\column[t]{5cm} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2b.pdf}}\vss} -\column[t]{6cm} -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -techmap -map macc_xilinx_wrap_map.v - -connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; -\end{lstlisting} -\end{columns} - -\vskip1cm -\hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 11/13} -Extract in {\tt test1}: -\begin{columns} -\column[t]{4.5cm} -\vbox to 0cm{ -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -design -push -read_verilog macc_xilinx_xmap.v -techmap -map macc_xilinx_swap_map.v -techmap -map macc_xilinx_wrap_map.v;; -design -save __macc_xilinx_xmap -design -pop -\end{lstlisting} -\vss} -\column[t]{5.5cm} -\vskip-1cm -\begin{lstlisting}[linewidth=5.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -extract -constports -ignore_parameters \ - -map %__macc_xilinx_xmap \ - -swap $__add_wrapper A,B ;; -\end{lstlisting} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf}}\vss} -\end{columns} - -\vskip2cm -\hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1d.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 12/13} -Extract in {\tt test2}: -\begin{columns} -\column[t]{4.5cm} -\vbox to 0cm{ -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -design -push -read_verilog macc_xilinx_xmap.v -techmap -map macc_xilinx_swap_map.v -techmap -map macc_xilinx_wrap_map.v;; -design -save __macc_xilinx_xmap -design -pop -\end{lstlisting} -\vss} -\column[t]{5.5cm} -\vskip-1cm -\begin{lstlisting}[linewidth=5.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -extract -constports -ignore_parameters \ - -map %__macc_xilinx_xmap \ - -swap $__add_wrapper A,B ;; -\end{lstlisting} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf}}\vss} -\end{columns} - -\vskip2cm -\hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 13/13} -Unwrap in {\tt test2}: - -\hfil\begin{tikzpicture} -\node at (0,0) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf}}; -\node at (0,-4) {\includegraphics[width=8cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2e.pdf}}; -\node at (1,-1.7) {\begin{lstlisting}[linewidth=5.5cm, frame=single, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -techmap -map macc_xilinx_unwrap_map.v ;; -\end{lstlisting}}; -\draw[-latex] (4,-0.7) .. controls (5,-1.7) .. (4,-2.7); -\end{tikzpicture} -\end{frame} - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Automatic design changes} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Changing the design from Yosys} - -\begin{frame}{\subsubsecname} -Yosys commands can be used to change the design in memory. Examples of this are: - -\begin{itemize} -\item {\bf Changes in design hierarchy} \\ -Commands such as {\tt flatten} and {\tt submod} can be used to change the design hierarchy, i.e. -flatten the hierarchy or moving parts of a module to a submodule. This has applications in synthesis -scripts as well as in reverse engineering and analysis. - -\item {\bf Behavioral changes} \\ -Commands such as {\tt techmap} can be used to make behavioral changes to the design, for example -changing asynchronous resets to synchronous resets. This has applications in design space exploration -(evaluation of various architectures for one circuit). -\end{itemize} -\end{frame} - -\subsubsection{Example: Async reset to sync reset} - -\begin{frame}[t, fragile]{\subsubsecname} -The following techmap map file replaces all positive-edge async reset flip-flops with -positive-edge sync reset flip-flops. The code is taken from the example Yosys script -for ASIC synthesis of the Amber ARMv2 CPU. - -\begin{columns} -\column[t]{6cm} -\vbox to 0cm{ -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -(* techmap_celltype = "$adff" *) -module adff2dff (CLK, ARST, D, Q); - - parameter WIDTH = 1; - parameter CLK_POLARITY = 1; - parameter ARST_POLARITY = 1; - parameter ARST_VALUE = 0; - - input CLK, ARST; - input [WIDTH-1:0] D; - output reg [WIDTH-1:0] Q; - - wire [1023:0] _TECHMAP_DO_ = "proc"; - - wire _TECHMAP_FAIL_ = !CLK_POLARITY || !ARST_POLARITY; -\end{lstlisting} -\vss} -\column[t]{4cm} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -// ..continued.. - - - always @(posedge CLK) - if (ARST) - Q <= ARST_VALUE; - else - <= D; - -endmodule -\end{lstlisting} -\end{columns} - -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item A lot can be achieved in Yosys just with the standard set of commands. -\item The commands {\tt techmap} and {\tt extract} can be used to prototype many complex synthesis tasks. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile deleted file mode 100644 index 993a9d9e10c..00000000000 --- a/manual/PRESENTATION_ExAdv/Makefile +++ /dev/null @@ -1,28 +0,0 @@ - -all: select.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf addshift.pdf \ - macc_simple_xmap.pdf macc_xilinx_xmap.pdf - -select.pdf: select.v select.ys - ../../yosys select.ys - -red_or3x1.pdf: red_or3x1_* - ../../yosys red_or3x1_test.ys - -sym_mul.pdf: sym_mul_* - ../../yosys sym_mul_test.ys - -mymul.pdf: mymul_* - ../../yosys mymul_test.ys - -mulshift.pdf: mulshift_* - ../../yosys mulshift_test.ys - -addshift.pdf: addshift_* - ../../yosys addshift_test.ys - -macc_simple_xmap.pdf: macc_simple_*.v macc_simple_test.ys - ../../yosys macc_simple_test.ys - -macc_xilinx_xmap.pdf: macc_xilinx_*.v macc_xilinx_test.ys - ../../yosys macc_xilinx_test.ys - diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys deleted file mode 100644 index f3e8af4f046..00000000000 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys +++ /dev/null @@ -1,43 +0,0 @@ -read_verilog macc_xilinx_test.v -read_verilog -lib -icells macc_xilinx_unwrap_map.v -read_verilog -lib -icells macc_xilinx_xmap.v -hierarchy -check ;; - -show -prefix macc_xilinx_test1a -format pdf -notitle test1 -show -prefix macc_xilinx_test2a -format pdf -notitle test2 - -techmap -map macc_xilinx_swap_map.v;; - -show -prefix macc_xilinx_test1b -format pdf -notitle test1 -show -prefix macc_xilinx_test2b -format pdf -notitle test2 - -techmap -map macc_xilinx_wrap_map.v - -connwrappers -unsigned $__mul_wrapper Y Y_WIDTH \ - -unsigned $__add_wrapper Y Y_WIDTH;; - -show -prefix macc_xilinx_test1c -format pdf -notitle test1 -show -prefix macc_xilinx_test2c -format pdf -notitle test2 - -design -push -read_verilog macc_xilinx_xmap.v -techmap -map macc_xilinx_swap_map.v -techmap -map macc_xilinx_wrap_map.v;; -design -save __macc_xilinx_xmap -design -pop - -extract -constports -ignore_parameters \ - -map %__macc_xilinx_xmap \ - -swap $__add_wrapper A,B ;; - -show -prefix macc_xilinx_test1d -format pdf -notitle test1 -show -prefix macc_xilinx_test2d -format pdf -notitle test2 - -techmap -map macc_xilinx_unwrap_map.v;; - -show -prefix macc_xilinx_test1e -format pdf -notitle test1 -show -prefix macc_xilinx_test2e -format pdf -notitle test2 - -design -load __macc_xilinx_xmap -show -prefix macc_xilinx_xmap -format pdf -notitle - diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex deleted file mode 100644 index 3f5113e3cf4..00000000000 --- a/manual/PRESENTATION_ExOth.tex +++ /dev/null @@ -1,227 +0,0 @@ - -\section{Yosys by example -- Beyond Synthesis} - -\begin{frame} -\sectionpage -\end{frame} - -\begin{frame}{Overview} -This section contains 2 subsections: -\begin{itemize} -\item Interactive Design Investigation -\item Symbolic Model Checking -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Interactive Design Investigation} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\begin{frame}{\subsecname} -Yosys can also be used to investigate designs (or netlists created -from other tools). - -\begin{itemize} -\item -The selection mechanism (see slides ``Using Selections''), especially patterns such -as {\tt \%ci} and {\tt \%co}, can be used to figure out how parts of the design -are connected. - -\item -Commands such as {\tt submod}, {\tt expose}, {\tt splice}, \dots can be used -to transform the design into an equivalent design that is easier to analyse. - -\item -Commands such as {\tt eval} and {\tt sat} can be used to investigate the -behavior of the circuit. -\end{itemize} -\end{frame} - -\begin{frame}[t, fragile]{Example: Reorganizing a module} -\begin{columns} -\column[t]{4cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExOth/scrambler.v} -\column[t]{7cm} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] -read_verilog scrambler.v - -hierarchy; proc;; - -cd scrambler -submod -name xorshift32 \ - xs %c %ci %D %c %ci:+[D] %D \ - %ci*:-$dff xs %co %ci %d -\end{lstlisting} -\end{columns} - -\hfil\includegraphics[width=11cm,trim=0 0cm 0 1.5cm]{PRESENTATION_ExOth/scrambler_p01.pdf} - -\hfil\includegraphics[width=11cm,trim=0 0cm 0 2cm]{PRESENTATION_ExOth/scrambler_p02.pdf} -\end{frame} - -\begin{frame}[t, fragile]{Example: Analysis of circuit behavior} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -> read_verilog scrambler.v -> hierarchy; proc;; cd scrambler -> submod -name xorshift32 xs %c %ci %D %c %ci:+[D] %D %ci*:-$dff xs %co %ci %d - -> cd xorshift32 -> rename n2 in -> rename n1 out - -> eval -set in 1 -show out -Eval result: \out = 270369. - -> eval -set in 270369 -show out -Eval result: \out = 67634689. - -> sat -set out 632435482 -Signal Name Dec Hex Bin --------------------- ---------- ---------- ------------------------------------- -\in 745495504 2c6f5bd0 00101100011011110101101111010000 -\out 632435482 25b2331a 00100101101100100011001100011010 -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Symbolic Model Checking} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\begin{frame}{\subsecname} -Symbolic Model Checking (SMC) is used to formally prove that a circuit has -(or has not) a given property. - -\bigskip -One application is Formal Equivalence Checking: Proving that two circuits -are identical. For example this is a very useful feature when debugging custom -passes in Yosys. - -\bigskip -Other applications include checking if a module conforms to interface -standards. - -\bigskip -The {\tt sat} command in Yosys can be used to perform Symbolic Model Checking. -\end{frame} - -\begin{frame}[t]{Example: Formal Equivalence Checking (1/2)} -Remember the following example? -\vskip1em - -\vbox to 0cm{ -\vskip-0.3cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/techmap_01_map.v} -}\vbox to 0cm{ -\vskip-0.5cm -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExSyn/techmap_01.v} -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/techmap_01.ys}} - -\vskip5cm\hskip5cm -Lets see if it is correct.. -\end{frame} - -\begin{frame}[t, fragile]{Example: Formal Equivalence Checking (2/2)} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] -# read test design -read_verilog techmap_01.v -hierarchy -top test - -# create two version of the design: test_orig and test_mapped -copy test test_orig -rename test test_mapped - -# apply the techmap only to test_mapped -techmap -map techmap_01_map.v test_mapped - -# create a miter circuit to test equivalence -miter -equiv -make_assert -make_outputs test_orig test_mapped miter -flatten miter - -# run equivalence check -sat -verify -prove-asserts -show-inputs -show-outputs miter -\end{lstlisting} - -\dots -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -Solving problem with 945 variables and 2505 clauses.. -SAT proof finished - no model found: SUCCESS! -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{Example: Symbolic Model Checking (1/2)} -\small -The following AXI4 Stream Master has a bug. But the bug is not exposed if the -slave keeps {\tt tready} asserted all the time. (Something a test bench might do.) - -\medskip -Symbolic Model Checking can be used to expose the bug and find a sequence -of values for {\tt tready} that yield the incorrect behavior. - -\vskip-1em -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{5pt}{6pt}\selectfont, language=verilog]{PRESENTATION_ExOth/axis_master.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{5pt}{6pt}\selectfont, language=verilog]{PRESENTATION_ExOth/axis_test.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{Example: Symbolic Model Checking (2/2)} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] -read_verilog -sv axis_master.v axis_test.v -hierarchy -top axis_test - -proc; flatten;; -sat -seq 50 -prove-asserts -\end{lstlisting} - -\bigskip -\dots with unmodified {\tt axis\_master.v}: -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -Solving problem with 159344 variables and 442126 clauses.. -SAT proof finished - model found: FAIL! -\end{lstlisting} - -\bigskip -\dots with fixed {\tt axis\_master.v}: -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -Solving problem with 159144 variables and 441626 clauses.. -SAT proof finished - no model found: SUCCESS! -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Yosys provides useful features beyond synthesis. -\item The commands {\tt sat} and {\tt eval} can be used to analyse the behavior of a circuit. -\item The {\tt sat} command can also be used for symbolic model checking. -\item This can be useful for debugging and testing designs and Yosys extensions alike. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - diff --git a/manual/PRESENTATION_ExOth/.gitignore b/manual/PRESENTATION_ExOth/.gitignore deleted file mode 100644 index cf658897d52..00000000000 --- a/manual/PRESENTATION_ExOth/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.dot diff --git a/manual/PRESENTATION_ExOth/Makefile b/manual/PRESENTATION_ExOth/Makefile deleted file mode 100644 index 4864d8d5203..00000000000 --- a/manual/PRESENTATION_ExOth/Makefile +++ /dev/null @@ -1,16 +0,0 @@ - -all: scrambler_p01.pdf scrambler_p02.pdf equiv.log axis_test.log - -scrambler_p01.pdf: scrambler.ys scrambler.v - ../../yosys scrambler.ys - -scrambler_p02.pdf: scrambler_p01.pdf - -equiv.log: equiv.ys - ../../yosys -l equiv.log_new equiv.ys - mv equiv.log_new equiv.log - -axis_test.log: axis_test.ys axis_master.v axis_test.v - ../../yosys -l axis_test.log_new axis_test.ys - mv axis_test.log_new axis_test.log - diff --git a/manual/PRESENTATION_ExOth/equiv.ys b/manual/PRESENTATION_ExOth/equiv.ys deleted file mode 100644 index 8db0a88a5fb..00000000000 --- a/manual/PRESENTATION_ExOth/equiv.ys +++ /dev/null @@ -1,17 +0,0 @@ -# read test design -read_verilog ../PRESENTATION_ExSyn/techmap_01.v -hierarchy -top test - -# create two version of the design: test_orig and test_mapped -copy test test_orig -rename test test_mapped - -# apply the techmap only to test_mapped -techmap -map ../PRESENTATION_ExSyn/techmap_01_map.v test_mapped - -# create a miter circuit to test equivalence -miter -equiv -make_assert -make_outputs test_orig test_mapped miter -flatten miter - -# run equivalence check -sat -verify -prove-asserts -show-inputs -show-outputs miter diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex deleted file mode 100644 index d7cfdc6f2fc..00000000000 --- a/manual/PRESENTATION_ExSyn.tex +++ /dev/null @@ -1,515 +0,0 @@ - -\section{Yosys by example -- Synthesis} - -\begin{frame} -\sectionpage -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Typical Phases of a Synthesis Flow} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Reading and elaborating the design -\item Higher-level synthesis and optimization -\begin{itemize} -\item Converting {\tt always}-blocks to logic and registers -\item Perform coarse-grain optimizations (resource sharing, const folding, ...) -\item Handling of memories and other coarse-grain blocks -\item Extracting and optimizing finite state machines -\end{itemize} -\item Convert remaining logic to bit-level logic functions -\item Perform optimizations on bit-level logic functions -\item Map bit-level logic gates and registers to cell library -\item Write results to output file -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Reading the design} - -\begin{frame}[fragile]{\subsecname} -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -read_verilog file1.v -read_verilog -I include_dir -D enable_foo -D WIDTH=12 file2.v -read_verilog -lib cell_library.v - -verilog_defaults -add -I include_dir -read_verilog file3.v -read_verilog file4.v -verilog_defaults -clear - -verilog_defaults -push -verilog_defaults -add -I include_dir -read_verilog file5.v -read_verilog file6.v -verilog_defaults -pop -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Design elaboration} - -\begin{frame}[fragile]{\subsecname} -During design elaboration Yosys figures out how the modules are hierarchically -connected. It also re-runs the AST parts of the Verilog frontend to create -all needed variations of parametric modules. - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# simplest form. at least this version should be used after reading all input files -# -hierarchy - -# recommended form. fails if parts of the design hierarchy are missing, removes -# everything that is unreachable from the top module, and marks the top module. -# -hierarchy -check -top top_module -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt proc} command} - -\begin{frame}[fragile]{\subsecname} -The Verilog frontend converts {\tt always}-blocks to RTL netlists for the -expressions and ``processes'' for the control- and memory elements. - -\medskip -The {\tt proc} command transforms this ``processes'' to netlists of RTL -multiplexer and register cells. - -\medskip -The {\tt proc} command is actually a macro-command that calls the following -other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -proc_clean # remove empty branches and processes -proc_rmdead # remove unreachable branches -proc_init # special handling of "initial" blocks -proc_arst # identify modeling of async resets -proc_mux # convert decision trees to multiplexer networks -proc_dff # extract registers from processes -proc_clean # if all went fine, this should remove all the processes -\end{lstlisting} - -\medskip -Many commands can not operate on modules with ``processes'' in them. Usually -a call to {\tt proc} is the first command in the actual synthesis procedure -after design elaboration. -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- Example 1/3} -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_01.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_01.ys} -\end{columns} -\hfil\includegraphics[width=8cm,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/proc_01.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 2/3} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2.5cm]{PRESENTATION_ExSyn/proc_02.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_02.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_02.ys} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 3/3} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -1.5cm]{PRESENTATION_ExSyn/proc_03.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_03.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_03.v} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt opt} command} - -\begin{frame}[fragile]{\subsecname} -The {\tt opt} command implements a series of simple optimizations. It also -is a macro command that calls other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -opt_expr # const folding and simple expression rewriting -opt_merge -nomux # merging identical cells - -do - opt_muxtree # remove never-active branches from multiplexer tree - opt_reduce # consolidate trees of boolean ops to reduce functions - opt_merge # merging identical cells - opt_rmdff # remove/simplify registers with constant inputs - opt_clean # remove unused objects (cells, wires) from design - opt_expr # const folding and simple expression rewriting -while [changed design] -\end{lstlisting} - -The command {\tt clean} can be used as alias for {\tt opt\_clean}. And {\tt ;;} -can be used as shortcut for {\tt clean}. For example: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -proc; opt; memory; opt_expr;; fsm;; -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 1/4} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -0.5cm]{PRESENTATION_ExSyn/opt_01.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_01.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_01.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 2/4} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm 0cm]{PRESENTATION_ExSyn/opt_02.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_02.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_02.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 3/4} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2cm]{PRESENTATION_ExSyn/opt_03.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_03.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_03.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 4/4} -\vbox to 0cm{\hskip6cm\includegraphics[width=6cm,trim=0cm 0cm 0cm -3cm]{PRESENTATION_ExSyn/opt_04.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_04.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_04.ys} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{When to use {\tt opt} or {\tt clean}} - -\begin{frame}{\subsecname} -Usually it does not hurt to call {\tt opt} after each regular command in the -synthesis script. But it increases the synthesis time, so it is favourable -to only call {\tt opt} when an improvement can be achieved. - -\bigskip -The designs in {\tt yosys-bigsim} are a good playground for experimenting with -the effects of calling {\tt opt} in various places of the flow. - -\bigskip -It generally is a good idea to call {\tt opt} before inherently expensive -commands such as {\tt sat} or {\tt freduce}, as the possible gain is much -higher in this cases as the possible loss. - -\bigskip -The {\tt clean} command on the other hand is very fast and many commands leave -a mess (dangling signal wires, etc). For example, most commands do not remove -any wires or cells. They just change the connections and depend on a later -call to clean to get rid of the now unused objects. So the occasional {\tt ;;} -is a good idea in every synthesis script. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt memory} command} - -\begin{frame}[fragile]{\subsecname} -In the RTL netlist, memory reads and writes are individual cells. This makes -consolidating the number of ports for a memory easier. The {\tt memory} -transforms memories to an implementation. Per default that is logic for address -decoders and registers. It also is a macro command that calls other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# this merges registers into the memory read- and write cells. -memory_dff - -# this collects all read and write cells for a memory and transforms them -# into one multi-port memory cell. -memory_collect - -# this takes the multi-port memory cell and transforms it to address decoder -# logic and registers. This step is skipped if "memory" is called with -nomap. -memory_map -\end{lstlisting} - -\bigskip -Usually it is preferred to use architecture-specific RAM resources for memory. -For example: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -memory -nomap; techmap -map my_memory_map.v; memory_map -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 1/2} -\vbox to 0cm{\includegraphics[width=0.7\linewidth,trim=0cm 0cm 0cm -10cm]{PRESENTATION_ExSyn/memory_01.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_01.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_01.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 2/2} -\vbox to 0cm{\hfill\includegraphics[width=7.5cm,trim=0cm 0cm 0cm -5cm]{PRESENTATION_ExSyn/memory_02.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_02.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_02.ys} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt fsm} command} - -\begin{frame}[fragile]{\subsecname{}} -The {\tt fsm} command identifies, extracts, optimizes (re-encodes), and -re-synthesizes finite state machines. It again is a macro that calls -a series of other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -fsm_detect # unless got option -nodetect -fsm_extract - -fsm_opt -clean -fsm_opt - -fsm_expand # if got option -expand -clean # if got option -expand -fsm_opt # if got option -expand - -fsm_recode # unless got option -norecode - -fsm_info - -fsm_export # if got option -export -fsm_map # unless got option -nomap -\end{lstlisting} -\end{frame} - -\begin{frame}{\subsecname{} -- details} -Some details on the most important commands from the {\tt fsm\_*} group: - -\bigskip -The {\tt fsm\_detect} command identifies FSM state registers and marks them -with the {\tt (* fsm\_encoding = "auto" *)} attribute, if they do not have the -{\tt fsm\_encoding} set already. Mark registers with {\tt (* fsm\_encoding = -"none" *)} to disable FSM optimization for a register. - -\bigskip -The {\tt fsm\_extract} command replaces the entire FSM (logic and state -registers) with a {\tt \$fsm} cell. - -\bigskip -The commands {\tt fsm\_opt} and {\tt fsm\_recode} can be used to optimize the -FSM. - -\bigskip -Finally the {\tt fsm\_map} command can be used to convert the (optimized) {\tt -\$fsm} cell back to logic and registers. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt techmap} command} - -\begin{frame}[t]{\subsecname} -\vbox to 0cm{\includegraphics[width=12cm,trim=-15cm 0cm 0cm -20cm]{PRESENTATION_ExSyn/techmap_01.pdf}\vss} -\vskip-0.8cm -The {\tt techmap} command replaces cells with implementations given as -verilog source. For example implementing a 32 bit adder using 16 bit adders: - -\vbox to 0cm{ -\vskip-0.3cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/techmap_01_map.v} -}\vbox to 0cm{ -\vskip-0.5cm -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExSyn/techmap_01.v} -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/techmap_01.ys} -} -\end{frame} - -\begin{frame}[t]{\subsecname{} -- stdcell mapping} -When {\tt techmap} is used without a map file, it uses a built-in map file -to map all RTL cell types to a generic library of built-in logic gates and registers. - -\bigskip -\begin{block}{The built-in logic gate types are:} -{\tt \$\_NOT\_ \$\_AND\_ \$\_OR\_ \$\_XOR\_ \$\_MUX\_} -\end{block} - -\bigskip -\begin{block}{The register types are:} -{\tt \$\_SR\_NN\_ \$\_SR\_NP\_ \$\_SR\_PN\_ \$\_SR\_PP\_ \\ -\$\_DFF\_N\_ \$\_DFF\_P\_ \\ -\$\_DFF\_NN0\_ \$\_DFF\_NN1\_ \$\_DFF\_NP0\_ \$\_DFF\_NP1\_ \\ -\$\_DFF\_PN0\_ \$\_DFF\_PN1\_ \$\_DFF\_PP0\_ \$\_DFF\_PP1\_ \\ -\$\_DFFSR\_NNN\_ \$\_DFFSR\_NNP\_ \$\_DFFSR\_NPN\_ \$\_DFFSR\_NPP\_ \\ -\$\_DFFSR\_PNN\_ \$\_DFFSR\_PNP\_ \$\_DFFSR\_PPN\_ \$\_DFFSR\_PPP\_ \\ -\$\_DLATCH\_N\_ \$\_DLATCH\_P\_} -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt abc} command} - -\begin{frame}{\subsecname} -The {\tt abc} command provides an interface to ABC\footnote[frame]{\url{http://www.eecs.berkeley.edu/~alanmi/abc/}}, -an open source tool for low-level logic synthesis. - -\medskip -The {\tt abc} command processes a netlist of internal gate types and can perform: -\begin{itemize} -\item logic minimization (optimization) -\item mapping of logic to standard cell library (liberty format) -\item mapping of logic to k-LUTs (for FPGA synthesis) -\end{itemize} - -\medskip -Optionally {\tt abc} can process registers from one clock domain and perform -sequential optimization (such as register balancing). - -\medskip -ABC is also controlled using scripts. An ABC script can be specified to use -more advanced ABC features. It is also possible to write the design with -{\tt write\_blif} and load the output file into ABC outside of Yosys. -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- Example} -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/abc_01.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/abc_01.ys} -\end{columns} -\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/abc_01.pdf} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Other special-purpose mapping commands} - -\begin{frame}{\subsecname} -\begin{block}{\tt dfflibmap} -This command maps the internal register cell types to the register types -described in a liberty file. -\end{block} - -\bigskip -\begin{block}{\tt hilomap} -Some architectures require special driver cells for driving a constant hi or lo -value. This command replaces simple constants with instances of such driver cells. -\end{block} - -\bigskip -\begin{block}{\tt iopadmap} -Top-level input/outputs must usually be implemented using special I/O-pad cells. -This command inserts this cells to the design. -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Example Synthesis Script} - -\begin{frame}[fragile]{\subsecname} -\begin{columns} -\column[t]{4cm} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=ys] -# read and elaborate design -read_verilog cpu_top.v cpu_ctrl.v cpu_regs.v -read_verilog -D WITH_MULT cpu_alu.v -hierarchy -check -top cpu_top - -# high-level synthesis -proc; opt; fsm;; memory -nomap; opt - -# substitute block rams -techmap -map map_rams.v - -# map remaining memories -memory_map - -# low-level synthesis -techmap; opt; flatten;; abc -lut6 -techmap -map map_xl_cells.v - -# add clock buffers -select -set xl_clocks t:FDRE %x:+FDRE[C] t:FDRE %d -iopadmap -inpad BUFGP O:I @xl_clocks - -# add io buffers -select -set xl_nonclocks w:* t:BUFGP %x:+BUFGP[I] %d -iopadmap -outpad OBUF I:O -inpad IBUF O:I @xl_nonclocks - -# write synthesis results -write_edif synth.edif -\end{lstlisting} -\column[t]{6cm} -\vskip1cm -\begin{block}{Teaser / Outlook} -\small\parbox{6cm}{ -The weird {\tt select} expressions at the end of this script are discussed in -the next part (Section 3, ``Advanced Synthesis'') of this presentation.} -\end{block} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Yosys provides commands for each phase of the synthesis. -\item Each command solves a (more or less) simple problem. -\item Complex commands are often only front-ends to simple commands. -\item {\tt proc; opt; fsm; opt; memory; opt; techmap; opt; abc;;} -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - diff --git a/manual/PRESENTATION_ExSyn/.gitignore b/manual/PRESENTATION_ExSyn/.gitignore deleted file mode 100644 index cf658897d52..00000000000 --- a/manual/PRESENTATION_ExSyn/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.dot diff --git a/manual/PRESENTATION_ExSyn/Makefile b/manual/PRESENTATION_ExSyn/Makefile deleted file mode 100644 index c34eae3ffcf..00000000000 --- a/manual/PRESENTATION_ExSyn/Makefile +++ /dev/null @@ -1,20 +0,0 @@ - -TARGETS += proc_01 proc_02 proc_03 -TARGETS += opt_01 opt_02 opt_03 opt_04 -TARGETS += memory_01 memory_02 -TARGETS += techmap_01 -TARGETS += abc_01 - -all: $(addsuffix .pdf,$(TARGETS)) - -define make_pdf_template -$(1).pdf: $(1)*.v $(1)*.ys - ../../yosys -p 'script $(1).ys; show -notitle -prefix $(1) -format pdf' -endef - -$(foreach trg,$(TARGETS),$(eval $(call make_pdf_template,$(trg)))) - -clean: - rm -f $(addsuffix .pdf,$(TARGETS)) - rm -f $(addsuffix .dot,$(TARGETS)) - diff --git a/manual/PRESENTATION_ExSyn/abc_01.v b/manual/PRESENTATION_ExSyn/abc_01.v deleted file mode 100644 index 3bc6863538d..00000000000 --- a/manual/PRESENTATION_ExSyn/abc_01.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(input clk, a, b, c, - output reg y); - - reg [2:0] q1, q2; - always @(posedge clk) begin - q1 <= { a, b, c }; - q2 <= q1; - y <= ^q2; - end -endmodule diff --git a/manual/PRESENTATION_ExSyn/abc_01.ys b/manual/PRESENTATION_ExSyn/abc_01.ys deleted file mode 100644 index bb0b3780ff3..00000000000 --- a/manual/PRESENTATION_ExSyn/abc_01.ys +++ /dev/null @@ -1,5 +0,0 @@ -read_verilog abc_01.v -read_verilog -lib abc_01_cells.v -hierarchy -check -top test -proc; opt; techmap -abc -dff -liberty abc_01_cells.lib;; diff --git a/manual/PRESENTATION_ExSyn/abc_01_cells.lib b/manual/PRESENTATION_ExSyn/abc_01_cells.lib deleted file mode 100644 index bf6b34788d0..00000000000 --- a/manual/PRESENTATION_ExSyn/abc_01_cells.lib +++ /dev/null @@ -1,54 +0,0 @@ -// test comment -/* test comment */ -library(demo) { - cell(BUF) { - area: 6; - pin(A) { direction: input; } - pin(Y) { direction: output; - function: "A"; } - } - cell(NOT) { - area: 3; - pin(A) { direction: input; } - pin(Y) { direction: output; - function: "A'"; } - } - cell(NAND) { - area: 4; - pin(A) { direction: input; } - pin(B) { direction: input; } - pin(Y) { direction: output; - function: "(A*B)'"; } - } - cell(NOR) { - area: 4; - pin(A) { direction: input; } - pin(B) { direction: input; } - pin(Y) { direction: output; - function: "(A+B)'"; } - } - cell(DFF) { - area: 18; - ff(IQ, IQN) { clocked_on: C; - next_state: D; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - } - cell(DFFSR) { - area: 18; - ff(IQ, IQN) { clocked_on: C; - next_state: D; - preset: S; - clear: R; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(S) { direction: input; } - pin(R) { direction: input; } - } -} diff --git a/manual/PRESENTATION_ExSyn/abc_01_cells.v b/manual/PRESENTATION_ExSyn/abc_01_cells.v deleted file mode 100644 index 44409479895..00000000000 --- a/manual/PRESENTATION_ExSyn/abc_01_cells.v +++ /dev/null @@ -1,40 +0,0 @@ - -module BUF(A, Y); -input A; -output Y = A; -endmodule - -module NOT(A, Y); -input A; -output Y = ~A; -endmodule - -module NAND(A, B, Y); -input A, B; -output Y = ~(A & B); -endmodule - -module NOR(A, B, Y); -input A, B; -output Y = ~(A | B); -endmodule - -module DFF(C, D, Q); -input C, D; -output reg Q; -always @(posedge C) - Q <= D; -endmodule - -module DFFSR(C, D, Q, S, R); -input C, D, S, R; -output reg Q; -always @(posedge C, posedge S, posedge R) - if (S) - Q <= 1'b1; - else if (R) - Q <= 1'b0; - else - Q <= D; -endmodule - diff --git a/manual/PRESENTATION_ExSyn/opt_01.v b/manual/PRESENTATION_ExSyn/opt_01.v deleted file mode 100644 index 5d3c1ea49fc..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_01.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input A, B, output Y); -assign Y = A ? A ? B : 1'b1 : B; -endmodule diff --git a/manual/PRESENTATION_ExSyn/opt_01.ys b/manual/PRESENTATION_ExSyn/opt_01.ys deleted file mode 100644 index 34ed123bee4..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_01.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_01.v -hierarchy -check -top test -opt diff --git a/manual/PRESENTATION_ExSyn/opt_02.v b/manual/PRESENTATION_ExSyn/opt_02.v deleted file mode 100644 index 762fc1a8993..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_02.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input A, output Y, Z); -assign Y = A == A, Z = A != A; -endmodule diff --git a/manual/PRESENTATION_ExSyn/opt_02.ys b/manual/PRESENTATION_ExSyn/opt_02.ys deleted file mode 100644 index fc92a636ed4..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_02.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_02.v -hierarchy -check -top test -opt diff --git a/manual/PRESENTATION_ExSyn/opt_03.v b/manual/PRESENTATION_ExSyn/opt_03.v deleted file mode 100644 index 134161bb80a..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_03.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [3:0] A, B, - output [3:0] Y, Z); -assign Y = A + B, Z = B + A; -endmodule diff --git a/manual/PRESENTATION_ExSyn/opt_03.ys b/manual/PRESENTATION_ExSyn/opt_03.ys deleted file mode 100644 index 282f06ddecc..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_03.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_03.v -hierarchy -check -top test -opt diff --git a/manual/PRESENTATION_ExSyn/opt_04.v b/manual/PRESENTATION_ExSyn/opt_04.v deleted file mode 100644 index 2ed44763953..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_04.v +++ /dev/null @@ -1,19 +0,0 @@ -module test(input CLK, ARST, - output [7:0] Q1, Q2, Q3); - -wire NO_CLK = 0; - -always @(posedge CLK, posedge ARST) - if (ARST) - Q1 <= 42; - -always @(posedge NO_CLK, posedge ARST) - if (ARST) - Q2 <= 42; - else - Q2 <= 23; - -always @(posedge CLK) - Q3 <= 42; - -endmodule diff --git a/manual/PRESENTATION_ExSyn/opt_04.ys b/manual/PRESENTATION_ExSyn/opt_04.ys deleted file mode 100644 index f5ddae29f20..00000000000 --- a/manual/PRESENTATION_ExSyn/opt_04.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_04.v -hierarchy -check -top test -proc; opt diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex deleted file mode 100644 index 1c3b79fa034..00000000000 --- a/manual/PRESENTATION_Intro.tex +++ /dev/null @@ -1,956 +0,0 @@ - -\section{Introduction to Yosys} - -\begin{frame} -\sectionpage -\end{frame} - -\iffalse -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Representations of (digital) Circuits} - -\begin{frame}[t]{\subsecname} -\begin{itemize} - \item Graphical - \begin{itemize} - \item \alert<1>{Schematic Diagram} - \item \alert<2>{Physical Layout} - \end{itemize} - \bigskip - \item Non-graphical - \begin{itemize} - \item \alert<3>{Netlists} - \item \alert<4>{Hardware Description Languages (HDLs)} - \end{itemize} -\end{itemize} -\bigskip -\begin{block}{Definition: -\only<1>{Schematic Diagram}% -\only<2>{Physical Layout}% -\only<3>{Netlists}% -\only<4>{Hardware Description Languages (HDLs)}} -\only<1>{ - Graphical representation of the circuit topology. Circuit elements - are represented by symbols and electrical connections by lines. The geometric - layout is for readability only. -}% -\only<2>{ - The actual physical geometry of the device (PCB or ASIC manufacturing masks). - This is the final product of the design process. -}% -\only<3>{ - A list of circuit elements and a list of connections. This is the raw circuit - topology. -}% -\only<4>{ - Computer languages (like programming languages) that can be used to describe - circuits. HDLs are much more powerful in describing huge circuits than - schematic diagrams. -}% -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\fi - -\subsection{Levels of Abstraction for Digital Circuits} - -\begin{frame}[t]{\subsecname} -\begin{itemize} - \item \alert<1>{System Level} - \item \alert<2>{High Level} - \item \alert<3>{Behavioral Level} - \item \alert<4>{Register-Transfer Level (RTL)} - \item \alert<5>{Logical Gate Level} - \item \alert<6>{Physical Gate Level} - \item \alert<7>{Switch Level} -\end{itemize} -\bigskip -\begin{block}{Definition: -\only<1>{System Level}% -\only<2>{High Level}% -\only<3>{Behavioral Level}% -\only<4>{Register-Transfer Level (RTL)}% -\only<5>{Logical Gate Level}% -\only<6>{Physical Gate Level}% -\only<7>{Switch Level}} -\only<1>{ - Overall view of the circuit. E.g. block-diagrams or instruction-set architecture descriptions. -}% -\only<2>{ - Functional implementation of circuit in high-level programming language (C, C++, SystemC, Matlab, Python, etc.). -}% -\only<3>{ - Cycle-accurate description of circuit in hardware description language (Verilog, VHDL, etc.). -}% -\only<4>{ - List of registers (flip-flops) and logic functions that calculate the next state from the previous one. Usually - a netlist utilizing high-level cells such as adders, multipliers, multiplexer, etc. -}% -\only<5>{ - Netlist of single-bit registers and basic logic gates (such as AND, OR, - NOT, etc.). Popular form: And-Inverter-Graphs (AIGs) with pairs of primary - inputs and outputs for each register bit. -}% -\only<6>{ - Netlist of cells that actually are available on the target architecture - (such as CMOS gates in an ASIC or LUTs in an FPGA). Optimized for - area, power, and/or speed (static timing or number of logic levels). -}% -\only<7>{ - Netlist of individual transistors. -}% -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Digital Circuit Synthesis} - -\begin{frame}{\subsecname} - Synthesis Tools (such as Yosys) can transform HDL code to circuits: - - \bigskip - \begin{center} - \begin{tikzpicture}[scale=0.8, every node/.style={transform shape}] - \tikzstyle{lvl} = [draw, fill=MyBlue, rectangle, minimum height=2em, minimum width=15em] - \node[lvl] (sys) {System Level}; - \node[lvl] (hl) [below of=sys] {High Level}; - \node[lvl] (beh) [below of=hl] {Behavioral Level}; - \node[lvl] (rtl) [below of=beh] {Register-Transfer Level (RTL)}; - \node[lvl] (lg) [below of=rtl] {Logical Gate Level}; - \node[lvl] (pg) [below of=lg] {Physical Gate Level}; - \node[lvl] (sw) [below of=pg] {Switch Level}; - - \draw[dotted] (sys.east) -- ++(1,0) coordinate (sysx); - \draw[dotted] (hl.east) -- ++(1,0) coordinate (hlx); - \draw[dotted] (beh.east) -- ++(1,0) coordinate (behx); - \draw[dotted] (rtl.east) -- ++(1,0) coordinate (rtlx); - \draw[dotted] (lg.east) -- ++(1,0) coordinate (lgx); - \draw[dotted] (pg.east) -- ++(1,0) coordinate (pgx); - \draw[dotted] (sw.east) -- ++(1,0) coordinate (swx); - - \draw[gray,|->] (sysx) -- node[right] {System Design} (hlx); - \draw[|->|] (hlx) -- node[right] {High Level Synthesis (HLS)} (behx); - \draw[->|] (behx) -- node[right] {Behavioral Synthesis} (rtlx); - \draw[->|] (rtlx) -- node[right] {RTL Synthesis} (lgx); - \draw[->|] (lgx) -- node[right] {Logic Synthesis} (pgx); - \draw[gray,->|] (pgx) -- node[right] {Cell Library} (swx); - - \draw[dotted] (behx) -- ++(4,0) coordinate (a); - \draw[dotted] (pgx) -- ++(4,0) coordinate (b); - \draw[|->|] (a) -- node[right] {Yosys} (b); - \end{tikzpicture} - \end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{What Yosys can and can't do} - -\begin{frame}{\subsecname} - -Things Yosys can do: -\begin{itemize} -\item Read and process (most of) modern Verilog-2005 code. -\item Perform all kinds of operations on netlist (RTL, Logic, Gate). -\item Perform logic optimizations and gate mapping with ABC\footnote[frame]{\url{http://www.eecs.berkeley.edu/~alanmi/abc/}}. -\end{itemize} - -\bigskip -Things Yosys can't do: -\begin{itemize} -\item Process high-level languages such as C/C++/SystemC. -\item Create physical layouts (place\&route). -\end{itemize} - -\bigskip -A typical flow combines Yosys with with a low-level implementation tool, such -as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC designs. - -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Yosys Data- and Control-Flow} - -\begin{frame}{\subsecname} - A (usually short) synthesis script controls Yosys. - - This scripts contain three types of commands: - \begin{itemize} - \item {\bf Frontends}, that read input files (usually Verilog). - \item {\bf Passes}, that perform transformations on the design in memory. - \item {\bf Backends}, that write the design in memory to a file (various formats are available: Verilog, BLIF, EDIF, SPICE, BTOR, \dots). - \end{itemize} - - \bigskip - \begin{center} - \begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \path (-1.5,3) coordinate (cursor); - \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); - \draw[fill=orange!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Frontend} ++(1,3) coordinate (cursor); - \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); - \draw[fill=green!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Pass} ++(1,3) coordinate (cursor); - \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); - \draw[fill=green!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Pass} ++(1,3) coordinate (cursor); - \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); - \draw[fill=green!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Pass} ++(1,3) coordinate (cursor); - \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); - \draw[fill=orange!10] ($ (cursor) + (1,-3) $) rectangle node[rotate=90] {Backend} ++(1,3) coordinate (cursor); - \draw[-latex] ($ (cursor) + (0,-1.5) $) -- ++(1,0); - - \path (-3,-0.5) coordinate (cursor); - \draw (cursor) -- node[below] {HDL} ++(3,0) coordinate (cursor); - \draw[|-|] (cursor) -- node[below] {Internal Format (RTLIL)} ++(8,0) coordinate (cursor); - \draw (cursor) -- node[below] {Netlist} ++(3,0); - - \path (-3,3.5) coordinate (cursor); - \draw[-] (cursor) -- node[above] {High-Level} ++(3,0) coordinate (cursor); - \draw[-] (cursor) -- ++(8,0) coordinate (cursor); - \draw[->] (cursor) -- node[above] {Low-Level} ++(3,0); - \end{tikzpicture} - \end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Program Components and Data Formats} - -\begin{frame}{\subsecname} - \begin{center} - \begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{process} = [draw, fill=green!10, rectangle, minimum height=3em, minimum width=10em, node distance=15em] - \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em] - \node[process] (vlog) {Verilog Frontend}; - \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend}; - \node[process] (ilang) [right of=vhdl] {Other Frontends}; - \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST}; - \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend}; - \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; - \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; - \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; - \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; - \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; - - \draw[-latex] (vlog) -- (ast); - \draw[-latex] (vhdl) -- (ast); - \draw[-latex] (ast) -- (astfe); - \draw[-latex] (astfe) -- (rtlil); - \draw[-latex] (ilang) -- (rtlil); - \draw[latex-latex] (rtlil) -- (pass); - \draw[-latex] (rtlil) -- (vlbe); - \draw[-latex] (rtlil) -- (ilangbe); - \draw[-latex] (rtlil) -- (otherbe); - \end{tikzpicture} - \end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Example Project} - -\begin{frame}[t]{\subsecname} -The following slides cover an example project. This project contains three files: -\begin{itemize} -\item A simple ASIC synthesis script -\item A digital design written in Verilog -\item A simple CMOS cell library -\end{itemize} -\vfill -Direct link to the files: \\ \footnotesize -\url{https://github.com/YosysHQ/yosys/tree/master/manual/PRESENTATION_Intro} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{frame}[t]{\subsecname{} -- Synthesis Script} - -\setbeamercolor{alerted text}{fg=white,bg=red} - -\begin{minipage}[t]{6cm} -\tt\scriptsize -{\color{YosysGreen}\# read design}\\ -\boxalert<1>{read\_verilog counter.v}\\ -\boxalert<2>{hierarchy -check -top counter} - -\medskip -{\color{YosysGreen}\# the high-level stuff}\\ -\boxalert<3>{proc}; \boxalert<4>{opt}; \boxalert<5>{fsm}; \boxalert<6>{opt}; \boxalert<7>{memory}; \boxalert<8>{opt} - -\medskip -{\color{YosysGreen}\# mapping to internal cell library}\\ -\boxalert<9>{techmap}; \boxalert<10>{opt} -\end{minipage} -\begin{minipage}[t]{5cm} -\tt\scriptsize -{\color{YosysGreen}\# mapping flip-flops to mycells.lib}\\ -\boxalert<11>{dfflibmap -liberty mycells.lib} - -\medskip -{\color{YosysGreen}\# mapping logic to mycells.lib}\\ -\boxalert<12>{abc -liberty mycells.lib} - -\medskip -{\color{YosysGreen}\# cleanup}\\ -\boxalert<13>{clean} - -\medskip -{\color{YosysGreen}\# write synthesized design}\\ -\boxalert<14>{write\_verilog synth.v} -\end{minipage} - -\vskip1cm - -\begin{block}{Command: \tt -\only<1>{read\_verilog counter.v}% -\only<2>{hierarchy -check -top counter}% -\only<3>{proc}% -\only<4>{opt}% -\only<5>{fsm}% -\only<6>{opt}% -\only<7>{memory}% -\only<8>{opt}% -\only<9>{techmap}% -\only<10>{opt}% -\only<11>{dfflibmap -liberty mycells.lib}% -\only<12>{abc -liberty mycells.lib}% -\only<13>{clean}% -\only<14>{write\_verilog synth.v}} -\only<1>{ - Read Verilog source file and convert to internal representation. -}% -\only<2>{ - Elaborate the design hierarchy. Should always be the first - command after reading the design. Can re-run AST front-end. -}% -\only<3>{ - Convert ``processes'' (the internal representation of behavioral - Verilog code) into multiplexers and registers. -}% -\only<4>{ - Perform some basic optimizations and cleanups. -}% -\only<5>{ - Analyze and optimize finite state machines. -}% -\only<6>{ - Perform some basic optimizations and cleanups. -}% -\only<7>{ - Analyze memories and create circuits to implement them. -}% -\only<8>{ - Perform some basic optimizations and cleanups. -}% -\only<9>{ - Map coarse-grain RTL cells (adders, etc.) to fine-grain - logic gates (AND, OR, NOT, etc.). -}% -\only<10>{ - Perform some basic optimizations and cleanups. -}% -\only<11>{ - Map registers to available hardware flip-flops. -}% -\only<12>{ - Map logic to available hardware gates. -}% -\only<13>{ - Clean up the design (just the last step of {\tt opt}). -}% -\only<14>{ - Write final synthesis result to output file. -}% -\end{block} - -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{frame}[fragile]{\subsecname{} -- Verilog Source: \tt counter.v} -\lstinputlisting[xleftmargin=1cm, language=Verilog]{PRESENTATION_Intro/counter.v} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- Cell Library: \tt mycells.lib} -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=liberty, lastline=20]{PRESENTATION_Intro/mycells.lib} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=liberty, firstline=21]{PRESENTATION_Intro/mycells.lib} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Running the Synthesis Script} - -\begin{frame}[t, fragile]{\subsecname{} -- Step 1/4} -\begin{verbatim} -read_verilog counter.v -hierarchy -check -top counter -\end{verbatim} - -\vfill -\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_Intro/counter_00.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Step 2/4} -\begin{verbatim} -proc; opt; fsm; opt; memory; opt -\end{verbatim} - -\vfill -\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_Intro/counter_01.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Step 3/4} -\begin{verbatim} -techmap; opt -\end{verbatim} - -\vfill -\includegraphics[width=\linewidth,trim=0 0cm 0 2cm]{PRESENTATION_Intro/counter_02.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Step 4/4} -\begin{verbatim} -dfflibmap -liberty mycells.lib -abc -liberty mycells.lib -clean -\end{verbatim} - -\vfill\hfil -\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_Intro/counter_03.pdf} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The synth command} - -\begin{frame}[fragile]{\subsecname{}} -Yosys contains a default (recommended example) synthesis script in form of the -{\tt synth} command. The following commands are executed by this synthesis command: - -\begin{columns} -\column[t]{5cm} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -begin: - hierarchy -check [-top ] - -coarse: - proc - opt - wreduce - alumacc - share - opt - fsm - opt -fast - memory -nomap - opt_clean -\end{lstlisting} -\column[t]{5cm} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -fine: - opt -fast -full - memory_map - opt -full - techmap - opt -fast - -abc: - abc -fast - opt -fast -\end{lstlisting} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Yosys Commands} - -\begin{frame}[fragile]{\subsecname{} 1/3 \hspace{0pt plus 1 filll} (excerpt)} -Command reference: -\begin{itemize} -\item Use ``{\tt help}'' for a command list and ``{\tt help \it command}'' for details. -\item Or run ``{\tt yosys -H}'' or ``{\tt yosys -h \it command}''. -\item Or go to \url{https://yosyshq.net/yosys/documentation.html}. -\end{itemize} - -\bigskip -Commands for design navigation and investigation: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - cd # a shortcut for 'select -module ' - ls # list modules or objects in modules - dump # print parts of the design in RTLIL format - show # generate schematics using graphviz - select # modify and view the list of selected objects -\end{lstlisting} - -\bigskip -Commands for executing scripts or entering interactive mode: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - shell # enter interactive command mode - history # show last interactive commands - script # execute commands from script file - tcl # execute a TCL script file -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 2/3 \hspace{0pt plus 1 filll} (excerpt)} -Commands for reading and elaborating the design: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - read_rtlil # read modules from RTLIL file - read_verilog # read modules from Verilog file - hierarchy # check, expand and clean up design hierarchy -\end{lstlisting} - -\bigskip -Commands for high-level synthesis: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - proc # translate processes to netlists - fsm # extract and optimize finite state machines - memory # translate memories to basic cells - opt # perform simple optimizations -\end{lstlisting} - -\bigskip -Commands for technology mapping: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - techmap # generic technology mapper - abc # use ABC for technology mapping - dfflibmap # technology mapping of flip-flops - hilomap # technology mapping of constant hi- and/or lo-drivers - iopadmap # technology mapping of i/o pads (or buffers) - flatten # flatten design -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 3/3 \hspace{0pt plus 1 filll} (excerpt)} -Commands for writing the results: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - write_blif # write design to BLIF file - write_btor # write design to BTOR file - write_edif # write design to EDIF netlist file - write_rtlil # write design to RTLIL file - write_spice # write design to SPICE netlist file - write_verilog # write design to Verilog file -\end{lstlisting} - -\bigskip -Script-Commands for standard synthesis tasks: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - synth # generic synthesis script - synth_xilinx # synthesis for Xilinx FPGAs -\end{lstlisting} - -\bigskip -Commands for model checking: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - sat # solve a SAT problem in the circuit - miter # automatically create a miter circuit - scc # detect strongly connected components (logic loops) -\end{lstlisting} - -\bigskip -... and many many more. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{More Verilog Examples} - -\begin{frame}[fragile]{\subsecname{} 1/3} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module detectprime(a, y); - input [4:0] a; - output y; - - integer i, j; - reg [31:0] lut; - - initial begin - for (i = 0; i < 32; i = i+1) begin - lut[i] = i > 1; - for (j = 2; j*j <= i; j = j+1) - if (i % j == 0) - lut[i] = 0; - end - end - - assign y = lut[a]; -endmodule -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 2/3} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module carryadd(a, b, y); - parameter WIDTH = 8; - input [WIDTH-1:0] a, b; - output [WIDTH-1:0] y; - - genvar i; - generate - for (i = 0; i < WIDTH; i = i+1) begin:STAGE - wire IN1 = a[i], IN2 = b[i]; - wire C, Y; - if (i == 0) - assign C = IN1 & IN2, Y = IN1 ^ IN2; - else - assign C = (IN1 & IN2) | ((IN1 | IN2) & STAGE[i-1].C), - Y = IN1 ^ IN2 ^ STAGE[i-1].C; - assign y[i] = Y; - end - endgenerate -endmodule -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 3/3} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{7pt}{8.5pt}\selectfont, language=Verilog] -module cam(clk, wr_enable, wr_addr, wr_data, rd_data, rd_addr, rd_match); - parameter WIDTH = 8; - parameter DEPTH = 16; - localparam ADDR_BITS = $clog2(DEPTH-1); - - input clk, wr_enable; - input [ADDR_BITS-1:0] wr_addr; - input [WIDTH-1:0] wr_data, rd_data; - output reg [ADDR_BITS-1:0] rd_addr; - output reg rd_match; - - integer i; - reg [WIDTH-1:0] mem [0:DEPTH-1]; - - always @(posedge clk) begin - rd_addr <= 'bx; - rd_match <= 0; - for (i = 0; i < DEPTH; i = i+1) - if (mem[i] == rd_data) begin - rd_addr <= i; - rd_match <= 1; - end - if (wr_enable) - mem[wr_addr] <= wr_data; - end -endmodule -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Currently unsupported Verilog-2005 language features} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Tri-state logic -\item The wor/wand wire types (maybe for 0.5) -\item Latched logic (is synthesized as logic with feedback loops) -\item Some non-synthesizable features that should be ignored in synthesis are not supported by the parser and cause a parser error (file a bug report if you encounter this problem) -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Verification of Yosys} - -\begin{frame}{\subsecname} -Continuously checking the correctness of Yosys and making sure that new features -do not break old ones is a high priority in Yosys. - -\bigskip -Two external test suites have been built for Yosys: VlogHammer and yosys-bigsim -(see next slides) - -\bigskip -In addition to that, yosys comes with $\approx\!200$ test cases used in ``{\tt make test}''. - -\bigskip -A debug build of Yosys also contains a lot of asserts and checks the integrity of -the internal state after each command. -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- VlogHammer} -VlogHammer is a Verilog regression test suite developed to test the different -subsystems in Yosys by comparing them to each other and to the output created -by some other tools (Xilinx Vivado, Xilinx XST, Altera Quartus II, ...). - -\bigskip -Yosys Subsystems tested: Verilog frontend, const folding, const eval, technology mapping, -simulation models, SAT models. - -\bigskip -Thousands of auto-generated test cases containing code such as: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -assign y9 = $signed(((+$signed((^(6'd2 ** a2))))<$unsigned($unsigned(((+a3)))))); -assign y10 = (-((+((+{2{(~^p13)}})))^~(!{{b5,b1,a0},(a1&p12),(a4+a3)}))); -assign y11 = (~&(-{(-3'sd3),($unsigned($signed($unsigned({p0,b4,b1}))))})); -\end{lstlisting} - -\bigskip -Some bugs in Yosys where found and fixed thanks to VlogHammer. Over 50 bugs in -the other tools used as external reference where found and reported so far. -\end{frame} - -\begin{frame}{\subsecname{} -- yosys-bigsim} -yosys-bigsim is a collection of real-world open-source Verilog designs and test -benches. yosys-bigsim compares the testbench outputs of simulations of the original -Verilog code and synthesis results. - -\bigskip -The following designs are included in yosys-bigsim (excerpt): -\begin{itemize} -\item {\tt openmsp430} -- an MSP430 compatible 16 bit CPU -\item {\tt aes\_5cycle\_2stage} -- an AES encryption core -\item {\tt softusb\_navre} -- an AVR compatible 8 bit CPU -\item {\tt amber23} -- an ARMv2 compatible 32 bit CPU -\item {\tt lm32} -- another 32 bit CPU from Lattice Semiconductor -\item {\tt verilog-pong} -- a hardware pong game with VGA output -\item {\tt elliptic\_curve\_group} -- ECG point-add and point-scalar-mul core -\item {\tt reed\_solomon\_decoder} -- a Reed-Solomon Error Correction Decoder -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Benefits of Open Source HDL Synthesis} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Cost (also applies to ``free as in free beer'' solutions) -\item Availability and Reproducibility -\item Framework- and all-in-one-aspects -\item Educational Tool -\end{itemize} - -\bigskip - -Yosys is open source under the ISC license. -\end{frame} - -\begin{frame}{\subsecname{} -- 1/3} -\begin{itemize} -\item Cost (also applies to ``free as in free beer'' solutions): \smallskip\par -Today the cost for a mask set in $\unit[180]{nm}$ technology is far less than -the cost for the design tools needed to design the mask layouts. Open Source -ASIC flows are an important enabler for ASIC-level Open Source Hardware. - -\bigskip -\item Availability and Reproducibility: \smallskip\par -If you are a researcher who is publishing, you want to use tools that everyone -else can also use. Even if most universities have access to all major -commercial tools, you usually do not have easy access to the version that was -used in a research project a couple of years ago. With Open Source tools you -can even release the source code of the tool you have used alongside your data. -\end{itemize} -\end{frame} - -\begin{frame}{\subsecname{} -- 2/3} -\begin{itemize} -\item Framework: \smallskip\par -Yosys is not only a tool. It is a framework that can be used as basis for other -developments, so researchers and hackers alike do not need to re-invent the -basic functionality. Extensibility was one of Yosys' design goals. - -\bigskip -\item All-in-one: \smallskip\par -Because of the framework characteristics of Yosys, an increasing number of features -become available in one tool. Yosys not only can be used for circuit synthesis but -also for formal equivalence checking, SAT solving, and for circuit analysis, to -name just a few other application domains. With proprietary software one needs to -learn a new tool for each of these applications. -\end{itemize} -\end{frame} - -\begin{frame}{\subsecname{} -- 3/3} -\begin{itemize} -\item Educational Tool: \smallskip\par -Proprietary synthesis tools are at times very secretive about their inner -workings. They often are ``black boxes''. Yosys is very open about its -internals and it is easy to observe the different steps of synthesis. -\end{itemize} - -\bigskip -\begin{block}{Yosys is licensed under the ISC license:} -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Typical Applications for Yosys} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Synthesis of final production designs -\item Pre-production synthesis (trial runs before investing in other tools) -\item Conversion of full-featured Verilog to simple Verilog -\item Conversion of Verilog to other formats (BLIF, BTOR, etc) -\item Demonstrating synthesis algorithms (e.g. for educational purposes) -\item Framework for experimenting with new algorithms -\item Framework for building custom flows\footnote[frame]{Not limited to synthesis -but also formal verification, reverse engineering, ...} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Projects (that I know of) using Yosys} - -\begin{frame}{\subsecname{} -- (1/2)} -\begin{itemize} -\item Ongoing PhD project on coarse grain synthesis \\ -{\setlength{\parindent}{0.5cm}\footnotesize -Johann Glaser and C. Wolf. Methodology and Example-Driven Interconnect -Synthesis for Designing Heterogeneous Coarse-Grain Reconfigurable -Architectures. In Jan Haase, editor, \it Models, Methods, and Tools for Complex -Chip Design. Lecture Notes in Electrical Engineering. Volume 265, 2014, pp -201-221. Springer, 2013.} - -\bigskip -\item I know several people that use Yosys simply as Verilog frontend for other -flows (using either the BLIF and BTOR backends). - -\bigskip -\item I know some analog chip designers that use Yosys for small digital -control logic because it is simpler than setting up a commercial flow. -\end{itemize} -\end{frame} - -\begin{frame}{\subsecname{} -- (2/2)} -\begin{itemize} -\item Efabless -\begin{itemize} -\smallskip \item Not much information on the website (\url{http://efabless.com}) yet. -\smallskip \item Very cheap 180nm prototyping process (partnering with various fabs) -\smallskip \item A semiconductor company, NOT an EDA company -\smallskip \item Web-based design environment -\smallskip \item HDL Synthesis using Yosys -\smallskip \item Custom place\&route tool - -\bigskip -\item efabless is building an Open Source IC as reference design. \\ -\hskip1cm (to be announced soon: \url{http://www.openic.io}) -\end{itemize} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Supported Platforms} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Main development OS: Kubuntu 14.04 -\item There is a PPA for ubuntu (not maintained by me) -\item Any current Debian-based system should work out of the box -\item When building on other Linux distributions: -\begin{itemize} -\item Needs compiler with some C++11 support -\item See README file for build instructions -\item Post to the subreddit if you get stuck -\end{itemize} -\item Ported to OS X (Darwin) and OpenBSD -\item Native win32 build with VisualStudio -\item Cross win32 build with MXE -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Other Open Source Tools} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Icarus Verilog \\ -\smallskip\hskip1cm{}Verilog Simulation (and also a good syntax checker) \\ -\smallskip\hskip1cm{}\url{http://iverilog.icarus.com/} - -\bigskip -\item Qflow (incl. TimberWolf, qrouter and Magic) \\ -\smallskip\hskip1cm{}A complete ASIC synthesis flow, using Yosys and ABC \\ -\smallskip\hskip1cm{}\url{http://opencircuitdesign.com/qflow/} - -\bigskip -\item ABC \\ -\smallskip\hskip1cm{}Logic optimization, technology mapping, and more \\ -\smallskip\hskip1cm{}\url{http://www.eecs.berkeley.edu/~alanmi/abc/} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Yosys needs you} - -\begin{frame}{\subsecname} -\dots as an active user: -\begin{itemize} -\item Use Yosys for on your own projects -\item .. even if you are not using it as final synthesis tool -\item Join the discussion on the Subreddit -\item Report bugs and send in feature requests -\end{itemize} - -\bigskip -\dots as a developer: -\begin{itemize} -\item Use Yosys as environment for your (research) work -\item .. you might also want to look into ABC for logic-level stuff -\item Fork the project on github or create loadable plugins -\item We need a VHDL frontend or a good VHDL-to-Verilog converter -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Documentation, Downloads, Contacts} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Website: \\ -\smallskip\hskip1cm\url{https://yosyshq.net/yosys/} - -\bigskip -\item Manual, Command Reference, Application Notes: \\ -\smallskip\hskip1cm\url{https://yosyshq.net/yosys/documentation.html} - -\bigskip -\item Instead of a mailing list we have a SubReddit: \\ -\smallskip\hskip1cm\url{http://www.reddit.com/r/yosys/} - -\bigskip -\item Direct link to the source code: \\ -\smallskip\hskip1cm\url{https://github.com/YosysHQ/yosys} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Yosys is a powerful tool and framework for Verilog synthesis. -\item It uses a command-based interface and can be controlled by scripts. -\item By combining existing commands and implementing new commands Yosys can -be used in a wide range of application far beyond simple synthesis. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - diff --git a/manual/PRESENTATION_Intro/.gitignore b/manual/PRESENTATION_Intro/.gitignore deleted file mode 100644 index d0c4618ac70..00000000000 --- a/manual/PRESENTATION_Intro/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -counter_00.dot -counter_01.dot -counter_02.dot -counter_03.dot diff --git a/manual/PRESENTATION_Intro/Makefile b/manual/PRESENTATION_Intro/Makefile deleted file mode 100644 index abc354e4691..00000000000 --- a/manual/PRESENTATION_Intro/Makefile +++ /dev/null @@ -1,10 +0,0 @@ - -all: counter_00.pdf counter_01.pdf counter_02.pdf counter_03.pdf - -counter_00.pdf: counter.v counter.ys mycells.lib - ../../yosys counter.ys - -counter_01.pdf: counter_00.pdf -counter_02.pdf: counter_00.pdf -counter_03.pdf: counter_00.pdf - diff --git a/manual/PRESENTATION_Intro/counter.ys b/manual/PRESENTATION_Intro/counter.ys deleted file mode 100644 index cc4e7cd3199..00000000000 --- a/manual/PRESENTATION_Intro/counter.ys +++ /dev/null @@ -1,27 +0,0 @@ -# read design -read_verilog counter.v -hierarchy -check -top counter - -show -notitle -stretch -format pdf -prefix counter_00 - -# the high-level stuff -proc; opt; memory; opt; fsm; opt - -show -notitle -stretch -format pdf -prefix counter_01 - -# mapping to internal cell library -techmap; opt - -splitnets -ports;; -show -notitle -stretch -format pdf -prefix counter_02 - -# mapping flip-flops to mycells.lib -dfflibmap -liberty mycells.lib - -# mapping logic to mycells.lib -abc -liberty mycells.lib - -# cleanup -clean - -show -notitle -stretch -lib mycells.v -format pdf -prefix counter_03 diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex deleted file mode 100644 index b0390cb9977..00000000000 --- a/manual/PRESENTATION_Prog.tex +++ /dev/null @@ -1,596 +0,0 @@ - -\section{Writing Yosys extensions in C++} - -\begin{frame} -\sectionpage -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Program Components and Data Formats} - -\begin{frame}{\subsecname} -\begin{center} -\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{process} = [draw, fill=green!10, rectangle, minimum height=3em, minimum width=10em, node distance=15em] - \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em] - \node[process] (vlog) {Verilog Frontend}; - \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend}; - \node[process] (ilang) [right of=vhdl] {Other Frontends}; - \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST}; - \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend}; - \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; - \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; - \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; - \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; - \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; - - \draw[-latex] (vlog) -- (ast); - \draw[-latex] (vhdl) -- (ast); - \draw[-latex] (ast) -- (astfe); - \draw[-latex] (astfe) -- (rtlil); - \draw[-latex] (ilang) -- (rtlil); - \draw[latex-latex] (rtlil) -- (pass); - \draw[-latex] (rtlil) -- (vlbe); - \draw[-latex] (rtlil) -- (ilangbe); - \draw[-latex] (rtlil) -- (otherbe); -\end{tikzpicture} -\end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Simplified RTLIL Entity-Relationship Diagram} - -\begin{frame}{\subsecname} -Between passses and frontends/backends the design is stored in Yosys' internal -RTLIL (RTL Intermediate Language) format. For writing Yosys extensions it is -key to understand this format. - -\bigskip -\begin{center} -\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}] - \node[entity] (design) {RTLIL::Design}; - \node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design); - - \node[entity] (process) [fill=green!10, right of=module, node distance=10em] {RTLIL::Process} (process.west) edge [-latex] (module); - \node[entity] (memory) [fill=red!10, below of=process] {RTLIL::Memory} edge [-latex] (module); - \node[entity] (wire) [fill=blue!10, above of=process] {RTLIL::Wire} (wire.west) edge [-latex] (module); - \node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module); - - \node[entity] (case) [fill=green!10, right of=process, node distance=10em] {RTLIL::CaseRule} edge [latex-latex] (process); - \node[entity] (sync) [fill=green!10, above of=case] {RTLIL::SyncRule} edge [-latex] (process); - \node[entity] (switch) [fill=green!10, below of=case] {RTLIL::SwitchRule} edge [-latex] (case); - \draw[latex-] (switch.east) -- ++(1em,0) |- (case.east); -\end{tikzpicture} -\end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{RTLIL without memories and processes} - -\begin{frame}[fragile]{\subsecname} -After the commands {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are -left with a much simpler version of RTLIL: - -\begin{center} -\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}] - \node[entity] (design) {RTLIL::Design}; - \node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design); - - \node[entity] (wire) [fill=blue!10, right of=module, node distance=10em] {RTLIL::Wire} (wire.west) edge [-latex] (module); - \node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module); -\end{tikzpicture} -\end{center} - -\bigskip -Many commands simply choose to only work on this simpler version: -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -for (RTLIL::Module *module : design->selected_modules() { - if (module->has_memories_warn() || module->has_processes_warn()) - continue; - .... -} -\end{lstlisting} - -For simplicity we only discuss this version of RTLIL in this presentation. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Using dump and show commands} - -\begin{frame}{\subsecname} -\begin{itemize} -\item The {\tt dump} command prints the design (or parts of it) in the text representation of RTLIL. - -\bigskip -\item The {\tt show} command visualizes how the components in the design are connected. -\end{itemize} - -\bigskip -When trying to understand what a command does, create a small test case and -look at the output of {\tt dump} and {\tt show} before and after the command -has been executed. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The RTLIL Data Structures} - -\begin{frame}{\subsecname} -The RTLIL data structures are simple structs utilizing {\tt pool<>} and -{\tt dict<>} containers (drop-in replacements for {\tt -std::unordered\_set<>} and {\tt std::unordered\_map<>}). - -\bigskip -\begin{itemize} -\item Most operations are performed directly on the RTLIL structs without -setter or getter functions. - -\bigskip -\item In debug builds a consistency checker is run over the in-memory design -between commands to make sure that the RTLIL representation is intact. - -\bigskip -\item Most RTLIL structs have helper methods that perform the most common operations. -\end{itemize} - -\bigskip -See {\tt yosys/kernel/rtlil.h} for details. -\end{frame} - -\subsubsection{RTLIL::IdString} - -\begin{frame}{\subsubsecname}{} -{\tt RTLIL::IdString} in many ways behave like a {\tt std::string}. It is used -for names of RTLIL objects. Internally a RTLIL::IdString object is only a -single integer. - -\medskip -The first character of a {\tt RTLIL::IdString} specifies if the name is {\it public\/} or {\it private\/}: - -\medskip -\begin{itemize} -\item {\tt RTLIL::IdString[0] == '\textbackslash\textbackslash'}: \\ -This is a public name. Usually this means it is a name that was declared in a Verilog file. - -\bigskip -\item {\tt RTLIL::IdString[0] == '\$'}: \\ -This is a private name. It was assigned by Yosys. -\end{itemize} - -\bigskip -Use the {\tt NEW\_ID} macro to create a new unique private name. -\end{frame} - -\subsubsection{RTLIL::Design and RTLIL::Module} - -\begin{frame}[t, fragile]{\subsubsecname} -The {\tt RTLIL::Design} and {\tt RTLIL::Module} structs are the top-level RTLIL -data structures. Yosys always operates on one active design, but can hold many designs in memory. - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Design { - dict modules_; - ... -}; - -struct RTLIL::Module { - RTLIL::IdString name; - dict wires_; - dict cells_; - std::vector connections_; - ... -}; -\end{lstlisting} - -(Use the various accessor functions instead of directly working with the {\tt *\_} members.) -\end{frame} - -\subsubsection{The RTLIL::Wire Structure} - -\begin{frame}[t, fragile]{\subsubsecname} -Each wire in the design is represented by a {\tt RTLIL::Wire} struct: - -\medskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Wire { - RTLIL::IdString name; - int width, start_offset, port_id; - bool port_input, port_output; - ... -}; -\end{lstlisting} - -\medskip -\hfil\begin{tabular}{p{3cm}l} -{\tt width} \dotfill & The total number of bits. E.g. 10 for {\tt [9:0]}. \\ -{\tt start\_offset} \dotfill & The lowest bit index. E.g. 3 for {\tt [5:3]}. \\ -{\tt port\_id} \dotfill & Zero for non-ports. Positive index for ports. \\ -{\tt port\_input} \dotfill & True for {\tt input} and {\tt inout} ports. \\ -{\tt port\_output} \dotfill & True for {\tt output} and {\tt inout} ports. \\ -\end{tabular} -\end{frame} - -\subsubsection{RTLIL::State and RTLIL::Const} - -\begin{frame}[t, fragile]{\subsubsecname} -The {\tt RTLIL::State} enum represents a simple 1-bit logic level: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -enum RTLIL::State { - S0 = 0, - S1 = 1, - Sx = 2, // undefined value or conflict - Sz = 3, // high-impedance / not-connected - Sa = 4, // don't care (used only in cases) - Sm = 5 // marker (used internally by some passes) -}; -\end{lstlisting} - -\bigskip -The {\tt RTLIL::Const} struct represents a constant multi-bit value: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Const { - std::vector bits; - ... -}; -\end{lstlisting} - -\bigskip -Notice that Yosys is not using special {\tt VCC} or {\tt GND} driver cells to represent constants. Instead -constants are part of the RTLIL representation itself. -\end{frame} - -\subsubsection{The RTLIL::SigSpec Structure} - -\begin{frame}[t, fragile]{\subsubsecname} -The {\tt RTLIL::SigSpec} struct represents a signal vector. Each bit can either be a bit from a wire -or a constant value. - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::SigBit -{ - RTLIL::Wire *wire; - union { - RTLIL::State data; // used if wire == NULL - int offset; // used if wire != NULL - }; - ... -}; - -struct RTLIL::SigSpec { - std::vector bits_; // LSB at index 0 - ... -}; -\end{lstlisting} - -\bigskip -The {\tt RTLIL::SigSpec} struct has a ton of additional helper methods to compare, analyze, and -manipulate instances of {\tt RTLIL::SigSpec}. -\end{frame} - -\subsubsection{The RTLIL::Cell Structure} - -\begin{frame}[t, fragile]{\subsubsecname (1/2)} -The {\tt RTLIL::Cell} struct represents an instance of a module or library cell. - -\smallskip -The ports of the cell -are associated with {\tt RTLIL::SigSpec} instances and the parameters are associated with {\tt RTLIL::Const} -instances: - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Cell { - RTLIL::IdString name, type; - dict connections_; - dict parameters; - ... -}; -\end{lstlisting} - -\bigskip -The {\tt type} may refer to another module in the same design, a cell name from a cell library, or a -cell name from the internal cell library: - -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] -$not $pos $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor -$reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod -$divfloor $modfloor $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff -$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ -$_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ -$_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ -$_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_ -$_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ $_DLATCHSR_PPP_ -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname (2/2)} -Simulation models (i.e. {\it documentation\/} :-) for the internal cell library: - -\smallskip -\hskip2em {\tt yosys/techlibs/common/simlib.v} and \\ -\hskip2em {\tt yosys/techlibs/common/simcells.v} - -\bigskip -The lower-case cell types (such as {\tt \$and}) are parameterized cells of variable -width. This so-called {\it RTL Cells\/} are the cells described in {\tt simlib.v}. - -\bigskip -The upper-case cell types (such as {\tt \$\_AND\_}) are single-bit cells that are not -parameterized. This so-called {\it Internal Logic Gates} are the cells described -in {\tt simcells.v}. - -\bigskip -The consistency checker also checks the interfaces to the internal cell library. -If you want to use private cell types for your own purposes, use the {\tt \$\_\_}-prefix -to avoid name collisions. -\end{frame} - -\subsubsection{Connecting wires or constant drivers} - -\begin{frame}[t, fragile]{\subsubsecname} -Additional connections between wires or between wires and constants are modelled using -{\tt RTLIL::Module::connections}: - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -typedef std::pair RTLIL::SigSig; - -struct RTLIL::Module { - ... - std::vector connections_; - ... -}; -\end{lstlisting} - -\bigskip -{\tt RTLIL::SigSig::first} is the driven signal and {\tt RTLIL::SigSig::second} is the driving signal. -Example usage (setting wire {\tt foo} to value {\tt 42}): -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -module->connect(module->wire("\\foo"), - RTLIL::SigSpec(42, module->wire("\\foo")->width)); -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Creating modules from scratch} - -\begin{frame}[t, fragile]{\subsecname} -Let's create the following module using the RTLIL API: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module absval(input signed [3:0] a, output [3:0] y); - assign y = a[3] ? -a : a; -endmodule -\end{lstlisting} - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -RTLIL::Module *module = new RTLIL::Module; -module->name = "\\absval"; - -RTLIL::Wire *a = module->addWire("\\a", 4); -a->port_input = true; -a->port_id = 1; - -RTLIL::Wire *y = module->addWire("\\y", 4); -y->port_output = true; -y->port_id = 2; - -RTLIL::Wire *a_inv = module->addWire(NEW_ID, 4); -module->addNeg(NEW_ID, a, a_inv, true); -module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); - -module->fixup_ports(); -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Modifying modules} - -\begin{frame}{\subsecname} -Most commands modify existing modules, not create new ones. - -When modifying existing modules, stick to the following DOs and DON'Ts: - -\begin{itemize} -\item Do not remove wires. Simply disconnect them and let a successive {\tt clean} command worry about removing it. - -\item Use {\tt module->fixup\_ports()} after changing the {\tt port\_*} properties of wires. - -\item You can safely remove cells or change the {\tt connections} property of a cell, but be careful when -changing the size of the {\tt SigSpec} connected to a cell port. - -\item Use the {\tt SigMap} helper class (see next slide) when you need a unique handle for each signal bit. -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Using the SigMap helper class} - -\begin{frame}[t, fragile]{\subsecname} -Consider the following module: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module test(input a, output x, y); - assign x = a, y = a; -endmodule -\end{lstlisting} - -In this case {\tt a}, {\tt x}, and {\tt y} are all different names for the same signal. However: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), - y(module->wire("\\y")); -log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" -\end{lstlisting} - -The {\tt SigMap} helper class can be used to map all such aliasing signals to a -unique signal from the group (usually the wire that is directly driven by a cell or port). - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -SigMap sigmap(module); -log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y), - sigmap(y) == sigmap(a)); // will print "1 1 1" -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Printing log messages} - -\begin{frame}[t, fragile]{\subsecname} -The {\tt log()} function is a {\tt printf()}-like function that can be used to create log messages. - -\medskip -Use {\tt log\_signal()} to create a C-string for a SigSpec object\footnote[frame]{The pointer returned -by {\tt log\_signal()} is automatically freed by the log framework at a later time.}: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -log("Mapped signal x: %s\n", log_signal(sigmap(x))); -\end{lstlisting} - -\medskip -Use {\tt log\_id()} to create a C-string for an {\tt RTLIL::IdString}: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -log("Name of this module: %s\n", log_id(module->name)); -\end{lstlisting} - -\medskip -Use {\tt log\_header()} and {\tt log\_push()}/{\tt log\_pop()} to structure log messages: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -log_header(design, "Doing important stuff!\n"); -log_push(); -for (int i = 0; i < 10; i++) - log("Log message #%d.\n", i); -log_pop(); -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Error handling} - -\begin{frame}[t, fragile]{\subsecname} -Use {\tt log\_error()} to report a non-recoverable error: - -\medskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -if (design->modules.count(module->name) != 0) - log_error("A module with the name %s already exists!\n", - RTLIL::id2cstr(module->name)); -\end{lstlisting} - -\bigskip -Use {\tt log\_cmd\_error()} to report a recoverable error: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -if (design->selection_stack.back().empty()) - log_cmd_error("This command can't operator on an empty selection!\n"); -\end{lstlisting} - -\bigskip -Use {\tt log\_assert()} and {\tt log\_abort()} instead of {\tt assert()} and {\tt abort()}. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Creating a command} - -\begin{frame}[t, fragile]{\subsecname} -Simply create a global instance of a class derived from {\tt Pass} to create -a new yosys command: - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -#include "kernel/yosys.h" -USING_YOSYS_NAMESPACE - -struct MyPass : public Pass { - MyPass() : Pass("my_cmd", "just a simple test") { } - virtual void execute(std::vector args, RTLIL::Design *design) - { - log("Arguments to my_cmd:\n"); - for (auto &arg : args) - log(" %s\n", arg.c_str()); - - log("Modules in current design:\n"); - for (auto mod : design->modules()) - log(" %s (%d wires, %d cells)\n", log_id(mod), - GetSize(mod->wires()), GetSize(mod->cells())); - } -} MyPass; -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Creating a plugin} - -\begin{frame}[fragile]{\subsecname} -Yosys can be extended by adding additional C++ code to the Yosys code base, or -by loading plugins into Yosys. - -\bigskip -Use the following command to compile a Yosys plugin: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -yosys-config --exec --cxx --cxxflags --ldflags \ - -o my_cmd.so -shared my_cmd.cc --ldlibs -\end{lstlisting} - -\bigskip -Or shorter: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -yosys-config --build my_cmd.so my_cmd.cc -\end{lstlisting} - -\bigskip -Load the plugin using the yosys {\tt -m} option: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -yosys -m ./my_cmd.so -p 'my_cmd foo bar' -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Writing Yosys extensions is very straight-forward. -\item \dots and even simpler if you don't need RTLIL::Memory or RTLIL::Process objects. - -\bigskip -\item Writing synthesis software? Consider learning the Yosys API and make your work -part of the Yosys framework. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - diff --git a/manual/PRESENTATION_Prog/Makefile b/manual/PRESENTATION_Prog/Makefile deleted file mode 100644 index 2ac8e5bed9f..00000000000 --- a/manual/PRESENTATION_Prog/Makefile +++ /dev/null @@ -1,21 +0,0 @@ - -all: test0.log test1.log test2.log - -CXXFLAGS=$(shell ../../yosys-config --cxxflags) -DATDIR=$(shell ../../yosys-config --datdir) - -my_cmd.so: my_cmd.cc - ../../yosys-config --exec --cxx $(subst $(DATDIR),../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs - -test0.log: my_cmd.so - ../../yosys -Ql test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v - mv test0.log_new test0.log - -test1.log: my_cmd.so - ../../yosys -Ql test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v - mv test1.log_new test1.log - -test2.log: my_cmd.so - ../../yosys -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v - mv test2.log_new test2.log - diff --git a/manual/clean.sh b/manual/clean.sh deleted file mode 100755 index addc34ed183..00000000000 --- a/manual/clean.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -for f in $( find . -name .gitignore ); do sed -Ee "s,^,find ${f%.gitignore} -name ',; s,$,' | xargs rm -f,;" $f; done | bash -v diff --git a/manual/presentation.sh b/manual/presentation.sh deleted file mode 100755 index ca8a6c93c10..00000000000 --- a/manual/presentation.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -fast_mode=false - -set -- $(getopt fu "$@") -while [ $# -gt 0 ]; do - case "$1" in - -f) - fast_mode=true - ;; - --) - shift - break - ;; - -*) - echo "$0: error - unrecognized option $1" 1>&2 - exit 1 - ;; - *) - break - esac - shift -done - -PDFTEX_OPT="-shell-escape -halt-on-error" - -set -ex - -if ! $fast_mode; then - ! md5sum *.aux *.snm *.nav *.toc > autoloop.old - make -C PRESENTATION_Intro - make -C PRESENTATION_ExSyn - make -C PRESENTATION_ExAdv - make -C PRESENTATION_ExOth - make -C PRESENTATION_Prog -fi - -set -ex - -pdflatex $PDFTEX_OPT presentation.tex - -if ! $fast_mode; then - while - md5sum *.aux *.snm *.nav *.toc > autoloop.new - ! cmp autoloop.old autoloop.new - do - cp autoloop.new autoloop.old - pdflatex $PDFTEX_OPT presentation.tex - done - - rm -f autoloop.old - rm -f autoloop.new -fi - diff --git a/manual/presentation.tex b/manual/presentation.tex deleted file mode 100644 index 7aba33c8b31..00000000000 --- a/manual/presentation.tex +++ /dev/null @@ -1,162 +0,0 @@ -\documentclass{beamer} -\hypersetup{bookmarksdepth=5} - -\usepackage[T1]{fontenc} % required for luximono! -\usepackage{lmodern} -\usepackage[scaled=0.8]{luximono} % typewriter font with bold face - -% To install the luximono font files: -% getnonfreefonts-sys --all or -% getnonfreefonts-sys luximono -% -% when there are trouble you might need to: -% - Create /etc/texmf/updmap.d/99local-luximono.cfg -% containing the single line: Map ul9.map -% - Run update-updmap followed by mktexlsr and updmap-sys -% -% This commands must be executed as root with a root environment -% (i.e. run "sudo su" and then execute the commands in the root -% shell, don't just prefix the commands with "sudo"). - -% formats the text according the set language -\usepackage[english]{babel} -\usepackage{amsmath} -\usepackage{multirow} -\usepackage{booktabs} -\usepackage{listings} -\usepackage{setspace} -\usepackage{skull} -\usepackage{units} - -\usepackage{tikz} -\usetikzlibrary{calc} -\usetikzlibrary{arrows} -\usetikzlibrary{scopes} -\usetikzlibrary{through} -\usetikzlibrary{shapes.geometric} - -\lstset{basicstyle=\ttfamily} - -\def\B#1{{\tt\textbackslash{}#1}} -\def\C#1{\lstinline[language=C++]{#1}} -\def\V#1{\lstinline[language=Verilog]{#1}} - -\lstdefinelanguage{liberty}{ - morecomment=[s]{/*}{*/}, - morekeywords={library,cell,area,pin,direction,function,clocked_on,next_state,clock,ff}, - morestring=[b]", -} - -\lstdefinelanguage{rtlil}{ - morecomment=[l]{\#}, - morekeywords={module,attribute,parameter,wire,memory,auto,width,offset,size,input,output,inout,cell,connect,switch,case,assign,sync,low,high,posedge,negedge,edge,always,update,process,end}, - morestring=[b]", -} - -\lstdefinelanguage{ys}{ - morecomment=[l]{\#}, -} - -\lstset{ - commentstyle=\color{YosysGreen}, -} - -\newenvironment{boxalertenv}{\begin{altenv}% -{\usebeamertemplate{alerted text begin}\usebeamercolor[fg]{alerted text}\usebeamerfont{alerted text}\setlength{\fboxsep}{1pt}\colorbox{bg}} -{\usebeamertemplate{alerted text end}}{\color{.}}{}}{\end{altenv}} - -\newcommand<>{\boxalert}[1]{{% -\begin{boxalertenv}#2{#1}\end{boxalertenv}% -}} - -\newcommand{\subsectionpagesuffix}{ -\vfill\begin{centering} -{\usebeamerfont{subsection name}\usebeamercolor[fg]{subsection name}of \sectionname~\insertsectionnumber} -\vskip1em\par -\setbeamercolor{graybox}{bg=gray} -\begin{beamercolorbox}[sep=8pt,center]{graybox} -\usebeamerfont{subsection title}\insertsection\par -\end{beamercolorbox} -\end{centering}} - -\title{Yosys Open SYnthesis Suite} -\author{Claire Xenia Wolf} -\institute{https://yosyshq.net/yosys/} - -\usetheme{Madrid} -\usecolortheme{seagull} -\beamertemplatenavigationsymbolsempty - -\definecolor{YosysGreen}{RGB}{85,136,102} -\definecolor{MyBlue}{RGB}{85,130,180} - -\setbeamercolor{title}{fg=black,bg=YosysGreen!70} -\setbeamercolor{titlelike}{fg=black,bg=YosysGreen!70} -\setbeamercolor{frametitle}{fg=black,bg=YosysGreen!70} -\setbeamercolor{block title}{fg=black,bg=YosysGreen!70} -\setbeamercolor{item projected}{fg=black,bg=YosysGreen} - -\begin{document} - -\begin{frame} -\titlepage -\end{frame} - -\setcounter{section}{-3} - -\section{Abstract} -\begin{frame}{Abstract} -Yosys is the first full-featured open source software for Verilog HDL -synthesis. It supports most of Verilog-2005 and is well tested with -real-world designs from the ASIC and FPGA world. - -\bigskip -Learn how to use Yosys to create your own custom synthesis flows and -discover why open source HDL synthesis is important for researchers, -hobbyists, educators and engineers alike. - -\bigskip -This presentation covers basic concepts of Yosys, writing synthesis scripts -for a wide range of applications, creating Yosys scripts for various -non-synthesis applications (such as formal equivalence checking) and -writing extensions to Yosys using the C++ API. -\end{frame} - -\section{About me} -\begin{frame}{About me} -Hi! I'm Claire Xenia Wolf. - -\bigskip -I like writing open source software. For example: -\begin{itemize} -\item Yosys -\item OpenSCAD (now maintained by Marius Kintel) -\item SPL (a not very popular scripting language) -\item EmbedVM (a very simple compiler+vm for 8 bit micros) -\item Lib(X)SVF (a library to play SVF/XSVF files over JTAG) -\item ROCK Linux (discontinued since 2010) -\end{itemize} -\end{frame} - -\section{Outline} -\begin{frame}{Outline} -Yosys is an Open Source Verilog synthesis tool, and more. - -\bigskip -Outline of this presentation: -\begin{itemize} -\item Introduction to the field and Yosys -\item Yosys by example: synthesis -\item Yosys by example: advanced synthesis -\item Yosys by example: beyond synthesis -\item Writing Yosys extensions in C++ -\end{itemize} -\end{frame} - -\include{PRESENTATION_Intro} -\include{PRESENTATION_ExSyn} -\include{PRESENTATION_ExAdv} -\include{PRESENTATION_ExOth} -\include{PRESENTATION_Prog} - -\end{document}