From 4f1cd66829926f0d5dd967f7d85c46f97902cdaa Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:20:24 +1200 Subject: [PATCH 001/108] New structure headings Also adds a note to readme for installing pdflatex if it's missing. --- README.md | 6 ++++-- docs/source/conf.py | 1 + docs/source/getting_started.rst | 14 ++++++++++++++ docs/source/index.rst | 9 +++++++++ docs/source/introduction.rst | 8 ++++++++ docs/source/test_suites.rst | 8 ++++++++ docs/source/using_yosys.rst | 25 +++++++++++++++++++++++++ docs/source/yosys_internals.rst | 23 +++++++++++++++++++++++ 8 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 docs/source/getting_started.rst create mode 100644 docs/source/introduction.rst create mode 100644 docs/source/test_suites.rst create mode 100644 docs/source/using_yosys.rst create mode 100644 docs/source/yosys_internals.rst diff --git a/README.md b/README.md index 5e5a8ec3e..87d9730a4 100644 --- a/README.md +++ b/README.md @@ -602,10 +602,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 The Python package, Sphinx, is needed along with those listed in `docs/source/requirements.txt`: diff --git a/docs/source/conf.py b/docs/source/conf.py index ab9618c8b..52a21afb2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -43,6 +43,7 @@ bibtex_bibfiles = ['literature.bib'] exclude_patterns = [ "CHAPTER_Eval.rst", "appendix/CHAPTER_StateOfTheArt.rst" + "test_suites.rst" ] latex_elements = { diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst new file mode 100644 index 000000000..75a58c089 --- /dev/null +++ b/docs/source/getting_started.rst @@ -0,0 +1,14 @@ +Getting started with Yosys +========================== + +Installation +------------ + +Supported platforms +~~~~~~~~~~~~~~~~~~~ + +Introduction to scripting in Yosys +---------------------------------- + +Example(s) +---------- diff --git a/docs/source/index.rst b/docs/source/index.rst index 111aea873..681c18f7a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -27,6 +27,15 @@ Yosys manual ================================================================================ +.. toctree:: + :caption: New docs + + introduction + getting_started + using_yosys + yosys_internals +.. test_suites + .. toctree:: :maxdepth: 2 :caption: Manual diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst new file mode 100644 index 000000000..c87326b9d --- /dev/null +++ b/docs/source/introduction.rst @@ -0,0 +1,8 @@ +What is Yosys +============= + +What you can do with Yosys +-------------------------- + +The extended Yosys universe +--------------------------- diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst new file mode 100644 index 000000000..fbf1e98b4 --- /dev/null +++ b/docs/source/test_suites.rst @@ -0,0 +1,8 @@ +Test suites +=========== + +Build tests +----------- + +Benchmarking +------------ diff --git a/docs/source/using_yosys.rst b/docs/source/using_yosys.rst new file mode 100644 index 000000000..89b456697 --- /dev/null +++ b/docs/source/using_yosys.rst @@ -0,0 +1,25 @@ +Using Yosys (advanced) +====================== + +More scripting +-------------- + +Selections +~~~~~~~~~~ + +Note on show/viz + +Troubleshooting +~~~~~~~~~~~~~~~ + +Memory map patterns +------------------- + +Flows, command types, and order +------------------------------- + +Synthesis granularity +~~~~~~~~~~~~~~~~~~~~~ + +Formal verification +~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals.rst b/docs/source/yosys_internals.rst new file mode 100644 index 000000000..6e22bdcbd --- /dev/null +++ b/docs/source/yosys_internals.rst @@ -0,0 +1,23 @@ +Yosys internals +=============== + +Control and data flow +--------------------- + +Frontends +~~~~~~~~~ + +Backends +~~~~~~~~ + +Passes +~~~~~~ + +RTLIL +----- + +Techmap +------- + +Writing extensions +------------------ From 045c04096eaa6814a1a13d2c3a8b5499fecf6c3a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:20:29 +1200 Subject: [PATCH 002/108] Reorganising documentation Also changing to furo theme. --- docs/source/CHAPTER_Approach.rst | 141 ------ docs/source/CHAPTER_Eval.rst | 233 ---------- docs/source/CHAPTER_Intro.rst | 96 ---- docs/source/_templates/page.html | 44 ++ docs/source/appendix.rst | 22 + .../source/appendix/CHAPTER_StateOfTheArt.rst | 410 ------------------ .../{CHAPTER_Auxlibs.rst => auxlibs.rst} | 2 +- .../{CHAPTER_Auxprogs.rst => auxprogs.rst} | 4 +- .../primer.rst} | 30 +- docs/source/cmd_ref.rst | 2 +- docs/source/conf.py | 34 +- docs/source/getting_started.rst | 14 - docs/source/getting_started/examples.rst | 50 +++ docs/source/getting_started/index.rst | 8 + docs/source/getting_started/installation.rst | 63 +++ .../getting_started/scripting_intro.rst | 28 ++ docs/source/index.rst | 82 +--- docs/source/introduction.rst | 91 ++++ docs/source/requirements.txt | 2 +- docs/source/using_yosys.rst | 25 -- docs/source/using_yosys/index.rst | 9 + .../memory_mapping.rst} | 0 docs/source/using_yosys/more_scripting.rst | 8 + .../opt_passes.rst} | 18 +- docs/source/using_yosys/selections.rst | 6 + docs/source/using_yosys/troubleshooting.rst | 4 + docs/source/using_yosys/yosys_flows.rst | 8 + docs/source/yosys_internals.rst | 23 - .../extensions.rst} | 16 +- .../yosys_internals/flow/control_and_data.rst | 31 ++ docs/source/yosys_internals/flow/index.rst | 10 + docs/source/yosys_internals/flow/overview.rst | 48 ++ .../flow/verilog_frontend.rst} | 12 +- .../formats/cell_library.rst} | 8 +- docs/source/yosys_internals/formats/index.rst | 11 + .../yosys_internals/formats/overview.rst | 53 +++ .../formats/rtlil.rst} | 189 +------- .../formats/rtlil_text.rst} | 53 ++- docs/source/yosys_internals/index.rst | 41 ++ .../techmap.rst} | 14 +- 40 files changed, 661 insertions(+), 1282 deletions(-) delete mode 100644 docs/source/CHAPTER_Approach.rst delete mode 100644 docs/source/CHAPTER_Eval.rst delete mode 100644 docs/source/CHAPTER_Intro.rst create mode 100644 docs/source/_templates/page.html create mode 100644 docs/source/appendix.rst delete mode 100644 docs/source/appendix/CHAPTER_StateOfTheArt.rst rename docs/source/appendix/{CHAPTER_Auxlibs.rst => auxlibs.rst} (98%) rename docs/source/appendix/{CHAPTER_Auxprogs.rst => auxprogs.rst} (84%) rename docs/source/{CHAPTER_Basics.rst => appendix/primer.rst} (97%) delete mode 100644 docs/source/getting_started.rst create mode 100644 docs/source/getting_started/examples.rst create mode 100644 docs/source/getting_started/index.rst create mode 100644 docs/source/getting_started/installation.rst create mode 100644 docs/source/getting_started/scripting_intro.rst delete mode 100644 docs/source/using_yosys.rst create mode 100644 docs/source/using_yosys/index.rst rename docs/source/{CHAPTER_Memorymap.rst => using_yosys/memory_mapping.rst} (100%) create mode 100644 docs/source/using_yosys/more_scripting.rst rename docs/source/{CHAPTER_Optimize.rst => using_yosys/opt_passes.rst} (96%) create mode 100644 docs/source/using_yosys/selections.rst create mode 100644 docs/source/using_yosys/troubleshooting.rst create mode 100644 docs/source/using_yosys/yosys_flows.rst delete mode 100644 docs/source/yosys_internals.rst rename docs/source/{CHAPTER_Prog.rst => yosys_internals/extensions.rst} (79%) create mode 100644 docs/source/yosys_internals/flow/control_and_data.rst create mode 100644 docs/source/yosys_internals/flow/index.rst create mode 100644 docs/source/yosys_internals/flow/overview.rst rename docs/source/{CHAPTER_Verilog.rst => yosys_internals/flow/verilog_frontend.rst} (98%) rename docs/source/{CHAPTER_CellLib.rst => yosys_internals/formats/cell_library.rst} (99%) create mode 100644 docs/source/yosys_internals/formats/index.rst create mode 100644 docs/source/yosys_internals/formats/overview.rst rename docs/source/{CHAPTER_Overview.rst => yosys_internals/formats/rtlil.rst} (68%) rename docs/source/{appendix/CHAPTER_TextRtlil.rst => yosys_internals/formats/rtlil_text.rst} (92%) create mode 100644 docs/source/yosys_internals/index.rst rename docs/source/{CHAPTER_Techmap.rst => yosys_internals/techmap.rst} (93%) diff --git a/docs/source/CHAPTER_Approach.rst b/docs/source/CHAPTER_Approach.rst deleted file mode 100644 index 32980e788..000000000 --- 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 -<fig:approach_flow>`). - -.. 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 3d463d3f9..000000000 --- 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 90b001c23..000000000 --- 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 <chapter:intro>` is this introduction. - -:numref:`Chapter %s <chapter:basics>` covers a short introduction to the world -of HDL synthesis. Basic principles and the terminology are outlined in this -chapter. - -:numref:`Chapter %s <chapter:approach>` 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 <chapter:overview>` 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 <chapter:celllib>` 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 <chapter:prog>` 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 <chapter:verilog>`, :numref:`%s <chapter:opt>` and -:numref:`%s <chapter:techmap>` 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/_templates/page.html b/docs/source/_templates/page.html new file mode 100644 index 000000000..d830124c1 --- /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 %} +<div class="toc-sticky toc-scroll"> + {# begin of custom part #} + <div class="toc-title-container"> + <span class="toc-title"> + YosysHQ + </span> + </div> + <div class="toc-tree-container yosyshq-links" style="padding-bottom: 0"> + <div class="toc-tree"> + <ul> + <li></li> + <li><a class="reference external" href="https://yosyshq.readthedocs.io">Docs</a></li> + <li><a class="reference external" href="https://blog.yosyshq.com">Blog</a></li> + <li><a class="reference external" href="https://www.yosyshq.com">Website</a></li> + </ul> + </div> + </div> + {# end of custom part #} + {% if not furo_hide_toc %} + <div class="toc-title-container"> + <span class="toc-title"> + {{ _("On this page") }} + </span> + </div> + <div class="toc-tree-container"> + <div class="toc-tree"> + {{ toc }} + </div> + </div> + {% endif %} +</div> +{% endblock %} + \ No newline at end of file diff --git a/docs/source/appendix.rst b/docs/source/appendix.rst new file mode 100644 index 000000000..87581793b --- /dev/null +++ b/docs/source/appendix.rst @@ -0,0 +1,22 @@ +Appendix +======== + +.. toctree:: + :maxdepth: 2 + :includehidden: + + appendix/primer + appendix/auxlibs + appendix/auxprogs + + appendix/APPNOTE_010_Verilog_to_BLIF.rst + appendix/APPNOTE_011_Design_Investigation.rst + appendix/APPNOTE_012_Verilog_to_BTOR.rst + + bib + +.. toctree:: + :maxdepth: 1 + :includehidden: + + cmd_ref diff --git a/docs/source/appendix/CHAPTER_StateOfTheArt.rst b/docs/source/appendix/CHAPTER_StateOfTheArt.rst deleted file mode 100644 index 894d0fbbe..000000000 --- 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 <fig:StateOfTheArt_always12>` -and :numref:`Fig. %s <fig:StateOfTheArt_always3>` -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 <fig:StateOfTheArt_arrays>` -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 <fig:StateOfTheArt_for>` 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 <fig:StateOfTheArt_gen>` 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:`<CHAPTER_eval>` 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/CHAPTER_Auxlibs.rst b/docs/source/appendix/auxlibs.rst similarity index 98% rename from docs/source/appendix/CHAPTER_Auxlibs.rst rename to docs/source/appendix/auxlibs.rst index 361f00e02..2f443c041 100644 --- a/docs/source/appendix/CHAPTER_Auxlibs.rst +++ b/docs/source/appendix/auxlibs.rst @@ -17,7 +17,7 @@ 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 +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/ diff --git a/docs/source/appendix/CHAPTER_Auxprogs.rst b/docs/source/appendix/auxprogs.rst similarity index 84% rename from docs/source/appendix/CHAPTER_Auxprogs.rst rename to docs/source/appendix/auxprogs.rst index e4f6f62cf..9071abfd1 100644 --- a/docs/source/appendix/CHAPTER_Auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -9,7 +9,7 @@ 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. +Yosys. See :ref:`chapter:prog` for details. .. _sec:filterlib: @@ -17,7 +17,7 @@ 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 <sec:techmap_extern>` for +information from a Liberty file. See :ref:`sec:techmap_extern` for details. yosys-abc 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 618bec545..ed1a3188c 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 <fig:Basics_abstractions>` lists the different levels of abstraction and how they relate to different kinds of synthesis. -.. figure:: ../images/basics_abstractions.* +.. figure:: ../../images/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 <fig:Basics_flow>`. -.. figure:: ../images/basics_flow.* +.. figure:: ../../images/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 <tab:Basics_tokens>`. 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/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/basics_ast.* :class: width-helper :name: fig:Basics_ast diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst index 4b9dc91f3..138e934e3 100644 --- a/docs/source/cmd_ref.rst +++ b/docs/source/cmd_ref.rst @@ -8,4 +8,4 @@ Command line reference :maxdepth: 1 :glob: - cmd/* + ../cmd/* diff --git a/docs/source/conf.py b/docs/source/conf.py index 52a21afb2..512521a83 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -7,11 +7,31 @@ author = 'YosysHQ GmbH' copyright ='2022 YosysHQ GmbH' # select HTML theme -html_theme = 'press' +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"] @@ -20,14 +40,6 @@ html_static_path = ['../static', "../images"] 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 @@ -41,8 +53,6 @@ bibtex_bibfiles = ['literature.bib'] # unused docs exclude_patterns = [ - "CHAPTER_Eval.rst", - "appendix/CHAPTER_StateOfTheArt.rst" "test_suites.rst" ] diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst deleted file mode 100644 index 75a58c089..000000000 --- a/docs/source/getting_started.rst +++ /dev/null @@ -1,14 +0,0 @@ -Getting started with Yosys -========================== - -Installation ------------- - -Supported platforms -~~~~~~~~~~~~~~~~~~~ - -Introduction to scripting in Yosys ----------------------------------- - -Example(s) ----------- diff --git a/docs/source/getting_started/examples.rst b/docs/source/getting_started/examples.rst new file mode 100644 index 000000000..88458c50e --- /dev/null +++ b/docs/source/getting_started/examples.rst @@ -0,0 +1,50 @@ +Example(s) +---------- + +.. _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`. diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst new file mode 100644 index 000000000..310a7029e --- /dev/null +++ b/docs/source/getting_started/index.rst @@ -0,0 +1,8 @@ +Getting started with Yosys +========================== + +.. toctree:: + + installation + scripting_intro + examples diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst new file mode 100644 index 000000000..b83296816 --- /dev/null +++ b/docs/source/getting_started/installation.rst @@ -0,0 +1,63 @@ +Installation +------------ + +Supported platforms +~~~~~~~~~~~~~~~~~~~ + +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. diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst new file mode 100644 index 000000000..5c6f7398c --- /dev/null +++ b/docs/source/getting_started/scripting_intro.rst @@ -0,0 +1,28 @@ +Scripting in Yosys +------------------ + +.. TODO: copypaste + +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 :ref:`sec:typusecase` 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. diff --git a/docs/source/index.rst b/docs/source/index.rst index 681c18f7a..0cae4aa0d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,82 +1,14 @@ -: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:: - :caption: New docs + :maxdepth: 3 introduction - getting_started - using_yosys - yosys_internals -.. test_suites - -.. toctree:: - :maxdepth: 2 - :caption: Manual - :numbered: - - CHAPTER_Intro - CHAPTER_Basics.rst - CHAPTER_Approach.rst - CHAPTER_Overview.rst - CHAPTER_CellLib.rst - CHAPTER_Prog.rst - - CHAPTER_Verilog.rst - CHAPTER_Optimize.rst - CHAPTER_Techmap.rst - CHAPTER_Memorymap.rst - CHAPTER_Eval.rst - -.. raw:: latex - - \appendix - -.. toctree:: - :maxdepth: 2 - :includehidden: - :caption: Appendix - - appendix/CHAPTER_Auxlibs.rst - appendix/CHAPTER_Auxprogs.rst - - 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 - - bib - -.. toctree:: - :maxdepth: 1 - :includehidden: - - cmd_ref + getting_started/index + using_yosys/index + yosys_internals/index + test_suites + appendix diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index c87326b9d..c4d6c1285 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -1,8 +1,99 @@ What is Yosys ============= +.. TODO: rewrite to not be a thesis abstract + +: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 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. + What you can do with Yosys -------------------------- The extended Yosys universe --------------------------- + +In no particular order: + +- SBY for formal verification +- EQY for equivalence checking +- MCY for mutation coverage + +History of Yosys +---------------- + +.. TODO: copypaste + +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 d357a83b7..74c8dd090 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/using_yosys.rst b/docs/source/using_yosys.rst deleted file mode 100644 index 89b456697..000000000 --- a/docs/source/using_yosys.rst +++ /dev/null @@ -1,25 +0,0 @@ -Using Yosys (advanced) -====================== - -More scripting --------------- - -Selections -~~~~~~~~~~ - -Note on show/viz - -Troubleshooting -~~~~~~~~~~~~~~~ - -Memory map patterns -------------------- - -Flows, command types, and order -------------------------------- - -Synthesis granularity -~~~~~~~~~~~~~~~~~~~~~ - -Formal verification -~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst new file mode 100644 index 000000000..ea451d395 --- /dev/null +++ b/docs/source/using_yosys/index.rst @@ -0,0 +1,9 @@ +Using Yosys (advanced) +====================== + +.. toctree:: + :maxdepth: 2 + + more_scripting + memory_mapping + yosys_flows diff --git a/docs/source/CHAPTER_Memorymap.rst b/docs/source/using_yosys/memory_mapping.rst similarity index 100% rename from docs/source/CHAPTER_Memorymap.rst rename to docs/source/using_yosys/memory_mapping.rst diff --git a/docs/source/using_yosys/more_scripting.rst b/docs/source/using_yosys/more_scripting.rst new file mode 100644 index 000000000..e9e005c5e --- /dev/null +++ b/docs/source/using_yosys/more_scripting.rst @@ -0,0 +1,8 @@ +More scripting +-------------- + +.. toctree:: + + opt_passes + selections + troubleshooting diff --git a/docs/source/CHAPTER_Optimize.rst b/docs/source/using_yosys/opt_passes.rst similarity index 96% rename from docs/source/CHAPTER_Optimize.rst rename to docs/source/using_yosys/opt_passes.rst index 53e0a67aa..8905a3455 100644 --- a/docs/source/CHAPTER_Optimize.rst +++ b/docs/source/using_yosys/opt_passes.rst @@ -1,7 +1,9 @@ .. _chapter:opt: -Optimizations -============= +Optimization passes +=================== + +.. TODO: copypaste Yosys employs a number of optimizations to generate better and cleaner results. This chapter outlines these optimizations. @@ -34,7 +36,7 @@ The opt_expr pass ~~~~~~~~~~~~~~~~~ This pass performs const folding on the internal combinational cell types -described in :numref:`Chap. %s <chapter:celllib>`. This means a cell with all +described in :ref:`chapter:celllib`. 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. @@ -67,7 +69,7 @@ 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`. +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 @@ -189,7 +191,7 @@ using the ``\fsm_encoding`` attribute (unless ``\fsm_encoding`` is set to 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 +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. @@ -254,7 +256,7 @@ 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 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. @@ -326,5 +328,5 @@ 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 -<sec:techmap_extern>` for details). +operations using ABC, such as technology mapping (see :ref:`sec:techmap_extern` +for details). diff --git a/docs/source/using_yosys/selections.rst b/docs/source/using_yosys/selections.rst new file mode 100644 index 000000000..bdbb762f4 --- /dev/null +++ b/docs/source/using_yosys/selections.rst @@ -0,0 +1,6 @@ +Selections +~~~~~~~~~~ + +See :doc:`/cmd/select` + +Also :doc:`/cmd/show` diff --git a/docs/source/using_yosys/troubleshooting.rst b/docs/source/using_yosys/troubleshooting.rst new file mode 100644 index 000000000..ff87d63cd --- /dev/null +++ b/docs/source/using_yosys/troubleshooting.rst @@ -0,0 +1,4 @@ +Troubleshooting +~~~~~~~~~~~~~~~ + +See :doc:`/cmd/bugpoint` diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst new file mode 100644 index 000000000..61317f7cd --- /dev/null +++ b/docs/source/using_yosys/yosys_flows.rst @@ -0,0 +1,8 @@ +Flows, command types, and order +------------------------------- + +Synthesis granularity +~~~~~~~~~~~~~~~~~~~~~ + +Formal verification +~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals.rst b/docs/source/yosys_internals.rst deleted file mode 100644 index 6e22bdcbd..000000000 --- a/docs/source/yosys_internals.rst +++ /dev/null @@ -1,23 +0,0 @@ -Yosys internals -=============== - -Control and data flow ---------------------- - -Frontends -~~~~~~~~~ - -Backends -~~~~~~~~ - -Passes -~~~~~~ - -RTLIL ------ - -Techmap -------- - -Writing extensions ------------------- diff --git a/docs/source/CHAPTER_Prog.rst b/docs/source/yosys_internals/extensions.rst similarity index 79% rename from docs/source/CHAPTER_Prog.rst rename to docs/source/yosys_internals/extensions.rst index 23aeed5a5..a9653a7d3 100644 --- a/docs/source/CHAPTER_Prog.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -1,7 +1,9 @@ .. _chapter:prog: -Programming Yosys extensions -============================ +Writing extensions +================== + +.. TODO: copypaste This chapter contains some bits and pieces of information about programming yosys extensions. Also consult the section on programming in @@ -15,11 +17,11 @@ 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 +.. literalinclude:: ../temp/GettingStarted :language: none :caption: guidelines/GettingStarted -.. literalinclude:: temp/CodingStyle +.. literalinclude:: ../temp/CodingStyle :language: none :caption: guidelines/CodingStyle @@ -30,17 +32,17 @@ 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 +.. literalinclude:: ../CHAPTER_Prog/stubnets.cc :language: c++ :linenos: :caption: docs/source/CHAPTER_Prog/stubnets.cc -.. literalinclude:: CHAPTER_Prog/Makefile +.. literalinclude:: ../CHAPTER_Prog/Makefile :language: makefile :linenos: :caption: docs/source/CHAPTER_Prog/Makefile -.. literalinclude:: CHAPTER_Prog/test.v +.. literalinclude:: ../CHAPTER_Prog/test.v :language: verilog :linenos: :caption: docs/source/CHAPTER_Prog/test.v 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 000000000..65eaaa5d5 --- /dev/null +++ b/docs/source/yosys_internals/flow/control_and_data.rst @@ -0,0 +1,31 @@ +Control and data flow +===================== + +.. TODO: copypaste + +The data- and control-flow of a typical synthesis tool is very similar to the +data- and control-flow of a typical compiler: different subsystems are called in +a predetermined order, each consuming the data generated by the last subsystem +and generating the data for the next subsystem (see :numref:`Fig. %s +<fig:approach_flow>`). + +.. 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. diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst new file mode 100644 index 000000000..a235996e9 --- /dev/null +++ b/docs/source/yosys_internals/flow/index.rst @@ -0,0 +1,10 @@ +Internal flow +============= + +.. toctree:: + :maxdepth: 2 + + 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 000000000..025d6f8b7 --- /dev/null +++ b/docs/source/yosys_internals/flow/overview.rst @@ -0,0 +1,48 @@ +Flow overview +============= + +.. TODO: copypaste + +:numref:`Figure %s <fig:Overview_flow>` 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) diff --git a/docs/source/CHAPTER_Verilog.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst similarity index 98% rename from docs/source/CHAPTER_Verilog.rst rename to docs/source/yosys_internals/flow/verilog_frontend.rst index 484844fba..cded945e5 100644 --- a/docs/source/CHAPTER_Verilog.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -9,7 +9,7 @@ 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 <fig:Verilog_flow>`. -.. figure:: ../images/verilog_flow.* +.. figure:: ../../../images/verilog_flow.* :class: width-helper :name: fig:Verilog_flow @@ -167,7 +167,7 @@ properties: - | 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 + ``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 @@ -220,7 +220,7 @@ performs the following transformations on the AST data structure: - Evaluate all ``generate``-statements and unroll all ``for``-loops. -- Perform const folding where it is necessary (e.g. in the value part +- 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. @@ -388,7 +388,7 @@ the following way: 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 + 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. @@ -397,7 +397,7 @@ the following way: 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 + 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 @@ -414,7 +414,7 @@ into the synchronization type (posedge) and signal (\\clock) for the 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 +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. diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/yosys_internals/formats/cell_library.rst similarity index 99% rename from docs/source/CHAPTER_CellLib.rst rename to docs/source/yosys_internals/formats/cell_library.rst index c89040868..67e1fc0ef 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -1,12 +1,14 @@ .. role:: verilog(code) :language: Verilog +.. TODO: copypaste + .. _chapter:celllib: Internal cell library ===================== -Most of the passes in Yosys operate on netlists, i.e. they only care about the +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. @@ -205,7 +207,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 @@ -814,7 +816,7 @@ techlibs/common/simcells.v in the Yosys source tree. ============== ============== ========= -Tables \ :numref:`%s <tab:CellLib_gates>`, :numref:`%s +Tables \ :numref:`%s <tab:CellLib_gates>`, :numref:`%s <tab:CellLib_gates_dffe>`, :numref:`%s <tab:CellLib_gates_adff>`, :numref:`%s <tab:CellLib_gates_adffe>`, :numref:`%s <tab:CellLib_gates_dffsr>`, :numref:`%s <tab:CellLib_gates_dffsre>`, :numref:`%s <tab:CellLib_gates_adlatch>`, diff --git a/docs/source/yosys_internals/formats/index.rst b/docs/source/yosys_internals/formats/index.rst new file mode 100644 index 000000000..4acf9202f --- /dev/null +++ b/docs/source/yosys_internals/formats/index.rst @@ -0,0 +1,11 @@ +Internal formats +================ + +.. toctree:: + :maxdepth: 2 + + overview + rtlil + 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 000000000..cbf5369bc --- /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/CHAPTER_Overview.rst b/docs/source/yosys_internals/formats/rtlil.rst similarity index 68% rename from docs/source/CHAPTER_Overview.rst rename to docs/source/yosys_internals/formats/rtlil.rst index 10d2ce478..d247a5da4 100644 --- a/docs/source/CHAPTER_Overview.rst +++ b/docs/source/yosys_internals/formats/rtlil.rst @@ -1,90 +1,12 @@ -.. _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 <fig:Overview_flow>` 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, +referred to by their full C++ name, i.e. including the RTLIL:: namespace prefix, in this document. :numref:`Figure %s <fig:Overview_RTLIL>` shows a simplified Entity-Relationship @@ -101,14 +23,14 @@ 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.* +.. 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 +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: @@ -133,7 +55,7 @@ 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 @@ -183,7 +105,7 @@ 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 @@ -220,7 +142,7 @@ 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 @@ -265,7 +187,7 @@ 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. @@ -288,10 +210,10 @@ 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 +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: @@ -412,7 +334,7 @@ RTLIL::Process: 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 +RTLIL::Process into e.g. a d-type flip-flop with asynchronous reset and a multiplexer for the enable signal: .. code:: RTLIL @@ -450,7 +372,7 @@ 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: @@ -479,92 +401,7 @@ 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 <sec:memcells>` 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 -<sec:typusecase>` 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. +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 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 dc3d72230..a7f1d843b 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: <autogen-id> ::= $ <nonws>+ 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. <integer> ::= -? <decimal-digit>+ 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. <file> ::= <autoidx-stmt>? <module>* 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-stmt> ::= autoidx <integer> <eol> 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. <module-end-stmt> ::= end <eol> Attribute statements -~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^ Declares an attribute with the given identifier and value. @@ -151,7 +151,7 @@ Declares an attribute with the given identifier and value. <attr-stmt> ::= attribute <id> <constant> <eol> 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 <sec:rtlil_sigspec>` for an overview of signal -specifications. +See :ref:`sec:rtlil_sigspec` for an overview of signal specifications. .. code:: BNF @@ -172,7 +171,7 @@ specifications. | { <sigspec>* } Connections -~~~~~~~~~~~ +^^^^^^^^^^^ Declares a connection between the given signals. @@ -181,12 +180,12 @@ Declares a connection between the given signals. <conn-stmt> ::= connect <sigspec> <sigspec> <eol> Wires -~~~~~ +^^^^^ Declares a wire, with zero or more attributes, with the given identifier and options in the enclosing module. -See :numref:`Sec. %s <sec:rtlil_cell_wire>` 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 <sec:rtlil_cell_wire>` 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 <sec:rtlil_memory>` for an overview of memory cells, and -:numref:`Sec. %s <sec:memcells>` 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 <sec:rtlil_memory>` for an overview of memory cells, and | offset <integer> 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 -<chapter:celllib>` for a detailed list of cell types. +Cells perform functions on input signals. See :ref:`chapter:celllib` 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 <sec:rtlil_process>` 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 <sec:rtlil_process>` for an overview of processes. <proc-end-stmt> ::= end <eol> 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. <switch-end-stmt> ::= end <eol> 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 000000000..e8d6fd1a0 --- /dev/null +++ b/docs/source/yosys_internals/index.rst @@ -0,0 +1,41 @@ +.. _chapter:overview: + +Yosys internals +=============== + +.. TODO: copypaste + +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. + +.. toctree:: + + flow/index + formats/index + techmap + extensions + +.. TODO: copypaste diff --git a/docs/source/CHAPTER_Techmap.rst b/docs/source/yosys_internals/techmap.rst similarity index 93% rename from docs/source/CHAPTER_Techmap.rst rename to docs/source/yosys_internals/techmap.rst index 6cd1eb44f..18eec664b 100644 --- a/docs/source/CHAPTER_Techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -1,5 +1,7 @@ .. _chapter:techmap: +.. TODO: copypaste + Technology mapping ================== @@ -10,8 +12,8 @@ transformed into a functionally equivalent netlist utilizing the cell types available in the target architecture. Technology mapping is often performed in two phases. In the first phase RTL -cells are mapped to an internal library of single-bit cells (see :numref:`Sec. -%s <sec:celllib_gates>`). 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 @@ -33,7 +35,7 @@ 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 +54,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`. @@ -77,7 +79,7 @@ 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. From cd6e63e1a9f129f28b149052b6c2788fa9ad44f9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:20:29 +1200 Subject: [PATCH 003/108] Moved presentation_prog --- docs/images/simplified_rtlil.tex | 20 + .../resources}/PRESENTATION_Prog/.gitignore | 0 .../resources}/PRESENTATION_Prog/Makefile | 0 .../resources}/PRESENTATION_Prog/absval_ref.v | 0 .../resources}/PRESENTATION_Prog/my_cmd.cc | 0 .../PRESENTATION_Prog/sigmap_test.v | 0 docs/source/using_yosys/selections.rst | 2 +- docs/source/yosys_internals/extensions.rst | 258 +++++++- docs/source/yosys_internals/formats/index.rst | 2 +- .../formats/{rtlil.rst => rtlil_rep.rst} | 0 manual/PRESENTATION_Prog.tex | 596 ------------------ 11 files changed, 257 insertions(+), 621 deletions(-) create mode 100644 docs/images/simplified_rtlil.tex rename {manual => docs/resources}/PRESENTATION_Prog/.gitignore (100%) rename {manual => docs/resources}/PRESENTATION_Prog/Makefile (100%) rename {manual => docs/resources}/PRESENTATION_Prog/absval_ref.v (100%) rename {manual => docs/resources}/PRESENTATION_Prog/my_cmd.cc (100%) rename {manual => docs/resources}/PRESENTATION_Prog/sigmap_test.v (100%) rename docs/source/yosys_internals/formats/{rtlil.rst => rtlil_rep.rst} (100%) delete mode 100644 manual/PRESENTATION_Prog.tex diff --git a/docs/images/simplified_rtlil.tex b/docs/images/simplified_rtlil.tex new file mode 100644 index 000000000..9dc0a7d4c --- /dev/null +++ b/docs/images/simplified_rtlil.tex @@ -0,0 +1,20 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\pagestyle{empty} + +\begin{document} +\begin{tikzpicture}[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{document} diff --git a/manual/PRESENTATION_Prog/.gitignore b/docs/resources/PRESENTATION_Prog/.gitignore similarity index 100% rename from manual/PRESENTATION_Prog/.gitignore rename to docs/resources/PRESENTATION_Prog/.gitignore diff --git a/manual/PRESENTATION_Prog/Makefile b/docs/resources/PRESENTATION_Prog/Makefile similarity index 100% rename from manual/PRESENTATION_Prog/Makefile rename to docs/resources/PRESENTATION_Prog/Makefile diff --git a/manual/PRESENTATION_Prog/absval_ref.v b/docs/resources/PRESENTATION_Prog/absval_ref.v similarity index 100% rename from manual/PRESENTATION_Prog/absval_ref.v rename to docs/resources/PRESENTATION_Prog/absval_ref.v diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/docs/resources/PRESENTATION_Prog/my_cmd.cc similarity index 100% rename from manual/PRESENTATION_Prog/my_cmd.cc rename to docs/resources/PRESENTATION_Prog/my_cmd.cc diff --git a/manual/PRESENTATION_Prog/sigmap_test.v b/docs/resources/PRESENTATION_Prog/sigmap_test.v similarity index 100% rename from manual/PRESENTATION_Prog/sigmap_test.v rename to docs/resources/PRESENTATION_Prog/sigmap_test.v diff --git a/docs/source/using_yosys/selections.rst b/docs/source/using_yosys/selections.rst index bdbb762f4..3b81785dc 100644 --- a/docs/source/using_yosys/selections.rst +++ b/docs/source/using_yosys/selections.rst @@ -3,4 +3,4 @@ Selections See :doc:`/cmd/select` -Also :doc:`/cmd/show` +Also :doc:`/cmd/show` and :doc:`/cmd/dump` diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index a9653a7d3..99eba5a76 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -5,44 +5,256 @@ Writing extensions .. TODO: copypaste -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. +This chapter contains some bits and pieces of information about programming +yosys extensions. 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. +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 + :language: none + :caption: guidelines/GettingStarted .. literalinclude:: ../temp/CodingStyle - :language: none - :caption: guidelines/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. +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 + :language: c++ + :linenos: + :caption: docs/source/CHAPTER_Prog/stubnets.cc .. literalinclude:: ../CHAPTER_Prog/Makefile - :language: makefile - :linenos: - :caption: docs/source/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 + :language: verilog + :linenos: + :caption: docs/source/CHAPTER_Prog/test.v + +Quick guide +----------- + +See also: ``docs/resources/PRESENTATION_Prog/*``. + +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 ``proc`` and ``memory`` (or ``memory -nomap``): + +.. figure:: ../../images/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: + +.. 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 ``dump`` and ``show`` before and after the command has +been executed can be helpful. The :doc:`/using_yosys/selections` document has +more information on using these commands. + +.. TODO: copypaste + +Creating modules from scratch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's create the following module using the RTLIL API: + +.. code:: Verilog + + module absval(input signed [3:0] a, output [3:0] y); + assign y = a[3] ? -a : a; + endmodule + +.. code:: 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(); + +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 ``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 slide) when you need a unique handle for each signal bit. + +Using the SigMap helper class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider the following module: + +.. code:: Verilog + + module test(input a, output x, y); + assign x = a, y = a; + endmodule + +In this case ``a``, ``x``, and ``y`` are all different names for the same signal. However: + +.. 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: + +.. 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: + +.. 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()``. + +Creating a command +~~~~~~~~~~~~~~~~~~ + +Simply create a global instance of a class derived from ``Pass`` to create +a new yosys command: + +.. code:: 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<std::string> 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; + +Creating a plugin +~~~~~~~~~~~~~~~~~ + +Yosys can be extended by adding additional C++ code to the Yosys code base, or +by loading plugins into Yosys. + +Use the following command to compile a Yosys plugin: + +.. code:: + + yosys-config --exec --cxx --cxxflags --ldflags \ + -o my_cmd.so -shared my_cmd.cc --ldlibs + +Or shorter: + +.. code:: + + yosys-config --build my_cmd.so my_cmd.cc + +Load the plugin using the yosys ``-m`` option: + +.. code:: + + yosys -m ./my_cmd.so -p 'my_cmd foo bar' diff --git a/docs/source/yosys_internals/formats/index.rst b/docs/source/yosys_internals/formats/index.rst index 4acf9202f..2e6fba017 100644 --- a/docs/source/yosys_internals/formats/index.rst +++ b/docs/source/yosys_internals/formats/index.rst @@ -5,7 +5,7 @@ Internal formats :maxdepth: 2 overview - rtlil + rtlil_rep rtlil_text cell_library diff --git a/docs/source/yosys_internals/formats/rtlil.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst similarity index 100% rename from docs/source/yosys_internals/formats/rtlil.rst rename to docs/source/yosys_internals/formats/rtlil_rep.rst diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex deleted file mode 100644 index b0390cb99..000000000 --- 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<RTLIL::IdString, RTLIL::Module*> modules_; - ... -}; - -struct RTLIL::Module { - RTLIL::IdString name; - dict<RTLIL::IdString, RTLIL::Wire*> wires_; - dict<RTLIL::IdString, RTLIL::Cell*> cells_; - std::vector<RTLIL::SigSig> 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<RTLIL::State> 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<RTLIL::SigBit> 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<RTLIL::IdString, RTLIL::SigSpec> connections_; - dict<RTLIL::IdString, RTLIL::Const> 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::SigSpec, RTLIL::SigSpec> RTLIL::SigSig; - -struct RTLIL::Module { - ... - std::vector<RTLIL::SigSig> 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<std::string> 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} - From 20c2708383a50733af55d051303fe44cdf6a1a14 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:20:29 +1200 Subject: [PATCH 004/108] Move presentation intro example Rework images makefile a bit to get it to import and build from resources folder(s). Currently requires running twice from a clean build due to the way it finds `.dot` files to convert. --- docs/.gitignore | 9 +- docs/images/Makefile | 23 +- docs/images/levels_of_abstraction.tex | 42 ++ .../resources}/PRESENTATION_Intro/.gitignore | 4 + docs/resources/PRESENTATION_Intro/Makefile | 10 + .../resources}/PRESENTATION_Intro/counter.v | 0 docs/resources/PRESENTATION_Intro/counter.ys | 21 + .../PRESENTATION_Intro/counter_outputs.ys | 8 +- .../resources}/PRESENTATION_Intro/mycells.lib | 0 .../resources}/PRESENTATION_Intro/mycells.v | 0 docs/source/getting_started/examples.rst | 117 ++++- docs/source/introduction.rst | 30 +- docs/source/yosys_internals/flow/index.rst | 10 + manual/PRESENTATION_Intro.tex | 403 ------------------ manual/PRESENTATION_Intro/Makefile | 10 - 15 files changed, 249 insertions(+), 438 deletions(-) create mode 100644 docs/images/levels_of_abstraction.tex rename {manual => docs/resources}/PRESENTATION_Intro/.gitignore (50%) create mode 100644 docs/resources/PRESENTATION_Intro/Makefile rename {manual => docs/resources}/PRESENTATION_Intro/counter.v (100%) create mode 100644 docs/resources/PRESENTATION_Intro/counter.ys rename manual/PRESENTATION_Intro/counter.ys => docs/resources/PRESENTATION_Intro/counter_outputs.ys (59%) rename {manual => docs/resources}/PRESENTATION_Intro/mycells.lib (100%) rename {manual => docs/resources}/PRESENTATION_Intro/mycells.v (100%) delete mode 100644 manual/PRESENTATION_Intro/Makefile diff --git a/docs/.gitignore b/docs/.gitignore index e36f2309a..40b781904 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -5,7 +5,8 @@ /images/*.aux /images/*.pdf /images/*.svg -/images/011/*.log -/images/011/*.aux -/images/011/*.pdf -/images/011/*.svg +/images/**/*.log +/images/**/*.aux +/images/**/*.pdf +/images/**/*.svg +/images/**/*.dot diff --git a/docs/images/Makefile b/docs/images/Makefile index a7216ec90..ed0255b09 100644 --- a/docs/images/Makefile +++ b/docs/images/Makefile @@ -1,9 +1,23 @@ -all: dots tex svg tidy +all: resources dots tex svg tidy + +RES_LIST:= PRESENTATION_Intro/ +RES_DIRS:= $(addprefix ../resources/,$(RES_LIST)) +.PHONY: resources +resources: $(RES_DIRS) +FORCE: +../resources/%: FORCE + @$(MAKE) -C $@ + @mkdir -p res/$* + @cp --update -t res/$* $@*.dot TEX_SOURCE:= $(wildcard *.tex) DOT_LOC:= ../source/APPNOTE_011_Design_Investigation DOT_SOURCE:= $(wildcard $(DOT_LOC)/*.dot) +RES_DOTS:= $(wildcard res/*/*.dot) +RES_DIRS:= $(sort $(dir $(RES_DOTS))) +RES_PDF:= $(RES_DOTS:%.dot=%.pdf) + 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 @@ -15,15 +29,18 @@ TEX_SOURCE+= 011/submod_dots.tex 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)) +SVG_OUTPUT:= $(patsubst %.pdf,%.svg,$(TEX_PDF) $(DOT_PDF) $(RES_PDF)) -dots: $(DOT_PDF) +dots: $(DOT_PDF) $(RES_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 $@ $< +res/%.pdf: res/%.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 $(<F) --interaction=nonstopmode diff --git a/docs/images/levels_of_abstraction.tex b/docs/images/levels_of_abstraction.tex new file mode 100644 index 000000000..55725d08e --- /dev/null +++ b/docs/images/levels_of_abstraction.tex @@ -0,0 +1,42 @@ +\documentclass[12pt,tikz]{standalone} +\pdfinfoomitdate 1 +\pdfsuppressptexinfo 1 +\pdftrailerid{} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{pgfplots} +\usepackage{tikz} +\pagestyle{empty} +\definecolor{MyBlue}{RGB}{85,130,180} + +\begin{document} +\begin{tikzpicture}[scale=1.2, 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{document} diff --git a/manual/PRESENTATION_Intro/.gitignore b/docs/resources/PRESENTATION_Intro/.gitignore similarity index 50% rename from manual/PRESENTATION_Intro/.gitignore rename to docs/resources/PRESENTATION_Intro/.gitignore index d0c4618ac..c3cbb8c51 100644 --- a/manual/PRESENTATION_Intro/.gitignore +++ b/docs/resources/PRESENTATION_Intro/.gitignore @@ -2,3 +2,7 @@ counter_00.dot counter_01.dot counter_02.dot counter_03.dot +counter_00.pdf +counter_01.pdf +counter_02.pdf +counter_03.pdf diff --git a/docs/resources/PRESENTATION_Intro/Makefile b/docs/resources/PRESENTATION_Intro/Makefile new file mode 100644 index 000000000..48946f1e1 --- /dev/null +++ b/docs/resources/PRESENTATION_Intro/Makefile @@ -0,0 +1,10 @@ + +all: counter_00.dot counter_01.dot counter_02.dot counter_03.dot + +counter_00.dot: counter.v counter.ys mycells.lib + ../../../yosys counter_outputs.ys + +counter_01.dot: counter_00.dot +counter_02.dot: counter_00.dot +counter_03.dot: counter_00.dot + diff --git a/manual/PRESENTATION_Intro/counter.v b/docs/resources/PRESENTATION_Intro/counter.v similarity index 100% rename from manual/PRESENTATION_Intro/counter.v rename to docs/resources/PRESENTATION_Intro/counter.v diff --git a/docs/resources/PRESENTATION_Intro/counter.ys b/docs/resources/PRESENTATION_Intro/counter.ys new file mode 100644 index 000000000..5582f1b78 --- /dev/null +++ b/docs/resources/PRESENTATION_Intro/counter.ys @@ -0,0 +1,21 @@ +# read design +read_verilog counter.v +hierarchy -check -top counter + +# the high-level stuff +proc; opt; memory; opt; fsm; opt + +# mapping to internal cell library +techmap; opt + +# mapping flip-flops to mycells.lib +dfflibmap -liberty mycells.lib + +# mapping logic to mycells.lib +abc -liberty mycells.lib + +# cleanup +clean + +# write synthesized design +write_verilog synth.v diff --git a/manual/PRESENTATION_Intro/counter.ys b/docs/resources/PRESENTATION_Intro/counter_outputs.ys similarity index 59% rename from manual/PRESENTATION_Intro/counter.ys rename to docs/resources/PRESENTATION_Intro/counter_outputs.ys index cc4e7cd31..a35c83d6f 100644 --- a/manual/PRESENTATION_Intro/counter.ys +++ b/docs/resources/PRESENTATION_Intro/counter_outputs.ys @@ -2,18 +2,18 @@ read_verilog counter.v hierarchy -check -top counter -show -notitle -stretch -format pdf -prefix counter_00 +show -notitle -format dot -prefix counter_00 # the high-level stuff proc; opt; memory; opt; fsm; opt -show -notitle -stretch -format pdf -prefix counter_01 +show -notitle -format dot -prefix counter_01 # mapping to internal cell library techmap; opt splitnets -ports;; -show -notitle -stretch -format pdf -prefix counter_02 +show -notitle -format dot -prefix counter_02 # mapping flip-flops to mycells.lib dfflibmap -liberty mycells.lib @@ -24,4 +24,4 @@ abc -liberty mycells.lib # cleanup clean -show -notitle -stretch -lib mycells.v -format pdf -prefix counter_03 +show -notitle -lib mycells.v -format dot -prefix counter_03 diff --git a/manual/PRESENTATION_Intro/mycells.lib b/docs/resources/PRESENTATION_Intro/mycells.lib similarity index 100% rename from manual/PRESENTATION_Intro/mycells.lib rename to docs/resources/PRESENTATION_Intro/mycells.lib diff --git a/manual/PRESENTATION_Intro/mycells.v b/docs/resources/PRESENTATION_Intro/mycells.v similarity index 100% rename from manual/PRESENTATION_Intro/mycells.v rename to docs/resources/PRESENTATION_Intro/mycells.v diff --git a/docs/source/getting_started/examples.rst b/docs/source/getting_started/examples.rst index 88458c50e..30a522ba3 100644 --- a/docs/source/getting_started/examples.rst +++ b/docs/source/getting_started/examples.rst @@ -13,38 +13,133 @@ synth.v using the cell library described by the Liberty file : .. code:: yoscrypt :number-lines: - # read input file to internal representation + #. read input file to internal representation read_verilog design.v - # convert high-level behavioral parts ("processes") to d-type flip-flops and muxes + #. convert high-level behavioral parts ("processes") to d-type flip-flops and muxes proc - # perform some simple optimizations + #. perform some simple optimizations opt - # convert high-level memory constructs to d-type flip-flops and multiplexers + #. convert high-level memory constructs to d-type flip-flops and multiplexers memory - # perform some simple optimizations + #. perform some simple optimizations opt - # convert design to (logical) gate-level netlists + #. convert design to (logical) gate-level netlists techmap - # perform some simple optimizations + #. perform some simple optimizations opt - # map internal register types to the ones from the cell library + #. 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 + #. use ABC to map remaining logic to cells from the cell library abc -liberty cells.lib - # cleanup + #. cleanup opt - # write results to output file + #. 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`. + +Simple synthesis script +~~~~~~~~~~~~~~~~~~~~~~~ + +This section covers an example project available in +``docs/resources/PRESENTATION_Intro/*``. The project contains a simple ASIC +synthesis script (``counter.ys``), a digital design written in Verilog +(``counter.v``), and a simple CMOS cell library (``mycells.lib``). + +.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_Intro/counter.ys`` + +.. role:: yoscrypt(code) + :language: yoscrypt + +#. :yoscrypt:`read_verilog counter.v` - Read Verilog source file and convert to + internal representation. +#. :yoscrypt:`hierarchy -check -top counter` - Elaborate the design hierarchy. + Should always be the first command after reading the design. Can re-run AST front-end. +#. :yoscrypt:`proc` - Convert ``processes`` (the internal representation of + behavioral Verilog code) into multiplexers and registers. +#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. +#. :yoscrypt:`fsm` - Analyze and optimize finite state machines. +#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. +#. :yoscrypt:`memory` - Analyze memories and create circuits to implement them. +#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. +#. :yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain + logic gates (AND, OR, NOT, etc.). +#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. +#. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available + hardware flip-flops. +#. :yoscrypt:`abc -liberty mycells.lib` - Map logic to available hardware gates. +#. :yoscrypt:`clean` - Clean up the design (just the last step of ``opt``). +#. :yoscrypt:`write_verilog synth.v` - Write final synthesis result to output + file. + +Running the script +^^^^^^^^^^^^^^^^^^ + +.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.v + :language: Verilog + :caption: ``docs/resources/PRESENTATION_Intro/counter.v`` + +.. literalinclude:: ../../resources/PRESENTATION_Intro/mycells.lib + :language: Liberty + :caption: ``docs/resources/PRESENTATION_Intro/mycells.lib`` + +Step 1 +"""""" + +.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys + :language: yoscrypt + :lines: 1-3 + +Result: + +.. figure:: ../../images/res/PRESENTATION_Intro/counter_00.* + :class: width-helper + +Step 2 +"""""" + +.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys + :language: yoscrypt + :lines: 5-6 + +Result: + +.. figure:: ../../images/res/PRESENTATION_Intro/counter_01.* + :class: width-helper + +Step 3 +"""""" + +.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys + :language: yoscrypt + :lines: 8-9 + +Result: + +.. figure:: ../../images/res/PRESENTATION_Intro/counter_02.* + :class: width-helper + +Step 4 +"""""" + +.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys + :language: yoscrypt + :lines: 11-18 + +Result: + +.. figure:: ../../images/res/PRESENTATION_Intro/counter_03.* + :class: width-helper diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index c4d6c1285..f9be83ec5 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -28,13 +28,37 @@ What is Yosys This document was originally published as bachelor thesis at the Vienna University of Technology :cite:p:`BACC`. -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. +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/levels_of_abstraction.* + :class: width-helper + :name: fig:Levels_of_abstraction + + Where Yosys exists in the layers of abstraction 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 + +Things you can't do +~~~~~~~~~~~~~~~~~~~ + +- Process high-level languages such as C/C++/SystemC +- Create physical layouts (place&route) + + Check out `nextpnr`_ for that + +.. _nextpnr: https://github.com/YosysHQ/nextpnr + The extended Yosys universe --------------------------- diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst index a235996e9..195e50f64 100644 --- a/docs/source/yosys_internals/flow/index.rst +++ b/docs/source/yosys_internals/flow/index.rst @@ -1,6 +1,16 @@ Internal flow ============= + +A (usually short) synthesis script controls Yosys. + +This 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: 2 diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 1c3b79fa0..acd909c12 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -8,247 +8,6 @@ \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} @@ -265,168 +24,6 @@ Direct link to the files: \\ \footnotesize %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\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{}} diff --git a/manual/PRESENTATION_Intro/Makefile b/manual/PRESENTATION_Intro/Makefile deleted file mode 100644 index abc354e46..000000000 --- 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 - From 9a9aa2c45af70c25cd6e919b52f783e124e74274 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:20:30 +1200 Subject: [PATCH 005/108] Finished presentation intro Also some other tidy up. --- .../getting_started/scripting_intro.rst | 93 ++- docs/source/introduction.rst | 54 ++ docs/source/test_suites.rst | 50 +- docs/source/using_yosys/index.rst | 2 +- .../index.rst} | 1 + .../{ => more_scripting}/opt_passes.rst | 107 ++-- .../{ => more_scripting}/selections.rst | 0 .../using_yosys/more_scripting/synth.rst | 9 + .../{ => more_scripting}/troubleshooting.rst | 0 docs/source/yosys_internals/extensions.rst | 4 +- manual/PRESENTATION_Intro.tex | 553 ------------------ 11 files changed, 259 insertions(+), 614 deletions(-) rename docs/source/using_yosys/{more_scripting.rst => more_scripting/index.rst} (92%) rename docs/source/using_yosys/{ => more_scripting}/opt_passes.rst (76%) rename docs/source/using_yosys/{ => more_scripting}/selections.rst (100%) create mode 100644 docs/source/using_yosys/more_scripting/synth.rst rename docs/source/using_yosys/{ => more_scripting}/troubleshooting.rst (100%) delete mode 100644 manual/PRESENTATION_Intro.tex diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 5c6f7398c..a6e891e2e 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -10,7 +10,93 @@ terminated using the newline character or a semicolon (;). Empty lines and lines starting with the hash sign (#) are ignored. See :ref:`sec:typusecase` for an example synthesis script. -The command ``help`` can be used to access the command reference manual. +The command ``help`` can be used to access the command reference manual, with +``help <command>`` providing details for a specific command. ``yosys -H`` or +``yosys -h <command>`` will do the same outside of an interactive prompt. The +entire reference manual is also available here at :doc:`/cmd_ref`. + +Example commands +~~~~~~~~~~~~~~~~ + +Commands for design navigation and investigation: + +.. code-block:: yoscrypt + + cd # a shortcut for 'select -module <name>' + 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 + +Commands for executing scripts or entering interactive mode: + +.. code-block:: yoscrypt + + shell # enter interactive command mode + history # show last interactive commands + script # execute commands from script file + tcl # execute a TCL script file + +Commands for reading and elaborating the design: + +.. code-block:: yoscrypt + + read_rtlil # read modules from RTLIL file + read_verilog # read modules from Verilog file + hierarchy # check, expand and clean up design hierarchy + + +Commands for high-level synthesis: + +.. code-block:: yoscrypt + + proc # translate processes to netlists + fsm # extract and optimize finite state machines + memory # translate memories to basic cells + opt # perform simple optimizations + + +Commands for technology mapping: + +.. code-block:: yoscrypt + + 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 + +Commands for writing the results: + +.. code-block:: yoscrypt + + 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 + + +Script-Commands for standard synthesis tasks: + +.. code-block:: yoscrypt + + synth # generic synthesis script + synth_xilinx # synthesis for Xilinx FPGAs + + +Commands for model checking: + +.. code-block:: yoscrypt + + sat # solve a SAT problem in the circuit + miter # automatically create a miter circuit + scc # detect strongly connected components (logic loops) + +Selections intro +~~~~~~~~~~~~~~~~ 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 @@ -24,5 +110,6 @@ selection. 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. +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`. diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index f9be83ec5..db43f2f78 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -59,6 +59,60 @@ Things you can't do .. _nextpnr: https://github.com/YosysHQ/nextpnr +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, ...) + +Benefits of open source HDL synthesis +------------------------------------- + +- Cost (also applies to ``free as in free beer`` solutions): + + 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. + +- 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. + +.. note:: 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. + The extended Yosys universe --------------------------- diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index fbf1e98b4..18cccca7c 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -1,8 +1,52 @@ Test suites =========== -Build tests ------------ +.. TODO: copypaste -Benchmarking +Continuously checking the correctness of Yosys and making sure that new features +do not break old ones is a high priority in Yosys. Two external test suites +have been built for Yosys: VlogHammer and yosys-bigsim. In addition to that, +yosys comes with approx 200 test cases used in ``make test``. A debug build of +Yosys also contains a lot of asserts and checks the integrity of the internal +state after each command. + +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, ...). + +Yosys Subsystems tested: Verilog frontend, const folding, const eval, technology +mapping, simulation models, SAT models. + +Thousands of auto-generated test cases containing code such as: + +.. code-block:: 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}))))})); + +Some bugs in Yosys were found and fixed thanks to VlogHammer. Over 50 bugs in +the other tools used as external reference where found and reported so far. + +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. + +The following designs are included in yosys-bigsim (excerpt): + +- ``openmsp430`` -- an MSP430 compatible 16 bit CPU +- ``aes_5cycle_2stage`` -- an AES encryption core +- ``softusb_navre`` -- an AVR compatible 8 bit CPU +- ``amber23`` -- an ARMv2 compatible 32 bit CPU +- ``lm32`` -- another 32 bit CPU from Lattice Semiconductor +- ``verilog-pong`` -- a hardware pong game with VGA output +- ``elliptic_curve_group`` -- ECG point-add and point-scalar-mul core +- ``reed_solomon_decoder`` -- a Reed-Solomon Error Correction Decoder + +Code available at https://github.com/YosysHQ/yosys-bigsim diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst index ea451d395..fd8b2171f 100644 --- a/docs/source/using_yosys/index.rst +++ b/docs/source/using_yosys/index.rst @@ -4,6 +4,6 @@ Using Yosys (advanced) .. toctree:: :maxdepth: 2 - more_scripting + more_scripting/index memory_mapping yosys_flows diff --git a/docs/source/using_yosys/more_scripting.rst b/docs/source/using_yosys/more_scripting/index.rst similarity index 92% rename from docs/source/using_yosys/more_scripting.rst rename to docs/source/using_yosys/more_scripting/index.rst index e9e005c5e..32aa8fc04 100644 --- a/docs/source/using_yosys/more_scripting.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -5,4 +5,5 @@ More scripting opt_passes selections + synth troubleshooting diff --git a/docs/source/using_yosys/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst similarity index 76% rename from docs/source/using_yosys/opt_passes.rst rename to docs/source/using_yosys/more_scripting/opt_passes.rst index 8905a3455..fc1ba6063 100644 --- a/docs/source/using_yosys/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -11,26 +11,26 @@ This chapter outlines these optimizations. Simple optimizations -------------------- -The Yosys pass opt runs a number of simple optimizations. This includes removing +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: +``opt`` pass executes the following passes that each perform a simple optimization: -- Once at the beginning of opt: +- Once at the beginning of ``opt``: - - opt_expr - - opt_merge -nomux + - ``opt_expr`` + - ``opt_merge -nomux`` - Repeat until result is stable: - - opt_muxtree - - opt_reduce - - opt_merge - - opt_rmdff - - opt_clean - - opt_expr + - ``opt_muxtree`` + - ``opt_reduce`` + - ``opt_merge`` + - ``opt_rmdff`` + - ``opt_clean`` + - ``opt_expr`` -The following section describes each of the opt\_ passes. +The following section describes each of the ``opt_`` passes. The opt_expr pass ~~~~~~~~~~~~~~~~~ @@ -40,7 +40,7 @@ described in :ref:`chapter:celllib`. 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. +.. table:: Const folding rules for ``$_AND_`` cells as used in opt_expr. :name: tab:opt_expr_and :align: center @@ -65,26 +65,26 @@ cases this pass can also optimize cells with some constant inputs. .. How to format table? :numref:`Table %s <tab:opt_expr_and>` 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 +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' +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. +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. +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 +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 @@ -107,16 +107,16 @@ 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. +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. +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. +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. @@ -124,8 +124,9 @@ 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. +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 ~~~~~~~~~~~~~~~~~~ @@ -141,9 +142,10 @@ 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. +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 --------------------------- @@ -187,12 +189,12 @@ fsm pass simply executes the following other passes: 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. +"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 +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 @@ -207,11 +209,12 @@ 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. +- 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 + 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 @@ -246,10 +249,10 @@ information is determined: 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. +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 @@ -281,17 +284,17 @@ transition table. For each state: 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 +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): +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 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. diff --git a/docs/source/using_yosys/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst similarity index 100% rename from docs/source/using_yosys/selections.rst rename to docs/source/using_yosys/more_scripting/selections.rst diff --git a/docs/source/using_yosys/more_scripting/synth.rst b/docs/source/using_yosys/more_scripting/synth.rst new file mode 100644 index 000000000..c56163360 --- /dev/null +++ b/docs/source/using_yosys/more_scripting/synth.rst @@ -0,0 +1,9 @@ +Introduction to synthesis +------------------------- + +The following commands are executed by the ``synth`` command: + +.. literalinclude:: /cmd/synth.rst + :start-at: begin: + :end-before: .. raw:: latex + :dedent: diff --git a/docs/source/using_yosys/troubleshooting.rst b/docs/source/using_yosys/more_scripting/troubleshooting.rst similarity index 100% rename from docs/source/using_yosys/troubleshooting.rst rename to docs/source/using_yosys/more_scripting/troubleshooting.rst diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index 99eba5a76..1b601acbd 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -78,8 +78,8 @@ It is possible to only work on this simpler version: When trying to understand what a command does, creating a small test case to look at the output of ``dump`` and ``show`` before and after the command has -been executed can be helpful. The :doc:`/using_yosys/selections` document has -more information on using these commands. +been executed can be helpful. The :doc:`/using_yosys/more_scripting/selections` +document has more information on using these commands. .. TODO: copypaste diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex deleted file mode 100644 index acd909c12..000000000 --- a/manual/PRESENTATION_Intro.tex +++ /dev/null @@ -1,553 +0,0 @@ - -\section{Introduction to Yosys} - -\begin{frame} -\sectionpage -\end{frame} - -\iffalse -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\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} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\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 <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 <name>' - 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} - From 2c75b103d6480d41a22a7045a11d30391cf95911 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 09:20:30 +1200 Subject: [PATCH 006/108] Include test suites doc with note --- docs/source/conf.py | 5 ----- docs/source/test_suites.rst | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 512521a83..bca4971e9 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -51,11 +51,6 @@ numfig = True bibtex_bibfiles = ['literature.bib'] -# unused docs -exclude_patterns = [ - "test_suites.rst" -] - latex_elements = { 'preamble': r''' \usepackage{lmodern} diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index 18cccca7c..bc56bbf77 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -1,6 +1,9 @@ Test suites =========== +.. note:: Potentially significantly out of date information + last updated circa 2015 + .. TODO: copypaste Continuously checking the correctness of Yosys and making sure that new features From 4b4037244642c7a508a6ca150ddea6393fc68b8f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 3 Aug 2023 10:23:39 +1200 Subject: [PATCH 007/108] Tidy/reflow some things --- .../appendix/APPNOTE_010_Verilog_to_BLIF.rst | 69 ++- .../APPNOTE_011_Design_Investigation.rst | 6 +- docs/source/appendix/primer.rst | 2 +- docs/source/getting_started/installation.rst | 14 +- .../getting_started/scripting_intro.rst | 10 +- docs/source/introduction.rst | 20 +- .../using_yosys/more_scripting/opt_passes.rst | 2 +- .../yosys_internals/flow/verilog_frontend.rst | 517 +++++++++--------- .../yosys_internals/formats/cell_library.rst | 22 +- .../yosys_internals/formats/rtlil_rep.rst | 214 ++++---- 10 files changed, 433 insertions(+), 443 deletions(-) diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index a48401dcc..d4448895b 100644 --- a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst +++ b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst @@ -189,13 +189,13 @@ 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.) +(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 +``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. @@ -235,18 +235,18 @@ signal is connected throughout the whole design hierarchy. 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. +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. +``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 @@ -298,39 +298,36 @@ 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. +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. +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. +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. +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. +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. +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. +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 index 44819e283..d2b33bd1c 100644 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst @@ -315,7 +315,7 @@ 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 ``<module_name>/``. For example -``a*/b\*`` would refer to all objects whose names start with ``b`` from all +``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 @@ -416,7 +416,7 @@ will select all ``$add ``cells that have the ``foo`` attribute set: select t:$add a:foo %i -The listing in :numref:`sumprod` uses the Yosys non-standard ``{... \*}`` syntax +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.) @@ -467,7 +467,7 @@ 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 +The action ``%ci*`` performs the ``%ci`` action over and over again until it has no effect anymore. .. figure:: ../../images/011/select_prod.* diff --git a/docs/source/appendix/primer.rst b/docs/source/appendix/primer.rst index ed1a3188c..6c9aa1673 100644 --- a/docs/source/appendix/primer.rst +++ b/docs/source/appendix/primer.rst @@ -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): diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index b83296816..0b7f52b1d 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -43,15 +43,15 @@ directories: 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. +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. +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. diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index a6e891e2e..9f7ae2ba7 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -99,14 +99,14 @@ Selections intro ~~~~~~~~~~~~~~~~ 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. +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 + 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. diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index db43f2f78..81d89d7a6 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -50,15 +50,6 @@ What you can do with Yosys - Perform all kinds of operations on netlist (RTL, Logic, Gate) - Perform logic optimizations and gate mapping with ABC -Things you can't do -~~~~~~~~~~~~~~~~~~~ - -- Process high-level languages such as C/C++/SystemC -- Create physical layouts (place&route) - + Check out `nextpnr`_ for that - -.. _nextpnr: https://github.com/YosysHQ/nextpnr - Typical applications for Yosys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -71,12 +62,21 @@ Typical applications for Yosys - 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 + +.. _nextpnr: https://github.com/YosysHQ/nextpnr + Benefits of open source HDL synthesis ------------------------------------- - Cost (also applies to ``free as in free beer`` solutions): - Today the cost for a mask set in $\unit[180]{nm}$ technology is far less than + 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. diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index fc1ba6063..387a3fb1f 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -143,7 +143,7 @@ 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 +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. diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index cded945e5..cb5b65d8a 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -19,54 +19,53 @@ 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. +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 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`. +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``. +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. +``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 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.) +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. +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 +``frontends/ast/ast.h``. An ``AST::AstNode`` object has the following properties: .. list-table:: AST node types with their corresponding Verilog constructs. @@ -152,35 +151,32 @@ properties: - | The node type | This enum (``AST::AstNodeType``) specifies the role of the node. - :numref:`Table %s <tab:Verilog_AstNodeType>` - contains a list of all node types. + :numref:`Table %s <tab:Verilog_AstNodeType>` contains a list of all node + types. - | The child nodes - | This is a list of pointers to all children in the abstract syntax - tree. + | 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. + | 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. + | 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. + | 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: +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: @@ -190,49 +186,50 @@ multiplications: append_attr($$, $3); } | -The generated AST data structure is then passed directly to the AST -frontend that performs the actual conversion to RTLIL. +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. +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 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. +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: +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). +- 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 ``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. + ``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 + ``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. +- 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, @@ -242,70 +239,66 @@ namely: 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. +- 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. +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. +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: +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. +``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 $\ <number> \\\ <original_name> for each -of the assigned signals. +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 ``$ <number> \ <original_name>`` 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 +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. +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. +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. +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: +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: @@ -325,9 +318,8 @@ the algorithm is supposed to do. Consider the following Verilog code: 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): +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: @@ -372,47 +364,47 @@ included): 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. +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: +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.) +- 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. + 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. + 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". + 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. +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 @@ -426,64 +418,62 @@ 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. + | 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 - (\\\ <name>) to the current temporary signal for the same thing - (initially $0\\\ <name>). +- | ``subst_lvalue_from`` and ``subst_lvalue_to`` + | These two variables contain the mapping from left-hand-side signals (``\ + <name>``) to the current temporary signal for the same thing (initially + ``$0\ <name>``). -- | ``current_case`` - | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the - root case of the generated ``RTLIL::Process``. +- | ``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. +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. +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`` +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 +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 +- 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. +- 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. +- 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 +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). +- 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 @@ -496,36 +486,33 @@ performed by the ProcessGenerator: Handling of cases and if-statements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When an AST_CASE node is discovered, the following actions are performed -by the ProcessGenerator: +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. + ``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``. +- 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 +- 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``. +- 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: +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. +- 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``. @@ -535,33 +522,30 @@ AST_CASE node: - 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. +- 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``. +- 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. +- 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. + ``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``. +- 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``. @@ -569,98 +553,99 @@ Finally the following steps are performed: - 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``. +- 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. +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. +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. +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 +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 +``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: +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_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 +- | 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. + 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. -- | 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_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. - | proc_dff - | This pass replaces the s to d-type flip-flops (with asynchronous - resets if necessary). + | This pass replaces the ``RTLIL::SyncRule`` s to d-type flip-flops (with + asynchronous resets if necessary). - | proc_dff - | This pass replaces the s with $memwr cells. + | This pass replaces the ``RTLIL::MemWriteAction`` s with ``$memwr`` cells. - | proc_clean - | A final call to proc_clean removes the now empty objects. + | A final call to ``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: +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. +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. +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 +.. TODO: these + +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. +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/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index 67e1fc0ef..7768c3cc9 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -816,17 +816,17 @@ techlibs/common/simcells.v in the Yosys source tree. ============== ============== ========= -Tables \ :numref:`%s <tab:CellLib_gates>`, :numref:`%s -<tab:CellLib_gates_dffe>`, :numref:`%s <tab:CellLib_gates_adff>`, :numref:`%s -<tab:CellLib_gates_adffe>`, :numref:`%s <tab:CellLib_gates_dffsr>`, :numref:`%s -<tab:CellLib_gates_dffsre>`, :numref:`%s <tab:CellLib_gates_adlatch>`, -:numref:`%s <tab:CellLib_gates_dlatchsr>` and :numref:`%s -<tab:CellLib_gates_sr>` 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 <tab:CellLib_gates>`, :numref:`%s <tab:CellLib_gates_dffe>`, +:numref:`%s <tab:CellLib_gates_adff>`, :numref:`%s <tab:CellLib_gates_adffe>`, +:numref:`%s <tab:CellLib_gates_dffsr>`, :numref:`%s <tab:CellLib_gates_dffsre>`, +:numref:`%s <tab:CellLib_gates_adlatch>`, :numref:`%s +<tab:CellLib_gates_dlatchsr>` and :numref:`%s <tab:CellLib_gates_sr>` 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: diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index d247a5da4..4ed7d9107 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -6,21 +6,21 @@ 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, +referred to by their full C++ name, i.e. including the ``RTLIL::`` namespace prefix, in this document. :numref:`Figure %s <fig:Overview_RTLIL>` 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 +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 +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 +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 +additional ``RTLIL::Design`` object and call the Verilog frontend with this other object to parse the cell library. .. figure:: ../../../images/overview_rtlil.* @@ -29,23 +29,23 @@ object to parse the cell library. Simplified RTLIL Entity-Relationship Diagram -There is only one active RTLIL::Design object that is used by all frontends, +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 +``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::Cell`` and ``RTLIL::Wire`` objects represent classical netlist data. -- RTLIL::Process objects represent the decision trees (if-then-else statements, +- ``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). +- ``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. +``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. @@ -63,19 +63,22 @@ 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. +``\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. +.. TODO: does opt_rmunused (still?) exist? + - 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 + 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. @@ -98,25 +101,25 @@ 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 "\". +``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. +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 -<fig:Overview_RTLIL>` an RTLIL::Module object contains the following additional -properties: +Besides the objects shown in the :ref:`ER diagram <fig:Overview_RTLIL>` above, +an ``RTLIL::Module`` object contains the following additional properties: - The module name - A list of attributes @@ -132,7 +135,7 @@ 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 +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 @@ -144,14 +147,14 @@ hash string.) 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. +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: +An ``RTLIL::Wire`` object has the following properties: - The wire name - A list of attributes @@ -174,15 +177,16 @@ 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: +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. +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: @@ -200,12 +204,12 @@ A "signal" is everything that can be applied to a cell port. I.e. - | 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. +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. +``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: @@ -213,9 +217,9 @@ 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: +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: @@ -230,9 +234,9 @@ logic of the behavioural code. Let's consider a simple example: 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: +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: @@ -255,34 +259,37 @@ The RTLIL::Process in RTLIL syntax: 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. +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::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::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. +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`). +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 @@ -299,8 +306,8 @@ 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. +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 @@ -313,8 +320,8 @@ 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: +the ``proc_arst`` pass. This pass transforms the above example to the following +``RTLIL::Process``: .. code:: RTLIL :number-lines: @@ -332,9 +339,9 @@ RTLIL::Process: 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 +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 @@ -358,11 +365,11 @@ multiplexer for the enable signal: 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. +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 +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 @@ -374,7 +381,7 @@ synthesis tasks. RTLIL::Memory ------------- -For every array (memory) in the HDL code an RTLIL::Memory object is created. A +For every array (memory) in the HDL code an ``RTLIL::Memory`` object is created. A memory object has the following properties: - The memory name @@ -382,27 +389,28 @@ memory object has the following properties: - 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. +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 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). +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"). + 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``). From 330a2272daf57cc37dc6d0bf42044f1b11f269eb Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:29:14 +1200 Subject: [PATCH 008/108] Converting PRESENTATION_ExSyn --- docs/images/Makefile | 2 +- .../resources}/PRESENTATION_ExSyn/.gitignore | 1 + .../resources}/PRESENTATION_ExSyn/Makefile | 2 +- .../resources}/PRESENTATION_ExSyn/abc_01.v | 0 .../resources}/PRESENTATION_ExSyn/abc_01.ys | 0 .../PRESENTATION_ExSyn/abc_01_cells.lib | 0 .../PRESENTATION_ExSyn/abc_01_cells.v | 0 .../resources}/PRESENTATION_ExSyn/memory_01.v | 0 .../PRESENTATION_ExSyn/memory_01.ys | 0 .../resources}/PRESENTATION_ExSyn/memory_02.v | 0 .../PRESENTATION_ExSyn/memory_02.ys | 0 .../resources}/PRESENTATION_ExSyn/opt_01.v | 0 .../resources}/PRESENTATION_ExSyn/opt_01.ys | 0 .../resources}/PRESENTATION_ExSyn/opt_02.v | 0 .../resources}/PRESENTATION_ExSyn/opt_02.ys | 0 .../resources}/PRESENTATION_ExSyn/opt_03.v | 0 .../resources}/PRESENTATION_ExSyn/opt_03.ys | 0 .../resources}/PRESENTATION_ExSyn/opt_04.v | 0 .../resources}/PRESENTATION_ExSyn/opt_04.ys | 0 .../resources}/PRESENTATION_ExSyn/proc_01.v | 0 .../resources}/PRESENTATION_ExSyn/proc_01.ys | 0 .../resources}/PRESENTATION_ExSyn/proc_02.v | 0 .../resources}/PRESENTATION_ExSyn/proc_02.ys | 0 .../resources}/PRESENTATION_ExSyn/proc_03.v | 0 .../resources}/PRESENTATION_ExSyn/proc_03.ys | 0 .../PRESENTATION_ExSyn/techmap_01.v | 0 .../PRESENTATION_ExSyn/techmap_01.ys | 0 .../PRESENTATION_ExSyn/techmap_01_map.v | 0 docs/source/getting_started/index.rst | 1 + .../source/getting_started/typical_phases.rst | 438 +++++++++++++++ manual/PRESENTATION_ExSyn.tex | 515 ------------------ 31 files changed, 442 insertions(+), 517 deletions(-) rename {manual => docs/resources}/PRESENTATION_ExSyn/.gitignore (50%) rename {manual => docs/resources}/PRESENTATION_ExSyn/Makefile (83%) rename {manual => docs/resources}/PRESENTATION_ExSyn/abc_01.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/abc_01.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/abc_01_cells.lib (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/abc_01_cells.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/memory_01.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/memory_01.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/memory_02.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/memory_02.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_01.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_01.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_02.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_02.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_03.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_03.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_04.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/opt_04.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/proc_01.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/proc_01.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/proc_02.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/proc_02.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/proc_03.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/proc_03.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/techmap_01.v (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/techmap_01.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExSyn/techmap_01_map.v (100%) create mode 100644 docs/source/getting_started/typical_phases.rst delete mode 100644 manual/PRESENTATION_ExSyn.tex diff --git a/docs/images/Makefile b/docs/images/Makefile index ed0255b09..4c84a01db 100644 --- a/docs/images/Makefile +++ b/docs/images/Makefile @@ -1,6 +1,6 @@ all: resources dots tex svg tidy -RES_LIST:= PRESENTATION_Intro/ +RES_LIST:= PRESENTATION_Intro/ PRESENTATION_ExSyn/ RES_DIRS:= $(addprefix ../resources/,$(RES_LIST)) .PHONY: resources resources: $(RES_DIRS) diff --git a/manual/PRESENTATION_ExSyn/.gitignore b/docs/resources/PRESENTATION_ExSyn/.gitignore similarity index 50% rename from manual/PRESENTATION_ExSyn/.gitignore rename to docs/resources/PRESENTATION_ExSyn/.gitignore index cf658897d..b4a858a01 100644 --- a/manual/PRESENTATION_ExSyn/.gitignore +++ b/docs/resources/PRESENTATION_ExSyn/.gitignore @@ -1 +1,2 @@ *.dot +*.pdf diff --git a/manual/PRESENTATION_ExSyn/Makefile b/docs/resources/PRESENTATION_ExSyn/Makefile similarity index 83% rename from manual/PRESENTATION_ExSyn/Makefile rename to docs/resources/PRESENTATION_ExSyn/Makefile index c34eae3ff..e9986ff05 100644 --- a/manual/PRESENTATION_ExSyn/Makefile +++ b/docs/resources/PRESENTATION_ExSyn/Makefile @@ -9,7 +9,7 @@ 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' + ../../../yosys -p 'script $(1).ys; show -notitle -prefix $(1) -format pdf' endef $(foreach trg,$(TARGETS),$(eval $(call make_pdf_template,$(trg)))) diff --git a/manual/PRESENTATION_ExSyn/abc_01.v b/docs/resources/PRESENTATION_ExSyn/abc_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/abc_01.v rename to docs/resources/PRESENTATION_ExSyn/abc_01.v diff --git a/manual/PRESENTATION_ExSyn/abc_01.ys b/docs/resources/PRESENTATION_ExSyn/abc_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/abc_01.ys rename to docs/resources/PRESENTATION_ExSyn/abc_01.ys diff --git a/manual/PRESENTATION_ExSyn/abc_01_cells.lib b/docs/resources/PRESENTATION_ExSyn/abc_01_cells.lib similarity index 100% rename from manual/PRESENTATION_ExSyn/abc_01_cells.lib rename to docs/resources/PRESENTATION_ExSyn/abc_01_cells.lib diff --git a/manual/PRESENTATION_ExSyn/abc_01_cells.v b/docs/resources/PRESENTATION_ExSyn/abc_01_cells.v similarity index 100% rename from manual/PRESENTATION_ExSyn/abc_01_cells.v rename to docs/resources/PRESENTATION_ExSyn/abc_01_cells.v diff --git a/manual/PRESENTATION_ExSyn/memory_01.v b/docs/resources/PRESENTATION_ExSyn/memory_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_01.v rename to docs/resources/PRESENTATION_ExSyn/memory_01.v diff --git a/manual/PRESENTATION_ExSyn/memory_01.ys b/docs/resources/PRESENTATION_ExSyn/memory_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_01.ys rename to docs/resources/PRESENTATION_ExSyn/memory_01.ys diff --git a/manual/PRESENTATION_ExSyn/memory_02.v b/docs/resources/PRESENTATION_ExSyn/memory_02.v similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_02.v rename to docs/resources/PRESENTATION_ExSyn/memory_02.v diff --git a/manual/PRESENTATION_ExSyn/memory_02.ys b/docs/resources/PRESENTATION_ExSyn/memory_02.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/memory_02.ys rename to docs/resources/PRESENTATION_ExSyn/memory_02.ys diff --git a/manual/PRESENTATION_ExSyn/opt_01.v b/docs/resources/PRESENTATION_ExSyn/opt_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_01.v rename to docs/resources/PRESENTATION_ExSyn/opt_01.v diff --git a/manual/PRESENTATION_ExSyn/opt_01.ys b/docs/resources/PRESENTATION_ExSyn/opt_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_01.ys rename to docs/resources/PRESENTATION_ExSyn/opt_01.ys diff --git a/manual/PRESENTATION_ExSyn/opt_02.v b/docs/resources/PRESENTATION_ExSyn/opt_02.v similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_02.v rename to docs/resources/PRESENTATION_ExSyn/opt_02.v diff --git a/manual/PRESENTATION_ExSyn/opt_02.ys b/docs/resources/PRESENTATION_ExSyn/opt_02.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_02.ys rename to docs/resources/PRESENTATION_ExSyn/opt_02.ys diff --git a/manual/PRESENTATION_ExSyn/opt_03.v b/docs/resources/PRESENTATION_ExSyn/opt_03.v similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_03.v rename to docs/resources/PRESENTATION_ExSyn/opt_03.v diff --git a/manual/PRESENTATION_ExSyn/opt_03.ys b/docs/resources/PRESENTATION_ExSyn/opt_03.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_03.ys rename to docs/resources/PRESENTATION_ExSyn/opt_03.ys diff --git a/manual/PRESENTATION_ExSyn/opt_04.v b/docs/resources/PRESENTATION_ExSyn/opt_04.v similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_04.v rename to docs/resources/PRESENTATION_ExSyn/opt_04.v diff --git a/manual/PRESENTATION_ExSyn/opt_04.ys b/docs/resources/PRESENTATION_ExSyn/opt_04.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/opt_04.ys rename to docs/resources/PRESENTATION_ExSyn/opt_04.ys diff --git a/manual/PRESENTATION_ExSyn/proc_01.v b/docs/resources/PRESENTATION_ExSyn/proc_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_01.v rename to docs/resources/PRESENTATION_ExSyn/proc_01.v diff --git a/manual/PRESENTATION_ExSyn/proc_01.ys b/docs/resources/PRESENTATION_ExSyn/proc_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_01.ys rename to docs/resources/PRESENTATION_ExSyn/proc_01.ys diff --git a/manual/PRESENTATION_ExSyn/proc_02.v b/docs/resources/PRESENTATION_ExSyn/proc_02.v similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_02.v rename to docs/resources/PRESENTATION_ExSyn/proc_02.v diff --git a/manual/PRESENTATION_ExSyn/proc_02.ys b/docs/resources/PRESENTATION_ExSyn/proc_02.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_02.ys rename to docs/resources/PRESENTATION_ExSyn/proc_02.ys diff --git a/manual/PRESENTATION_ExSyn/proc_03.v b/docs/resources/PRESENTATION_ExSyn/proc_03.v similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_03.v rename to docs/resources/PRESENTATION_ExSyn/proc_03.v diff --git a/manual/PRESENTATION_ExSyn/proc_03.ys b/docs/resources/PRESENTATION_ExSyn/proc_03.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/proc_03.ys rename to docs/resources/PRESENTATION_ExSyn/proc_03.ys diff --git a/manual/PRESENTATION_ExSyn/techmap_01.v b/docs/resources/PRESENTATION_ExSyn/techmap_01.v similarity index 100% rename from manual/PRESENTATION_ExSyn/techmap_01.v rename to docs/resources/PRESENTATION_ExSyn/techmap_01.v diff --git a/manual/PRESENTATION_ExSyn/techmap_01.ys b/docs/resources/PRESENTATION_ExSyn/techmap_01.ys similarity index 100% rename from manual/PRESENTATION_ExSyn/techmap_01.ys rename to docs/resources/PRESENTATION_ExSyn/techmap_01.ys diff --git a/manual/PRESENTATION_ExSyn/techmap_01_map.v b/docs/resources/PRESENTATION_ExSyn/techmap_01_map.v similarity index 100% rename from manual/PRESENTATION_ExSyn/techmap_01_map.v rename to docs/resources/PRESENTATION_ExSyn/techmap_01_map.v diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index 310a7029e..e53e344d8 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -5,4 +5,5 @@ Getting started with Yosys installation scripting_intro + typical_phases examples diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst new file mode 100644 index 000000000..b64732479 --- /dev/null +++ b/docs/source/getting_started/typical_phases.rst @@ -0,0 +1,438 @@ +Typical Phases of a Synthesis Flow +---------------------------------- + +- Reading and elaborating the design +- Higher-level synthesis and optimization + + - Converting ``always``-blocks to logic and registers + - Perform coarse-grain optimizations (resource sharing, const folding, ...) + - Handling of memories and other coarse-grain blocks + - Extracting and optimizing finite state machines + +- Convert remaining logic to bit-level logic functions +- Perform optimizations on bit-level logic functions +- Map bit-level logic gates and registers to cell library +- Write results to output file + + +Reading the design +~~~~~~~~~~~~~~~~~~ + +.. code-block:: yoscrypt + + 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 + + +Design elaboration +~~~~~~~~~~~~~~~~~~ + +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. + +.. code-block:: yoscrypt + + # 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 + + +The ``proc`` command +~~~~~~~~~~~~~~~~~~~~~~ + +The Verilog frontend converts ``always``-blocks to RTL netlists for the +expressions and "processess" for the control- and memory elements. + +The ``proc`` command transforms this "processess" to netlists of RTL multiplexer +and register cells. + +The ``proc`` command is actually a macro-command that calls the following other +commands: + +.. code-block:: yoscrypt + + 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 + +Many commands can not operate on modules with "processess" in them. Usually a +call to ``proc`` is the first command in the actual synthesis procedure after +design elaboration. + +Example +^^^^^^^ + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/proc_01.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/proc_01.ys`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/proc_01.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExSyn/proc_02.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_02.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/proc_02.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_02.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/proc_02.ys`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/proc_03.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_03.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/proc_03.ys`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_03.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/proc_03.v`` + + +The ``opt`` command +~~~~~~~~~~~~~~~~~~~~~ + +The ``opt`` command implements a series of simple optimizations. It also is a +macro command that calls other commands: + +.. code-block:: yoscrypt + + 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] + +The command ``clean`` can be used as alias for ``opt_clean``. And ``;;`` can be +used as shortcut for ``clean``. For example: + +.. code-block:: yoscrypt + + proc; opt; memory; opt_expr;; fsm;; + +Example +^^^^^^^ + +.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_01.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_01.ys`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_01.v`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_02.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_02.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_02.ys`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_02.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_02.v`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_03.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_03.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_03.ys`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_03.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_03.v`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_04.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_04.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_04.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_04.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/opt_04.ys`` + + +When to use ``opt`` or ``clean`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually it does not hurt to call ``opt`` after each regular command in the +synthesis script. But it increases the synthesis time, so it is favourable to +only call ``opt`` when an improvement can be achieved. + +The designs in ``yosys-bigsim`` are a good playground for experimenting with the +effects of calling ``opt`` in various places of the flow. + +It generally is a good idea to call ``opt`` before inherently expensive commands +such as ``sat`` or ``freduce``, as the possible gain is much higher in this +cases as the possible loss. + +The ``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 ``;;`` is a good +idea in every synthesis script. + +The ``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 ``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: + +.. code-block:: yoscrypt + + # 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 + +Usually it is preferred to use architecture-specific RAM resources for memory. +For example: + +.. code-block:: yoscrypt + + memory -nomap; techmap -map my_memory_map.v; memory_map + +Example +^^^^^^^ + +.. figure:: ../../images/res/PRESENTATION_ExSyn/memory_01.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/memory_01.ys`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/memory_01.v`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/memory_02.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_02.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/memory_02.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_02.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/memory_02.ys`` + + +The ``fsm`` command +~~~~~~~~~~~~~~~~~~~~~ + +The ``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: + +.. code-block:: yoscrypt + + 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 + +Some details on the most important commands from the ``fsm_*`` group: + +The ``fsm_detect`` command identifies FSM state registers and marks them with +the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the +``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" +*)`` to disable FSM optimization for a register. + +The ``fsm_extract`` command replaces the entire FSM (logic and state registers) +with a ``$fsm`` cell. + +The commands ``fsm_opt`` and ``fsm_recode`` can be used to optimize the FSM. + +Finally the ``fsm_map`` command can be used to convert the (optimized) ``$fsm`` +cell back to logic and registers. + +The ``techmap`` command +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. figure:: ../../images/res/PRESENTATION_ExSyn/techmap_01.* + :class: width-helper + +The ``techmap`` command replaces cells with implementations given as +verilog source. For example implementing a 32 bit adder using 16 bit adders: + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.ys`` + +stdcell mapping +^^^^^^^^^^^^^^^ + +When ``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. + +The built-in logic gate types are: ``$_NOT_``, ``$_AND_``, ``$_OR_``, +``$_XOR_``, and ``$_MUX_``. + +The register types are: ``$_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_``, and ``$_DLATCH_P_``. + +See :doc:`/yosys_internals/formats/cell_library` for more about the internal +cells used. + +The ``abc`` command +~~~~~~~~~~~~~~~~~~~~~ + +The ``abc`` command provides an interface to ABC_, an open source tool for +low-level logic synthesis. + +.. _ABC: http://www.eecs.berkeley.edu/~alanmi/abc/ + +The ``abc`` command processes a netlist of internal gate types and can perform: + +- logic minimization (optimization) +- mapping of logic to standard cell library (liberty format) +- mapping of logic to k-LUTs (for FPGA synthesis) + +Optionally ``abc`` can process registers from one clock domain and perform +sequential optimization (such as register balancing). + +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 +``write_blif`` and load the output file into ABC outside of Yosys. + +Example +^^^^^^^ + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/abc_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/abc_01.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/abc_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/abc_01.ys`` + +.. figure:: ../../images/res/PRESENTATION_ExSyn/abc_01.* + :class: width-helper + +Other special-purpose mapping commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``dfflibmap`` + This command maps the internal register cell types to the register types + described in a liberty file. + +``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. + +``iopadmap`` + Top-level input/outputs must usually be implemented using special I/O-pad + cells. This command inserts this cells to the design. + +Example Synthesis Script +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: yoscrypt + + # 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 + +The weird ``select`` expressions at the end of this script are discussed later +in :doc:`using_yosys/more_scripting/selections</using_yosys/more_scripting/selections>`. diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex deleted file mode 100644 index d7cfdc6f2..000000000 --- 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} - From 7ab051778ec61fb2462a482ab1f0eddc2661f8dc Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:40:36 +1200 Subject: [PATCH 009/108] Add copypaste reminder for typical_phases.rst --- docs/source/getting_started/typical_phases.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index b64732479..b27a8d823 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -1,6 +1,8 @@ Typical Phases of a Synthesis Flow ---------------------------------- +.. TODO: copypaste + - Reading and elaborating the design - Higher-level synthesis and optimization From 8ade2182b0fa6678aa9e255b8ffe99b4b2979d38 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:58:40 +1200 Subject: [PATCH 010/108] Move (most of) ExOth and ExAdv slides --- docs/images/Makefile | 2 +- .../resources}/PRESENTATION_ExAdv/.gitignore | 1 + .../resources}/PRESENTATION_ExAdv/Makefile | 17 +- .../PRESENTATION_ExAdv/addshift_map.v | 0 .../PRESENTATION_ExAdv/addshift_test.v | 0 .../PRESENTATION_ExAdv/addshift_test.ys | 0 .../PRESENTATION_ExAdv/macc_simple_test.v | 0 .../PRESENTATION_ExAdv/macc_simple_test.ys | 0 .../PRESENTATION_ExAdv/macc_simple_test_01.v | 0 .../PRESENTATION_ExAdv/macc_simple_test_02.v | 0 .../PRESENTATION_ExAdv/macc_simple_xmap.v | 0 .../PRESENTATION_ExAdv/macc_xilinx_swap_map.v | 0 .../PRESENTATION_ExAdv/macc_xilinx_test.v | 0 .../PRESENTATION_ExAdv/macc_xilinx_test.ys | 0 .../macc_xilinx_unwrap_map.v | 0 .../PRESENTATION_ExAdv/macc_xilinx_wrap_map.v | 0 .../PRESENTATION_ExAdv/macc_xilinx_xmap.v | 0 .../PRESENTATION_ExAdv/mulshift_map.v | 0 .../PRESENTATION_ExAdv/mulshift_test.v | 0 .../PRESENTATION_ExAdv/mulshift_test.ys | 0 .../resources}/PRESENTATION_ExAdv/mymul_map.v | 0 .../PRESENTATION_ExAdv/mymul_test.v | 0 .../PRESENTATION_ExAdv/mymul_test.ys | 0 .../PRESENTATION_ExAdv/red_or3x1_cells.v | 0 .../PRESENTATION_ExAdv/red_or3x1_map.v | 0 .../PRESENTATION_ExAdv/red_or3x1_test.v | 0 .../PRESENTATION_ExAdv/red_or3x1_test.ys | 0 .../resources}/PRESENTATION_ExAdv/select.v | 0 .../resources}/PRESENTATION_ExAdv/select.ys | 0 .../PRESENTATION_ExAdv/sym_mul_cells.v | 0 .../PRESENTATION_ExAdv/sym_mul_map.v | 0 .../PRESENTATION_ExAdv/sym_mul_test.v | 0 .../PRESENTATION_ExAdv/sym_mul_test.ys | 0 docs/resources/PRESENTATION_ExOth/.gitignore | 3 + .../resources}/PRESENTATION_ExOth/Makefile | 7 +- .../PRESENTATION_ExOth/axis_master.v | 0 .../resources}/PRESENTATION_ExOth/axis_test.v | 0 .../PRESENTATION_ExOth/axis_test.ys | 0 .../resources}/PRESENTATION_ExOth/equiv.ys | 0 .../resources}/PRESENTATION_ExOth/scrambler.v | 0 .../PRESENTATION_ExOth/scrambler.ys | 0 .../using_yosys/more_scripting/selections.rst | 249 +++++- .../yosys_internals/flow/command_ordering.rst | 271 ++++++ docs/source/yosys_internals/flow/index.rst | 2 + .../yosys_internals/flow/model_checking.rst | 106 +++ docs/source/yosys_internals/techmap.rst | 185 ++++- manual/PRESENTATION_ExAdv.tex | 784 ------------------ manual/PRESENTATION_ExOth.tex | 227 ----- manual/PRESENTATION_ExOth/.gitignore | 1 - 49 files changed, 828 insertions(+), 1027 deletions(-) rename {manual => docs/resources}/PRESENTATION_ExAdv/.gitignore (50%) rename {manual => docs/resources}/PRESENTATION_ExAdv/Makefile (62%) rename {manual => docs/resources}/PRESENTATION_ExAdv/addshift_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/addshift_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/addshift_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_simple_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_simple_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_simple_test_01.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_simple_test_02.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_simple_xmap.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_xilinx_swap_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_xilinx_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_xilinx_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/macc_xilinx_xmap.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/mulshift_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/mulshift_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/mulshift_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/mymul_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/mymul_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/mymul_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/red_or3x1_cells.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/red_or3x1_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/red_or3x1_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/red_or3x1_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/select.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/select.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/sym_mul_cells.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/sym_mul_map.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/sym_mul_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExAdv/sym_mul_test.ys (100%) create mode 100644 docs/resources/PRESENTATION_ExOth/.gitignore rename {manual => docs/resources}/PRESENTATION_ExOth/Makefile (69%) rename {manual => docs/resources}/PRESENTATION_ExOth/axis_master.v (100%) rename {manual => docs/resources}/PRESENTATION_ExOth/axis_test.v (100%) rename {manual => docs/resources}/PRESENTATION_ExOth/axis_test.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExOth/equiv.ys (100%) rename {manual => docs/resources}/PRESENTATION_ExOth/scrambler.v (100%) rename {manual => docs/resources}/PRESENTATION_ExOth/scrambler.ys (100%) create mode 100644 docs/source/yosys_internals/flow/command_ordering.rst create mode 100644 docs/source/yosys_internals/flow/model_checking.rst delete mode 100644 manual/PRESENTATION_ExOth.tex delete mode 100644 manual/PRESENTATION_ExOth/.gitignore diff --git a/docs/images/Makefile b/docs/images/Makefile index 4c84a01db..61fa6cd70 100644 --- a/docs/images/Makefile +++ b/docs/images/Makefile @@ -1,6 +1,6 @@ all: resources dots tex svg tidy -RES_LIST:= PRESENTATION_Intro/ PRESENTATION_ExSyn/ +RES_LIST:= PRESENTATION_Intro/ PRESENTATION_ExSyn/ PRESENTATION_ExAdv/ PRESENTATION_ExOth/ RES_DIRS:= $(addprefix ../resources/,$(RES_LIST)) .PHONY: resources resources: $(RES_DIRS) diff --git a/manual/PRESENTATION_ExAdv/.gitignore b/docs/resources/PRESENTATION_ExAdv/.gitignore similarity index 50% rename from manual/PRESENTATION_ExAdv/.gitignore rename to docs/resources/PRESENTATION_ExAdv/.gitignore index cf658897d..b4a858a01 100644 --- a/manual/PRESENTATION_ExAdv/.gitignore +++ b/docs/resources/PRESENTATION_ExAdv/.gitignore @@ -1 +1,2 @@ *.dot +*.pdf diff --git a/manual/PRESENTATION_ExAdv/Makefile b/docs/resources/PRESENTATION_ExAdv/Makefile similarity index 62% rename from manual/PRESENTATION_ExAdv/Makefile rename to docs/resources/PRESENTATION_ExAdv/Makefile index 993a9d9e1..8954ee254 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/docs/resources/PRESENTATION_ExAdv/Makefile @@ -1,28 +1,29 @@ +YOSYS = ../../../yosys 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 + $(YOSYS) select.ys red_or3x1.pdf: red_or3x1_* - ../../yosys red_or3x1_test.ys + $(YOSYS) red_or3x1_test.ys sym_mul.pdf: sym_mul_* - ../../yosys sym_mul_test.ys + $(YOSYS) sym_mul_test.ys mymul.pdf: mymul_* - ../../yosys mymul_test.ys + $(YOSYS) mymul_test.ys mulshift.pdf: mulshift_* - ../../yosys mulshift_test.ys + $(YOSYS) mulshift_test.ys addshift.pdf: addshift_* - ../../yosys addshift_test.ys + $(YOSYS) addshift_test.ys macc_simple_xmap.pdf: macc_simple_*.v macc_simple_test.ys - ../../yosys 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 + $(YOSYS) macc_xilinx_test.ys diff --git a/manual/PRESENTATION_ExAdv/addshift_map.v b/docs/resources/PRESENTATION_ExAdv/addshift_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/addshift_map.v rename to docs/resources/PRESENTATION_ExAdv/addshift_map.v diff --git a/manual/PRESENTATION_ExAdv/addshift_test.v b/docs/resources/PRESENTATION_ExAdv/addshift_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/addshift_test.v rename to docs/resources/PRESENTATION_ExAdv/addshift_test.v diff --git a/manual/PRESENTATION_ExAdv/addshift_test.ys b/docs/resources/PRESENTATION_ExAdv/addshift_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/addshift_test.ys rename to docs/resources/PRESENTATION_ExAdv/addshift_test.ys diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.v b/docs/resources/PRESENTATION_ExAdv/macc_simple_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test.v rename to docs/resources/PRESENTATION_ExAdv/macc_simple_test.v diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.ys b/docs/resources/PRESENTATION_ExAdv/macc_simple_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test.ys rename to docs/resources/PRESENTATION_ExAdv/macc_simple_test.ys diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test_01.v b/docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test_01.v rename to docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test_02.v b/docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_test_02.v rename to docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v diff --git a/manual/PRESENTATION_ExAdv/macc_simple_xmap.v b/docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_simple_xmap.v rename to docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v b/docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v rename to docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v b/docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_test.v rename to docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys b/docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_test.ys rename to docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.ys diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v b/docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v rename to docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v b/docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v rename to docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v b/docs/resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v similarity index 100% rename from manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v rename to docs/resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v diff --git a/manual/PRESENTATION_ExAdv/mulshift_map.v b/docs/resources/PRESENTATION_ExAdv/mulshift_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mulshift_map.v rename to docs/resources/PRESENTATION_ExAdv/mulshift_map.v diff --git a/manual/PRESENTATION_ExAdv/mulshift_test.v b/docs/resources/PRESENTATION_ExAdv/mulshift_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mulshift_test.v rename to docs/resources/PRESENTATION_ExAdv/mulshift_test.v diff --git a/manual/PRESENTATION_ExAdv/mulshift_test.ys b/docs/resources/PRESENTATION_ExAdv/mulshift_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/mulshift_test.ys rename to docs/resources/PRESENTATION_ExAdv/mulshift_test.ys diff --git a/manual/PRESENTATION_ExAdv/mymul_map.v b/docs/resources/PRESENTATION_ExAdv/mymul_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mymul_map.v rename to docs/resources/PRESENTATION_ExAdv/mymul_map.v diff --git a/manual/PRESENTATION_ExAdv/mymul_test.v b/docs/resources/PRESENTATION_ExAdv/mymul_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/mymul_test.v rename to docs/resources/PRESENTATION_ExAdv/mymul_test.v diff --git a/manual/PRESENTATION_ExAdv/mymul_test.ys b/docs/resources/PRESENTATION_ExAdv/mymul_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/mymul_test.ys rename to docs/resources/PRESENTATION_ExAdv/mymul_test.ys diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_cells.v b/docs/resources/PRESENTATION_ExAdv/red_or3x1_cells.v similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_cells.v rename to docs/resources/PRESENTATION_ExAdv/red_or3x1_cells.v diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_map.v b/docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_map.v rename to docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_test.v b/docs/resources/PRESENTATION_ExAdv/red_or3x1_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_test.v rename to docs/resources/PRESENTATION_ExAdv/red_or3x1_test.v diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_test.ys b/docs/resources/PRESENTATION_ExAdv/red_or3x1_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/red_or3x1_test.ys rename to docs/resources/PRESENTATION_ExAdv/red_or3x1_test.ys diff --git a/manual/PRESENTATION_ExAdv/select.v b/docs/resources/PRESENTATION_ExAdv/select.v similarity index 100% rename from manual/PRESENTATION_ExAdv/select.v rename to docs/resources/PRESENTATION_ExAdv/select.v diff --git a/manual/PRESENTATION_ExAdv/select.ys b/docs/resources/PRESENTATION_ExAdv/select.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/select.ys rename to docs/resources/PRESENTATION_ExAdv/select.ys diff --git a/manual/PRESENTATION_ExAdv/sym_mul_cells.v b/docs/resources/PRESENTATION_ExAdv/sym_mul_cells.v similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_cells.v rename to docs/resources/PRESENTATION_ExAdv/sym_mul_cells.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_map.v b/docs/resources/PRESENTATION_ExAdv/sym_mul_map.v similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_map.v rename to docs/resources/PRESENTATION_ExAdv/sym_mul_map.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_test.v b/docs/resources/PRESENTATION_ExAdv/sym_mul_test.v similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_test.v rename to docs/resources/PRESENTATION_ExAdv/sym_mul_test.v diff --git a/manual/PRESENTATION_ExAdv/sym_mul_test.ys b/docs/resources/PRESENTATION_ExAdv/sym_mul_test.ys similarity index 100% rename from manual/PRESENTATION_ExAdv/sym_mul_test.ys rename to docs/resources/PRESENTATION_ExAdv/sym_mul_test.ys diff --git a/docs/resources/PRESENTATION_ExOth/.gitignore b/docs/resources/PRESENTATION_ExOth/.gitignore new file mode 100644 index 000000000..3af2b8451 --- /dev/null +++ b/docs/resources/PRESENTATION_ExOth/.gitignore @@ -0,0 +1,3 @@ +*.dot +*.pdf +*.log diff --git a/manual/PRESENTATION_ExOth/Makefile b/docs/resources/PRESENTATION_ExOth/Makefile similarity index 69% rename from manual/PRESENTATION_ExOth/Makefile rename to docs/resources/PRESENTATION_ExOth/Makefile index 4864d8d52..4291f9976 100644 --- a/manual/PRESENTATION_ExOth/Makefile +++ b/docs/resources/PRESENTATION_ExOth/Makefile @@ -1,16 +1,17 @@ +YOSYS = ../../../yosys all: scrambler_p01.pdf scrambler_p02.pdf equiv.log axis_test.log scrambler_p01.pdf: scrambler.ys scrambler.v - ../../yosys scrambler.ys + $(YOSYS) scrambler.ys scrambler_p02.pdf: scrambler_p01.pdf equiv.log: equiv.ys - ../../yosys -l equiv.log_new 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 + $(YOSYS) -l axis_test.log_new axis_test.ys mv axis_test.log_new axis_test.log diff --git a/manual/PRESENTATION_ExOth/axis_master.v b/docs/resources/PRESENTATION_ExOth/axis_master.v similarity index 100% rename from manual/PRESENTATION_ExOth/axis_master.v rename to docs/resources/PRESENTATION_ExOth/axis_master.v diff --git a/manual/PRESENTATION_ExOth/axis_test.v b/docs/resources/PRESENTATION_ExOth/axis_test.v similarity index 100% rename from manual/PRESENTATION_ExOth/axis_test.v rename to docs/resources/PRESENTATION_ExOth/axis_test.v diff --git a/manual/PRESENTATION_ExOth/axis_test.ys b/docs/resources/PRESENTATION_ExOth/axis_test.ys similarity index 100% rename from manual/PRESENTATION_ExOth/axis_test.ys rename to docs/resources/PRESENTATION_ExOth/axis_test.ys diff --git a/manual/PRESENTATION_ExOth/equiv.ys b/docs/resources/PRESENTATION_ExOth/equiv.ys similarity index 100% rename from manual/PRESENTATION_ExOth/equiv.ys rename to docs/resources/PRESENTATION_ExOth/equiv.ys diff --git a/manual/PRESENTATION_ExOth/scrambler.v b/docs/resources/PRESENTATION_ExOth/scrambler.v similarity index 100% rename from manual/PRESENTATION_ExOth/scrambler.v rename to docs/resources/PRESENTATION_ExOth/scrambler.v diff --git a/manual/PRESENTATION_ExOth/scrambler.ys b/docs/resources/PRESENTATION_ExOth/scrambler.ys similarity index 100% rename from manual/PRESENTATION_ExOth/scrambler.ys rename to docs/resources/PRESENTATION_ExOth/scrambler.ys diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 3b81785dc..6b67b1691 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -1,6 +1,251 @@ Selections -~~~~~~~~~~ +---------- + +.. TODO: copypaste + + +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: + +.. code:: yoscrypt + + delete # will delete the whole design, but + + delete foobar # will only delete the module foobar. + +The ``select`` command can be used to create a selection for subsequent +commands. For example: + +.. code:: yoscrypt + + select foobar # select the module foobar + delete # delete selected objects + select -clear # reset selection (select whole design) See :doc:`/cmd/select` -Also :doc:`/cmd/show` and :doc:`/cmd/dump` +How to make a selection +~~~~~~~~~~~~~~~~~~~~~~~ + +Selection by object name +^^^^^^^^^^^^^^^^^^^^^^^^ + +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. + +.. code:: yoscrypt + + 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 + +Module and design context +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Commands can be executed in *module/* or *design/* context. Until now +all commands have been executed in design context. The ``cd`` command can be +used to switch to module context. + +In module context all commands only effect the active module. Objects in the +module are selected without the ``<module_name>/`` 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 for interactive design investigation. + +Selecting by object property or type +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Special patterns can be used to select by object property or type. For example: + +.. code:: yoscrypt + + 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 + +A complete list of this pattern expressions can be found in the command +reference to the ``select`` command. + +Combining selection +^^^^^^^^^^^^^^^^^^^ + +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: + +.. code:: yoscrypt + + select t:$dff r:WIDTH>1 # all cells of type $dff and/or with a parameter WIDTH > 1 + +Special ``%``-commands can be used to combine the elements on the stack: + +.. code:: yoscrypt + + select t:$dff r:WIDTH>1 %i # all cells of type $dff *AND* with a parameter WIDTH > 1 + +Examples for ``%``-codes (see :doc:`/cmd/select` for full list): + +- ``%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 + +Expanding selections +^^^^^^^^^^^^^^^^^^^^ + +Selections of cells and wires can be expanded along connections using +``%``-codes for selecting input cones (``%ci``), output cones (``%co``), or +both (``%x``). + +.. code:: yoscrypt + + # select all wires that are inputs to $add cells + select t:$add %ci w:* %i + +Additional constraints such as port names can be specified. + +.. code:: yoscrypt + + # 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] + +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. The commands ``select -add`` and ``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 + +Creating selection variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Selections can be stored under a name with the ``select -set <name>`` +command. The stored selections can be used in later select expressions +using the syntax ``@<name>``. + +.. code:: yoscrypt + + 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 + +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. + +.. code:: yoscrypt + + 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 + +Example: + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/select.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/select.ys`` + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/select.* + :class: width-helper + +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 ``submod``, ``expose``, and ``splice`` can be used to + transform the design into an equivalent design that is easier to analyse. +- Commands such as ``eval`` and ``sat`` can be used to investigate the behavior + of the circuit. +- :doc:`/cmd/show`. +- :doc:`/cmd/dump`. + +Reorganizing a module +^^^^^^^^^^^^^^^^^^^^^ + +.. literalinclude:: ../../../resources/PRESENTATION_ExOth/scrambler.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExOth/scrambler.v`` + + +.. code:: yoscrypt + + 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 + +.. figure:: ../../../images/res/PRESENTATION_ExOth/scrambler_p01.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExOth/scrambler_p02.* + :class: width-helper + +Analysis of circuit behavior +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: text + + > 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 diff --git a/docs/source/yosys_internals/flow/command_ordering.rst b/docs/source/yosys_internals/flow/command_ordering.rst new file mode 100644 index 000000000..1724ba5e3 --- /dev/null +++ b/docs/source/yosys_internals/flow/command_ordering.rst @@ -0,0 +1,271 @@ +Command ordering +---------------- + +.. TODO: copypaste + +Intro to coarse-grain synthesis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In coarse-grain synthesis the target architecture has cells of the same +complexity or larger complexity than the internal RTL representation. + +For example: + +.. code:: verilog + + wire [15:0] a, b; + wire [31:0] c, y; + assign y = a * b + c; + +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. + +Fine-grain synthesis would be matching the circuit elements to smaller +components, such as LUTs, gates, or half- and full-adders. + +The extract pass +~~~~~~~~~~~~~~~~ + +- Like the ``techmap`` pass, the ``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 ``extract`` pass will replace the matching subcircuit + with an instance of the module from the map file. +- In a way the ``extract`` pass is the inverse of the techmap pass. + +.. TODO: copypaste + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* + :class: width-helper + + before `extract` + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_00b.* + :class: width-helper + + after `extract` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_xmap.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v`` + +.. code:: yoscrypt + + read_verilog macc_simple_test.v + hierarchy -check -top test + + extract -map macc_simple_xmap.v;; + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_test_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v`` + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* + :class: width-helper + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_test_02.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v`` + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/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 ``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 ``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 ``extract`` command can be used to replace circuits with cells + of the target architecture. + +unwrap + The remaining wrapper cell can be unwrapped using ``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: ``macc_xilinx_swap_map.v`` + +Make sure ``A`` is the smaller port on all multipliers + +.. TODO: copypaste + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v`` + +Wrapping multipliers: ``macc_xilinx_wrap_map.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v + :language: verilog + :lines: 1-46 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` + +Wrapping adders: ``macc_xilinx_wrap_map.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v + :language: verilog + :lines: 48-89 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` + +Extract: ``macc_xilinx_xmap.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v + :language: verilog + :caption: ``docs/resources/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 ``extract`` command. + +Unwrapping multipliers: ``macc_xilinx_unwrap_map.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v + :language: verilog + :lines: 1-30 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` + +Unwrapping adders: ``macc_xilinx_unwrap_map.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v + :language: verilog + :lines: 32-61 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v + :language: verilog + :lines: 1-6 + :caption: ``test1`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* + :class: width-helper + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v + :language: verilog + :lines: 8-13 + :caption: ``test2`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* + :class: width-helper + +Wrapping in ``test1``: + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* + :class: width-helper + +.. code:: yoscrypt + + techmap -map macc_xilinx_wrap_map.v + + connwrappers -unsigned $__mul_wrapper \ + Y Y_WIDTH \ + -unsigned $__add_wrapper \ + Y Y_WIDTH ;; + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* + :class: width-helper + +Wrapping in ``test2``: + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* + :class: width-helper + +.. code:: yoscrypt + + techmap -map macc_xilinx_wrap_map.v + + connwrappers -unsigned $__mul_wrapper \ + Y Y_WIDTH \ + -unsigned $__add_wrapper \ + Y Y_WIDTH ;; + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* + :class: width-helper + +Extract in ``test1``: + +.. code:: yoscrypt + + 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 ;; + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1d.* + :class: width-helper + +Extract in ``test2``: + +.. code:: yoscrypt + + 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 ;; + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* + :class: width-helper + +Unwrap in ``test2``: + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* + :class: width-helper + +.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2e.* + :class: width-helper + +.. code:: yoscrypt + + techmap -map macc_xilinx_unwrap_map.v ;; diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst index 195e50f64..868aa08fe 100644 --- a/docs/source/yosys_internals/flow/index.rst +++ b/docs/source/yosys_internals/flow/index.rst @@ -17,4 +17,6 @@ This scripts contain three types of commands: overview control_and_data verilog_frontend + command_ordering + model_checking diff --git a/docs/source/yosys_internals/flow/model_checking.rst b/docs/source/yosys_internals/flow/model_checking.rst new file mode 100644 index 000000000..3ac73fd6f --- /dev/null +++ b/docs/source/yosys_internals/flow/model_checking.rst @@ -0,0 +1,106 @@ +Symbolic model checking +----------------------- + +.. TODO: copypaste + +.. 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. + +Symbolic Model Checking (SMC) is used to formally prove that a circuit has (or +has not) a given property. + +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. + +Other applications include checking if a module conforms to interface standards. + +The ``sat`` command in Yosys can be used to perform Symbolic Model Checking. + +Checking techmap +~~~~~~~~~~~~~~~~ + +Remember the following example from :doc:`/getting_started/typical_phases`? + +.. literalinclude:: ../../../resources/PRESENTATION_ExSyn/techmap_01_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01_map.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExSyn/techmap_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExSyn/techmap_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.ys`` + +Lets see if it is correct.. + +.. code:: yoscrypt + + # 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 + +Result: + +.. code:: + + Solving problem with 945 variables and 2505 clauses.. + SAT proof finished - no model found: SUCCESS! + +AXI4 Stream Master +~~~~~~~~~~~~~~~~~~ + +The following AXI4 Stream Master has a bug. But the bug is not exposed if the +slave keeps ``tready`` asserted all the time. (Something a test bench might do.) + +Symbolic Model Checking can be used to expose the bug and find a sequence of +values for ``tready`` that yield the incorrect behavior. + +.. literalinclude:: ../../../resources/PRESENTATION_ExOth/axis_master.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExOth/axis_master.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExOth/axis_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExOth/axis_test.v`` + + +.. code:: yoscrypt + + read_verilog -sv axis_master.v axis_test.v + hierarchy -top axis_test + + proc; flatten;; + sat -seq 50 -prove-asserts + +Result with unmodified ``axis_master.v``: + +.. code:: + + Solving problem with 159344 variables and 442126 clauses.. + SAT proof finished - model found: FAIL! + +Result with fixed ``axis_master.v``: + +.. code:: + + Solving problem with 159144 variables and 441626 clauses.. + SAT proof finished - no model found: SUCCESS! diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index 18eec664b..745e5e2f5 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -31,7 +31,7 @@ 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 @@ -105,3 +105,186 @@ reporting bugs in the tools involved. When the information in the Liberty file used by Yosys and ABC are not part of the sensitive information, the additional tool yosys-filterlib (see :ref:`sec:filterlib`) can be used to strip the sensitive information from the Liberty file. + +Techmap by example +------------------ + +.. TODO: copypaste + +As a quick recap, the ``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. + +Mapping OR3X1 +~~~~~~~~~~~~~ + +.. note:: + + This is a simple example for demonstration only. Techmap shouldn't be used + to implement basic logic optimization. + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v`` + +.. figure:: ../../images/res/PRESENTATION_ExAdv/red_or3x1.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_test.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/red_or3x1_test.ys`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/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/res/PRESENTATION_ExAdv/sym_mul.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/sym_mul_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/sym_mul_test.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_test.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/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 ``proc`` + - Perform expensive optimizations (such as ``freduce``) on cells where + this is known to work well. + - Interacting with custom commands. + +.. note:: PROTIP: + Commands such as ``shell``, ``show -pause``, and ``dump`` can be use + in the ``_TECHMAP_DO_*`` scripts for debugging map modules. + +Example: + +.. figure:: ../../images/res/PRESENTATION_ExAdv/mymul.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/mymul_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/mymul_test.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_test.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/mymul_test.ys`` + +Handling constant inputs +~~~~~~~~~~~~~~~~~~~~~~~~ + +- The special parameters ``_TECHMAP_CONSTMSK_<port-name>_`` and + ``_TECHMAP_CONSTVAL_<port-name>_`` 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/res/PRESENTATION_ExAdv/mulshift.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/mulshift_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/mulshift_test.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_test.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/mulshift_test.ys`` + +Handling shorted inputs +~~~~~~~~~~~~~~~~~~~~~~~ + +- The special parameters ``_TECHMAP_BITS_CONNMAP_`` and + ``_TECHMAP_CONNMAP_<port-name>_`` can be used to handle shorted inputs. +- Each bit of the port correlates to an ``_TECHMAP_BITS_CONNMAP_`` bits wide + number in ``_TECHMAP_CONNMAP_<port-name>_``. +- Each unique signal bit is assigned its own number. Identical fields in the ``_TECHMAP_CONNMAP_<port-name>_`` 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/res/PRESENTATION_ExAdv/addshift.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/addshift_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/addshift_test.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_test.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/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 this 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/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 6a426ff2b..9acae2718 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -15,790 +15,6 @@ This section contains 4 subsections: \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 <module\_name>/} 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 <name>} -command. The stored selections can be used in later select expressions -using the syntax {\tt @<name>}. - -\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 <port-name>\tt \_} and -{\tt \_TECHMAP\_CONSTVAL\_\it <port-name>\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 <port-name>\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 <port-name>\tt \_}. -\medskip -\item Each unique signal bit is assigned its own number. Identical fields in the {\tt -\_TECHMAP\_CONNMAP\_\it <port-name>\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} diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex deleted file mode 100644 index 3f5113e3c..000000000 --- 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 cf658897d..000000000 --- a/manual/PRESENTATION_ExOth/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.dot From afc25afaf9cd199ee055c507c8fe9a7a27a5178c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:58:52 +1200 Subject: [PATCH 011/108] Minor tidying --- docs/source/appendix/APPNOTE_011_Design_Investigation.rst | 6 +++--- docs/source/getting_started/typical_phases.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst index d2b33bd1c..a7291106e 100644 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst @@ -276,7 +276,7 @@ Interactive navigation $procmux$5 .. code-block:: RTLIL - :caption: Output of ``dump \$2`` using the design from :numref:`example_src` + :caption: Output of ``dump $2`` using the design from :numref:`example_src` and :numref:`example_out` :name: dump2 @@ -474,7 +474,7 @@ has no effect anymore. :class: width-helper :name: select_prod - Objects selected by ``select prod \%ci...`` + 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 @@ -541,7 +541,7 @@ Or we could decide to tell the ``%ci`` action to not follow the ``CLK`` input: :class: width-helper :name: memdemo_01 - Output of ``show y \%ci2:+\$dff[Q,D] \%ci*:-\$mux[S]:-\$dff`` + 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: diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index b27a8d823..45921aa75 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -1,4 +1,4 @@ -Typical Phases of a Synthesis Flow +Typical phases of a synthesis flow ---------------------------------- .. TODO: copypaste From ce9e56db47938c186a5d4e274377159055c5e6c8 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 8 Aug 2023 09:50:36 +1200 Subject: [PATCH 012/108] Move the last presentation slides --- .../using_yosys/more_scripting/selections.rst | 62 ++++++- manual/.gitignore | 12 -- manual/PRESENTATION_ExAdv.tex | 112 ------------ manual/clean.sh | 2 - manual/presentation.sh | 54 ------ manual/presentation.tex | 162 ------------------ 6 files changed, 53 insertions(+), 351 deletions(-) delete mode 100644 manual/.gitignore delete mode 100644 manual/PRESENTATION_ExAdv.tex delete mode 100755 manual/clean.sh delete mode 100755 manual/presentation.sh delete mode 100644 manual/presentation.tex diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 6b67b1691..5e5bf8ae4 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -199,15 +199,22 @@ tools). 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. -Reorganizing a module -^^^^^^^^^^^^^^^^^^^^^ +Changing design hierarchy +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Commands such as ``flatten`` and ``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 ``submod`` is shown below for +reorganizing a module in Yosys and checking the resulting circuit. .. literalinclude:: ../../../resources/PRESENTATION_ExOth/scrambler.v :language: verilog :caption: ``docs/resources/PRESENTATION_ExOth/scrambler.v`` - .. code:: yoscrypt read_verilog scrambler.v @@ -225,15 +232,10 @@ Reorganizing a module .. figure:: ../../../images/res/PRESENTATION_ExOth/scrambler_p02.* :class: width-helper -Analysis of circuit behavior -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Analyzing the resulting circuit with :doc:`/cmd/eval`: .. code:: text - > 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 @@ -249,3 +251,45 @@ Analysis of circuit behavior -------------------- ---------- ---------- ------------------------------------- \in 745495504 2c6f5bd0 00101100011011110101101111010000 \out 632435482 25b2331a 00100101101100100011001100011010 + +Behavioral changes +^^^^^^^^^^^^^^^^^^ + +Commands such as ``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. + +.. 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 + <= D; + + endmodule + +For more on the ``techmap`` command, see the page on +:doc:`/yosys_internals/techmap` or the +:doc:`techmap command reference document</cmd/techmap>`. diff --git a/manual/.gitignore b/manual/.gitignore deleted file mode 100644 index 110f65b19..000000000 --- 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 9acae2718..000000000 --- a/manual/PRESENTATION_ExAdv.tex +++ /dev/null @@ -1,112 +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{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/clean.sh b/manual/clean.sh deleted file mode 100755 index addc34ed1..000000000 --- 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 ca8a6c93c..000000000 --- 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 7aba33c8b..000000000 --- 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} From d8b8880ad6dfbf67563e4e792061605ae838a4fd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:04:07 +1200 Subject: [PATCH 013/108] Convert todo comments to directives Could be left in for final version, but my current thinking is not? --- docs/source/conf.py | 4 ++++ docs/source/getting_started/scripting_intro.rst | 2 +- docs/source/getting_started/typical_phases.rst | 2 +- docs/source/index.rst | 5 +++++ docs/source/introduction.rst | 4 ++-- docs/source/test_suites.rst | 2 +- .../source/using_yosys/more_scripting/opt_passes.rst | 2 +- .../source/using_yosys/more_scripting/selections.rst | 3 +-- docs/source/yosys_internals/extensions.rst | 4 ++-- .../source/yosys_internals/flow/command_ordering.rst | 6 +++--- .../source/yosys_internals/flow/control_and_data.rst | 2 +- docs/source/yosys_internals/flow/model_checking.rst | 2 +- docs/source/yosys_internals/flow/overview.rst | 2 +- .../source/yosys_internals/flow/verilog_frontend.rst | 12 +++++++----- docs/source/yosys_internals/formats/cell_library.rst | 2 +- docs/source/yosys_internals/formats/rtlil_rep.rst | 2 +- docs/source/yosys_internals/index.rst | 4 ++-- docs/source/yosys_internals/techmap.rst | 4 ++-- 18 files changed, 37 insertions(+), 27 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index bca4971e9..fb2e603f1 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -59,6 +59,10 @@ latex_elements = { ''' } +# include todos during rewrite +extensions.append('sphinx.ext.todo') +todo_include_todos = True + def setup(sphinx): sys.path += [os.path.dirname(__file__) + "/../util"] from RtlilLexer import RtlilLexer diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 9f7ae2ba7..10894e4e8 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -1,7 +1,7 @@ Scripting in Yosys ------------------ -.. TODO: copypaste +.. todo:: copypaste Yosys reads and processes commands from synthesis scripts, command line arguments and an interactive command prompt. Yosys commands consist of a command diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index 45921aa75..7f4f0880b 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -1,7 +1,7 @@ Typical phases of a synthesis flow ---------------------------------- -.. TODO: copypaste +.. todo:: copypaste - Reading and elaborating the design - Higher-level synthesis and optimization diff --git a/docs/source/index.rst b/docs/source/index.rst index 0cae4aa0d..df335444d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,3 +12,8 @@ Yosys Open SYnthesis Suite test_suites appendix + +TODOs +----- + +.. todolist:: diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 81d89d7a6..8c9450feb 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -1,7 +1,7 @@ What is Yosys ============= -.. TODO: rewrite to not be a thesis abstract +.. todo:: rewrite to not be a thesis abstract :Abstract: Most of today's digital design is done in HDL code (mostly Verilog or @@ -125,7 +125,7 @@ In no particular order: History of Yosys ---------------- -.. TODO: copypaste +.. todo:: copypaste 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 diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index bc56bbf77..7f23754b2 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -4,7 +4,7 @@ Test suites .. note:: Potentially significantly out of date information last updated circa 2015 -.. TODO: copypaste +.. todo:: copypaste Continuously checking the correctness of Yosys and making sure that new features do not break old ones is a high priority in Yosys. Two external test suites diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index 387a3fb1f..06eafe4e9 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -3,7 +3,7 @@ Optimization passes =================== -.. TODO: copypaste +.. todo:: copypaste Yosys employs a number of optimizations to generate better and cleaner results. This chapter outlines these optimizations. diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 5e5bf8ae4..528989877 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -1,8 +1,7 @@ Selections ---------- -.. TODO: copypaste - +.. todo:: copypaste 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: diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index 1b601acbd..225aa23eb 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -3,7 +3,7 @@ Writing extensions ================== -.. TODO: copypaste +.. todo:: copypaste This chapter contains some bits and pieces of information about programming yosys extensions. Don't be afraid to ask questions on the YosysHQ Slack. @@ -81,7 +81,7 @@ look at the output of ``dump`` and ``show`` before and after the command has been executed can be helpful. The :doc:`/using_yosys/more_scripting/selections` document has more information on using these commands. -.. TODO: copypaste +.. todo:: copypaste Creating modules from scratch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/flow/command_ordering.rst b/docs/source/yosys_internals/flow/command_ordering.rst index 1724ba5e3..8419ea4a2 100644 --- a/docs/source/yosys_internals/flow/command_ordering.rst +++ b/docs/source/yosys_internals/flow/command_ordering.rst @@ -1,7 +1,7 @@ Command ordering ---------------- -.. TODO: copypaste +.. todo:: copypaste Intro to coarse-grain synthesis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -36,7 +36,7 @@ The extract pass with an instance of the module from the map file. - In a way the ``extract`` pass is the inverse of the techmap pass. -.. TODO: copypaste +.. todo:: copypaste .. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* :class: width-helper @@ -118,7 +118,7 @@ Preconditioning: ``macc_xilinx_swap_map.v`` Make sure ``A`` is the smaller port on all multipliers -.. TODO: copypaste +.. todo:: copypaste .. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v :language: verilog diff --git a/docs/source/yosys_internals/flow/control_and_data.rst b/docs/source/yosys_internals/flow/control_and_data.rst index 65eaaa5d5..961687f79 100644 --- a/docs/source/yosys_internals/flow/control_and_data.rst +++ b/docs/source/yosys_internals/flow/control_and_data.rst @@ -1,7 +1,7 @@ Control and data flow ===================== -.. TODO: copypaste +.. todo:: copypaste 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 diff --git a/docs/source/yosys_internals/flow/model_checking.rst b/docs/source/yosys_internals/flow/model_checking.rst index 3ac73fd6f..c023109c9 100644 --- a/docs/source/yosys_internals/flow/model_checking.rst +++ b/docs/source/yosys_internals/flow/model_checking.rst @@ -1,7 +1,7 @@ Symbolic model checking ----------------------- -.. TODO: copypaste +.. todo:: copypaste .. note:: diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst index 025d6f8b7..acb7dbaab 100644 --- a/docs/source/yosys_internals/flow/overview.rst +++ b/docs/source/yosys_internals/flow/overview.rst @@ -1,7 +1,7 @@ Flow overview ============= -.. TODO: copypaste +.. todo:: copypaste :numref:`Figure %s <fig:Overview_flow>` shows the simplified data flow within Yosys. Rectangles in the figure represent program modules and ellipses internal diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index cb5b65d8a..fcfda6746 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -639,13 +639,15 @@ to extend the actual Verilog frontend. Synthesizing Verilog arrays --------------------------- -.. TODO: these +.. todo:: -Add some information on the generation of ``$memrd`` and ``$memwr`` cells and -how they are processed in the memory pass. + 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. +.. todo:: + + 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/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index 7768c3cc9..8fa9e94dc 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -1,7 +1,7 @@ .. role:: verilog(code) :language: Verilog -.. TODO: copypaste +.. todo:: copypaste .. _chapter:celllib: diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index 4ed7d9107..a65fedc30 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -74,7 +74,7 @@ This has three advantages: - First, it is impossible that an auto-generated identifier collides with an identifier that was provided by the user. -.. TODO: does opt_rmunused (still?) exist? +.. todo:: does opt_rmunused (still?) exist? - Second, the information about which identifiers were originally provided by the user is always available which can help guide some optimizations. For diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst index e8d6fd1a0..c8b55cb8d 100644 --- a/docs/source/yosys_internals/index.rst +++ b/docs/source/yosys_internals/index.rst @@ -3,7 +3,7 @@ Yosys internals =============== -.. TODO: copypaste +.. todo:: copypaste Yosys is an extensible open source hardware synthesis tool. It is aimed at designers who are looking for an easily accessible, universal, and @@ -38,4 +38,4 @@ can be used as reference to implement a similar system in any language. techmap extensions -.. TODO: copypaste +.. todo:: copypaste diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index 745e5e2f5..a095ef6bf 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -1,6 +1,6 @@ .. _chapter:techmap: -.. TODO: copypaste +.. todo:: copypaste Technology mapping ================== @@ -109,7 +109,7 @@ sensitive information from the Liberty file. Techmap by example ------------------ -.. TODO: copypaste +.. todo:: copypaste As a quick recap, the ``techmap`` command replaces cells in the design with implementations given as Verilog code (called "map files"). It can replace From 8203a01ba9608d14610efac5e254688721865a06 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:51:57 +1200 Subject: [PATCH 014/108] Adding custom domain for cmdref --- docs/source/conf.py | 9 +- docs/source/index.rst | 6 + docs/static/yosyshq.css | 4 +- docs/util/__init__.py | 0 docs/util/cmdref.py | 240 ++++++++++++++++++++++++++++++++++++++++ kernel/register.cc | 5 +- 6 files changed, 256 insertions(+), 8 deletions(-) create mode 100644 docs/util/__init__.py create mode 100644 docs/util/cmdref.py diff --git a/docs/source/conf.py b/docs/source/conf.py index fb2e603f1..a043f0b49 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -63,10 +63,13 @@ latex_elements = { extensions.append('sphinx.ext.todo') todo_include_todos = True +# 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/index.rst b/docs/source/index.rst index df335444d..0a776393a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,6 +13,12 @@ Yosys Open SYnthesis Suite appendix +Indices +------- + +- :ref:`commandindex` +- :ref:`tagindex` + TODOs ----- diff --git a/docs/static/yosyshq.css b/docs/static/yosyshq.css index 0be7f7728..91a15c129 100644 --- a/docs/static/yosyshq.css +++ b/docs/static/yosyshq.css @@ -63,12 +63,12 @@ p { color: #6ecbd7 !important; } -.cmdref .highlight-yoscrypt .highlight pre { +.cmd.def .highlight-yoscrypt, .cmd.def .highlight pre { padding: 0%; margin: 0%; } -.cmdref .highlight-none .highlight pre { +.cmd.def .highlight-none, .cmd.def .highlight pre { padding-top: 0%; margin-top: 0%; } diff --git a/docs/util/__init__.py b/docs/util/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/util/cmdref.py b/docs/util/cmdref.py new file mode 100644 index 000000000..175bd20f0 --- /dev/null +++ b/docs/util/cmdref.py @@ -0,0 +1,240 @@ +# 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) + tmap = self.env.domaindata['cmd']['obj2tag'] + tmap[name] = list(self.options.get('tags', '').split(' ')) + objs = self.env.domaindata['cmd']['objects'] + objs.append((name, + sig, + self.options.get('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 -> object + } + + 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) + for name, sig, typ, docname, anchor, prio + in self.get_objects() if sig == target] + + if len(match) > 0: + todocname = match[0][0] + targ = match[0][1] + + return make_refnode(builder,fromdocname,todocname, + targ, contnode, targ) + else: + print("Awww, found nothing") + 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/kernel/register.cc b/kernel/register.cc index 9ffb17c1a..c9b9f238a 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -786,9 +786,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; From 9fcf353734130efbf1ea15b9314ca856c3be4e06 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:53:36 +1200 Subject: [PATCH 015/108] Makefile adjustments to match top make Hopefully matches enough that any `make docs` call will work from the yosys being built, while still being overridable locally. --- docs/resources/PRESENTATION_ExAdv/Makefile | 4 +++- docs/resources/PRESENTATION_ExOth/Makefile | 4 +++- docs/resources/PRESENTATION_ExSyn/Makefile | 6 +++++- docs/resources/PRESENTATION_Intro/Makefile | 5 ++++- docs/resources/PRESENTATION_Prog/Makefile | 15 +++++++++------ 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docs/resources/PRESENTATION_ExAdv/Makefile b/docs/resources/PRESENTATION_ExAdv/Makefile index 8954ee254..fc6ba6902 100644 --- a/docs/resources/PRESENTATION_ExAdv/Makefile +++ b/docs/resources/PRESENTATION_ExAdv/Makefile @@ -1,4 +1,6 @@ -YOSYS = ../../../yosys +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys all: select.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf addshift.pdf \ macc_simple_xmap.pdf macc_xilinx_xmap.pdf diff --git a/docs/resources/PRESENTATION_ExOth/Makefile b/docs/resources/PRESENTATION_ExOth/Makefile index 4291f9976..afd84c3c6 100644 --- a/docs/resources/PRESENTATION_ExOth/Makefile +++ b/docs/resources/PRESENTATION_ExOth/Makefile @@ -1,4 +1,6 @@ -YOSYS = ../../../yosys +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys all: scrambler_p01.pdf scrambler_p02.pdf equiv.log axis_test.log diff --git a/docs/resources/PRESENTATION_ExSyn/Makefile b/docs/resources/PRESENTATION_ExSyn/Makefile index e9986ff05..a9015e8d5 100644 --- a/docs/resources/PRESENTATION_ExSyn/Makefile +++ b/docs/resources/PRESENTATION_ExSyn/Makefile @@ -5,11 +5,15 @@ TARGETS += memory_01 memory_02 TARGETS += techmap_01 TARGETS += abc_01 +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys + 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' + $(YOSYS) -p 'script $(1).ys; show -notitle -prefix $(1) -format pdf' endef $(foreach trg,$(TARGETS),$(eval $(call make_pdf_template,$(trg)))) diff --git a/docs/resources/PRESENTATION_Intro/Makefile b/docs/resources/PRESENTATION_Intro/Makefile index 48946f1e1..2c5fdcf4c 100644 --- a/docs/resources/PRESENTATION_Intro/Makefile +++ b/docs/resources/PRESENTATION_Intro/Makefile @@ -1,8 +1,11 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys all: counter_00.dot counter_01.dot counter_02.dot counter_03.dot counter_00.dot: counter.v counter.ys mycells.lib - ../../../yosys counter_outputs.ys + $(YOSYS) counter_outputs.ys counter_01.dot: counter_00.dot counter_02.dot: counter_00.dot diff --git a/docs/resources/PRESENTATION_Prog/Makefile b/docs/resources/PRESENTATION_Prog/Makefile index 2ac8e5bed..60ca513a8 100644 --- a/docs/resources/PRESENTATION_Prog/Makefile +++ b/docs/resources/PRESENTATION_Prog/Makefile @@ -1,21 +1,24 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys all: test0.log test1.log test2.log -CXXFLAGS=$(shell ../../yosys-config --cxxflags) -DATDIR=$(shell ../../yosys-config --datdir) +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 + $(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 + $(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 + $(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 + $(YOSYS) -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v mv test2.log_new test2.log From f8333e52f77eda341b87db2965650023bce7003d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:19:13 +1200 Subject: [PATCH 016/108] cmd links use title text --- docs/util/cmdref.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/util/cmdref.py b/docs/util/cmdref.py index 175bd20f0..795a3e8ff 100644 --- a/docs/util/cmdref.py +++ b/docs/util/cmdref.py @@ -52,12 +52,15 @@ class CommandNode(ObjectDescription): signode['ids'].append('cmd' + '-' + sig) if 'noindex' not in self.options: name = "{}.{}.{}".format('cmd', type(self).__name__, sig) - tmap = self.env.domaindata['cmd']['obj2tag'] - tmap[name] = list(self.options.get('tags', '').split(' ')) + 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, - self.options.get('title'), + title, self.env.docname, 'cmd' + '-' + sig, 0)) @@ -193,8 +196,9 @@ class CommandDomain(Domain): } initial_data = { - 'objects': [], # object list - 'obj2tag': {}, # name -> object + 'objects': [], # object list + 'obj2tag': {}, # name -> tags + 'obj2title': {}, # name -> title } def get_full_qualified_name(self, node): @@ -210,16 +214,18 @@ class CommandDomain(Domain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): - match = [(docname, anchor) + match = [(docname, anchor, name) for name, sig, typ, docname, anchor, prio in self.get_objects() if sig == target] - if len(match) > 0: + 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, targ) + targ, contnode, title) else: print("Awww, found nothing") return None From 685da6a2e5676624575a0016fadbea2a280aabbd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:45:18 +1200 Subject: [PATCH 017/108] Converting a number of inline commands to refs Also reflowing text for line width. Maybe look into supporting commands with options? --- .../appendix/APPNOTE_010_Verilog_to_BLIF.rst | 4 +- .../APPNOTE_011_Design_Investigation.rst | 293 +++++++++--------- .../appendix/APPNOTE_012_Verilog_to_BTOR.rst | 2 +- docs/source/getting_started/examples.rst | 3 +- .../getting_started/scripting_intro.rst | 16 +- .../source/getting_started/typical_phases.rst | 126 ++++---- docs/source/using_yosys/memory_mapping.rst | 13 +- .../using_yosys/more_scripting/opt_passes.rst | 74 ++--- .../using_yosys/more_scripting/selections.rst | 42 +-- .../using_yosys/more_scripting/synth.rst | 2 +- docs/source/yosys_internals/extensions.rst | 16 +- .../yosys_internals/flow/command_ordering.rst | 33 +- .../yosys_internals/flow/model_checking.rst | 3 +- .../yosys_internals/flow/verilog_frontend.rst | 32 +- .../yosys_internals/formats/cell_library.rst | 57 ++-- .../yosys_internals/formats/rtlil_rep.rst | 46 +-- docs/source/yosys_internals/techmap.rst | 20 +- 17 files changed, 398 insertions(+), 384 deletions(-) diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index d4448895b..d8f8fec46 100644 --- a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst +++ b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst @@ -235,8 +235,8 @@ signal is connected throughout the whole design hierarchy. 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 +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 diff --git a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst index a7291106e..3adcc4913 100644 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst @@ -6,9 +6,9 @@ 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. +2013-12-08. The README file covers how to install Yosys. The :cmd:ref:`show` +command requires a working installation of `GraphViz`_ and `xdot` for generating +the actual circuit diagrams. .. _Yosys GIT: https://github.com/YosysHQ/yosys @@ -23,8 +23,8 @@ 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:`intro_show` introduces the :cmd:ref:`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 @@ -41,7 +41,7 @@ Introduction to the show command ================================ .. code-block:: console - :caption: Yosys script with ``show`` commands and example design + :caption: Yosys script with :cmd:ref:`show` commands and example design :name: example_src $ cat example.ys @@ -64,24 +64,24 @@ Introduction to the show command :class: width-helper :name: example_out - Output of the three ``show`` commands from :numref:`example_src` + Output of the three :cmd:ref:`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). +The :cmd:ref:`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. +demonstrate the usage of show in a simple setting. Note that :cmd:ref:`show` is +called with the :cmd:ref:`-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 @@ -111,28 +111,28 @@ 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 +The :cmd:ref:`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 +``BUF``-node. This 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 -``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``. +:cmd:ref:`clean` (or :cmd:ref:`proc`, which includes :cmd:ref:`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 :cmd:ref:`clean` before calling :cmd:ref:`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. +In this script we directly call :cmd:ref:`proc` as next step, which finally +leads us to the 3rd diagram in :numref:`example_out`. 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. .. figure:: ../../images/011/splice.* :class: width-helper @@ -148,7 +148,7 @@ behavior of the circuit. :class: width-helper :name: splitnets_libfile - Effects of ``splitnets`` command and of providing a cell library. (The + Effects of :cmd:ref:`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 @@ -158,8 +158,8 @@ 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. +vector are accessed. The example :cmd:ref:`show` in :numref:`splice_src` +demonstrates how such circuits are visualized by the :cmd:ref:`show` command. The key elements in understanding this circuit diagram are of course the boxes with round corners and rows labeled ``<MSB_LEFT>:<LSB_LEFT> - @@ -191,11 +191,11 @@ 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 <filename>`` option. -Secondly it is possible to load cell libraries into the design with the +passed directly to the :cmd:ref:`show` command using the ``-lib <filename>`` +option. Secondly it is possible to load cell libraries into the design with the ``read_verilog -lib <filename>`` 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. +subsequent calls to the :cmd:ref:`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 @@ -206,21 +206,21 @@ 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. +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. 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 <integer>`` argument, which randomly assigns colors to the nets. -The integer (> 0) is used as seed value for the random color assignments. +individual signal wires. For this cases it can be useful to call :cmd:ref:`show` +with the ``-colors <integer>`` 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. +the :cmd:ref:`show` command. .. _navigate: @@ -232,13 +232,13 @@ 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``. +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 ``write_verilog -noexpr`` @@ -249,7 +249,7 @@ Interactive navigation ---------------------- .. code-block:: none - :caption: Demonstration of ``ls`` and ``cd`` using ``example.v`` from :numref:`example_src` + :caption: Demonstration of :cmd:ref:`ls` and :cmd:ref:`cd` using ``example.v`` from :numref:`example_src` :name: lscd yosys> ls @@ -293,17 +293,17 @@ Interactive navigation 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 +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 ``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`. +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 `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 @@ -312,16 +312,16 @@ 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 ``<module_name>/``. For example -``a*/b*`` would refer to all objects whose names start with ``b`` from all -modules whose names start with ``a``. +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 +``<module_name>/``. 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. +The :cmd:ref:`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. @@ -333,23 +333,24 @@ Working with selections :class: width-helper :name: seladd - Output of ``show`` after ``select $2`` or ``select t:$add`` (see also + Output of :cmd:ref:`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. +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. -But for most interactive work we want to further narrow the set of -selected objects. This can be done using the ``select`` command. +But for most interactive work we want to further narrow the set of selected +objects. This can be done using the :cmd:ref:`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. +For example, if the command ``select $2`` is executed, a subsequent +:cmd:ref:`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 @@ -366,13 +367,13 @@ 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. +means that it will use the engine behind the :cmd:ref:`select` command to +evaluate additional arguments and use the resulting selection instead of the +selection created by the last :cmd:ref:`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. +Normally the :cmd:ref:`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. @@ -391,9 +392,9 @@ Operations on selections 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 +The :cmd:ref:`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: @@ -445,7 +446,7 @@ 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. +in the stack maintained by the :cmd:ref:`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 @@ -484,8 +485,8 @@ 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`. +to the ``memdemo`` module with ``cd memdemo``. If we type :cmd:ref:`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 @@ -580,7 +581,7 @@ Storing and recalling selections The current selection can be stored in memory with the command ``select -set <name>``. It can later be recalled using ``select @<name>``. In fact, the ``@<name>`` expression pushes the stored selection on the stack maintained by -the ``select`` command. So for example +the :cmd:ref:`select` command. So for example .. code-block:: yoscrypt @@ -593,9 +594,9 @@ 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. +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. .. _poke: @@ -610,10 +611,10 @@ 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. +:numref:`submod` shows how the :cmd:ref:`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 @@ -621,7 +622,7 @@ name of the new cell in the current module. .. code-block:: yoscrypt :caption: The circuit from :numref:`memdemo_src` and :numref:`memdemo_00` - broken up using ``submod`` + broken up using :cmd:ref:`submod` :name: submod select -set outstage y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff @@ -634,8 +635,8 @@ name of the new cell in the current module. 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``): +The :cmd:ref:`eval` command can be used to evaluate combinatorial circuits. For +example (see :numref:`submod` for the circuit diagram of ``selstage``): :: @@ -676,11 +677,11 @@ The ``-table`` option can be used to create a truth table. For example: 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. +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 this commands can be applied. Solving combinatorial SAT problems ---------------------------------- @@ -754,18 +755,18 @@ Solving combinatorial SAT problems \____ $$$|__/|________/|__/|_______/|__/ \__/ -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. +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/ -The ``sat`` command works very similar to the ``eval`` command. The main +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: @@ -792,8 +793,8 @@ corresponding input values. For Example: \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 +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 @@ -812,8 +813,8 @@ 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 upper 8 bits of ``a`` and ``b`` to zero for the :cmd:ref:`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 @@ -917,18 +918,18 @@ to this question, as produced by the following command: 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 +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 ``sat`` command to initialize all -registers to the undef (``x``) state. The way the ``x`` state is treated in +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 ``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. +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. @@ -938,27 +939,27 @@ 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. +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. .. _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. +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 (:cmd:ref:`eval`) or by evaluation which +input values and initial conditions can result in a certain behavior at the +outputs (:cmd:ref:`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 diff --git a/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst index e9e44d1cd..adb551494 100644 --- a/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst +++ b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst @@ -180,7 +180,7 @@ to the Yosys documentation, or run ``yosys -h <command_name>``. 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. +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 diff --git a/docs/source/getting_started/examples.rst b/docs/source/getting_started/examples.rst index 30a522ba3..0c3f66365 100644 --- a/docs/source/getting_started/examples.rst +++ b/docs/source/getting_started/examples.rst @@ -81,7 +81,8 @@ synthesis script (``counter.ys``), a digital design written in Verilog #. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available hardware flip-flops. #. :yoscrypt:`abc -liberty mycells.lib` - Map logic to available hardware gates. -#. :yoscrypt:`clean` - Clean up the design (just the last step of ``opt``). +#. :yoscrypt:`clean` - Clean up the design (just the last step of + :cmd:ref:`opt`). #. :yoscrypt:`write_verilog synth.v` - Write final synthesis result to output file. diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 10894e4e8..594f7cee8 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -10,10 +10,10 @@ terminated using the newline character or a semicolon (;). Empty lines and lines starting with the hash sign (#) are ignored. See :ref:`sec:typusecase` for an example synthesis script. -The command ``help`` can be used to access the command reference manual, with -``help <command>`` providing details for a specific command. ``yosys -H`` or -``yosys -h <command>`` will do the same outside of an interactive prompt. The -entire reference manual is also available here at :doc:`/cmd_ref`. +The command :cmd:ref:`help` can be used to access the command reference manual, +with ``help <command>`` providing details for a specific command. ``yosys -H`` +or ``yosys -h <command>`` will do the same outside of an interactive prompt. +The entire reference manual is also available here at :doc:`/cmd_ref`. Example commands ~~~~~~~~~~~~~~~~ @@ -99,10 +99,10 @@ Selections intro ~~~~~~~~~~~~~~~~ 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. +selected parts of the design. For example the command :cmd:ref:`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 diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index 7f4f0880b..e3c105755 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -57,17 +57,17 @@ needed variations of parametric modules. hierarchy -check -top top_module -The ``proc`` command -~~~~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`proc` command +~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Verilog frontend converts ``always``-blocks to RTL netlists for the expressions and "processess" for the control- and memory elements. -The ``proc`` command transforms this "processess" to netlists of RTL multiplexer -and register cells. +The :cmd:ref:`proc` command transforms this "processess" to netlists of RTL +multiplexer and register cells. -The ``proc`` command is actually a macro-command that calls the following other -commands: +The :cmd:ref:`proc` command is actually a macro-command that calls the following +other commands: .. code-block:: yoscrypt @@ -80,8 +80,8 @@ commands: proc_clean # if all went fine, this should remove all the processes Many commands can not operate on modules with "processess" in them. Usually a -call to ``proc`` is the first command in the actual synthesis procedure after -design elaboration. +call to :cmd:ref:`proc` is the first command in the actual synthesis procedure +after design elaboration. Example ^^^^^^^ @@ -120,11 +120,11 @@ Example :caption: ``docs/resources/PRESENTATION_ExSyn/proc_03.v`` -The ``opt`` command -~~~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`opt` command +~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``opt`` command implements a series of simple optimizations. It also is a -macro command that calls other commands: +The :cmd:ref:`opt` command implements a series of simple optimizations. It also +is a macro command that calls other commands: .. code-block:: yoscrypt @@ -140,8 +140,8 @@ macro command that calls other commands: opt_expr # const folding and simple expression rewriting while [changed design] -The command ``clean`` can be used as alias for ``opt_clean``. And ``;;`` can be -used as shortcut for ``clean``. For example: +The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And +``;;`` can be used as shortcut for :cmd:ref:`clean`. For example: .. code-block:: yoscrypt @@ -195,31 +195,31 @@ Example :caption: ``docs/resources/PRESENTATION_ExSyn/opt_04.ys`` -When to use ``opt`` or ``clean`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When to use :cmd:ref:`opt` or :cmd:ref:`clean` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Usually it does not hurt to call ``opt`` after each regular command in the -synthesis script. But it increases the synthesis time, so it is favourable to -only call ``opt`` when an improvement can be achieved. +Usually it does not hurt to call :cmd:ref:`opt` after each regular command in +the synthesis script. But it increases the synthesis time, so it is favourable +to only call :cmd:ref:`opt` when an improvement can be achieved. The designs in ``yosys-bigsim`` are a good playground for experimenting with the -effects of calling ``opt`` in various places of the flow. +effects of calling :cmd:ref:`opt` in various places of the flow. -It generally is a good idea to call ``opt`` before inherently expensive commands -such as ``sat`` or ``freduce``, as the possible gain is much higher in this -cases as the possible loss. +It generally is a good idea to call :cmd:ref:`opt` before inherently expensive +commands such as :cmd:ref:`sat` or :cmd:ref:`freduce`, as the possible gain is +much higher in this cases as the possible loss. -The ``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 ``;;`` is a good -idea in every synthesis script. +The :cmd:ref:`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 +``;;`` is a good idea in every synthesis script. -The ``memory`` command -~~~~~~~~~~~~~~~~~~~~~~~~ +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 ``memory`` +consolidating the number of ports for a memory easier. The :cmd:ref:`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: @@ -269,12 +269,12 @@ Example :caption: ``docs/resources/PRESENTATION_ExSyn/memory_02.ys`` -The ``fsm`` command -~~~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`fsm` command +~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``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: +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: .. code-block:: yoscrypt @@ -298,26 +298,27 @@ a series of other commands: Some details on the most important commands from the ``fsm_*`` group: -The ``fsm_detect`` command identifies FSM state registers and marks them with -the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the +The :cmd:ref:`fsm_detect` command identifies FSM state registers and marks them +with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the ``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" *)`` to disable FSM optimization for a register. -The ``fsm_extract`` command replaces the entire FSM (logic and state registers) -with a ``$fsm`` cell. +The :cmd:ref:`fsm_extract` command replaces the entire FSM (logic and state +registers) with a ``$fsm`` cell. -The commands ``fsm_opt`` and ``fsm_recode`` can be used to optimize the FSM. +The commands :cmd:ref:`fsm_opt` and :cmd:ref:`fsm_recode` can be used to +optimize the FSM. -Finally the ``fsm_map`` command can be used to convert the (optimized) ``$fsm`` -cell back to logic and registers. +Finally the :cmd:ref:`fsm_map` command can be used to convert the (optimized) +``$fsm`` cell back to logic and registers. -The ``techmap`` command -~~~~~~~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`techmap` command +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. figure:: ../../images/res/PRESENTATION_ExSyn/techmap_01.* :class: width-helper -The ``techmap`` command replaces cells with implementations given as +The :cmd:ref:`techmap` command replaces cells with implementations given as verilog source. For example implementing a 32 bit adder using 16 bit adders: .. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01_map.v @@ -335,8 +336,9 @@ verilog source. For example implementing a 32 bit adder using 16 bit adders: stdcell mapping ^^^^^^^^^^^^^^^ -When ``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. +When :cmd:ref:`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. The built-in logic gate types are: ``$_NOT_``, ``$_AND_``, ``$_OR_``, ``$_XOR_``, and ``$_MUX_``. @@ -351,26 +353,27 @@ The register types are: ``$_SR_NN_``, ``$_SR_NP_``, ``$_SR_PN_``, ``$_SR_PP_``, See :doc:`/yosys_internals/formats/cell_library` for more about the internal cells used. -The ``abc`` command -~~~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`abc` command +~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``abc`` command provides an interface to ABC_, an open source tool for -low-level logic synthesis. +The :cmd:ref:`abc` command provides an interface to ABC_, an open source tool +for low-level logic synthesis. .. _ABC: http://www.eecs.berkeley.edu/~alanmi/abc/ -The ``abc`` command processes a netlist of internal gate types and can perform: +The :cmd:ref:`abc` command processes a netlist of internal gate types and can +perform: - logic minimization (optimization) - mapping of logic to standard cell library (liberty format) - mapping of logic to k-LUTs (for FPGA synthesis) -Optionally ``abc`` can process registers from one clock domain and perform -sequential optimization (such as register balancing). +Optionally :cmd:ref:`abc` can process registers from one clock domain and +perform sequential optimization (such as register balancing). 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 -``write_blif`` and load the output file into ABC outside of Yosys. +:cmd:ref:`write_blif` and load the output file into ABC outside of Yosys. Example ^^^^^^^ @@ -389,16 +392,16 @@ Example Other special-purpose mapping commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``dfflibmap`` +:cmd:ref:`dfflibmap` This command maps the internal register cell types to the register types described in a liberty file. -``hilomap`` +: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. -``iopadmap`` +:cmd:ref:`iopadmap` Top-level input/outputs must usually be implemented using special I/O-pad cells. This command inserts this cells to the design. @@ -436,5 +439,6 @@ Example Synthesis Script # write synthesis results write_edif synth.edif -The weird ``select`` expressions at the end of this script are discussed later -in :doc:`using_yosys/more_scripting/selections</using_yosys/more_scripting/selections>`. +The weird :cmd:ref:`select` expressions at the end of this script are discussed +later in +:doc:`using_yosys/more_scripting/selections</using_yosys/more_scripting/selections>`. diff --git a/docs/source/using_yosys/memory_mapping.rst b/docs/source/using_yosys/memory_mapping.rst index cdc381eed..41654a0c5 100644 --- a/docs/source/using_yosys/memory_mapping.rst +++ b/docs/source/using_yosys/memory_mapping.rst @@ -3,12 +3,13 @@ Memory mapping ============== -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. +Documentation for the Yosys :cmd:ref:`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. See also: `passes/memory/memlib.md <https://github.com/YosysHQ/yosys/blob/master/passes/memory/memlib.md>`_ diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index 06eafe4e9..3fd742560 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -11,12 +11,13 @@ 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: +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. At the time of +this writing the :cmd:ref:`opt` pass executes the following passes that each +perform a simple optimization: -- Once at the beginning of ``opt``: +- Once at the beginning of :cmd:ref:`opt`: - ``opt_expr`` - ``opt_merge -nomux`` @@ -32,15 +33,15 @@ after each major step in the synthesis script. At the time of this writing the The following section describes each of the ``opt_`` passes. -The opt_expr pass -~~~~~~~~~~~~~~~~~ +The :cmd:ref:`opt_expr` pass +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This pass performs const folding on the internal combinational cell types -described in :ref:`chapter:celllib`. 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. +described in :ref:`chapter:celllib`. 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. +.. table:: Const folding rules for ``$_AND_`` cells as used in :cmd:ref:`opt_expr`. :name: tab:opt_expr_and :align: center @@ -80,15 +81,16 @@ 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. +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. -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 :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. -The opt_muxtree pass -~~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`opt_muxtree` pass +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This pass optimizes trees of multiplexer cells by analyzing the select inputs. Consider the following simple example: @@ -99,12 +101,12 @@ Consider the following simple example: 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``. +multiplexer and 0 for the inner multiplexer. The :cmd:ref:`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 -~~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`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 @@ -121,22 +123,22 @@ Lastly this pass consolidates trees of ``$reduce_and`` cells and trees of These three simple optimizations are performed in a loop until a stable result is produced. -The opt_rmdff pass -~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`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 -~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`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 -~~~~~~~~~~~~~~~~~~ +The :cmd:ref:`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 @@ -144,8 +146,8 @@ 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. +trees to be merged, which might prevent :cmd:ref:`opt_muxtree` to identify +possible optimizations. FSM extraction and encoding --------------------------- @@ -193,9 +195,9 @@ using the ``\fsm_encoding`` attribute (unless ``\fsm_encoding`` is set to ``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. +Note that these optimizations operate on an RTL netlist. I.e. the :cmd:ref:`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`. @@ -295,8 +297,8 @@ 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. + ``\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. diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 528989877..e3a93d163 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -12,7 +12,7 @@ used to apply commands only to part of the design. For example: delete foobar # will only delete the module foobar. -The ``select`` command can be used to create a selection for subsequent +The :cmd:ref:`select` command can be used to create a selection for subsequent commands. For example: .. code:: yoscrypt @@ -42,8 +42,8 @@ in synthesis scripts that are hand-tailored for a specific design. Module and design context ^^^^^^^^^^^^^^^^^^^^^^^^^ -Commands can be executed in *module/* or *design/* context. Until now -all commands have been executed in design context. The ``cd`` command can be +Commands can be executed in *module/* or *design/* context. Until now all +commands have been executed in design context. The :cmd:ref:`cd` command can be used to switch to module context. In module context all commands only effect the active module. Objects in the @@ -76,7 +76,7 @@ Special patterns can be used to select by object property or type. For example: select foo/t:$add # select all $add cells from the module foo A complete list of this pattern expressions can be found in the command -reference to the ``select`` command. +reference to the :cmd:ref:`select` command. Combining selection ^^^^^^^^^^^^^^^^^^^ @@ -190,12 +190,13 @@ 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 ``submod``, ``expose``, and ``splice`` can be used to - transform the design into an equivalent design that is easier to analyse. -- Commands such as ``eval`` and ``sat`` can be used to investigate the behavior - of the circuit. +- 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 @@ -204,10 +205,10 @@ tools). Changing design hierarchy ^^^^^^^^^^^^^^^^^^^^^^^^^ -Commands such as ``flatten`` and ``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 ``submod`` is shown below for +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:: ../../../resources/PRESENTATION_ExOth/scrambler.v @@ -254,10 +255,10 @@ Analyzing the resulting circuit with :doc:`/cmd/eval`: Behavioral changes ^^^^^^^^^^^^^^^^^^ -Commands such as ``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). +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 @@ -289,6 +290,5 @@ Yosys script for ASIC synthesis of the Amber ARMv2 CPU. endmodule -For more on the ``techmap`` command, see the page on -:doc:`/yosys_internals/techmap` or the -:doc:`techmap command reference document</cmd/techmap>`. +For more on the :cmd:ref:`techmap` command, see the page on +:doc:`/yosys_internals/techmap`. diff --git a/docs/source/using_yosys/more_scripting/synth.rst b/docs/source/using_yosys/more_scripting/synth.rst index c56163360..ad01d1630 100644 --- a/docs/source/using_yosys/more_scripting/synth.rst +++ b/docs/source/using_yosys/more_scripting/synth.rst @@ -1,7 +1,7 @@ Introduction to synthesis ------------------------- -The following commands are executed by the ``synth`` command: +The following commands are executed by the :cmd:ref:`synth` command: .. literalinclude:: /cmd/synth.rst :start-at: begin: diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index 225aa23eb..d7c21154d 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -58,7 +58,7 @@ 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 ``proc`` and ``memory`` (or ``memory -nomap``): +commands :cmd:ref:`proc` and :cmd:ref:`memory` (or ``memory -nomap``): .. figure:: ../../images/simplified_rtlil.* :class: width-helper @@ -77,9 +77,10 @@ It is possible to only work on this simpler version: } When trying to understand what a command does, creating a small test case to -look at the output of ``dump`` and ``show`` before and after the command has -been executed can be helpful. The :doc:`/using_yosys/more_scripting/selections` -document has more information on using these commands. +look at the output of :cmd:ref:`dump` and :cmd:ref:`show` before and after the +command has been executed can be helpful. The +:doc:`/using_yosys/more_scripting/selections` document has more information on +using these commands. .. todo:: copypaste @@ -120,15 +121,16 @@ 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 ``clean`` - command worry about removing it. +- 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 slide) when you need a unique handle for each signal bit. +- Use the ``SigMap`` helper class (see next section) when you need a unique + handle for each signal bit. Using the SigMap helper class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/flow/command_ordering.rst b/docs/source/yosys_internals/flow/command_ordering.rst index 8419ea4a2..df351c486 100644 --- a/docs/source/yosys_internals/flow/command_ordering.rst +++ b/docs/source/yosys_internals/flow/command_ordering.rst @@ -28,13 +28,13 @@ components, such as LUTs, gates, or half- and full-adders. The extract pass ~~~~~~~~~~~~~~~~ -- Like the ``techmap`` pass, the ``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 ``extract`` pass will replace the matching subcircuit - with an instance of the module from the map file. -- In a way the ``extract`` pass is the inverse of the techmap 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:: copypaste @@ -93,19 +93,19 @@ 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 ``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 ``connwrappers`` command to connect up the bit-extended in- and - outputs of the wrapper cells. + 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 ``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 ``extract`` command can be used to replace circuits with cells - of the target architecture. + 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 ``techmap``. + The remaining wrapper cell can be unwrapped using :cmd:ref:`techmap`. Example: DSP48_MACC ~~~~~~~~~~~~~~~~~~~ @@ -144,7 +144,8 @@ Extract: ``macc_xilinx_xmap.v`` :language: verilog :caption: ``docs/resources/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 ``extract`` command. +... 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: ``macc_xilinx_unwrap_map.v`` diff --git a/docs/source/yosys_internals/flow/model_checking.rst b/docs/source/yosys_internals/flow/model_checking.rst index c023109c9..3d8b35125 100644 --- a/docs/source/yosys_internals/flow/model_checking.rst +++ b/docs/source/yosys_internals/flow/model_checking.rst @@ -17,7 +17,8 @@ passes in Yosys. Other applications include checking if a module conforms to interface standards. -The ``sat`` command in Yosys can be used to perform Symbolic Model Checking. +The :cmd:ref:`sat` command in Yosys can be used to perform Symbolic Model +Checking. Checking techmap ~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index fcfda6746..fbb82b416 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -407,9 +407,9 @@ transformed into a set of d-type flip-flops and the 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. +``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 :cmd:ref:`proc_adff` pass. The ProcessGenerator algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -591,16 +591,16 @@ 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: +from a behavioural model to an RTL representation is performed by the +:cmd:ref:`proc` pass and the passes it launches: -- | proc_clean and proc_rmdead +- | :cmd:ref:`proc_clean` and :cmd:ref:`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. + :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. -- | proc_arst +- | :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 @@ -608,22 +608,22 @@ pass and the passes it launches: reset path. After this pass the sync rule for the reset is level-sensitive and the top-level ``RTLIL::SwitchRule`` has been removed. -- | proc_mux +- | :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. -- | proc_dff +- | :cmd:ref:`proc_dff` | This pass replaces the ``RTLIL::SyncRule`` s to d-type flip-flops (with asynchronous resets if necessary). -- | proc_dff +- | :cmd:ref:`proc_dff` | This pass replaces the ``RTLIL::MemWriteAction`` s with ``$memwr`` cells. -- | proc_clean - | A final call to ``proc_clean`` removes the now empty ``RTLIL::Process`` - objects. +- | :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: diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index 8fa9e94dc..6667b8b67 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -255,8 +255,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 @@ -270,8 +270,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 @@ -433,16 +433,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 @@ -468,13 +469,13 @@ synthesis to succeed. 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. +``$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: @@ -600,15 +601,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 ~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index a65fedc30..904f80682 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -6,22 +6,22 @@ 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. +referred to by their full C++ name, i.e. including the ``RTLIL::`` namespace +prefix, in this document. :numref:`Figure %s <fig:Overview_RTLIL>` 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. +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. +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 @@ -31,9 +31,9 @@ object to parse the cell library. 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::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. @@ -44,8 +44,8 @@ from three different categories: - ``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. +``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. @@ -78,9 +78,9 @@ This has three advantages: - 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. + example the :cmd:ref:`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 @@ -184,8 +184,8 @@ An ``RTLIL::Cell`` object has the following properties: - 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 +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: @@ -320,8 +320,8 @@ 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``: +the :cmd:ref:`proc_arst` pass. This pass transforms the above example to the +following ``RTLIL::Process``: .. code:: RTLIL :number-lines: @@ -381,8 +381,8 @@ synthesis tasks. RTLIL::Memory ------------- -For every array (memory) in the HDL code an ``RTLIL::Memory`` object is created. A -memory object has the following properties: +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 diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index a095ef6bf..64f89777b 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -111,10 +111,9 @@ Techmap by example .. todo:: copypaste -As a quick recap, the ``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. +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 @@ -188,14 +187,15 @@ Scripting in map modules - You can even call techmap recursively! - Example use-cases: - - Using always blocks in map module: call ``proc`` - - Perform expensive optimizations (such as ``freduce``) on cells where - this is known to work well. + - 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 ``shell``, ``show -pause``, and ``dump`` can be use - in the ``_TECHMAP_DO_*`` scripts for debugging map modules. +.. 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: From e2c0f8fc50f97cd9a83b73b09f06b716a35aecdf Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:13:29 +1200 Subject: [PATCH 018/108] Some tidy up --- .../appendix/APPNOTE_011_Design_Investigation.rst | 8 ++++---- docs/source/getting_started/index.rst | 1 + docs/source/using_yosys/more_scripting/index.rst | 3 ++- .../using_yosys/more_scripting/opt_passes.rst | 14 +++++++++----- docs/source/yosys_internals/flow/index.rst | 2 +- .../yosys_internals/flow/verilog_frontend.rst | 4 +++- docs/source/yosys_internals/formats/index.rst | 2 +- docs/source/yosys_internals/formats/rtlil_rep.rst | 6 +++--- docs/source/yosys_internals/index.rst | 7 +++---- docs/util/cmdref.py | 2 +- 10 files changed, 28 insertions(+), 21 deletions(-) diff --git a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst index 3adcc4913..698f2da2c 100644 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst @@ -78,10 +78,10 @@ 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 :cmd:ref:`show` is -called with the :cmd:ref:`-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. +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 diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index e53e344d8..0828adf39 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -2,6 +2,7 @@ Getting started with Yosys ========================== .. toctree:: + :maxdepth: 3 installation scripting_intro diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 32aa8fc04..32879c0d4 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -1,7 +1,8 @@ More scripting -------------- -.. toctree:: +.. toctree:: + :maxdepth: 3 opt_passes selections diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index 3fd742560..15f2e20af 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -63,7 +63,7 @@ can also optimize cells with some constant inputs. 1 :math:`b` :math:`b` ========= ========= =========== -.. How to format table? +.. todo:: How to format table? :numref:`Table %s <tab:opt_expr_and>` shows the replacement rules used for optimizing an ``$_AND_`` gate. The first three rules implement the obvious const @@ -96,9 +96,11 @@ 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 + 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 :cmd:ref:`opt_muxtree` pass @@ -123,8 +125,10 @@ Lastly this pass consolidates trees of ``$reduce_and`` cells and trees of These three simple optimizations are performed in a loop until a stable result is produced. -The :cmd:ref:`opt_rmdff` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The ``opt_rmdff`` pass +~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: The ``opt_rmdff`` pass doesn't exist anymore? 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 diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst index 868aa08fe..3d05ea0bf 100644 --- a/docs/source/yosys_internals/flow/index.rst +++ b/docs/source/yosys_internals/flow/index.rst @@ -12,7 +12,7 @@ This scripts contain three types of commands: available: Verilog, BLIF, EDIF, SPICE, BTOR, . . .). .. toctree:: - :maxdepth: 2 + :maxdepth: 3 overview control_and_data diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index fbb82b416..2c8af3ad3 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -409,7 +409,9 @@ 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 :cmd:ref:`proc_adff` pass. +is done by the ``proc_adff`` pass. + +.. todo:: The ``proc_adff`` pass doesn't exist anymore? The ProcessGenerator algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/formats/index.rst b/docs/source/yosys_internals/formats/index.rst index 2e6fba017..aa77d1ea6 100644 --- a/docs/source/yosys_internals/formats/index.rst +++ b/docs/source/yosys_internals/formats/index.rst @@ -2,7 +2,7 @@ Internal formats ================ .. toctree:: - :maxdepth: 2 + :maxdepth: 3 overview rtlil_rep diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index 904f80682..fa356e785 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -78,9 +78,9 @@ This has three advantages: - Second, the information about which identifiers were originally provided by the user is always available which can help guide some optimizations. For - example the :cmd:ref:`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. + 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 diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst index c8b55cb8d..3389d88a0 100644 --- a/docs/source/yosys_internals/index.rst +++ b/docs/source/yosys_internals/index.rst @@ -23,7 +23,7 @@ wide range of real-world designs, including the `OpenRISC 1200 CPU`_, the .. _k68 CPU: http://opencores.org/projects/k68 -As of this writing a Yosys VHDL frontend is in development. +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 @@ -31,11 +31,10 @@ 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:: +.. toctree:: + :maxdepth: 3 flow/index formats/index techmap extensions - -.. todo:: copypaste diff --git a/docs/util/cmdref.py b/docs/util/cmdref.py index 795a3e8ff..ec146e231 100644 --- a/docs/util/cmdref.py +++ b/docs/util/cmdref.py @@ -227,7 +227,7 @@ class CommandDomain(Domain): return make_refnode(builder,fromdocname,todocname, targ, contnode, title) else: - print("Awww, found nothing") + print(f"Missing ref for {target} in {fromdocname} ") return None def setup(app): From aad8a3b9592edc474f42e00293301647dce64791 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:50:37 +1200 Subject: [PATCH 019/108] Rearrange command ordering and model checking Now under the yosys flows section. --- docs/source/using_yosys/yosys_flows.rst | 383 +++++++++++++++++- .../yosys_internals/flow/command_ordering.rst | 272 ------------- docs/source/yosys_internals/flow/index.rst | 2 - .../yosys_internals/flow/model_checking.rst | 107 ----- 4 files changed, 379 insertions(+), 385 deletions(-) delete mode 100644 docs/source/yosys_internals/flow/command_ordering.rst delete mode 100644 docs/source/yosys_internals/flow/model_checking.rst diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 61317f7cd..7a51385c1 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -1,8 +1,383 @@ Flows, command types, and order -------------------------------- +=============================== -Synthesis granularity -~~~~~~~~~~~~~~~~~~~~~ +Command order +------------- -Formal verification +.. todo:: copypaste + +Intro to coarse-grain synthesis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In coarse-grain synthesis the target architecture has cells of the same +complexity or larger complexity than the internal RTL representation. + +For example: + +.. code:: verilog + + wire [15:0] a, b; + wire [31:0] c, y; + assign y = a * b + c; + +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. + +Fine-grain synthesis would be matching the circuit elements to smaller +components, such as LUTs, gates, or half- and full-adders. + +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:: copypaste + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* + :class: width-helper + + before `extract` + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_00b.* + :class: width-helper + + after `extract` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_xmap.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v`` + +.. code:: yoscrypt + + read_verilog macc_simple_test.v + hierarchy -check -top test + + extract -map macc_simple_xmap.v;; + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v`` + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test_02.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v`` + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/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 ``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: ``macc_xilinx_swap_map.v`` + +Make sure ``A`` is the smaller port on all multipliers + +.. todo:: copypaste + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v`` + +Wrapping multipliers: ``macc_xilinx_wrap_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v + :language: verilog + :lines: 1-46 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` + +Wrapping adders: ``macc_xilinx_wrap_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v + :language: verilog + :lines: 48-89 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` + +Extract: ``macc_xilinx_xmap.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v + :language: verilog + :caption: ``docs/resources/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 :cmd:ref:`extract` command. + +Unwrapping multipliers: ``macc_xilinx_unwrap_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v + :language: verilog + :lines: 1-30 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` + +Unwrapping adders: ``macc_xilinx_unwrap_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v + :language: verilog + :lines: 32-61 + :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v + :language: verilog + :lines: 1-6 + :caption: ``test1`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* + :class: width-helper + +.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v + :language: verilog + :lines: 8-13 + :caption: ``test2`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* + :class: width-helper + +Wrapping in ``test1``: + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* + :class: width-helper + +.. code:: yoscrypt + + techmap -map macc_xilinx_wrap_map.v + + connwrappers -unsigned $__mul_wrapper \ + Y Y_WIDTH \ + -unsigned $__add_wrapper \ + Y Y_WIDTH ;; + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* + :class: width-helper + +Wrapping in ``test2``: + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* + :class: width-helper + +.. code:: yoscrypt + + techmap -map macc_xilinx_wrap_map.v + + connwrappers -unsigned $__mul_wrapper \ + Y Y_WIDTH \ + -unsigned $__add_wrapper \ + Y Y_WIDTH ;; + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* + :class: width-helper + +Extract in ``test1``: + +.. code:: yoscrypt + + 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 ;; + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1d.* + :class: width-helper + +Extract in ``test2``: + +.. code:: yoscrypt + + 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 ;; + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* + :class: width-helper + +Unwrap in ``test2``: + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* + :class: width-helper + +.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2e.* + :class: width-helper + +.. code:: yoscrypt + + techmap -map macc_xilinx_unwrap_map.v ;; + +Symbolic model checking +----------------------- + +.. todo:: copypaste + +.. 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. + +Symbolic Model Checking (SMC) is used to formally prove that a circuit has (or +has not) a given property. + +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. + +Other applications include checking if a module conforms to interface standards. + +The :cmd:ref:`sat` command in Yosys can be used to perform Symbolic Model +Checking. + +Checking techmap +~~~~~~~~~~~~~~~~ + +Remember the following example from :doc:`/getting_started/typical_phases`? + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01_map.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01_map.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.ys`` + +Lets see if it is correct.. + +.. code:: yoscrypt + + # 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 + +Result: + +.. code:: + + Solving problem with 945 variables and 2505 clauses.. + SAT proof finished - no model found: SUCCESS! + +AXI4 Stream Master +~~~~~~~~~~~~~~~~~~ + +The following AXI4 Stream Master has a bug. But the bug is not exposed if the +slave keeps ``tready`` asserted all the time. (Something a test bench might do.) + +Symbolic Model Checking can be used to expose the bug and find a sequence of +values for ``tready`` that yield the incorrect behavior. + +.. literalinclude:: ../../resources/PRESENTATION_ExOth/axis_master.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExOth/axis_master.v`` + +.. literalinclude:: ../../resources/PRESENTATION_ExOth/axis_test.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExOth/axis_test.v`` + + +.. code:: yoscrypt + + read_verilog -sv axis_master.v axis_test.v + hierarchy -top axis_test + + proc; flatten;; + sat -seq 50 -prove-asserts + +Result with unmodified ``axis_master.v``: + +.. code:: + + Solving problem with 159344 variables and 442126 clauses.. + SAT proof finished - model found: FAIL! + +Result with fixed ``axis_master.v``: + +.. code:: + + Solving problem with 159144 variables and 441626 clauses.. + SAT proof finished - no model found: SUCCESS! diff --git a/docs/source/yosys_internals/flow/command_ordering.rst b/docs/source/yosys_internals/flow/command_ordering.rst deleted file mode 100644 index df351c486..000000000 --- a/docs/source/yosys_internals/flow/command_ordering.rst +++ /dev/null @@ -1,272 +0,0 @@ -Command ordering ----------------- - -.. todo:: copypaste - -Intro to coarse-grain synthesis -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In coarse-grain synthesis the target architecture has cells of the same -complexity or larger complexity than the internal RTL representation. - -For example: - -.. code:: verilog - - wire [15:0] a, b; - wire [31:0] c, y; - assign y = a * b + c; - -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. - -Fine-grain synthesis would be matching the circuit elements to smaller -components, such as LUTs, gates, or half- and full-adders. - -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:: copypaste - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* - :class: width-helper - - before `extract` - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_00b.* - :class: width-helper - - after `extract` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_test.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_xmap.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v`` - -.. code:: yoscrypt - - read_verilog macc_simple_test.v - hierarchy -check -top test - - extract -map macc_simple_xmap.v;; - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_test_01.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v`` - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* - :class: width-helper - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_simple_test_02.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v`` - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/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 ``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: ``macc_xilinx_swap_map.v`` - -Make sure ``A`` is the smaller port on all multipliers - -.. todo:: copypaste - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v`` - -Wrapping multipliers: ``macc_xilinx_wrap_map.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v - :language: verilog - :lines: 1-46 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` - -Wrapping adders: ``macc_xilinx_wrap_map.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v - :language: verilog - :lines: 48-89 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` - -Extract: ``macc_xilinx_xmap.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v - :language: verilog - :caption: ``docs/resources/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 :cmd:ref:`extract` command. - -Unwrapping multipliers: ``macc_xilinx_unwrap_map.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v - :language: verilog - :lines: 1-30 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` - -Unwrapping adders: ``macc_xilinx_unwrap_map.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v - :language: verilog - :lines: 32-61 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v - :language: verilog - :lines: 1-6 - :caption: ``test1`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* - :class: width-helper - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v - :language: verilog - :lines: 8-13 - :caption: ``test2`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* - :class: width-helper - -Wrapping in ``test1``: - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* - :class: width-helper - -.. code:: yoscrypt - - techmap -map macc_xilinx_wrap_map.v - - connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* - :class: width-helper - -Wrapping in ``test2``: - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* - :class: width-helper - -.. code:: yoscrypt - - techmap -map macc_xilinx_wrap_map.v - - connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* - :class: width-helper - -Extract in ``test1``: - -.. code:: yoscrypt - - 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 ;; - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1d.* - :class: width-helper - -Extract in ``test2``: - -.. code:: yoscrypt - - 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 ;; - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* - :class: width-helper - -Unwrap in ``test2``: - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* - :class: width-helper - -.. figure:: ../../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2e.* - :class: width-helper - -.. code:: yoscrypt - - techmap -map macc_xilinx_unwrap_map.v ;; diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst index 3d05ea0bf..e2b5b658c 100644 --- a/docs/source/yosys_internals/flow/index.rst +++ b/docs/source/yosys_internals/flow/index.rst @@ -17,6 +17,4 @@ This scripts contain three types of commands: overview control_and_data verilog_frontend - command_ordering - model_checking diff --git a/docs/source/yosys_internals/flow/model_checking.rst b/docs/source/yosys_internals/flow/model_checking.rst deleted file mode 100644 index 3d8b35125..000000000 --- a/docs/source/yosys_internals/flow/model_checking.rst +++ /dev/null @@ -1,107 +0,0 @@ -Symbolic model checking ------------------------ - -.. todo:: copypaste - -.. 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. - -Symbolic Model Checking (SMC) is used to formally prove that a circuit has (or -has not) a given property. - -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. - -Other applications include checking if a module conforms to interface standards. - -The :cmd:ref:`sat` command in Yosys can be used to perform Symbolic Model -Checking. - -Checking techmap -~~~~~~~~~~~~~~~~ - -Remember the following example from :doc:`/getting_started/typical_phases`? - -.. literalinclude:: ../../../resources/PRESENTATION_ExSyn/techmap_01_map.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01_map.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExSyn/techmap_01.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExSyn/techmap_01.ys - :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.ys`` - -Lets see if it is correct.. - -.. code:: yoscrypt - - # 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 - -Result: - -.. code:: - - Solving problem with 945 variables and 2505 clauses.. - SAT proof finished - no model found: SUCCESS! - -AXI4 Stream Master -~~~~~~~~~~~~~~~~~~ - -The following AXI4 Stream Master has a bug. But the bug is not exposed if the -slave keeps ``tready`` asserted all the time. (Something a test bench might do.) - -Symbolic Model Checking can be used to expose the bug and find a sequence of -values for ``tready`` that yield the incorrect behavior. - -.. literalinclude:: ../../../resources/PRESENTATION_ExOth/axis_master.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExOth/axis_master.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExOth/axis_test.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExOth/axis_test.v`` - - -.. code:: yoscrypt - - read_verilog -sv axis_master.v axis_test.v - hierarchy -top axis_test - - proc; flatten;; - sat -seq 50 -prove-asserts - -Result with unmodified ``axis_master.v``: - -.. code:: - - Solving problem with 159344 variables and 442126 clauses.. - SAT proof finished - model found: FAIL! - -Result with fixed ``axis_master.v``: - -.. code:: - - Solving problem with 159144 variables and 441626 clauses.. - SAT proof finished - no model found: SUCCESS! From 70c47690b3d4832692eef50cc16dd6f00f40de1f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 28 Aug 2023 10:09:34 +1200 Subject: [PATCH 020/108] Updating todo text and assorted fixes Fix #3905 by removing emoji (and move the comment into the if block for less ambiguity). Adds `latexmk` to README. Note that latexpdf doesn't seem to like `cmd:ref` links, possibly because the reference location is inside a latex comment block, but I was under the impression that there was a reference location in there previously which was working fine. May be related to how the `cmd:def` block expands (or doesn't as the case may be). --- README.md | 2 +- docs/source/using_yosys/memory_mapping.rst | 2 +- docs/source/using_yosys/more_scripting/opt_passes.rst | 2 +- docs/source/yosys_internals/formats/rtlil_rep.rst | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 87d9730a4..7e6aba22b 100644 --- a/README.md +++ b/README.md @@ -607,7 +607,7 @@ following are used for building the website: PDFLaTeX, included with most LaTeX distributions, is also needed during the build process for the website. Or, run the following: - $ sudo apt install texlive-latex-base texlive-latex-extra + $ 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/source/using_yosys/memory_mapping.rst b/docs/source/using_yosys/memory_mapping.rst index 41654a0c5..21cea5319 100644 --- a/docs/source/using_yosys/memory_mapping.rst +++ b/docs/source/using_yosys/memory_mapping.rst @@ -198,8 +198,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 diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index 15f2e20af..f8b558854 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -128,7 +128,7 @@ is produced. The ``opt_rmdff`` pass ~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: The ``opt_rmdff`` pass doesn't exist anymore? +.. todo:: Update to ``opt_dff`` 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 diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index fa356e785..78fa47ba4 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -59,7 +59,7 @@ 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 ($). +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 @@ -74,7 +74,7 @@ This has three advantages: - First, it is impossible that an auto-generated identifier collides with an identifier that was provided by the user. -.. todo:: does opt_rmunused (still?) exist? +.. todo:: ``opt_clean`` (or clean), also ``-purge`` - Second, the information about which identifiers were originally provided by the user is always available which can help guide some optimizations. For @@ -86,7 +86,7 @@ This has three advantages: 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\_. + 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 @@ -158,7 +158,7 @@ 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) +- 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) @@ -167,7 +167,7 @@ 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 +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. From 93c9bf2f5dc1490b27dd8d565d1457f0f352afe2 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:21:15 +1200 Subject: [PATCH 021/108] docs: Updating todos --- docs/source/getting_started/scripting_intro.rst | 2 +- docs/source/getting_started/typical_phases.rst | 2 +- docs/source/introduction.rst | 4 +++- docs/source/test_suites.rst | 2 +- .../source/using_yosys/more_scripting/opt_passes.rst | 2 +- .../source/using_yosys/more_scripting/selections.rst | 2 +- docs/source/using_yosys/yosys_flows.rst | 12 ++++++++---- docs/source/yosys_internals/extensions.rst | 6 +++--- .../source/yosys_internals/flow/control_and_data.rst | 2 +- docs/source/yosys_internals/flow/overview.rst | 2 +- docs/source/yosys_internals/formats/cell_library.rst | 4 ++-- docs/source/yosys_internals/index.rst | 2 +- docs/source/yosys_internals/techmap.rst | 6 +++--- 13 files changed, 27 insertions(+), 21 deletions(-) diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 594f7cee8..9ebdc1d9d 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -1,7 +1,7 @@ Scripting in Yosys ------------------ -.. todo:: copypaste +.. todo:: check logical consistency Yosys reads and processes commands from synthesis scripts, command line arguments and an interactive command prompt. Yosys commands consist of a command diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index e3c105755..9d48ac71b 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -1,7 +1,7 @@ Typical phases of a synthesis flow ---------------------------------- -.. todo:: copypaste +.. todo:: expand text - Reading and elaborating the design - Higher-level synthesis and optimization diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 8c9450feb..20add9bb5 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -116,6 +116,8 @@ Benefits of open source HDL synthesis The extended Yosys universe --------------------------- +.. todo:: links and add SCY + In no particular order: - SBY for formal verification @@ -125,7 +127,7 @@ In no particular order: History of Yosys ---------------- -.. todo:: copypaste +.. todo:: make less academic 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 diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index 7f23754b2..fde337b28 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -4,7 +4,7 @@ Test suites .. note:: Potentially significantly out of date information last updated circa 2015 -.. todo:: copypaste +.. todo:: update content from 2015 Continuously checking the correctness of Yosys and making sure that new features do not break old ones is a high priority in Yosys. Two external test suites diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index f8b558854..4437a4796 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -3,7 +3,7 @@ Optimization passes =================== -.. todo:: copypaste +.. todo:: check text context, also check the optimization passes still do what they say Yosys employs a number of optimizations to generate better and cleaner results. This chapter outlines these optimizations. diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index e3a93d163..2c36778c8 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -1,7 +1,7 @@ Selections ---------- -.. todo:: copypaste +.. todo:: expand on text 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: diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 7a51385c1..633a8ec77 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -4,7 +4,7 @@ Flows, command types, and order Command order ------------- -.. todo:: copypaste +.. todo:: check text is coherent Intro to coarse-grain synthesis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -39,7 +39,7 @@ The extract pass 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:: copypaste +.. todo:: add/expand supporting text .. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* :class: width-helper @@ -121,7 +121,7 @@ Preconditioning: ``macc_xilinx_swap_map.v`` Make sure ``A`` is the smaller port on all multipliers -.. todo:: copypaste +.. todo:: add/expand supporting text .. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v :language: verilog @@ -277,7 +277,7 @@ Unwrap in ``test2``: Symbolic model checking ----------------------- -.. todo:: copypaste +.. todo:: check text context .. note:: @@ -299,6 +299,8 @@ Checking. Checking techmap ~~~~~~~~~~~~~~~~ +.. todo:: add/expand supporting text + Remember the following example from :doc:`/getting_started/typical_phases`? .. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01_map.v @@ -351,6 +353,8 @@ slave keeps ``tready`` asserted all the time. (Something a test bench might do.) Symbolic Model Checking can be used to expose the bug and find a sequence of values for ``tready`` that yield the incorrect behavior. +.. todo:: add/expand supporting text + .. literalinclude:: ../../resources/PRESENTATION_ExOth/axis_master.v :language: verilog :caption: ``docs/resources/PRESENTATION_ExOth/axis_master.v`` diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index d7c21154d..5ef4b5c90 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -3,7 +3,7 @@ Writing extensions ================== -.. todo:: copypaste +.. todo:: check text is coherent This chapter contains some bits and pieces of information about programming yosys extensions. Don't be afraid to ask questions on the YosysHQ Slack. @@ -82,11 +82,11 @@ command has been executed can be helpful. The :doc:`/using_yosys/more_scripting/selections` document has more information on using these commands. -.. todo:: copypaste - Creating modules from scratch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. todo:: add/expand supporting text + Let's create the following module using the RTLIL API: .. code:: Verilog diff --git a/docs/source/yosys_internals/flow/control_and_data.rst b/docs/source/yosys_internals/flow/control_and_data.rst index 961687f79..69b7346b5 100644 --- a/docs/source/yosys_internals/flow/control_and_data.rst +++ b/docs/source/yosys_internals/flow/control_and_data.rst @@ -1,7 +1,7 @@ Control and data flow ===================== -.. todo:: copypaste +.. 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 diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst index acb7dbaab..c1dddfcbb 100644 --- a/docs/source/yosys_internals/flow/overview.rst +++ b/docs/source/yosys_internals/flow/overview.rst @@ -1,7 +1,7 @@ Flow overview ============= -.. todo:: copypaste +.. todo:: less academic :numref:`Figure %s <fig:Overview_flow>` shows the simplified data flow within Yosys. Rectangles in the figure represent program modules and ellipses internal diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index 6667b8b67..cb2f99bb2 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -1,13 +1,13 @@ .. role:: verilog(code) :language: Verilog -.. todo:: copypaste - .. _chapter:celllib: Internal cell library ===================== +.. 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. diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst index 3389d88a0..001e2536c 100644 --- a/docs/source/yosys_internals/index.rst +++ b/docs/source/yosys_internals/index.rst @@ -3,7 +3,7 @@ Yosys internals =============== -.. todo:: copypaste +.. 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 diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index 64f89777b..d0aadbd4d 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -1,6 +1,6 @@ .. _chapter:techmap: -.. todo:: copypaste +.. todo:: less academic, check text is coherent Technology mapping ================== @@ -109,8 +109,6 @@ sensitive information from the Liberty file. Techmap by example ------------------ -.. todo:: copypaste - 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. @@ -125,6 +123,8 @@ Yosys' internal cell types (such as ``$or``) as well as user-defined cell types. Mapping OR3X1 ~~~~~~~~~~~~~ +.. todo:: add/expand supporting text + .. note:: This is a simple example for demonstration only. Techmap shouldn't be used From 10ecbe9f5bd383912badd141022afb91a2eda49f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:26:57 +1200 Subject: [PATCH 022/108] docs: updating memory mapping text More complete code examples and confirming Verific support thanks to @povik --- docs/source/using_yosys/memory_mapping.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/source/using_yosys/memory_mapping.rst b/docs/source/using_yosys/memory_mapping.rst index 21cea5319..7fd0a3eb9 100644 --- a/docs/source/using_yosys/memory_mapping.rst +++ b/docs/source/using_yosys/memory_mapping.rst @@ -248,6 +248,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 @@ -374,7 +375,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 @@ -408,8 +409,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]; @@ -590,14 +591,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 `Synchronous SDP with write-first behavior`_ for compatibility with Yosys + Verilog frontend. .. code:: verilog @@ -614,8 +615,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 synchronous read + port`_) for compatibility with Yosys Verilog frontend. .. code:: verilog From b0f8059bceeb96362c588c05cf714439d3ac38f9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 10 Oct 2023 10:12:50 +1300 Subject: [PATCH 023/108] Moving images and static folders Images now included relative to the `docs/source` folder instead of the rst file. Also makes sure to add the updated `yosyshq.css` (which as a sidenote has ended up as `custom.css` in most of the other docs). --- docs/.gitignore | 18 ++-- .../_images}/011/example_out.tex | 0 .../_images}/011/select_prod.tex | 0 .../_images}/011/splitnets_libfile.tex | 0 .../_images}/011/submod_dots.tex | 0 docs/{images => source/_images}/Makefile | 0 .../_images}/approach_flow.png | Bin .../_images}/approach_flow.tex | 0 .../_images}/basics_abstractions.png | Bin .../_images}/basics_abstractions.tex | 0 .../{images => source/_images}/basics_ast.png | Bin .../{images => source/_images}/basics_ast.tex | 0 .../_images}/basics_flow.png | Bin .../_images}/basics_flow.tex | 0 .../_images}/basics_parsetree.png | Bin .../_images}/basics_parsetree.tex | 0 .../_images}/levels_of_abstraction.tex | 0 .../_images}/overview_flow.png | Bin .../_images}/overview_flow.tex | 0 .../_images}/overview_rtlil.png | Bin .../_images}/overview_rtlil.tex | 0 .../_images}/simplified_rtlil.tex | 0 .../_images}/verilog_flow.png | Bin .../_images}/verilog_flow.tex | 0 docs/source/_static/custom.css | 15 ++++ docs/{static => source/_static}/favico.png | Bin docs/{static => source/_static}/logo.png | Bin docs/source/_static/yosyshq.css | 26 ++++++ .../APPNOTE_011_Design_Investigation.rst | 20 ++--- docs/source/appendix/primer.rst | 8 +- docs/source/conf.py | 6 +- docs/source/getting_started/examples.rst | 8 +- .../source/getting_started/typical_phases.rst | 22 ++--- docs/source/introduction.rst | 2 +- .../using_yosys/more_scripting/selections.rst | 6 +- docs/source/using_yosys/yosys_flows.rst | 40 ++++----- docs/source/yosys_internals/extensions.rst | 2 +- .../yosys_internals/flow/control_and_data.rst | 2 +- docs/source/yosys_internals/flow/overview.rst | 2 +- .../yosys_internals/flow/verilog_frontend.rst | 2 +- .../yosys_internals/formats/rtlil_rep.rst | 2 +- docs/source/yosys_internals/techmap.rst | 10 +-- docs/static/custom.css | 1 - docs/static/yosyshq.css | 78 ------------------ 44 files changed, 116 insertions(+), 154 deletions(-) rename docs/{images => source/_images}/011/example_out.tex (100%) rename docs/{images => source/_images}/011/select_prod.tex (100%) rename docs/{images => source/_images}/011/splitnets_libfile.tex (100%) rename docs/{images => source/_images}/011/submod_dots.tex (100%) rename docs/{images => source/_images}/Makefile (100%) rename docs/{images => source/_images}/approach_flow.png (100%) rename docs/{images => source/_images}/approach_flow.tex (100%) rename docs/{images => source/_images}/basics_abstractions.png (100%) rename docs/{images => source/_images}/basics_abstractions.tex (100%) rename docs/{images => source/_images}/basics_ast.png (100%) rename docs/{images => source/_images}/basics_ast.tex (100%) rename docs/{images => source/_images}/basics_flow.png (100%) rename docs/{images => source/_images}/basics_flow.tex (100%) rename docs/{images => source/_images}/basics_parsetree.png (100%) rename docs/{images => source/_images}/basics_parsetree.tex (100%) rename docs/{images => source/_images}/levels_of_abstraction.tex (100%) rename docs/{images => source/_images}/overview_flow.png (100%) rename docs/{images => source/_images}/overview_flow.tex (100%) rename docs/{images => source/_images}/overview_rtlil.png (100%) rename docs/{images => source/_images}/overview_rtlil.tex (100%) rename docs/{images => source/_images}/simplified_rtlil.tex (100%) rename docs/{images => source/_images}/verilog_flow.png (100%) rename docs/{images => source/_images}/verilog_flow.tex (100%) create mode 100644 docs/source/_static/custom.css rename docs/{static => source/_static}/favico.png (100%) rename docs/{static => source/_static}/logo.png (100%) create mode 100644 docs/source/_static/yosyshq.css delete mode 100644 docs/static/custom.css delete mode 100644 docs/static/yosyshq.css diff --git a/docs/.gitignore b/docs/.gitignore index 40b781904..50f03d13c 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,12 +1,12 @@ /build/ /source/cmd /source/temp -/images/*.log -/images/*.aux -/images/*.pdf -/images/*.svg -/images/**/*.log -/images/**/*.aux -/images/**/*.pdf -/images/**/*.svg -/images/**/*.dot +/source/_images/*.log +/source/_images/*.aux +/source/_images/*.pdf +/source/_images/*.svg +/source/_images/**/*.log +/source/_images/**/*.aux +/source/_images/**/*.pdf +/source/_images/**/*.svg +/source/_images/**/*.dot diff --git a/docs/images/011/example_out.tex b/docs/source/_images/011/example_out.tex similarity index 100% rename from docs/images/011/example_out.tex rename to docs/source/_images/011/example_out.tex diff --git a/docs/images/011/select_prod.tex b/docs/source/_images/011/select_prod.tex similarity index 100% rename from docs/images/011/select_prod.tex rename to docs/source/_images/011/select_prod.tex diff --git a/docs/images/011/splitnets_libfile.tex b/docs/source/_images/011/splitnets_libfile.tex similarity index 100% rename from docs/images/011/splitnets_libfile.tex rename to docs/source/_images/011/splitnets_libfile.tex diff --git a/docs/images/011/submod_dots.tex b/docs/source/_images/011/submod_dots.tex similarity index 100% rename from docs/images/011/submod_dots.tex rename to docs/source/_images/011/submod_dots.tex diff --git a/docs/images/Makefile b/docs/source/_images/Makefile similarity index 100% rename from docs/images/Makefile rename to docs/source/_images/Makefile diff --git a/docs/images/approach_flow.png b/docs/source/_images/approach_flow.png similarity index 100% rename from docs/images/approach_flow.png rename to docs/source/_images/approach_flow.png diff --git a/docs/images/approach_flow.tex b/docs/source/_images/approach_flow.tex similarity index 100% rename from docs/images/approach_flow.tex rename to docs/source/_images/approach_flow.tex diff --git a/docs/images/basics_abstractions.png b/docs/source/_images/basics_abstractions.png similarity index 100% rename from docs/images/basics_abstractions.png rename to docs/source/_images/basics_abstractions.png diff --git a/docs/images/basics_abstractions.tex b/docs/source/_images/basics_abstractions.tex similarity index 100% rename from docs/images/basics_abstractions.tex rename to docs/source/_images/basics_abstractions.tex diff --git a/docs/images/basics_ast.png b/docs/source/_images/basics_ast.png similarity index 100% rename from docs/images/basics_ast.png rename to docs/source/_images/basics_ast.png diff --git a/docs/images/basics_ast.tex b/docs/source/_images/basics_ast.tex similarity index 100% rename from docs/images/basics_ast.tex rename to docs/source/_images/basics_ast.tex diff --git a/docs/images/basics_flow.png b/docs/source/_images/basics_flow.png similarity index 100% rename from docs/images/basics_flow.png rename to docs/source/_images/basics_flow.png diff --git a/docs/images/basics_flow.tex b/docs/source/_images/basics_flow.tex similarity index 100% rename from docs/images/basics_flow.tex rename to docs/source/_images/basics_flow.tex diff --git a/docs/images/basics_parsetree.png b/docs/source/_images/basics_parsetree.png similarity index 100% rename from docs/images/basics_parsetree.png rename to docs/source/_images/basics_parsetree.png diff --git a/docs/images/basics_parsetree.tex b/docs/source/_images/basics_parsetree.tex similarity index 100% rename from docs/images/basics_parsetree.tex rename to docs/source/_images/basics_parsetree.tex diff --git a/docs/images/levels_of_abstraction.tex b/docs/source/_images/levels_of_abstraction.tex similarity index 100% rename from docs/images/levels_of_abstraction.tex rename to docs/source/_images/levels_of_abstraction.tex diff --git a/docs/images/overview_flow.png b/docs/source/_images/overview_flow.png similarity index 100% rename from docs/images/overview_flow.png rename to docs/source/_images/overview_flow.png diff --git a/docs/images/overview_flow.tex b/docs/source/_images/overview_flow.tex similarity index 100% rename from docs/images/overview_flow.tex rename to docs/source/_images/overview_flow.tex diff --git a/docs/images/overview_rtlil.png b/docs/source/_images/overview_rtlil.png similarity index 100% rename from docs/images/overview_rtlil.png rename to docs/source/_images/overview_rtlil.png diff --git a/docs/images/overview_rtlil.tex b/docs/source/_images/overview_rtlil.tex similarity index 100% rename from docs/images/overview_rtlil.tex rename to docs/source/_images/overview_rtlil.tex diff --git a/docs/images/simplified_rtlil.tex b/docs/source/_images/simplified_rtlil.tex similarity index 100% rename from docs/images/simplified_rtlil.tex rename to docs/source/_images/simplified_rtlil.tex diff --git a/docs/images/verilog_flow.png b/docs/source/_images/verilog_flow.png similarity index 100% rename from docs/images/verilog_flow.png rename to docs/source/_images/verilog_flow.png diff --git a/docs/images/verilog_flow.tex b/docs/source/_images/verilog_flow.tex similarity index 100% rename from docs/images/verilog_flow.tex rename to docs/source/_images/verilog_flow.tex diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 000000000..21ede09b4 --- /dev/null +++ b/docs/source/_static/custom.css @@ -0,0 +1,15 @@ +/* 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%; +} \ No newline at end of file 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 000000000..57ae8f87a --- /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/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst index 698f2da2c..5552408cc 100644 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst @@ -60,7 +60,7 @@ Introduction to the show command y <= c ? a + b : 2'd0; endmodule -.. figure:: ../../images/011/example_out.* +.. figure:: /_images/011/example_out.* :class: width-helper :name: example_out @@ -134,7 +134,7 @@ leads us to the 3rd diagram in :numref:`example_out`. Here we see that the :cmd:ref:`proc`, but also determined correctly that it can remove the first ``$mux`` cell without changing the behavior of the circuit. -.. figure:: ../../images/011/splice.* +.. figure:: /_images/011/splice.* :class: width-helper :name: splice_dia @@ -144,7 +144,7 @@ leads us to the 3rd diagram in :numref:`example_out`. Here we see that the :caption: ``splice.v`` :name: splice_src -.. figure:: ../../images/011/splitnets_libfile.* +.. figure:: /_images/011/splitnets_libfile.* :class: width-helper :name: splitnets_libfile @@ -329,7 +329,7 @@ run from module-context and not design-context. Working with selections ----------------------- -.. figure:: ../../images/011/example_03.* +.. figure:: /_images/011/example_03.* :class: width-helper :name: seladd @@ -386,7 +386,7 @@ Operations on selections :name: sumprod :language: verilog -.. figure:: ../../images/011/sumprod_00.* +.. figure:: /_images/011/sumprod_00.* :class: width-helper :name: sumprod_00 @@ -434,7 +434,7 @@ 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.* +.. figure:: /_images/011/sumprod_01.* :class: width-helper :name: sumprod_01 @@ -471,7 +471,7 @@ 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.* +.. figure:: /_images/011/select_prod.* :class: width-helper :name: select_prod @@ -493,7 +493,7 @@ see the diagram shown in :numref:`memdemo_00`. :name: memdemo_src :language: verilog -.. figure:: ../../images/011/memdemo_00.* +.. figure:: /_images/011/memdemo_00.* :class: width-helper :name: memdemo_00 @@ -538,7 +538,7 @@ Or we could decide to tell the ``%ci`` action to not follow the ``CLK`` input: show y %ci2:-[CLK] -.. figure:: ../../images/011/memdemo_01.* +.. figure:: /_images/011/memdemo_01.* :class: width-helper :name: memdemo_01 @@ -616,7 +616,7 @@ 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.* +.. figure:: /_images/011/submod_dots.* :class: width-helper :name: submod_dots diff --git a/docs/source/appendix/primer.rst b/docs/source/appendix/primer.rst index 6c9aa1673..9a905c6f2 100644 --- a/docs/source/appendix/primer.rst +++ b/docs/source/appendix/primer.rst @@ -23,7 +23,7 @@ circuit to a functionally equivalent low-level representation of a circuit. :numref:`Figure %s <fig:Basics_abstractions>` lists the different levels of abstraction and how they relate to different kinds of synthesis. -.. figure:: ../../images/basics_abstractions.* +.. figure:: /_images/basics_abstractions.* :class: width-helper :name: fig:Basics_abstractions @@ -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 <fig:Basics_flow>`. -.. figure:: ../../images/basics_flow.* +.. figure:: /_images/basics_flow.* :class: width-helper :name: fig:Basics_flow @@ -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/basics_parsetree.* :class: width-helper :name: fig:Basics_parsetree @@ -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/basics_ast.* :class: width-helper :name: fig:Basics_ast diff --git a/docs/source/conf.py b/docs/source/conf.py index a043f0b49..003887498 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -9,8 +9,8 @@ copyright ='2022 YosysHQ GmbH' # select HTML theme html_theme = 'furo' templates_path = ["_templates"] -html_logo = '../static/logo.png' -html_favicon = '../static/favico.png' +html_logo = '_static/logo.png' +html_favicon = '_static/favico.png' html_css_files = ['yosyshq.css', 'custom.css'] html_theme_options = { @@ -34,7 +34,7 @@ html_theme_options = { } # 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' diff --git a/docs/source/getting_started/examples.rst b/docs/source/getting_started/examples.rst index 0c3f66365..8342b685c 100644 --- a/docs/source/getting_started/examples.rst +++ b/docs/source/getting_started/examples.rst @@ -106,7 +106,7 @@ Step 1 Result: -.. figure:: ../../images/res/PRESENTATION_Intro/counter_00.* +.. figure:: /_images/res/PRESENTATION_Intro/counter_00.* :class: width-helper Step 2 @@ -118,7 +118,7 @@ Step 2 Result: -.. figure:: ../../images/res/PRESENTATION_Intro/counter_01.* +.. figure:: /_images/res/PRESENTATION_Intro/counter_01.* :class: width-helper Step 3 @@ -130,7 +130,7 @@ Step 3 Result: -.. figure:: ../../images/res/PRESENTATION_Intro/counter_02.* +.. figure:: /_images/res/PRESENTATION_Intro/counter_02.* :class: width-helper Step 4 @@ -142,5 +142,5 @@ Step 4 Result: -.. figure:: ../../images/res/PRESENTATION_Intro/counter_03.* +.. figure:: /_images/res/PRESENTATION_Intro/counter_03.* :class: width-helper diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index 9d48ac71b..a06ee1e17 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -94,10 +94,10 @@ Example :language: yoscrypt :caption: ``docs/resources/PRESENTATION_ExSyn/proc_01.ys`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/proc_01.* +.. figure:: /_images/res/PRESENTATION_ExSyn/proc_01.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExSyn/proc_02.* +.. figure:: /_images/res/PRESENTATION_ExSyn/proc_02.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_02.v @@ -108,7 +108,7 @@ Example :language: yoscrypt :caption: ``docs/resources/PRESENTATION_ExSyn/proc_02.ys`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/proc_03.* +.. figure:: /_images/res/PRESENTATION_ExSyn/proc_03.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_03.ys @@ -150,7 +150,7 @@ The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And Example ^^^^^^^ -.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_01.* +.. figure:: /_images/res/PRESENTATION_ExSyn/opt_01.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_01.ys @@ -161,7 +161,7 @@ Example :language: verilog :caption: ``docs/resources/PRESENTATION_ExSyn/opt_01.v`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_02.* +.. figure:: /_images/res/PRESENTATION_ExSyn/opt_02.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_02.ys @@ -172,7 +172,7 @@ Example :language: verilog :caption: ``docs/resources/PRESENTATION_ExSyn/opt_02.v`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_03.* +.. figure:: /_images/res/PRESENTATION_ExSyn/opt_03.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_03.ys @@ -183,7 +183,7 @@ Example :language: verilog :caption: ``docs/resources/PRESENTATION_ExSyn/opt_03.v`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/opt_04.* +.. figure:: /_images/res/PRESENTATION_ExSyn/opt_04.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_04.v @@ -246,7 +246,7 @@ For example: Example ^^^^^^^ -.. figure:: ../../images/res/PRESENTATION_ExSyn/memory_01.* +.. figure:: /_images/res/PRESENTATION_ExSyn/memory_01.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_01.ys @@ -257,7 +257,7 @@ Example :language: verilog :caption: ``docs/resources/PRESENTATION_ExSyn/memory_01.v`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/memory_02.* +.. figure:: /_images/res/PRESENTATION_ExSyn/memory_02.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_02.v @@ -315,7 +315,7 @@ Finally the :cmd:ref:`fsm_map` command can be used to convert the (optimized) The :cmd:ref:`techmap` command ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. figure:: ../../images/res/PRESENTATION_ExSyn/techmap_01.* +.. figure:: /_images/res/PRESENTATION_ExSyn/techmap_01.* :class: width-helper The :cmd:ref:`techmap` command replaces cells with implementations given as @@ -386,7 +386,7 @@ Example :language: yoscrypt :caption: ``docs/resources/PRESENTATION_ExSyn/abc_01.ys`` -.. figure:: ../../images/res/PRESENTATION_ExSyn/abc_01.* +.. figure:: /_images/res/PRESENTATION_ExSyn/abc_01.* :class: width-helper Other special-purpose mapping commands diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 20add9bb5..6a3f8802e 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -37,7 +37,7 @@ 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/levels_of_abstraction.* +.. figure:: /_images/levels_of_abstraction.* :class: width-helper :name: fig:Levels_of_abstraction diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 2c36778c8..2957a1c2f 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -181,7 +181,7 @@ Example: :language: yoscrypt :caption: ``docs/resources/PRESENTATION_ExAdv/select.ys`` -.. figure:: ../../../images/res/PRESENTATION_ExAdv/select.* +.. figure:: /_images/res/PRESENTATION_ExAdv/select.* :class: width-helper Interactive Design Investigation @@ -226,10 +226,10 @@ reorganizing a module in Yosys and checking the resulting circuit. xs %c %ci %D %c %ci:+[D] %D \ %ci*:-$dff xs %co %ci %d -.. figure:: ../../../images/res/PRESENTATION_ExOth/scrambler_p01.* +.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p01.* :class: width-helper -.. figure:: ../../../images/res/PRESENTATION_ExOth/scrambler_p02.* +.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p02.* :class: width-helper Analyzing the resulting circuit with :doc:`/cmd/eval`: diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 633a8ec77..0bd824b20 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -41,12 +41,12 @@ The extract pass .. todo:: add/expand supporting text -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* :class: width-helper before `extract` -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_00b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_00b.* :class: width-helper after `extract` @@ -70,20 +70,20 @@ The extract pass :language: verilog :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v`` -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test_02.v :language: verilog :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v`` -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_simple_test_02b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_02b.* :class: width-helper The wrap-extract-unwrap method @@ -169,10 +169,10 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` :lines: 1-6 :caption: ``test1`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v @@ -180,15 +180,15 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` :lines: 8-13 :caption: ``test2`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* :class: width-helper Wrapping in ``test1``: -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* :class: width-helper .. code:: yoscrypt @@ -200,12 +200,12 @@ Wrapping in ``test1``: -unsigned $__add_wrapper \ Y Y_WIDTH ;; -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* :class: width-helper Wrapping in ``test2``: -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* :class: width-helper .. code:: yoscrypt @@ -217,7 +217,7 @@ Wrapping in ``test2``: -unsigned $__add_wrapper \ Y Y_WIDTH ;; -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* :class: width-helper Extract in ``test1``: @@ -235,10 +235,10 @@ Extract in ``test1``: -map %__macc_xilinx_xmap \ -swap $__add_wrapper A,B ;; -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test1d.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1d.* :class: width-helper Extract in ``test2``: @@ -256,18 +256,18 @@ Extract in ``test2``: -map %__macc_xilinx_xmap \ -swap $__add_wrapper A,B ;; -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* :class: width-helper Unwrap in ``test2``: -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* :class: width-helper -.. figure:: ../../images/res/PRESENTATION_ExAdv/macc_xilinx_test2e.* +.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2e.* :class: width-helper .. code:: yoscrypt diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index 5ef4b5c90..68d023d64 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -60,7 +60,7 @@ provides. This document will focus on the much simpler version of RTLIL left after the commands :cmd:ref:`proc` and :cmd:ref:`memory` (or ``memory -nomap``): -.. figure:: ../../images/simplified_rtlil.* +.. figure:: /_images/simplified_rtlil.* :class: width-helper :name: fig:Simplified_RTLIL diff --git a/docs/source/yosys_internals/flow/control_and_data.rst b/docs/source/yosys_internals/flow/control_and_data.rst index 69b7346b5..b2ec418ad 100644 --- a/docs/source/yosys_internals/flow/control_and_data.rst +++ b/docs/source/yosys_internals/flow/control_and_data.rst @@ -9,7 +9,7 @@ a predetermined order, each consuming the data generated by the last subsystem and generating the data for the next subsystem (see :numref:`Fig. %s <fig:approach_flow>`). -.. figure:: ../../../images/approach_flow.* +.. figure:: /_images/approach_flow.* :class: width-helper :name: fig:approach_flow diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst index c1dddfcbb..1c2adc01c 100644 --- a/docs/source/yosys_internals/flow/overview.rst +++ b/docs/source/yosys_internals/flow/overview.rst @@ -40,7 +40,7 @@ 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.* +.. figure:: /_images/overview_flow.* :class: width-helper :name: fig:Overview_flow diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index 2c8af3ad3..72907c121 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -9,7 +9,7 @@ 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 <fig:Verilog_flow>`. -.. figure:: ../../../images/verilog_flow.* +.. figure:: /_images/verilog_flow.* :class: width-helper :name: fig:Verilog_flow diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index 78fa47ba4..b6b437b90 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -23,7 +23,7 @@ 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.* +.. figure:: /_images/overview_rtlil.* :class: width-helper :name: fig:Overview_RTLIL diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index d0aadbd4d..b89ca9cb9 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -134,7 +134,7 @@ Mapping OR3X1 :language: verilog :caption: ``docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v`` -.. figure:: ../../images/res/PRESENTATION_ExAdv/red_or3x1.* +.. figure:: /_images/res/PRESENTATION_ExAdv/red_or3x1.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_test.ys @@ -160,7 +160,7 @@ Conditional techmap Example: -.. figure:: ../../images/res/PRESENTATION_ExAdv/sym_mul.* +.. figure:: /_images/res/PRESENTATION_ExAdv/sym_mul.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_map.v @@ -199,7 +199,7 @@ Scripting in map modules Example: -.. figure:: ../../images/res/PRESENTATION_ExAdv/mymul.* +.. figure:: /_images/res/PRESENTATION_ExAdv/mymul.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_map.v @@ -229,7 +229,7 @@ Handling constant inputs Example: -.. figure:: ../../images/res/PRESENTATION_ExAdv/mulshift.* +.. figure:: /_images/res/PRESENTATION_ExAdv/mulshift.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_map.v @@ -260,7 +260,7 @@ Handling shorted inputs Example: -.. figure:: ../../images/res/PRESENTATION_ExAdv/addshift.* +.. figure:: /_images/res/PRESENTATION_ExAdv/addshift.* :class: width-helper .. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_map.v diff --git a/docs/static/custom.css b/docs/static/custom.css deleted file mode 100644 index 40a8c178f..000000000 --- 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 91a15c129..000000000 --- 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; -} - -.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%; -} - -.width-helper { - max-width: 100%; -} From a019c26b9df24c4ae28014f01e8f0375df9636a1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 10 Oct 2023 12:27:00 +1300 Subject: [PATCH 024/108] docs: Moving 011 into main body of manual Mostly in the `more_scripting` section, with part of the intro in the `scripting_intro`. Also includes an extra todo on the installation page and some extra notes on where to find `show` details where relevant. --- .../APPNOTE_011_Design_Investigation.rst | 646 +------------- docs/source/getting_started/installation.rst | 2 + .../getting_started/scripting_intro.rst | 51 ++ .../using_yosys/more_scripting/index.rst | 1 + .../interactive_investigation.rst | 786 ++++++++++++++++++ .../using_yosys/more_scripting/selections.rst | 117 +-- 6 files changed, 846 insertions(+), 757 deletions(-) create mode 100644 docs/source/using_yosys/more_scripting/interactive_investigation.rst diff --git a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst index 5552408cc..3cbd0eb90 100644 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst @@ -6,323 +6,31 @@ 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 :cmd:ref:`show` -command requires a working installation of `GraphViz`_ and `xdot` for generating -the actual circuit diagrams. +2013-12-08. The README file covers how to install Yosys. .. _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 :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`show` commands from :numref:`example_src` - -The :cmd:ref:`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 :cmd:ref:`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 -``<bit_width>'<bits>`` 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 :cmd:ref:`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 :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:`proc`, which includes :cmd:ref:`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 :cmd:ref:`clean` before calling :cmd:ref:`show`. - -In this script we directly call :cmd:ref:`proc` as next step, which finally -leads us to the 3rd diagram in :numref:`example_out`. 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. - -.. 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 :cmd:ref:`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 :cmd:ref:`show` in :numref:`splice_src` -demonstrates how such circuits are visualized by the :cmd:ref:`show` command. - -The key elements in understanding this circuit diagram are of course the boxes -with round corners and rows labeled ``<MSB_LEFT>:<LSB_LEFT> - -<MSB_RIGHT>:<LSB_RIGHT>``. Each of this boxes has one signal per row on one side -and a common signal for all rows on the other side. The ``<MSB>:<LSB>`` 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 :cmd:ref:`show` command using the ``-lib <filename>`` -option. Secondly it is possible to load cell libraries into the design with the -``read_verilog -lib <filename>`` 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 :cmd:ref:`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 :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. - -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 :cmd:ref:`show` -with the ``-colors <integer>`` 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 :cmd:ref:`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 -: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 ``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 :cmd:ref:`ls` and :cmd:ref:`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 :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 `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 -: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 -``<module_name>/``. 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 ``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. @@ -336,12 +44,6 @@ Working with selections Output of :cmd:ref:`show` after ``select $2`` or ``select t:$add`` (see also :numref:`example_out`) -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. - But for most interactive work we want to further narrow the set of selected objects. This can be done using the :cmd:ref:`select` command. @@ -598,352 +300,6 @@ 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. -.. _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 :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`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 :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 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 :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/ - -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: - -:: - - 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.) - -: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 :cmd:ref:`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 :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. - -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. - .. _conclusion: Conclusion diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 0b7f52b1d..1677445fa 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -1,6 +1,8 @@ Installation ------------ +.. todo:: update and finish installation instructions + Supported platforms ~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 9ebdc1d9d..35015ceb9 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -98,6 +98,8 @@ Commands for model checking: Selections intro ~~~~~~~~~~~~~~~~ +.. todo:: reorder text for logical consistency + Most commands can operate not only on the entire design but also specifically on selected parts of the design. For example the command :cmd:ref:`dump` will print all selected objects in the current design while ``dump foobar`` will only print @@ -113,3 +115,52 @@ print all wires that are connected to the ``\A`` port of a ``$add`` cell. 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`. + +The show command +~~~~~~~~~~~~~~~~ + +The :cmd:ref:`show` command requires a working installation of `GraphViz`_ and +`xdot`_ for generating the actual circuit diagrams. Below is an example of how +this command can be used, showing the changes in the generated circuit at +different stages of the yosys tool flow. + +.. _GraphViz: http://www.graphviz.org/ + +.. _xdot: https://github.com/jrfonseca/xdot.py + +.. code-block:: console + :caption: Yosys script with :cmd:ref:`show` commands and example design + :name: show_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: show_out + + Output of the three :cmd:ref:`show` commands from :numref:`show_src` + +A circuit diagram is generated 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). + +For more information on the :cmd:ref:`show` command, including a guide on what +the different symbols represent, see :ref:`interactive_show` and the +:doc:`/using_yosys/more_scripting/interactive_investigation` page. diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 32879c0d4..8fb460613 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -6,5 +6,6 @@ More scripting opt_passes selections + interactive_investigation synth 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 000000000..6eab48bf5 --- /dev/null +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -0,0 +1,786 @@ +Interactive design investigation +-------------------------------- + +.. _interactive_show: + +A look at the show command +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section introduces the :cmd:ref:`show` command and explains the symbols +used in the circuit diagrams generated by it. + +A simple circuit +^^^^^^^^^^^^^^^^ + +The code listings below show a simple synthesis script and a Verilog file that +demonstrate the usage of show in a simple setting. 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. The ``show -pause`` command also allows +the user to enter an interactive shell to further investigate the circuit before +continuing synthesis. + +.. code-block:: yoscrypt + :caption: ``docs/source/APPNOTE_011_Design_Investigation/example.ys`` + + read_verilog example.v + show -pause # first + proc + show -pause # second + opt + show -pause # third + +.. literalinclude:: /APPNOTE_011_Design_Investigation/example.v + :language: Verilog + :caption: ``docs/source/APPNOTE_011_Design_Investigation/example.v`` + +This script, when executed, will show the design after each of the three +synthesis commands. + +.. figure:: /_images/011/example_00.* + :class: width-helper + + Output of the first :cmd:ref:`show` command above + +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 +``<bit_width>'<bits>`` 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 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-flip, which brings us to the second diagram: + +.. figure:: /_images/011/example_01.* + :class: width-helper + + Output of the second :cmd:ref:`show` command above + +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/011/example_02.* + :class: width-helper + :name: example_out + + Output of the third :cmd:ref:`show` command above + +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:: /APPNOTE_011_Design_Investigation/splice.v + :caption: ``splice.v`` + :name: splice_src + +Notice how the output for this circuit from the :cmd:ref:`show` command below +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/011/splice.* + :class: width-helper + :name: splice_dia + + Output of ``yosys -p 'proc; opt; show' splice.v`` + +The key elements in understanding this circuit diagram are of course the boxes +with round corners and rows labeled ``<MSB_LEFT>:<LSB_LEFT> - +<MSB_RIGHT>:<LSB_RIGHT>``. Each of this boxes has one signal per row on one side +and a common signal for all rows on the other side. The ``<MSB>:<LSB>`` 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 +^^^^^^^^^^^^^^^^^^^ + +The diagram below shows two common pitfalls when working with +designs mapped to a cell library: + +.. figure:: /_images/011/cmos_00.* + :class: width-helper + +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/011/cmos_01.* + :class: width-helper + + Effects of :cmd:ref:`splitnets` command and of providing a cell library. (The + circuit is a half-adder built from simple CMOS gates.) + +For the second 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 :cmd:ref:`show` command using the ``-lib <filename>`` +option. Secondly it is possible to load cell libraries into the design with the +``read_verilog -lib <filename>`` 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, the second 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 :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. + +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 :cmd:ref:`show` +with the ``-colors <integer>`` 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 :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 ``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 +^^^^^^^^^^^^^^^^^^^^^^ + +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 `ls` command lists the objects within that module. The +code block below demonstrates this using the design from :ref:`interactive_show`: + +.. code-block:: none + :caption: Demonstration of :cmd:ref:`ls` and :cmd:ref:`cd` + :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 + +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 :ref:`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 +``<module_name>/``. 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 ``dump $2`` will print the below. 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. + +.. code-block:: RTLIL + :caption: Output of ``dump $2`` using the design from ``example.v`` + :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 + +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. + +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:: ../../../resources/PRESENTATION_ExOth/scrambler.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExOth/scrambler.v`` + +.. code:: yoscrypt + + 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 + +.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p01.* + :class: width-helper + +.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p02.* + :class: width-helper + +Analyzing the resulting circuit with :doc:`/cmd/eval`: + +.. 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. + +.. 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 + <= 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. + +.. literalinclude:: /APPNOTE_011_Design_Investigation/memdemo.v + :caption: ``memdemo.v``, a demo circuit for demonstrating some advanced Yosys features + :language: verilog + +Let's consider the design above. 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 :cmd:ref:`show` now we see +the following diagram: + +.. figure:: /_images/011/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. The code below does exactly that, +utilising the :cmd:ref:`submod` command to split the circuit into three +sections: ``outstage``, ``selstage``, and ``scramble``. + +.. code-block:: yoscrypt + :caption: The circuit from ``memdemo.v`` broken up using :cmd:ref:`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 + +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/011/submod_02.* + :class: width-helper + + ``outstage`` + +.. figure:: /_images/011/submod_03.* + :class: width-helper + + ``selstage`` + +.. figure:: /_images/011/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. + +:: + + 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 this 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: + +:: + + 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:: /APPNOTE_011_Design_Investigation/primetest.v + :language: verilog + :caption: ``primetest.v``, a simple miter circuit for testing if a number is + prime. But it has a problem. + :name: primetest + +The code above 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. + +.. code-block:: + :caption: Experiments with the miter circuit from ``primetest.v``. + + 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 above 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. + +.. code-block:: + :caption: Miter circuit from ``primetest.v``, with the upper 8 bits of ``a`` + and ``b`` constrained to prevent overflow. + + 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 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 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 ``memdemo.v`` 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: + +.. 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: + +.. 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/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 2957a1c2f..b51ea34ea 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -21,7 +21,9 @@ commands. For example: delete # delete selected objects select -clear # reset selection (select whole design) -See :doc:`/cmd/select` +Many of the examples on this page make use of the :cmd:ref:`show` command to +visually demonstrate the effect of selections. For a more detailed look at this +command, refer to :ref:`interactive_show`. How to make a selection ~~~~~~~~~~~~~~~~~~~~~~~ @@ -78,8 +80,8 @@ Special patterns can be used to select by object property or type. For example: A complete list of this pattern expressions can be found in the command reference to the :cmd:ref:`select` command. -Combining selection -^^^^^^^^^^^^^^^^^^^ +Combining selections +^^^^^^^^^^^^^^^^^^^^ 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: @@ -183,112 +185,3 @@ Example: .. figure:: /_images/res/PRESENTATION_ExAdv/select.* :class: width-helper - -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. - -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:: ../../../resources/PRESENTATION_ExOth/scrambler.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExOth/scrambler.v`` - -.. code:: yoscrypt - - 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 - -.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p01.* - :class: width-helper - -.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p02.* - :class: width-helper - -Analyzing the resulting circuit with :doc:`/cmd/eval`: - -.. 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. - -.. 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 - <= D; - - endmodule - -For more on the :cmd:ref:`techmap` command, see the page on -:doc:`/yosys_internals/techmap`. From 9e35848c8e5793c4c9416249be621e0a12230513 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 10 Oct 2023 12:36:10 +1300 Subject: [PATCH 025/108] docs: initial 011 selections move Also deleting the 011 document. --- docs/source/appendix.rst | 1 - .../APPNOTE_011_Design_Investigation.rst | 322 ------------------ .../using_yosys/more_scripting/selections.rst | 268 +++++++++++++++ 3 files changed, 268 insertions(+), 323 deletions(-) delete mode 100644 docs/source/appendix/APPNOTE_011_Design_Investigation.rst diff --git a/docs/source/appendix.rst b/docs/source/appendix.rst index 87581793b..04ee2945c 100644 --- a/docs/source/appendix.rst +++ b/docs/source/appendix.rst @@ -10,7 +10,6 @@ Appendix appendix/auxprogs appendix/APPNOTE_010_Verilog_to_BLIF.rst - appendix/APPNOTE_011_Design_Investigation.rst appendix/APPNOTE_012_Verilog_to_BTOR.rst bib 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 3cbd0eb90..000000000 --- a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst +++ /dev/null @@ -1,322 +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. - -.. _Yosys GIT: https://github.com/YosysHQ/yosys - -.. _Rev. 2b90ba1: https://github.com/YosysHQ/yosys/tree/2b90ba1 - -Overview -======== - -This application note is structured as follows: - -: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:`conclusion` concludes the document and summarizes the key points. - -.. _navigate: - -Navigating the design -===================== - -Interactive navigation ----------------------- - -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 :cmd:ref:`show` after ``select $2`` or ``select t:$add`` (see also - :numref:`example_out`) - -But for most interactive work we want to further narrow the set of selected -objects. This can be done using the :cmd:ref:`select` command. - -For example, if the command ``select $2`` is executed, a subsequent -:cmd:ref:`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 :cmd:ref:`select` command to -evaluate additional arguments and use the resulting selection instead of the -selection created by the last :cmd:ref:`select` command. - -Normally the :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`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 -<name>``. It can later be recalled using ``select @<name>``. In fact, the -``@<name>`` expression pushes the stored selection on the stack maintained by -the :cmd:ref:`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 :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. - -.. _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 (:cmd:ref:`eval`) or by evaluation which -input values and initial conditions can result in a certain behavior at the -outputs (:cmd:ref:`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/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index b51ea34ea..b1a07ca01 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -185,3 +185,271 @@ Example: .. figure:: /_images/res/PRESENTATION_ExAdv/select.* :class: width-helper + +.. todo:: combine below sections into above where possible + +Working with selections +~~~~~~~~~~~~~~~~~~~~~~~ + +.. figure:: /_images/011/example_03.* + :class: width-helper + :name: seladd + + Output of :cmd:ref:`show` after ``select $2`` or ``select t:$add`` (see also + :numref:`example_out`) + +But for most interactive work we want to further narrow the set of selected +objects. This can be done using the :cmd:ref:`select` command. + +For example, if the command ``select $2`` is executed, a subsequent +:cmd:ref:`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 :cmd:ref:`select` command to +evaluate additional arguments and use the resulting selection instead of the +selection created by the last :cmd:ref:`select` command. + +Normally the :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`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 +<name>``. It can later be recalled using ``select @<name>``. In fact, the +``@<name>`` expression pushes the stored selection on the stack maintained by +the :cmd:ref:`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 :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. From c61ab7d62714252a7b34dc63e33321e244f78a75 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:13:06 +1300 Subject: [PATCH 026/108] docs: Tidying interactive investigation More :numref: because I figured out they were only failing if I didn't do a full re-make. Reflow first section a little to help readability. Also includes a css change to prevent code block caption text from bunching into the caption number. --- docs/source/_static/custom.css | 7 +- .../interactive_investigation.rst | 147 ++++++++++-------- 2 files changed, 91 insertions(+), 63 deletions(-) diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css index 21ede09b4..b08194c05 100644 --- a/docs/source/_static/custom.css +++ b/docs/source/_static/custom.css @@ -12,4 +12,9 @@ /* Make images full width */ .width-helper { max-width: 100%; -} \ No newline at end of file +} + +/* 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/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index 6eab48bf5..e7d5f3487 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -1,26 +1,38 @@ Interactive design investigation -------------------------------- +.. role:: yoscrypt(code) + :language: yoscrypt + .. _interactive_show: A look at the show command ~~~~~~~~~~~~~~~~~~~~~~~~~~ -This section introduces the :cmd:ref:`show` command and explains the symbols -used in the circuit diagrams generated by it. +This section explores the :cmd:ref:`show` command and explains the symbols used +in the circuit diagrams generated by it. A simple circuit ^^^^^^^^^^^^^^^^ -The code listings below show a simple synthesis script and a Verilog file that -demonstrate the usage of show in a simple setting. 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. The ``show -pause`` command also allows -the user to enter an interactive shell to further investigate the circuit before -continuing synthesis. +:numref:`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:: /APPNOTE_011_Design_Investigation/example.v + :language: Verilog + :caption: ``docs/source/APPNOTE_011_Design_Investigation/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. .. code-block:: yoscrypt :caption: ``docs/source/APPNOTE_011_Design_Investigation/example.ys`` + :name: example_ys read_verilog example.v show -pause # first @@ -29,17 +41,14 @@ continuing synthesis. opt show -pause # third -.. literalinclude:: /APPNOTE_011_Design_Investigation/example.v - :language: Verilog - :caption: ``docs/source/APPNOTE_011_Design_Investigation/example.v`` - This script, when executed, will show the design after each of the three -synthesis commands. +synthesis commands. We will now look at each of these diagrams and explain what +is shown. .. figure:: /_images/011/example_00.* :class: width-helper - Output of the first :cmd:ref:`show` command above + 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 @@ -71,7 +80,7 @@ multiplexer and a d-type flip-flip, which brings us to the second diagram: .. figure:: /_images/011/example_01.* :class: width-helper - Output of the second :cmd:ref:`show` command above + 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 @@ -94,7 +103,7 @@ leads us to the third diagram: :class: width-helper :name: example_out - Output of the third :cmd:ref:`show` command above + Output of the third :cmd:ref:`show` command in :numref:`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 @@ -110,12 +119,12 @@ accesses. :caption: ``splice.v`` :name: splice_src -Notice how the output for this circuit from the :cmd:ref:`show` command below -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. +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/011/splice.* :class: width-helper @@ -142,11 +151,15 @@ Yosys commands. Gate level netlists ^^^^^^^^^^^^^^^^^^^ -The diagram below shows two common pitfalls when working with -designs mapped to a cell library: +:numref:`first_pitfall` shows two common pitfalls when working with designs +mapped to a cell library: .. figure:: /_images/011/cmos_00.* :class: width-helper + :name: first_pitfall + + A half-adder built from simple CMOS gates, demonstrating common pitfalls when + using :cmd:ref:`show` 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 @@ -156,24 +169,25 @@ individual bits, resulting in an unnecessary complex diagram. .. figure:: /_images/011/cmos_01.* :class: width-helper + :name: second_pitfall - Effects of :cmd:ref:`splitnets` command and of providing a cell library. (The - circuit is a half-adder built from simple CMOS gates.) + Effects of :cmd:ref:`splitnets` command and of providing a cell library on + design in :numref:`first_pitfall` -For the second 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 +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 <filename>`` option. Secondly it is possible to load cell libraries into the design with the ``read_verilog -lib <filename>`` 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, the second 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. +In addition to that, :numref:`second_pitfall` 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 ^^^^^^^^^^^^^^^^^^^ @@ -228,11 +242,14 @@ 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 `ls` command lists the objects within that module. The -code block below demonstrates this using the design from :ref:`interactive_show`: +switch back). Now the `ls` command lists the objects within that module. +:numref:`lscd` below demonstrates this using the ``example.v`` from +`A simple circuit`_ + +.. todo:: update yosys output with $ternary$example.v$3 .. code-block:: none - :caption: Demonstration of :cmd:ref:`ls` and :cmd:ref:`cd` + :caption: Demonstration of :cmd:ref:`ls` and :cmd:ref:`cd` having run ``yosys example.v`` :name: lscd yosys> ls @@ -264,8 +281,8 @@ 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 :ref:`example_out` are just abbreviations of -the actual cell names, namely the part after the last dollar-sign. Most +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. @@ -277,12 +294,12 @@ Usually all interactive work is done with one module selected using the 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 ``dump $2`` will print the below. 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. +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. .. code-block:: RTLIL - :caption: Output of ``dump $2`` using the design from ``example.v`` + :caption: Output of ``dump $2`` using ``example.v`` from `A simple circuit`_ :name: dump2 attribute \src "example.v:5" @@ -420,8 +437,9 @@ if the circuit under investigation is encapsulated in a separate module. .. literalinclude:: /APPNOTE_011_Design_Investigation/memdemo.v :caption: ``memdemo.v``, a demo circuit for demonstrating some advanced Yosys features :language: verilog + :name: memdemo_v -Let's consider the design above. It serves no purpose other than being a +Let's consider :numref:`memdemo_v`. 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 :cmd:ref:`show` now we see @@ -433,7 +451,7 @@ the following diagram: ``memdemo`` Because this produces a rather large circuit, it can be useful to split it into -smaller parts for viewing and working with. The code below does exactly that, +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``. @@ -459,6 +477,7 @@ below. .. figure:: /_images/011/submod_03.* :class: width-helper + :name: selstage ``selstage`` @@ -472,7 +491,7 @@ 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. +above and is shown in :numref:`selstage`. :: @@ -580,12 +599,13 @@ circuit.) prime. But it has a problem. :name: primetest -The code above shows a miter circuit that is supposed to be used as a prime +: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. .. code-block:: :caption: Experiments with the miter circuit from ``primetest.v``. + :name: prime_shell yosys [primetest]> sat -prove ok 1 -set p 31 @@ -617,18 +637,20 @@ number test. If ``ok`` is 1 for all input values ``a`` and ``b`` for a given \ok 0 0 0 \p 31 1f 0000000000011111 -The Yosys shell session shown above 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. +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. .. code-block:: :caption: Miter circuit from ``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 @@ -656,10 +678,10 @@ to zero for the :cmd:ref:`sat` call, as is done below. \____ $$$|__/|________/|__/|_______/|__/ \__/ -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. +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 @@ -671,9 +693,10 @@ 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 entire memdemo module from ``memdemo.v`` 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: +the entire memdemo module from ``memdemo.v`` (:numref:`memdemo_v` above) 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: .. code-block:: yoscrypt From 8335044c35d523b723336b3f3e1e63cd0b0998a7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 11 Oct 2023 12:46:26 +1300 Subject: [PATCH 027/108] docs: reflowing selections doc Combined presentation sections with appnote sections. Moved a bunch of Yosys one-liners in-line. Better reference in interactive investigation to memdemo as a part of advanced logic cone selection (esp. because the show commands use some of the advanced features) --- .../interactive_investigation.rst | 19 +- .../using_yosys/more_scripting/selections.rst | 414 ++++++++---------- 2 files changed, 177 insertions(+), 256 deletions(-) diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index e7d5f3487..06b93bb90 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -434,16 +434,7 @@ 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. -.. literalinclude:: /APPNOTE_011_Design_Investigation/memdemo.v - :caption: ``memdemo.v``, a demo circuit for demonstrating some advanced Yosys features - :language: verilog - :name: memdemo_v - -Let's consider :numref:`memdemo_v`. 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 :cmd:ref:`show` now we see -the following diagram: +Recall the ``memdemo`` design from :ref:`advanced_logic_cones`: .. figure:: /_images/011/memdemo_00.* :class: width-helper @@ -693,10 +684,10 @@ 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 entire memdemo module from ``memdemo.v`` (:numref:`memdemo_v` above) 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: +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: .. code-block:: yoscrypt diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index b1a07ca01..78b20ea35 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -1,16 +1,11 @@ Selections ---------- -.. todo:: expand on text +.. role:: yoscrypt(code) + :language: yoscrypt -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: - -.. code:: yoscrypt - - delete # will delete the whole design, but - - delete foobar # will only delete the module foobar. +The selection framework +~~~~~~~~~~~~~~~~~~~~~~~ The :cmd:ref:`select` command can be used to create a selection for subsequent commands. For example: @@ -19,11 +14,28 @@ commands. For example: select foobar # select the module foobar delete # delete selected objects - select -clear # reset selection (select whole design) -Many of the examples on this page make use of the :cmd:ref:`show` command to -visually demonstrate the effect of selections. For a more detailed look at this -command, refer to :ref:`interactive_show`. +Normally the :cmd:ref:`select` command overwrites a previous selection. The +commands :yoscrypt:`select -add` and :yoscrypt:`select -del` can be used to add +or remove objects from the current selection. + +The command :yoscrypt:`select -clear` can be used to reset the selection to the +default, which is a complete selection of everything in the current module. + +This selection framework can also be used directly in many other commands. +Whenever a command has ``[selection]`` as last argument in its usage help, this +means that it will use the engine behind the :cmd:ref:`select` command to +evaluate additional arguments and use the resulting selection instead of the +selection created by the last :cmd:ref:`select` command. + +For example, the command :cmd:ref:`delete` will delete everything in the current +selection; while :yoscrypt:`delete foobar` will only delete the module foobar. +If no :cmd:ref:`select` command has been made, then the "current selection" will +be the whole design. + +.. note:: Many of the examples on this page make use of the :cmd:ref:`show` + command to visually demonstrate the effect of selections. For a more + detailed look at this command, refer to :ref:`interactive_show`. How to make a selection ~~~~~~~~~~~~~~~~~~~~~~~ @@ -48,7 +60,7 @@ Commands can be executed in *module/* or *design/* context. Until now all commands have been executed in design context. The :cmd:ref:`cd` command can be used to switch to module context. -In module context all commands only effect the active module. Objects in the +In module context, all commands only effect the active module. Objects in the module are selected without the ``<module_name>/`` prefix. For example: .. code:: yoscrypt @@ -62,233 +74,102 @@ module are selected without the ``<module_name>/`` prefix. For example: cd .. # switch back to design Note: Most synthesis scripts never switch to module context. But it is a very -powerful tool for interactive design investigation. +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: -.. code:: yoscrypt +- 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` - 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 +A complete list of pattern expressions can be found in :doc:`/cmd/select`. -A complete list of this pattern expressions can be found in the command -reference to the :cmd:ref:`select` command. +Operations on selections +~~~~~~~~~~~~~~~~~~~~~~~~ Combining selections ^^^^^^^^^^^^^^^^^^^^ -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: +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: -.. code:: yoscrypt +.. literalinclude:: /APPNOTE_011_Design_Investigation/foobaraddsub.v + :caption: Test module for operations on selections + :name: foobaraddsub + :language: verilog - select t:$dff r:WIDTH>1 # all cells of type $dff and/or with a parameter WIDTH > 1 +.. code-block:: + :caption: Output for command ``select t:$add a:foo -list`` on :numref:`foobaraddsub` -Special ``%``-commands can be used to combine the elements on the stack: + 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 -.. code:: yoscrypt +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: - select t:$dff r:WIDTH>1 %i # all cells of type $dff *AND* with a parameter WIDTH > 1 +.. 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 -Examples for ``%``-codes (see :doc:`/cmd/select` for full list): +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 ^^^^^^^^^^^^^^^^^^^^ -Selections of cells and wires can be expanded along connections using -``%``-codes for selecting input cones (``%ci``), output cones (``%co``), or -both (``%x``). +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.) -.. code:: yoscrypt - - # select all wires that are inputs to $add cells - select t:$add %ci w:* %i - -Additional constraints such as port names can be specified. - -.. code:: yoscrypt - - # 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] - -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. The commands ``select -add`` and ``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 - -Creating selection variables -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Selections can be stored under a name with the ``select -set <name>`` -command. The stored selections can be used in later select expressions -using the syntax ``@<name>``. - -.. code:: yoscrypt - - 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 - -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. - -.. code:: yoscrypt - - 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 - -Example: - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.v - :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/select.v`` - -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.ys - :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/select.ys`` - -.. figure:: /_images/res/PRESENTATION_ExAdv/select.* - :class: width-helper - -.. todo:: combine below sections into above where possible - -Working with selections -~~~~~~~~~~~~~~~~~~~~~~~ - -.. figure:: /_images/011/example_03.* - :class: width-helper - :name: seladd - - Output of :cmd:ref:`show` after ``select $2`` or ``select t:$add`` (see also - :numref:`example_out`) - -But for most interactive work we want to further narrow the set of selected -objects. This can be done using the :cmd:ref:`select` command. - -For example, if the command ``select $2`` is executed, a subsequent -:cmd:ref:`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 :cmd:ref:`select` command to -evaluate additional arguments and use the resulting selection instead of the -selection created by the last :cmd:ref:`select` command. - -Normally the :cmd:ref:`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 +.. literalinclude:: /APPNOTE_011_Design_Investigation/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/011/sumprod_00.* :class: width-helper :name: sumprod_00 Output of ``show a:sumstuff`` on :numref:`sumprod` -The :cmd:ref:`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. +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 -``show a:sumstuff %x`` yields the diagram shown in :numref:`sumprod_01`. +:yoscrypt:`show a:sumstuff %x` yields the diagram shown in :numref:`sumprod_01`: .. figure:: /_images/011/sumprod_01.* :class: width-helper @@ -297,27 +178,39 @@ selected wire it selects all cells connected to the wire and vice versa. So 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 :cmd:ref:`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. +As with 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: +The following sequence of diagrams demonstrates this step-wise expansion: -.. code-block:: yoscrypt +.. figure:: /_images/011/sumprod_02.* + :class: width-helper - show prod - show prod %ci - show prod %ci %ci - show prod %ci %ci %ci + Output of ``show prod`` on :numref:`sumprod` + +.. figure:: /_images/011/sumprod_03.* + :class: width-helper + + Output of ``show prod %ci`` on :numref:`sumprod` + +.. figure:: /_images/011/sumprod_04.* + :class: width-helper + + Output of ``show prod %ci %ci`` on :numref:`sumprod` + +.. figure:: /_images/011/sumprod_05.* + :class: width-helper + + Output of ``show prod %ci %ci %ci`` on :numref:`sumprod` 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 @@ -327,28 +220,28 @@ 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...`` +.. _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 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 :cmd:ref:`show` now we -see the diagram shown in :numref:`memdemo_00`. +Lets consider :numref:`memdemo_src`. It serves no purpose other than being a +non-trivial circuit for demonstrating some of the advanced Yosys features. -.. literalinclude:: ../APPNOTE_011_Design_Investigation/memdemo.v +.. literalinclude:: /APPNOTE_011_Design_Investigation/memdemo.v :caption: Demo circuit for demonstrating some advanced Yosys features :name: memdemo_src :language: verilog +We synthesize the circuit using ``proc; opt; memory; opt`` and change to the +``memdemo`` module with ``cd memdemo``. If we type :cmd:ref:`show` now we see +the diagram shown in :numref:`memdemo_00`. + .. figure:: /_images/011/memdemo_00.* :class: width-helper :name: memdemo_00 @@ -377,12 +270,12 @@ cells: 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, +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. -Since we know that the only cell considered in this case is a ``$dff`` cell, -we could as well only specify the port names: +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 @@ -400,16 +293,16 @@ Or we could decide to tell the ``%ci`` action to not follow the ``CLK`` input: 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: +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 +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 @@ -429,7 +322,30 @@ 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. +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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -437,19 +353,33 @@ Storing and recalling selections The current selection can be stored in memory with the command ``select -set <name>``. It can later be recalled using ``select @<name>``. In fact, the ``@<name>`` expression pushes the stored selection on the stack maintained by -the :cmd:ref:`select` command. So for example - -.. code-block:: yoscrypt - - select @foo @bar %i - +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. +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: + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.v + :language: verilog + :caption: ``docs/resources/PRESENTATION_ExAdv/select.v`` + +.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.ys + :language: yoscrypt + :caption: ``docs/resources/PRESENTATION_ExAdv/select.ys`` + :name: select_ys + +.. figure:: /_images/res/PRESENTATION_ExAdv/select.* + :class: width-helper + + Circuit diagram produced by :numref:`select_ys` From ebcbb94a2156768b1633f7bcfb5664c18ea82303 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 12 Oct 2023 04:50:27 +1300 Subject: [PATCH 028/108] Fixing makefile --- Makefile | 2 +- docs/source/_images/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a93930be0..0fa2e94b9 100644 --- a/Makefile +++ b/Makefile @@ -971,7 +971,7 @@ docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) PHONY: docs/gen_images docs/guidelines docs/gen_images: - $(Q) $(MAKE) -C docs/images all + $(Q) $(MAKE) -C docs/source/_images all DOCS_GUIDELINE_FILES := GettingStarted CodingStyle docs/guidelines: diff --git a/docs/source/_images/Makefile b/docs/source/_images/Makefile index 61fa6cd70..d0e41561a 100644 --- a/docs/source/_images/Makefile +++ b/docs/source/_images/Makefile @@ -1,7 +1,7 @@ all: resources dots tex svg tidy RES_LIST:= PRESENTATION_Intro/ PRESENTATION_ExSyn/ PRESENTATION_ExAdv/ PRESENTATION_ExOth/ -RES_DIRS:= $(addprefix ../resources/,$(RES_LIST)) +RES_DIRS:= $(addprefix ../../resources/,$(RES_LIST)) .PHONY: resources resources: $(RES_DIRS) FORCE: From 5a7a7b319a0f1eff202ba28f9f8029cff7a740e5 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 12 Oct 2023 05:02:33 +1300 Subject: [PATCH 029/108] Fix make clean --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0fa2e94b9..da2e8e2dc 100644 --- a/Makefile +++ b/Makefile @@ -998,7 +998,7 @@ 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 + $(MAKE) -C docs/source/_images clean rm -rf docs/source/cmd docs/util/__pycache__ clean-abc: From 17749ce6884be4484711b7ff0c0a0353b4e99f49 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 16 Oct 2023 21:10:03 +1300 Subject: [PATCH 030/108] docs: absolute cmd directory --- docs/source/cmd_ref.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst index 138e934e3..24b24015a 100644 --- a/docs/source/cmd_ref.rst +++ b/docs/source/cmd_ref.rst @@ -8,4 +8,4 @@ Command line reference :maxdepth: 1 :glob: - ../cmd/* + /cmd/* From abd92225a3d98fe1e2a6081d41cbfb3a88d31f8e Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:33:00 +1300 Subject: [PATCH 031/108] Replace 010 and 012 with pdf Comment out the body text and instead include just the abstract and a download link. Also orphan the pages so they aren't accessible except by direct link, or via search. --- .../APPNOTE_010_Verilog_to_BLIF.pdf | Bin 0 -> 113239 bytes .../APPNOTE_012_Verilog_to_BTOR.pdf | Bin 0 -> 129459 bytes docs/source/appendix.rst | 3 - .../appendix/APPNOTE_010_Verilog_to_BLIF.rst | 664 +++++++++--------- .../appendix/APPNOTE_012_Verilog_to_BTOR.rst | 570 +++++++-------- 5 files changed, 642 insertions(+), 595 deletions(-) create mode 100644 docs/source/_downloads/APPNOTE_010_Verilog_to_BLIF.pdf create mode 100644 docs/source/_downloads/APPNOTE_012_Verilog_to_BTOR.pdf 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 0000000000000000000000000000000000000000..91fc1aac8e82201ef54fb42956fd232cd695c6ea GIT binary patch literal 113239 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 SCV(;yoh>_i_CiZz+5Z7<L;zX< literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f3ffd6f308d65526ac57b8c104825ff0e179fb75 GIT binary patch literal 129459 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 z%0A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%0DY5DIF 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:D0!AAG?wI(1+kb9T?; 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 literal 0 HcmV?d00001 diff --git a/docs/source/appendix.rst b/docs/source/appendix.rst index 04ee2945c..0b0a2d15b 100644 --- a/docs/source/appendix.rst +++ b/docs/source/appendix.rst @@ -9,9 +9,6 @@ Appendix appendix/auxlibs appendix/auxprogs - appendix/APPNOTE_010_Verilog_to_BLIF.rst - appendix/APPNOTE_012_Verilog_to_BTOR.rst - bib .. toctree:: diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index d8f8fec46..cc658f03f 100644 --- a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst +++ b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst @@ -1,333 +1,363 @@ +:orphan: + ==================================== 010: Converting Verilog to BLIF page ==================================== -Installation -============ +Abstract +======== -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. +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. -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. +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 GIT: https://github.com/YosysHQ/yosys +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. -.. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e +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. -.. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim +Download +======== -Getting started -=============== +This document was originally published in April 2015: +:download:`Converting Verilog to BLIF PDF</_downloads/APPNOTE_012_Verilog_to_BTOR.pdf>` -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: - -.. code:: sh - - yosys -o softusb_navre.blif -S softusb_navre.v +.. + Installation + ============ -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. + 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. -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. + 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. -Using a synthesis script -======================== + .. _Yosys GIT: https://github.com/YosysHQ/yosys -With a script file we have better control over Yosys. The following -script file replicates what the command from the last section did: + .. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e -.. 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 :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 <stdint.h> - #include <stdbool.h> - - #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. + .. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim + + 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. + + .. _Navré processor: http://opencores.org/projects/navre + + Converting softusb_navre.v to softusb_navre.blif could not be easier: + + .. code:: sh + + 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. + + 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 + ======================== + + 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 + + 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 <stdint.h> + #include <stdbool.h> + + #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_012_Verilog_to_BTOR.rst b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst index adb551494..1874b0148 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 +======== -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. +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. -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. +Download +======== -This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04. +This document was originally published in November 2013: +:download:`Converting Verilog to BTOR PDF</_downloads/APPNOTE_012_Verilog_to_BTOR.pdf>` -.. _Yosys GIT: https://github.com/YosysHQ/yosys +.. + Installation + ============ -.. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f + 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. -Quick start -=========== + 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. -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`. + This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04. -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: + .. _Yosys GIT: https://github.com/YosysHQ/yosys -.. code:: sh + .. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f - verilog2btor.sh fsm.v fsm.btor test + Quick start + =========== -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. + 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`. -To specify the properties (that need to be checked), we have two -options: + 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 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. + .. code:: sh -- 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`. + verilog2btor.sh fsm.v fsm.btor test -.. code-block:: verilog - :caption: Specifying property in Verilog design with ``assert`` - :name: specifying_property_assert + 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. - module test(input clk, input rst, output y); + To specify the properties (that need to be checked), we have two + options: - reg [2:0] state; + - 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. - always @(posedge clk) begin - if (rst || state == 3) begin - state <= 0; - end else begin - assert(state < 3); - state <= state + 1; - end - end + - 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`. - assign y = state[2]; + .. code-block:: verilog + :caption: Specifying property in Verilog design with ``assert`` + :name: specifying_property_assert - assert property (y !== 1'b1); + module test(input clk, input rst, output y); - endmodule + reg [2:0] state; -.. code-block:: verilog - :caption: Specifying property in Verilog design with output wire - :name: specifying_property_output + always @(posedge clk) begin + if (rst || state == 3) begin + state <= 0; + end else begin + assert(state < 3); + state <= state + 1; + end + end - module test(input clk, input rst, - output y, output safety1); + assign y = state[2]; - reg [2:0] state; + assert property (y !== 1'b1); - always @(posedge clk) begin - if (rst || state == 3) - state <= 0; - else - state <= state + 1; - end + endmodule - assign y = state[2]; + .. code-block:: verilog + :caption: Specifying property in Verilog design with output wire + :name: specifying_property_output - assign safety1 = !(y !== 1'b1); + module test(input clk, input rst, + output y, output safety1); - endmodule + reg [2:0] state; -We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file: + always @(posedge clk) begin + if (rst || state == 3) + state <= 0; + else + state <= state + 1; + end -.. _Boolector: http://fmv.jku.at/boolector/ + assign y = state[2]; -.. code:: sh + assign safety1 = !(y !== 1'b1); - $ boolector fsm.btor - unsat + endmodule -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 run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file: -.. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php + .. _Boolector: http://fmv.jku.at/boolector/ -Detailed flow -============= + .. code:: 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``. + $ boolector fsm.btor + unsat -.. code-block:: yoscrypt - :caption: Synthesis Flow for BTOR with memories - :name: btor_script_memory + 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. - 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; + .. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php -Here is short description of what is happening in the script line by -line: + Detailed flow + ============= -#. Reading the input file. + 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``. -#. 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. + .. code-block:: yoscrypt + :caption: Synthesis Flow for BTOR with memories + :name: btor_script_memory -#. Checking the design hierarchy. + 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; -#. Converting processes to multiplexers (muxs) and flip-flops. + Here is short description of what is happening in the script line by + line: -#. Removing undef signals from muxs. + #. Reading the input file. -#. Hiding all signal names that are not used as module ports. + #. 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. -#. Explicit type conversion, by introducing slice and concat cells in the - circuit. + #. Checking the design hierarchy. -#. Converting write memories to synchronous memories, and collecting the - memories to multi-port memories. + #. Converting processes to multiplexers (muxs) and flip-flops. -#. Flattening the design to get only one module. + #. Removing undef signals from muxs. -#. Separating read and write memories. + #. Hiding all signal names that are not used as module ports. -#. Splitting the signals that are partially assigned + #. Explicit type conversion, by introducing slice and concat cells in the + circuit. -#. Setting undef to zero value. + #. Converting write memories to synchronous memories, and collecting the + memories to multi-port memories. -#. Final optimization pass. + #. Flattening the design to get only one module. -#. Writing BTOR file. + #. Separating read and write memories. -For detailed description of the commands mentioned above, please refer -to the Yosys documentation, or run ``yosys -h <command_name>``. - -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. + #. Splitting the signals that are partially assigned + + #. Setting undef to zero value. + + #. Final optimization pass. + + #. Writing BTOR file. + + For detailed description of the commands mentioned above, please refer + to the Yosys documentation, or run ``yosys -h <command_name>``. + + 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. From a1c3755dd6cbb3d25055e0ff4fc8350a442515b0 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:33:22 +1300 Subject: [PATCH 032/108] Fix typo --- .../using_yosys/more_scripting/interactive_investigation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index 06b93bb90..7d4243faf 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -75,7 +75,7 @@ original ``always``-block in the second line. Note how 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-flip, which brings us to the second diagram: +multiplexer and a d-type flip-flop, which brings us to the second diagram: .. figure:: /_images/011/example_01.* :class: width-helper From e49903f8b1dda5986cc51f756be3fb9feeadff2b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:57:22 +1300 Subject: [PATCH 033/108] List all synth commands on synth page --- .../using_yosys/more_scripting/synth.rst | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/source/using_yosys/more_scripting/synth.rst b/docs/source/using_yosys/more_scripting/synth.rst index ad01d1630..4e6a2cce1 100644 --- a/docs/source/using_yosys/more_scripting/synth.rst +++ b/docs/source/using_yosys/more_scripting/synth.rst @@ -1,9 +1,40 @@ Introduction to synthesis ------------------------- +The generic ``synth`` +~~~~~~~~~~~~~~~~~~~~~ + The following commands are executed by the :cmd:ref:`synth` command: .. literalinclude:: /cmd/synth.rst :start-at: begin: :end-before: .. raw:: latex :dedent: + +Packaged ``synth_*`` commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: are all these synth commands supported? + +The following is a list of all synth commands included in Yosys for different +platforms. Each command runs a script of sub commands specific to the platform +being targeted. + +- :doc:`/cmd/synth_achronix` +- :doc:`/cmd/synth_anlogic` +- :doc:`/cmd/synth_coolrunner2` +- :doc:`/cmd/synth_easic` +- :doc:`/cmd/synth_ecp5` +- :doc:`/cmd/synth_efinix` +- :doc:`/cmd/synth_fabulous` +- :doc:`/cmd/synth_gatemate` +- :doc:`/cmd/synth_gowin` +- :doc:`/cmd/synth_greenpak4` +- :doc:`/cmd/synth_ice40` +- :doc:`/cmd/synth_intel` +- :doc:`/cmd/synth_intel_alm` +- :doc:`/cmd/synth_machxo2` +- :doc:`/cmd/synth_nexus` +- :doc:`/cmd/synth_quicklogic` +- :doc:`/cmd/synth_sf2` +- :doc:`/cmd/synth_xilinx` From d4e45cdccb80297a40330a3fe8700730f3e53063 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:13:48 +1300 Subject: [PATCH 034/108] docs: Stub new(er) auxlibs and auxprogs Still need to actually be filled in. Also rearranges auxlibs to be alphabetical order. --- docs/source/appendix/auxlibs.rst | 49 ++++++++++++++++++++++--------- docs/source/appendix/auxprogs.rst | 10 +++++++ 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/docs/source/appendix/auxlibs.rst b/docs/source/appendix/auxlibs.rst index 2f443c041..861634648 100644 --- a/docs/source/appendix/auxlibs.rst +++ b/docs/source/appendix/auxlibs.rst @@ -4,12 +4,7 @@ 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. +.. todo:: fill out the newer auxiliary libs BigInt ------ @@ -22,15 +17,10 @@ ConstEval class provided in kernel/consteval.h. See also: http://mattmccutchen.net/bigint/ -.. _sec:SubCircuit: +dlfcn-win32 +----------- -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`). +The files in ``libs/dlfcn-win32`` provide... ezSAT ----- @@ -40,3 +30,34 @@ 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`). +fst +--- + +The files in ``libs/fst`` provide... + +json11 +------ + +The files in ``libs/json11`` provide... + +MiniSAT +------- + +The files in ``libs/minisat`` provide... + +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 index 9071abfd1..a80e8f535 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -1,6 +1,8 @@ Auxiliary programs ================== +.. todo:: check this list is up to date and correct, esp yosys-smtbmc + Besides the main yosys executable, the Yosys distribution contains a set of additional helper programs. @@ -27,3 +29,11 @@ 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. + +yosys-smtbmc +------------ + +yosys-witness +------------- + +yosys-witness is a new tool to inspect and convert yosys witness traces. From 74c1fc1cdd2ee83b48aea0ff19b943305f4a1f9d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 30 Oct 2023 22:38:47 +1300 Subject: [PATCH 035/108] docs: Reference chapters with doc tag Fix some formatting. --- docs/source/appendix/auxprogs.rst | 2 +- docs/source/introduction.rst | 3 ++- docs/source/using_yosys/more_scripting/opt_passes.rst | 6 +++--- docs/source/yosys_internals/extensions.rst | 2 -- docs/source/yosys_internals/formats/rtlil_text.rst | 4 ++-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index a80e8f535..41570b086 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -11,7 +11,7 @@ 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 :ref:`chapter:prog` for details. +Yosys. See :doc:`/yosys_internals/extensions` for details. .. _sec:filterlib: diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 6a3f8802e..62c76584d 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -67,7 +67,8 @@ Things you can't do - Process high-level languages such as C/C++/SystemC - Create physical layouts (place&route) - + Check out `nextpnr`_ for that + + - Check out `nextpnr`_ for that .. _nextpnr: https://github.com/YosysHQ/nextpnr diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index 4437a4796..f3c9c92f9 100644 --- a/docs/source/using_yosys/more_scripting/opt_passes.rst +++ b/docs/source/using_yosys/more_scripting/opt_passes.rst @@ -37,9 +37,9 @@ The :cmd:ref:`opt_expr` pass ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This pass performs const folding on the internal combinational cell types -described in :ref:`chapter:celllib`. 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. +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 diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index 68d023d64..ec9f2b8d0 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -1,5 +1,3 @@ -.. _chapter:prog: - Writing extensions ================== diff --git a/docs/source/yosys_internals/formats/rtlil_text.rst b/docs/source/yosys_internals/formats/rtlil_text.rst index a7f1d843b..8b5c10681 100644 --- a/docs/source/yosys_internals/formats/rtlil_text.rst +++ b/docs/source/yosys_internals/formats/rtlil_text.rst @@ -223,8 +223,8 @@ 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 :ref:`chapter:celllib` 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 From 8e07030feee20cfbee78a1bf15feca6021d0db72 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:13:28 +1300 Subject: [PATCH 036/108] docs: update auxiliary programs Now includes usage output, (hopefully) generated by the tool during the docs build process so it will always be up to date. Included in makefile as `docs/usage` target. Also some updates/additions to the description text, esp `yosys-filterlib` and `yosys-smtbmc`. --- Makefile | 11 ++++++++-- docs/source/appendix/auxlibs.rst | 4 ++-- docs/source/appendix/auxprogs.rst | 34 ++++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index da2e8e2dc..62485f150 100644 --- a/Makefile +++ b/Makefile @@ -969,7 +969,7 @@ 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_images docs/guidelines docs/usage docs/gen_images: $(Q) $(MAKE) -C docs/source/_images all @@ -978,8 +978,15 @@ 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-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_images docs/guidelines docs/usage $(Q) $(MAKE) -C docs $(DOC_TARGET) clean: diff --git a/docs/source/appendix/auxlibs.rst b/docs/source/appendix/auxlibs.rst index 861634648..a77eb8b3f 100644 --- a/docs/source/appendix/auxlibs.rst +++ b/docs/source/appendix/auxlibs.rst @@ -1,8 +1,8 @@ Auxiliary libraries =================== -The Yosys source distribution contains some auxiliary libraries that are bundled -with Yosys. +The Yosys source distribution contains some auxiliary libraries that are +compiled into Yosys and can be used in plugins. .. todo:: fill out the newer auxiliary libs diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index 41570b086..6b2d04d71 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -1,26 +1,32 @@ Auxiliary programs ================== -.. todo:: check this list is up to date and correct, esp yosys-smtbmc - 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 +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/extensions` for details. +.. literalinclude:: /temp/yosys-config + :start-at: Usage + .. _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 :ref:`sec:techmap_extern` for -details. +.. todo:: how does a filterlib rules-file work? is this still supported? + +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 --------- @@ -30,10 +36,24 @@ 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. +``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 From 2b10bd5070a2bbbf9873348916ede184f69f9eeb Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:47:55 +1300 Subject: [PATCH 037/108] docs: update images makefile Correct path to 011 source. Also path for resources target. Set timezone to 'Z' for faketime. Not sure how to avoid needing to `make resources` before `make all` (or running `make all` twice) in order to properly generate the presentation images. --- docs/source/_images/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/source/_images/Makefile b/docs/source/_images/Makefile index d0e41561a..f0a7795b6 100644 --- a/docs/source/_images/Makefile +++ b/docs/source/_images/Makefile @@ -5,13 +5,13 @@ RES_DIRS:= $(addprefix ../../resources/,$(RES_LIST)) .PHONY: resources resources: $(RES_DIRS) FORCE: -../resources/%: FORCE +../../resources/%: FORCE @$(MAKE) -C $@ @mkdir -p res/$* @cp --update -t res/$* $@*.dot TEX_SOURCE:= $(wildcard *.tex) -DOT_LOC:= ../source/APPNOTE_011_Design_Investigation +DOT_LOC:= ../APPNOTE_011_Design_Investigation DOT_SOURCE:= $(wildcard $(DOT_LOC)/*.dot) RES_DOTS:= $(wildcard res/*/*.dot) @@ -36,13 +36,13 @@ tex: $(TEX_PDF) svg: $(SVG_OUTPUT) 011/%.pdf: $(DOT_LOC)/%.dot - faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< + TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< res/%.pdf: res/%.dot - faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< + TZ='Z' 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 $(<F) --interaction=nonstopmode + cd 011 && TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' pdflatex $(<F) --interaction=nonstopmode %.pdf: %.tex pdflatex $< --interaction=nonstopmode @@ -59,3 +59,4 @@ clean: tidy rm -f *.pdf rm -f *.svg rm -f 011/*.pdf 011/*.svg + rm -rf $(RES_DIRS) From a283595798962cef94e2fc953af61584106ff5aa Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 1 Nov 2023 13:29:40 +1300 Subject: [PATCH 038/108] docs: call make resources before make all Should fix the issue where `make all` in the images directory can't wildcard files that don't exist yet. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 0b8cb96dd..8418aefde 100644 --- a/Makefile +++ b/Makefile @@ -971,6 +971,7 @@ docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) PHONY: docs/gen_images docs/guidelines docs/usage docs/gen_images: + $(Q) $(MAKE) -C docs/source/_images resources $(Q) $(MAKE) -C docs/source/_images all DOCS_GUIDELINE_FILES := GettingStarted CodingStyle From 3d70867809038026073ec6a94849835bf902bb67 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:26:57 +1300 Subject: [PATCH 039/108] docs: remove synth_machxo2, add _lattice --- docs/source/using_yosys/more_scripting/synth.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/using_yosys/more_scripting/synth.rst b/docs/source/using_yosys/more_scripting/synth.rst index 4e6a2cce1..2ac717f05 100644 --- a/docs/source/using_yosys/more_scripting/synth.rst +++ b/docs/source/using_yosys/more_scripting/synth.rst @@ -33,7 +33,7 @@ being targeted. - :doc:`/cmd/synth_ice40` - :doc:`/cmd/synth_intel` - :doc:`/cmd/synth_intel_alm` -- :doc:`/cmd/synth_machxo2` +- :doc:`/cmd/synth_lattice` - :doc:`/cmd/synth_nexus` - :doc:`/cmd/synth_quicklogic` - :doc:`/cmd/synth_sf2` From dbc38d72cf610b81b94d76303cfa0288e94b9363 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:55:39 +1300 Subject: [PATCH 040/108] docs: moving code examples Code now resides in `docs/source/code_examples`. `CHAPTER_Prog` -> `stubnets` `APPNOTE_011_Design_Investigation` -> `selections` and `show` `resources/PRESENTATION_Intro` -> `intro` `resources/PRESENTATION_ExSyn` -> `synth_flow` `resources/PRESENTATION_ExAdv` -> `techmap`, `macc`, and `selections` `resources/PRESENTATION_ExOth` -> `scrambler` and `axis` Note that generated images are not yet configured to build from the new code locations. --- docs/resources/PRESENTATION_ExAdv/Makefile | 31 ---- docs/resources/PRESENTATION_ExOth/.gitignore | 3 - docs/resources/PRESENTATION_ExOth/Makefile | 19 --- docs/resources/PRESENTATION_ExOth/equiv.ys | 17 --- docs/resources/PRESENTATION_ExSyn/.gitignore | 2 - docs/resources/PRESENTATION_Intro/.gitignore | 8 - .../cmos_00.dot | 34 ----- .../cmos_01.dot | 23 --- .../example_00.dot | 23 --- .../example_01.dot | 33 ----- .../example_02.dot | 20 --- .../example_03.dot | 11 -- .../APPNOTE_011_Design_Investigation/make.sh | 23 --- .../memdemo_00.dot | 138 ------------------ .../memdemo_01.dot | 29 ---- .../splice.dot | 39 ----- .../submod_00.dot | 45 ------ .../submod_01.dot | 87 ----------- .../submod_02.dot | 33 ----- .../submod_03.dot | 26 ---- .../sumprod_00.dot | 18 --- .../sumprod_01.dot | 15 -- .../sumprod_02.dot | 5 - .../sumprod_03.dot | 11 -- .../sumprod_04.dot | 11 -- .../sumprod_05.dot | 15 -- .../code_examples}/.gitignore | 0 .../code_examples/axis}/axis_master.v | 0 .../code_examples/axis}/axis_test.v | 0 .../code_examples/axis}/axis_test.ys | 2 +- .../code_examples/intro}/Makefile | 0 .../code_examples/intro}/counter.v | 0 .../code_examples/intro}/counter.ys | 0 .../code_examples/intro}/counter_outputs.ys | 0 .../code_examples/intro}/mycells.lib | 0 .../code_examples/intro}/mycells.v | 0 docs/source/code_examples/macc/Makefile | 12 ++ .../code_examples/macc}/macc_simple_test.v | 0 .../code_examples/macc}/macc_simple_test.ys | 0 .../code_examples/macc}/macc_simple_test_01.v | 0 .../code_examples/macc}/macc_simple_test_02.v | 0 .../code_examples/macc}/macc_simple_xmap.v | 0 .../macc}/macc_xilinx_swap_map.v | 0 .../code_examples/macc}/macc_xilinx_test.v | 0 .../code_examples/macc}/macc_xilinx_test.ys | 0 .../macc}/macc_xilinx_unwrap_map.v | 0 .../macc}/macc_xilinx_wrap_map.v | 0 .../code_examples/macc}/macc_xilinx_xmap.v | 0 .../primetest.v | 0 docs/source/code_examples/scrambler/Makefile | 8 + .../code_examples/scrambler}/scrambler.v | 0 .../code_examples/scrambler}/scrambler.ys | 5 +- docs/source/code_examples/selections/Makefile | 32 ++++ .../selections}/foobaraddsub.v | 0 .../selections}/memdemo.v | 0 .../code_examples/selections}/select.v | 0 .../code_examples/selections}/select.ys | 2 +- .../selections}/submod.ys | 0 .../selections}/sumprod.v | 0 docs/source/code_examples/show/Makefile | 23 +++ .../show}/cmos.v | 0 .../show}/example.v | 0 .../show}/example.ys | 0 .../show}/splice.v | 0 .../stubnets}/.gitignore | 0 .../stubnets}/Makefile | 0 .../stubnets}/stubnets.cc | 0 .../stubnets}/test.v | 0 .../code_examples/synth_flow}/Makefile | 0 .../code_examples/synth_flow}/abc_01.v | 0 .../code_examples/synth_flow}/abc_01.ys | 0 .../synth_flow}/abc_01_cells.lib | 0 .../code_examples/synth_flow}/abc_01_cells.v | 0 .../code_examples/synth_flow}/memory_01.v | 0 .../code_examples/synth_flow}/memory_01.ys | 0 .../code_examples/synth_flow}/memory_02.v | 0 .../code_examples/synth_flow}/memory_02.ys | 0 .../code_examples/synth_flow}/opt_01.v | 0 .../code_examples/synth_flow}/opt_01.ys | 0 .../code_examples/synth_flow}/opt_02.v | 0 .../code_examples/synth_flow}/opt_02.ys | 0 .../code_examples/synth_flow}/opt_03.v | 0 .../code_examples/synth_flow}/opt_03.ys | 0 .../code_examples/synth_flow}/opt_04.v | 0 .../code_examples/synth_flow}/opt_04.ys | 0 .../code_examples/synth_flow}/proc_01.v | 0 .../code_examples/synth_flow}/proc_01.ys | 0 .../code_examples/synth_flow}/proc_02.v | 0 .../code_examples/synth_flow}/proc_02.ys | 0 .../code_examples/synth_flow}/proc_03.v | 0 .../code_examples/synth_flow}/proc_03.ys | 0 .../code_examples/synth_flow}/techmap_01.v | 0 .../code_examples/synth_flow}/techmap_01.ys | 0 .../synth_flow}/techmap_01_map.v | 0 docs/source/code_examples/techmap/Makefile | 21 +++ .../code_examples/techmap}/addshift_map.v | 0 .../code_examples/techmap}/addshift_test.v | 0 .../code_examples/techmap}/addshift_test.ys | 2 +- .../code_examples/techmap}/mulshift_map.v | 0 .../code_examples/techmap}/mulshift_test.v | 0 .../code_examples/techmap}/mulshift_test.ys | 2 +- .../code_examples/techmap}/mymul_map.v | 0 .../code_examples/techmap}/mymul_test.v | 0 .../code_examples/techmap}/mymul_test.ys | 2 +- .../code_examples/techmap}/red_or3x1_cells.v | 0 .../code_examples/techmap}/red_or3x1_map.v | 0 .../code_examples/techmap}/red_or3x1_test.v | 0 .../code_examples/techmap}/red_or3x1_test.ys | 2 +- .../code_examples/techmap}/sym_mul_cells.v | 0 .../code_examples/techmap}/sym_mul_map.v | 0 .../code_examples/techmap}/sym_mul_test.v | 0 .../code_examples/techmap}/sym_mul_test.ys | 2 +- docs/source/getting_started/examples.rst | 22 +-- .../source/getting_started/typical_phases.rst | 92 ++++++------ .../interactive_investigation.rst | 44 +++--- .../using_yosys/more_scripting/selections.rst | 14 +- docs/source/using_yosys/yosys_flows.rst | 79 +++++----- docs/source/yosys_internals/extensions.rst | 24 ++- docs/source/yosys_internals/techmap.rst | 60 ++++---- 119 files changed, 264 insertions(+), 905 deletions(-) delete mode 100644 docs/resources/PRESENTATION_ExAdv/Makefile delete mode 100644 docs/resources/PRESENTATION_ExOth/.gitignore delete mode 100644 docs/resources/PRESENTATION_ExOth/Makefile delete mode 100644 docs/resources/PRESENTATION_ExOth/equiv.ys delete mode 100644 docs/resources/PRESENTATION_ExSyn/.gitignore delete mode 100644 docs/resources/PRESENTATION_Intro/.gitignore delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/cmos_00.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/example_00.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/example_01.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/example_02.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/example_03.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/make.sh delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/splice.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/submod_00.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/submod_01.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/submod_02.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/submod_03.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot delete mode 100644 docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot rename docs/{resources/PRESENTATION_ExAdv => source/code_examples}/.gitignore (100%) rename docs/{resources/PRESENTATION_ExOth => source/code_examples/axis}/axis_master.v (100%) rename docs/{resources/PRESENTATION_ExOth => source/code_examples/axis}/axis_test.v (100%) rename docs/{resources/PRESENTATION_ExOth => source/code_examples/axis}/axis_test.ys (70%) rename docs/{resources/PRESENTATION_Intro => source/code_examples/intro}/Makefile (100%) rename docs/{resources/PRESENTATION_Intro => source/code_examples/intro}/counter.v (100%) rename docs/{resources/PRESENTATION_Intro => source/code_examples/intro}/counter.ys (100%) rename docs/{resources/PRESENTATION_Intro => source/code_examples/intro}/counter_outputs.ys (100%) rename docs/{resources/PRESENTATION_Intro => source/code_examples/intro}/mycells.lib (100%) rename docs/{resources/PRESENTATION_Intro => source/code_examples/intro}/mycells.v (100%) create mode 100644 docs/source/code_examples/macc/Makefile rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_simple_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_simple_test.ys (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_simple_test_01.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_simple_test_02.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_simple_xmap.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_xilinx_swap_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_xilinx_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_xilinx_test.ys (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_xilinx_unwrap_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_xilinx_wrap_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/macc}/macc_xilinx_xmap.v (100%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples}/primetest.v (100%) create mode 100644 docs/source/code_examples/scrambler/Makefile rename docs/{resources/PRESENTATION_ExOth => source/code_examples/scrambler}/scrambler.v (100%) rename docs/{resources/PRESENTATION_ExOth => source/code_examples/scrambler}/scrambler.ys (69%) create mode 100644 docs/source/code_examples/selections/Makefile rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/selections}/foobaraddsub.v (100%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/selections}/memdemo.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/selections}/select.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/selections}/select.ys (85%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/selections}/submod.ys (100%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/selections}/sumprod.v (100%) create mode 100644 docs/source/code_examples/show/Makefile rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/show}/cmos.v (100%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/show}/example.v (100%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/show}/example.ys (100%) rename docs/source/{APPNOTE_011_Design_Investigation => code_examples/show}/splice.v (100%) rename docs/source/{CHAPTER_Prog => code_examples/stubnets}/.gitignore (100%) rename docs/source/{CHAPTER_Prog => code_examples/stubnets}/Makefile (100%) rename docs/source/{CHAPTER_Prog => code_examples/stubnets}/stubnets.cc (100%) rename docs/source/{CHAPTER_Prog => code_examples/stubnets}/test.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/Makefile (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/abc_01.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/abc_01.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/abc_01_cells.lib (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/abc_01_cells.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/memory_01.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/memory_01.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/memory_02.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/memory_02.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_01.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_01.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_02.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_02.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_03.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_03.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_04.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/opt_04.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/proc_01.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/proc_01.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/proc_02.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/proc_02.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/proc_03.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/proc_03.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/techmap_01.v (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/techmap_01.ys (100%) rename docs/{resources/PRESENTATION_ExSyn => source/code_examples/synth_flow}/techmap_01_map.v (100%) create mode 100644 docs/source/code_examples/techmap/Makefile rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/addshift_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/addshift_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/addshift_test.ys (67%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/mulshift_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/mulshift_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/mulshift_test.ys (64%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/mymul_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/mymul_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/mymul_test.ys (84%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/red_or3x1_cells.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/red_or3x1_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/red_or3x1_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/red_or3x1_test.ys (63%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/sym_mul_cells.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/sym_mul_map.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/sym_mul_test.v (100%) rename docs/{resources/PRESENTATION_ExAdv => source/code_examples/techmap}/sym_mul_test.ys (57%) diff --git a/docs/resources/PRESENTATION_ExAdv/Makefile b/docs/resources/PRESENTATION_ExAdv/Makefile deleted file mode 100644 index fc6ba6902..000000000 --- a/docs/resources/PRESENTATION_ExAdv/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -PROGRAM_PREFIX := - -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys - -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/docs/resources/PRESENTATION_ExOth/.gitignore b/docs/resources/PRESENTATION_ExOth/.gitignore deleted file mode 100644 index 3af2b8451..000000000 --- a/docs/resources/PRESENTATION_ExOth/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.dot -*.pdf -*.log diff --git a/docs/resources/PRESENTATION_ExOth/Makefile b/docs/resources/PRESENTATION_ExOth/Makefile deleted file mode 100644 index afd84c3c6..000000000 --- a/docs/resources/PRESENTATION_ExOth/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -PROGRAM_PREFIX := - -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys - -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/docs/resources/PRESENTATION_ExOth/equiv.ys b/docs/resources/PRESENTATION_ExOth/equiv.ys deleted file mode 100644 index 8db0a88a5..000000000 --- a/docs/resources/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/docs/resources/PRESENTATION_ExSyn/.gitignore b/docs/resources/PRESENTATION_ExSyn/.gitignore deleted file mode 100644 index b4a858a01..000000000 --- a/docs/resources/PRESENTATION_ExSyn/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.dot -*.pdf diff --git a/docs/resources/PRESENTATION_Intro/.gitignore b/docs/resources/PRESENTATION_Intro/.gitignore deleted file mode 100644 index c3cbb8c51..000000000 --- a/docs/resources/PRESENTATION_Intro/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -counter_00.dot -counter_01.dot -counter_02.dot -counter_03.dot -counter_00.pdf -counter_01.pdf -counter_02.pdf -counter_03.pdf diff --git a/docs/source/APPNOTE_011_Design_Investigation/cmos_00.dot b/docs/source/APPNOTE_011_Design_Investigation/cmos_00.dot deleted file mode 100644 index 49c630080..000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/cmos_00.dot +++ /dev/null @@ -1,34 +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", color="black", fontcolor="black" ]; -c10 [ shape=record, label="{{<p7> A|<p8> B|<p9> Y}|$g0\nNOR|{}}" ]; -c11 [ shape=record, label="{{<p7> A|<p9> Y}|$g1\nNOT|{}}" ]; -c12 [ shape=record, label="{{<p7> A|<p9> Y}|$g2\nNOT|{}}" ]; -c13 [ shape=record, label="{{<p7> A|<p8> B|<p9> Y}|$g3\nNOR|{}}" ]; -x0 [ shape=record, style=rounded, label="<s0> 1:1 - 0:0 " ]; -x0:e -> c13:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c14 [ shape=record, label="{{<p7> A|<p8> B|<p9> Y}|$g4\nNOR|{}}" ]; -x1 [ shape=record, style=rounded, label="<s0> 1:1 - 0:0 " ]; -x1:e -> c14:p8:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -x2 [ shape=record, style=rounded, label="<s0> 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 ea6f4403c..000000000 --- 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="{{<p8> A|<p9> B}|$g0\nNOR|{<p10> Y}}" ]; -c12 [ shape=record, label="{{<p8> A}|$g1\nNOT|{<p10> Y}}" ]; -c13 [ shape=record, label="{{<p8> A}|$g2\nNOT|{<p10> Y}}" ]; -c14 [ shape=record, label="{{<p8> A|<p9> B}|$g3\nNOR|{<p10> Y}}" ]; -c15 [ shape=record, label="{{<p8> A|<p9> B}|$g4\nNOR|{<p10> 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_00.dot b/docs/source/APPNOTE_011_Design_Investigation/example_00.dot deleted file mode 100644 index 1e23ed0ea..000000000 --- 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="{{<p9> A|<p10> B}|$2\n$add|{<p11> Y}}" ]; -v0 [ label="2'00" ]; -c14 [ shape=record, label="{{<p9> A|<p10> B|<p13> S}|$3\n$mux|{<p11> 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 e89292b51..000000000 --- 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="{{<p11> A|<p12> B}|$2\n$add|{<p13> Y}}" ]; -c18 [ shape=record, label="{{<p15> CLK|<p16> D}|$7\n$dff|{<p17> Q}}" ]; -c20 [ shape=record, label="{{<p11> A|<p12> B|<p19> S}|$5\n$mux|{<p13> Y}}" ]; -v0 [ label="2'00" ]; -c21 [ shape=record, label="{{<p11> A|<p12> B|<p19> S}|$3\n$mux|{<p13> 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 f950ed2ed..000000000 --- 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="{{<p8> A|<p9> B}|$2\n$add|{<p10> Y}}" ]; -c15 [ shape=record, label="{{<p12> CLK|<p13> D}|$7\n$dff|{<p14> Q}}" ]; -c17 [ shape=record, label="{{<p8> A|<p9> B|<p16> S}|$5\n$mux|{<p10> 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 e19d24af7..000000000 --- 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="{{<p1> A|<p2> B}|$2\n$add|{<p3> 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 3845dac6b..000000000 --- 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 0336a9aac..000000000 --- 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="{{<p33> A|<p34> B}|$28\n$add|{<p35> Y}}" ]; -c37 [ shape=record, label="{{<p33> A|<p34> B}|$31\n$add|{<p35> Y}}" ]; -c38 [ shape=record, label="{{<p33> A|<p34> B}|$34\n$add|{<p35> Y}}" ]; -c39 [ shape=record, label="{{<p33> A|<p34> B}|$37\n$add|{<p35> Y}}" ]; -c41 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$110\n$mux|{<p35> Y}}" ]; -x0 [ shape=record, style=rounded, label="<s0> 1:1 - 0:0 " ]; -x0:e -> c41:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c42 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$113\n$mux|{<p35> Y}}" ]; -x1 [ shape=record, style=rounded, label="<s0> 0:0 - 0:0 " ]; -x1:e -> c42:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c43 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$116\n$mux|{<p35> Y}}" ]; -x2 [ shape=record, style=rounded, label="<s0> 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="{{<p33> A|<p34> B}|$145\n$and|{<p35> Y}}" ]; -v4 [ label="1'1" ]; -c45 [ shape=record, label="{{<p33> A|<p34> B}|$175\n$and|{<p35> Y}}" ]; -v5 [ label="1'1" ]; -c46 [ shape=record, label="{{<p33> A|<p34> B}|$205\n$and|{<p35> Y}}" ]; -v6 [ label="1'1" ]; -c47 [ shape=record, label="{{<p33> A|<p34> B}|$235\n$and|{<p35> Y}}" ]; -v7 [ label="2'00" ]; -c48 [ shape=record, label="{{<p33> A|<p34> B}|$143\n$eq|{<p35> Y}}" ]; -v8 [ label="2'01" ]; -c49 [ shape=record, label="{{<p33> A|<p34> B}|$173\n$eq|{<p35> Y}}" ]; -v9 [ label="2'10" ]; -c50 [ shape=record, label="{{<p33> A|<p34> B}|$203\n$eq|{<p35> Y}}" ]; -v10 [ label="2'11" ]; -c51 [ shape=record, label="{{<p33> A|<p34> B}|$233\n$eq|{<p35> Y}}" ]; -c52 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$147\n$mux|{<p35> Y}}" ]; -c53 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$177\n$mux|{<p35> Y}}" ]; -c54 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$207\n$mux|{<p35> Y}}" ]; -c55 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$237\n$mux|{<p35> Y}}" ]; -c59 [ shape=record, label="{{<p56> CLK|<p57> D}|$66\n$dff|{<p58> Q}}" ]; -c60 [ shape=record, label="{{<p56> CLK|<p57> D}|$68\n$dff|{<p58> Q}}" ]; -c61 [ shape=record, label="{{<p56> CLK|<p57> D}|$70\n$dff|{<p58> Q}}" ]; -c62 [ shape=record, label="{{<p56> CLK|<p57> D}|$72\n$dff|{<p58> Q}}" ]; -c63 [ shape=record, label="{{<p56> CLK|<p57> D}|$59\n$dff|{<p58> Q}}" ]; -c64 [ shape=record, label="{{<p56> CLK|<p57> D}|$63\n$dff|{<p58> Q}}" ]; -c65 [ shape=record, label="{{<p56> CLK|<p57> D}|$64\n$dff|{<p58> Q}}" ]; -c66 [ shape=record, label="{{<p33> A}|$39\n$reduce_bool|{<p35> Y}}" ]; -v11 [ label="4'0000" ]; -c67 [ shape=record, label="{{<p33> A|<p34> B|<p40> S}|$40\n$mux|{<p35> Y}}" ]; -x12 [ shape=record, style=rounded, label="<s1> 3:2 - 1:0 |<s0> 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="{{<p33> A|<p34> B}|$38\n$xor|{<p35> Y}}" ]; -x13 [ shape=record, style=rounded, label="<s1> 1:0 - 3:2 |<s0> 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 2ad92c78b..000000000 --- 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="{{<p9> A|<p10> B|<p11> S}|$110\n$mux|{<p12> Y}}" ]; -v1 [ label="$0\\s2[1:0] [0]" ]; -c14 [ shape=record, label="{{<p9> A|<p10> B|<p11> S}|$113\n$mux|{<p12> Y}}" ]; -v2 [ label="$0\\s2[1:0] [0]" ]; -c15 [ shape=record, label="{{<p9> A|<p10> B|<p11> S}|$116\n$mux|{<p12> Y}}" ]; -v3 [ label="clk" ]; -c19 [ shape=record, label="{{<p16> CLK|<p17> D}|$64\n$dff|{<p18> 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 4657feed1..000000000 --- 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="{{<p9> A}|$2\n$neg|{<p10> Y}}" ]; -x0 [ shape=record, style=rounded, label="<s1> 1:0 - 3:2 |<s0> 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="<s0> 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="{{<p9> A}|$1\n$not|{<p10> Y}}" ]; -x2 [ shape=record, style=rounded, label="<s1> 1:0 - 3:2 |<s0> 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="<s1> 3:2 - 1:0 |<s0> 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="<s1> 0:0 - 1:1 |<s0> 1:1 - 0:0 " ]; -x5 [ shape=record, style=rounded, label="<s1> 1:0 - 3:2 |<s0> 1:0 - 1:0 " ]; -x6 [ shape=record, style=rounded, label="<s0> 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 2e55268ee..000000000 --- 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="{{<p14> CLK|<p15> D}|$59\n$dff|{<p16> Q}}" ]; -c18 [ shape=record, label="{{<p14> CLK|<p15> D}|$63\n$dff|{<p16> Q}}" ]; -c20 [ shape=record, label="{{<p5> clk|<p7> mem[0]|<p8> mem[1]|<p9> mem[2]|<p10> mem[3]|<p19> n1}|outstage\noutstage|{<p13> y}}" ]; -c21 [ shape=record, label="{{<p5> clk|<p6> d|<p19> n1}|scramble\nscramble|{<p7> mem[0]|<p8> mem[1]|<p9> mem[2]|<p10> mem[3]}}" ]; -c23 [ shape=record, label="{{<p6> d|<p11> s1|<p12> s2}|selstage\nselstage|{<p19> n1|<p22> 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 f8f8c008a..000000000 --- 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="{{<p24> A|<p25> B}|$28\n$add|{<p26> Y}}" ]; -c28 [ shape=record, label="{{<p24> A|<p25> B}|$31\n$add|{<p26> Y}}" ]; -c29 [ shape=record, label="{{<p24> A|<p25> B}|$34\n$add|{<p26> Y}}" ]; -c30 [ shape=record, label="{{<p24> A|<p25> B}|$37\n$add|{<p26> Y}}" ]; -v0 [ label="1'1" ]; -c31 [ shape=record, label="{{<p24> A|<p25> B}|$145\n$and|{<p26> Y}}" ]; -v1 [ label="1'1" ]; -c32 [ shape=record, label="{{<p24> A|<p25> B}|$175\n$and|{<p26> Y}}" ]; -v2 [ label="1'1" ]; -c33 [ shape=record, label="{{<p24> A|<p25> B}|$205\n$and|{<p26> Y}}" ]; -v3 [ label="1'1" ]; -c34 [ shape=record, label="{{<p24> A|<p25> B}|$235\n$and|{<p26> Y}}" ]; -v4 [ label="2'00" ]; -c35 [ shape=record, label="{{<p24> A|<p25> B}|$143\n$eq|{<p26> Y}}" ]; -v5 [ label="2'01" ]; -c36 [ shape=record, label="{{<p24> A|<p25> B}|$173\n$eq|{<p26> Y}}" ]; -v6 [ label="2'10" ]; -c37 [ shape=record, label="{{<p24> A|<p25> B}|$203\n$eq|{<p26> Y}}" ]; -v7 [ label="2'11" ]; -c38 [ shape=record, label="{{<p24> A|<p25> B}|$233\n$eq|{<p26> Y}}" ]; -c40 [ shape=record, label="{{<p24> A|<p25> B|<p39> S}|$147\n$mux|{<p26> Y}}" ]; -c41 [ shape=record, label="{{<p24> A|<p25> B|<p39> S}|$177\n$mux|{<p26> Y}}" ]; -c42 [ shape=record, label="{{<p24> A|<p25> B|<p39> S}|$207\n$mux|{<p26> Y}}" ]; -c43 [ shape=record, label="{{<p24> A|<p25> B|<p39> S}|$237\n$mux|{<p26> Y}}" ]; -c47 [ shape=record, label="{{<p44> CLK|<p45> D}|$66\n$dff|{<p46> Q}}" ]; -c48 [ shape=record, label="{{<p44> CLK|<p45> D}|$68\n$dff|{<p46> Q}}" ]; -c49 [ shape=record, label="{{<p44> CLK|<p45> D}|$70\n$dff|{<p46> Q}}" ]; -c50 [ shape=record, label="{{<p44> CLK|<p45> D}|$72\n$dff|{<p46> 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 1a672c484..000000000 --- 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="{{<p11> A|<p12> B|<p13> S}|$110\n$mux|{<p14> Y}}" ]; -x0 [ shape=record, style=rounded, label="<s0> 1:1 - 0:0 " ]; -x0:e -> c15:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c16 [ shape=record, label="{{<p11> A|<p12> B|<p13> S}|$113\n$mux|{<p14> Y}}" ]; -x1 [ shape=record, style=rounded, label="<s0> 0:0 - 0:0 " ]; -x1:e -> c16:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c17 [ shape=record, label="{{<p11> A|<p12> B|<p13> S}|$116\n$mux|{<p14> Y}}" ]; -x2 [ shape=record, style=rounded, label="<s0> 0:0 - 0:0 " ]; -x2:e -> c17:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c21 [ shape=record, label="{{<p18> CLK|<p19> D}|$64\n$dff|{<p20> 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 0dbbe3baa..000000000 --- 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="{{<p8> A}|$39\n$reduce_bool|{<p9> Y}}" ]; -v0 [ label="4'0000" ]; -c13 [ shape=record, label="{{<p8> A|<p11> B|<p12> S}|$40\n$mux|{<p9> Y}}" ]; -x1 [ shape=record, style=rounded, label="<s1> 3:2 - 1:0 |<s0> 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="{{<p8> A|<p11> B}|$38\n$xor|{<p9> Y}}" ]; -x2 [ shape=record, style=rounded, label="<s1> 1:0 - 3:2 |<s0> 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 06522dcc9..000000000 --- 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="{{<p1> A|<p2> B}|$1\n$add|{<p3> Y}}" ]; -v3 [ label="$1_Y" ]; -v4 [ label="c" ]; -v5 [ label="sum" ]; -c5 [ shape=record, label="{{<p1> A|<p2> B}|$2\n$add|{<p3> 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 aefe7a6da..000000000 --- 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="{{<p6> A|<p7> B}|$1\n$add|{<p8> Y}}" ]; -c10 [ shape=record, label="{{<p6> A|<p7> B}|$2\n$add|{<p8> 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 4646c9947..000000000 --- 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 dcfea2b56..000000000 --- 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="{{<p2> A|<p3> B}|$4\n$mul|{<p4> 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 e77c41aa2..000000000 --- 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="{{<p4> A|<p5> B}|$4\n$mul|{<p6> 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 b54441290..000000000 --- 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="{{<p4> A|<p5> B}|$3\n$mul|{<p6> Y}}" ]; -c8 [ shape=record, label="{{<p4> A|<p5> B}|$4\n$mul|{<p6> 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/resources/PRESENTATION_ExAdv/.gitignore b/docs/source/code_examples/.gitignore similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/.gitignore rename to docs/source/code_examples/.gitignore diff --git a/docs/resources/PRESENTATION_ExOth/axis_master.v b/docs/source/code_examples/axis/axis_master.v similarity index 100% rename from docs/resources/PRESENTATION_ExOth/axis_master.v rename to docs/source/code_examples/axis/axis_master.v diff --git a/docs/resources/PRESENTATION_ExOth/axis_test.v b/docs/source/code_examples/axis/axis_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExOth/axis_test.v rename to docs/source/code_examples/axis/axis_test.v diff --git a/docs/resources/PRESENTATION_ExOth/axis_test.ys b/docs/source/code_examples/axis/axis_test.ys similarity index 70% rename from docs/resources/PRESENTATION_ExOth/axis_test.ys rename to docs/source/code_examples/axis/axis_test.ys index 19663ac77..a55d017d9 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_Intro/Makefile b/docs/source/code_examples/intro/Makefile similarity index 100% rename from docs/resources/PRESENTATION_Intro/Makefile rename to docs/source/code_examples/intro/Makefile diff --git a/docs/resources/PRESENTATION_Intro/counter.v b/docs/source/code_examples/intro/counter.v similarity index 100% rename from docs/resources/PRESENTATION_Intro/counter.v rename to docs/source/code_examples/intro/counter.v diff --git a/docs/resources/PRESENTATION_Intro/counter.ys b/docs/source/code_examples/intro/counter.ys similarity index 100% rename from docs/resources/PRESENTATION_Intro/counter.ys rename to docs/source/code_examples/intro/counter.ys diff --git a/docs/resources/PRESENTATION_Intro/counter_outputs.ys b/docs/source/code_examples/intro/counter_outputs.ys similarity index 100% rename from docs/resources/PRESENTATION_Intro/counter_outputs.ys rename to docs/source/code_examples/intro/counter_outputs.ys diff --git a/docs/resources/PRESENTATION_Intro/mycells.lib b/docs/source/code_examples/intro/mycells.lib similarity index 100% rename from docs/resources/PRESENTATION_Intro/mycells.lib rename to docs/source/code_examples/intro/mycells.lib diff --git a/docs/resources/PRESENTATION_Intro/mycells.v b/docs/source/code_examples/intro/mycells.v similarity index 100% rename from docs/resources/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 000000000..91ec83288 --- /dev/null +++ b/docs/source/code_examples/macc/Makefile @@ -0,0 +1,12 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys + +all: macc_simple_xmap.pdf macc_xilinx_xmap.pdf + +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/docs/resources/PRESENTATION_ExAdv/macc_simple_test.v b/docs/source/code_examples/macc/macc_simple_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_simple_test.v rename to docs/source/code_examples/macc/macc_simple_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_simple_test.ys b/docs/source/code_examples/macc/macc_simple_test.ys similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_simple_test.ys rename to docs/source/code_examples/macc/macc_simple_test.ys diff --git a/docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v b/docs/source/code_examples/macc/macc_simple_test_01.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v rename to docs/source/code_examples/macc/macc_simple_test_01.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v b/docs/source/code_examples/macc/macc_simple_test_02.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v rename to docs/source/code_examples/macc/macc_simple_test_02.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v b/docs/source/code_examples/macc/macc_simple_xmap.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v rename to docs/source/code_examples/macc/macc_simple_xmap.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v b/docs/source/code_examples/macc/macc_xilinx_swap_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v rename to docs/source/code_examples/macc/macc_xilinx_swap_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v b/docs/source/code_examples/macc/macc_xilinx_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v rename to docs/source/code_examples/macc/macc_xilinx_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.ys b/docs/source/code_examples/macc/macc_xilinx_test.ys similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.ys rename to docs/source/code_examples/macc/macc_xilinx_test.ys diff --git a/docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v b/docs/source/code_examples/macc/macc_xilinx_unwrap_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v rename to docs/source/code_examples/macc/macc_xilinx_unwrap_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v b/docs/source/code_examples/macc/macc_xilinx_wrap_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v rename to docs/source/code_examples/macc/macc_xilinx_wrap_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v b/docs/source/code_examples/macc/macc_xilinx_xmap.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v rename to docs/source/code_examples/macc/macc_xilinx_xmap.v diff --git a/docs/source/APPNOTE_011_Design_Investigation/primetest.v b/docs/source/code_examples/primetest.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/primetest.v rename to docs/source/code_examples/primetest.v diff --git a/docs/source/code_examples/scrambler/Makefile b/docs/source/code_examples/scrambler/Makefile new file mode 100644 index 000000000..1e9425558 --- /dev/null +++ b/docs/source/code_examples/scrambler/Makefile @@ -0,0 +1,8 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys + +all: scrambler_p01.dot scrambler_p02.dot + +scrambler_p01.dot scrambler_p02.dot: scrambler.ys scrambler.v + $(YOSYS) scrambler.ys diff --git a/docs/resources/PRESENTATION_ExOth/scrambler.v b/docs/source/code_examples/scrambler/scrambler.v similarity index 100% rename from docs/resources/PRESENTATION_ExOth/scrambler.v rename to docs/source/code_examples/scrambler/scrambler.v diff --git a/docs/resources/PRESENTATION_ExOth/scrambler.ys b/docs/source/code_examples/scrambler/scrambler.ys similarity index 69% rename from docs/resources/PRESENTATION_ExOth/scrambler.ys rename to docs/source/code_examples/scrambler/scrambler.ys index 2ef14c56e..f14caa6f7 100644 --- a/docs/resources/PRESENTATION_ExOth/scrambler.ys +++ b/docs/source/code_examples/scrambler/scrambler.ys @@ -1,4 +1,3 @@ - read_verilog scrambler.v hierarchy; proc;; @@ -7,8 +6,8 @@ cd scrambler submod -name xorshift32 xs %c %ci %D %c %ci:+[D] %D %ci*:-$dff xs %co %ci %d cd .. -show -prefix scrambler_p01 -format pdf -notitle scrambler -show -prefix scrambler_p02 -format pdf -notitle xorshift32 +show -prefix scrambler_p01 -format dot -notitle scrambler +show -prefix scrambler_p02 -format dot -notitle xorshift32 echo on diff --git a/docs/source/code_examples/selections/Makefile b/docs/source/code_examples/selections/Makefile new file mode 100644 index 000000000..384ce12a9 --- /dev/null +++ b/docs/source/code_examples/selections/Makefile @@ -0,0 +1,32 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +SUMPROD = sumprod_00 sumprod_01 sumprod_02 sumprod_03 sumprod_04 sumprod_05 +SUMPROD_DOTS := $(addsuffix .dot,$(SUMPROD)) + +MEMDEMO = memdemo_00 memdemo_01 +MEMDEMO_DOTS := $(addsuffix .dot,$(MEMDEMO)) + +SUBMOD = submod_00 submod_01 submod_02 submod_03 +SUBMOD_DOTS := $(addsuffix .dot,$(SUBMOD)) + +all: select.dot $(SUMPROD_DOTS) $(MEMDEMO_DOTS) + +select.dot: select.v select.ys + $(YOSYS) select.ys + +$(SUMPROD_DOTS): sumprod.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 + +$(MEMDEMO_DOTS): memdemo.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 + +$(SUBMOD_DOTS): submod.ys memdemo.v + $(YOSYS) submod.ys diff --git a/docs/source/APPNOTE_011_Design_Investigation/foobaraddsub.v b/docs/source/code_examples/selections/foobaraddsub.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/foobaraddsub.v rename to docs/source/code_examples/selections/foobaraddsub.v diff --git a/docs/source/APPNOTE_011_Design_Investigation/memdemo.v b/docs/source/code_examples/selections/memdemo.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/memdemo.v rename to docs/source/code_examples/selections/memdemo.v diff --git a/docs/resources/PRESENTATION_ExAdv/select.v b/docs/source/code_examples/selections/select.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/select.v rename to docs/source/code_examples/selections/select.v diff --git a/docs/resources/PRESENTATION_ExAdv/select.ys b/docs/source/code_examples/selections/select.ys similarity index 85% rename from docs/resources/PRESENTATION_ExAdv/select.ys rename to docs/source/code_examples/selections/select.ys index 9832c104b..565ce90a3 100644 --- a/docs/resources/PRESENTATION_ExAdv/select.ys +++ b/docs/source/code_examples/selections/select.ys @@ -5,6 +5,6 @@ cd test select -set cone_a state_a %ci*:-$dff select -set cone_b state_b %ci*:-$dff select -set cone_ab @cone_a @cone_b %i -show -prefix select -format pdf -notitle \ +show -prefix select -format dot -notitle \ -color red @cone_ab -color magenta @cone_a \ -color blue @cone_b diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod.ys b/docs/source/code_examples/selections/submod.ys similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/submod.ys rename to docs/source/code_examples/selections/submod.ys diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod.v b/docs/source/code_examples/selections/sumprod.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/sumprod.v rename to docs/source/code_examples/selections/sumprod.v diff --git a/docs/source/code_examples/show/Makefile b/docs/source/code_examples/show/Makefile new file mode 100644 index 000000000..9cc4fc58d --- /dev/null +++ b/docs/source/code_examples/show/Makefile @@ -0,0 +1,23 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +EXAMPLE = example_00 example_01 example_02 example_03 +EXAMPLE_DOTS := $(addsuffix .dot,$(EXAMPLE)) + +CMOS = cmos_00 cmos_01 +CMOS_DOTS := $(addsuffix .dot,$(CMOS)) + +all: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) + +splice.dot: splice.v + $(YOSYS) -p 'proc; opt; show -format dot -prefix splice' splice.v + +$(EXAMPLE_DOTS): example.v example.ys + $(YOSYS) example.ys + +cmos_00.dot: cmos.v + $(YOSYS) -p 'read_verilog cmos.v; techmap; abc -liberty ../intro/mycells.lib;; show -format dot -prefix cmos_00' + +cmos_01.dot: cmos.v + $(YOSYS) -p 'read_verilog cmos.v; techmap; splitnets -ports; abc -liberty ../intro/mycells.lib;; show -lib ../intro/mycells.v -format dot -prefix cmos_01' diff --git a/docs/source/APPNOTE_011_Design_Investigation/cmos.v b/docs/source/code_examples/show/cmos.v similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/cmos.v rename to docs/source/code_examples/show/cmos.v 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/APPNOTE_011_Design_Investigation/example.ys b/docs/source/code_examples/show/example.ys similarity index 100% rename from docs/source/APPNOTE_011_Design_Investigation/example.ys rename to docs/source/code_examples/show/example.ys 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 100% rename from docs/source/CHAPTER_Prog/Makefile rename to docs/source/code_examples/stubnets/Makefile 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/resources/PRESENTATION_ExSyn/Makefile b/docs/source/code_examples/synth_flow/Makefile similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/Makefile rename to docs/source/code_examples/synth_flow/Makefile diff --git a/docs/resources/PRESENTATION_ExSyn/abc_01.v b/docs/source/code_examples/synth_flow/abc_01.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/abc_01.v rename to docs/source/code_examples/synth_flow/abc_01.v diff --git a/docs/resources/PRESENTATION_ExSyn/abc_01.ys b/docs/source/code_examples/synth_flow/abc_01.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/abc_01.ys rename to docs/source/code_examples/synth_flow/abc_01.ys diff --git a/docs/resources/PRESENTATION_ExSyn/abc_01_cells.lib b/docs/source/code_examples/synth_flow/abc_01_cells.lib similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/abc_01_cells.lib rename to docs/source/code_examples/synth_flow/abc_01_cells.lib diff --git a/docs/resources/PRESENTATION_ExSyn/abc_01_cells.v b/docs/source/code_examples/synth_flow/abc_01_cells.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/abc_01_cells.v rename to docs/source/code_examples/synth_flow/abc_01_cells.v diff --git a/docs/resources/PRESENTATION_ExSyn/memory_01.v b/docs/source/code_examples/synth_flow/memory_01.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/memory_01.v rename to docs/source/code_examples/synth_flow/memory_01.v diff --git a/docs/resources/PRESENTATION_ExSyn/memory_01.ys b/docs/source/code_examples/synth_flow/memory_01.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/memory_01.ys rename to docs/source/code_examples/synth_flow/memory_01.ys diff --git a/docs/resources/PRESENTATION_ExSyn/memory_02.v b/docs/source/code_examples/synth_flow/memory_02.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/memory_02.v rename to docs/source/code_examples/synth_flow/memory_02.v diff --git a/docs/resources/PRESENTATION_ExSyn/memory_02.ys b/docs/source/code_examples/synth_flow/memory_02.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/memory_02.ys rename to docs/source/code_examples/synth_flow/memory_02.ys diff --git a/docs/resources/PRESENTATION_ExSyn/opt_01.v b/docs/source/code_examples/synth_flow/opt_01.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_01.v rename to docs/source/code_examples/synth_flow/opt_01.v diff --git a/docs/resources/PRESENTATION_ExSyn/opt_01.ys b/docs/source/code_examples/synth_flow/opt_01.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_01.ys rename to docs/source/code_examples/synth_flow/opt_01.ys diff --git a/docs/resources/PRESENTATION_ExSyn/opt_02.v b/docs/source/code_examples/synth_flow/opt_02.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_02.v rename to docs/source/code_examples/synth_flow/opt_02.v diff --git a/docs/resources/PRESENTATION_ExSyn/opt_02.ys b/docs/source/code_examples/synth_flow/opt_02.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_02.ys rename to docs/source/code_examples/synth_flow/opt_02.ys diff --git a/docs/resources/PRESENTATION_ExSyn/opt_03.v b/docs/source/code_examples/synth_flow/opt_03.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_03.v rename to docs/source/code_examples/synth_flow/opt_03.v diff --git a/docs/resources/PRESENTATION_ExSyn/opt_03.ys b/docs/source/code_examples/synth_flow/opt_03.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_03.ys rename to docs/source/code_examples/synth_flow/opt_03.ys diff --git a/docs/resources/PRESENTATION_ExSyn/opt_04.v b/docs/source/code_examples/synth_flow/opt_04.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_04.v rename to docs/source/code_examples/synth_flow/opt_04.v diff --git a/docs/resources/PRESENTATION_ExSyn/opt_04.ys b/docs/source/code_examples/synth_flow/opt_04.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/opt_04.ys rename to docs/source/code_examples/synth_flow/opt_04.ys diff --git a/docs/resources/PRESENTATION_ExSyn/proc_01.v b/docs/source/code_examples/synth_flow/proc_01.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/proc_01.v rename to docs/source/code_examples/synth_flow/proc_01.v diff --git a/docs/resources/PRESENTATION_ExSyn/proc_01.ys b/docs/source/code_examples/synth_flow/proc_01.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/proc_01.ys rename to docs/source/code_examples/synth_flow/proc_01.ys diff --git a/docs/resources/PRESENTATION_ExSyn/proc_02.v b/docs/source/code_examples/synth_flow/proc_02.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/proc_02.v rename to docs/source/code_examples/synth_flow/proc_02.v diff --git a/docs/resources/PRESENTATION_ExSyn/proc_02.ys b/docs/source/code_examples/synth_flow/proc_02.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/proc_02.ys rename to docs/source/code_examples/synth_flow/proc_02.ys diff --git a/docs/resources/PRESENTATION_ExSyn/proc_03.v b/docs/source/code_examples/synth_flow/proc_03.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/proc_03.v rename to docs/source/code_examples/synth_flow/proc_03.v diff --git a/docs/resources/PRESENTATION_ExSyn/proc_03.ys b/docs/source/code_examples/synth_flow/proc_03.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/proc_03.ys rename to docs/source/code_examples/synth_flow/proc_03.ys diff --git a/docs/resources/PRESENTATION_ExSyn/techmap_01.v b/docs/source/code_examples/synth_flow/techmap_01.v similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/techmap_01.v rename to docs/source/code_examples/synth_flow/techmap_01.v diff --git a/docs/resources/PRESENTATION_ExSyn/techmap_01.ys b/docs/source/code_examples/synth_flow/techmap_01.ys similarity index 100% rename from docs/resources/PRESENTATION_ExSyn/techmap_01.ys rename to docs/source/code_examples/synth_flow/techmap_01.ys diff --git a/docs/resources/PRESENTATION_ExSyn/techmap_01_map.v b/docs/source/code_examples/synth_flow/techmap_01_map.v similarity index 100% rename from docs/resources/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 000000000..b48972fd9 --- /dev/null +++ b/docs/source/code_examples/techmap/Makefile @@ -0,0 +1,21 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys + +all: 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 + diff --git a/docs/resources/PRESENTATION_ExAdv/addshift_map.v b/docs/source/code_examples/techmap/addshift_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/addshift_map.v rename to docs/source/code_examples/techmap/addshift_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/addshift_test.v b/docs/source/code_examples/techmap/addshift_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/addshift_test.v rename to docs/source/code_examples/techmap/addshift_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/addshift_test.ys b/docs/source/code_examples/techmap/addshift_test.ys similarity index 67% rename from docs/resources/PRESENTATION_ExAdv/addshift_test.ys rename to docs/source/code_examples/techmap/addshift_test.ys index c08f1106a..c15691b33 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_ExAdv/mulshift_map.v b/docs/source/code_examples/techmap/mulshift_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/mulshift_map.v rename to docs/source/code_examples/techmap/mulshift_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/mulshift_test.v b/docs/source/code_examples/techmap/mulshift_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/mulshift_test.v rename to docs/source/code_examples/techmap/mulshift_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/mulshift_test.ys b/docs/source/code_examples/techmap/mulshift_test.ys similarity index 64% rename from docs/resources/PRESENTATION_ExAdv/mulshift_test.ys rename to docs/source/code_examples/techmap/mulshift_test.ys index c5dac49eb..79daaf0c4 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_ExAdv/mymul_map.v b/docs/source/code_examples/techmap/mymul_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/mymul_map.v rename to docs/source/code_examples/techmap/mymul_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/mymul_test.v b/docs/source/code_examples/techmap/mymul_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/mymul_test.v rename to docs/source/code_examples/techmap/mymul_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/mymul_test.ys b/docs/source/code_examples/techmap/mymul_test.ys similarity index 84% rename from docs/resources/PRESENTATION_ExAdv/mymul_test.ys rename to docs/source/code_examples/techmap/mymul_test.ys index 48203e319..b7176fdc4 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_ExAdv/red_or3x1_cells.v b/docs/source/code_examples/techmap/red_or3x1_cells.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/red_or3x1_cells.v rename to docs/source/code_examples/techmap/red_or3x1_cells.v diff --git a/docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v b/docs/source/code_examples/techmap/red_or3x1_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v rename to docs/source/code_examples/techmap/red_or3x1_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/red_or3x1_test.v b/docs/source/code_examples/techmap/red_or3x1_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/red_or3x1_test.v rename to docs/source/code_examples/techmap/red_or3x1_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/red_or3x1_test.ys b/docs/source/code_examples/techmap/red_or3x1_test.ys similarity index 63% rename from docs/resources/PRESENTATION_ExAdv/red_or3x1_test.ys rename to docs/source/code_examples/techmap/red_or3x1_test.ys index b92346034..891b8177b 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_ExAdv/sym_mul_cells.v b/docs/source/code_examples/techmap/sym_mul_cells.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/sym_mul_cells.v rename to docs/source/code_examples/techmap/sym_mul_cells.v diff --git a/docs/resources/PRESENTATION_ExAdv/sym_mul_map.v b/docs/source/code_examples/techmap/sym_mul_map.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/sym_mul_map.v rename to docs/source/code_examples/techmap/sym_mul_map.v diff --git a/docs/resources/PRESENTATION_ExAdv/sym_mul_test.v b/docs/source/code_examples/techmap/sym_mul_test.v similarity index 100% rename from docs/resources/PRESENTATION_ExAdv/sym_mul_test.v rename to docs/source/code_examples/techmap/sym_mul_test.v diff --git a/docs/resources/PRESENTATION_ExAdv/sym_mul_test.ys b/docs/source/code_examples/techmap/sym_mul_test.ys similarity index 57% rename from docs/resources/PRESENTATION_ExAdv/sym_mul_test.ys rename to docs/source/code_examples/techmap/sym_mul_test.ys index 0c07e7e87..f19bee64a 100644 --- a/docs/resources/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/getting_started/examples.rst b/docs/source/getting_started/examples.rst index 8342b685c..8fecb4985 100644 --- a/docs/source/getting_started/examples.rst +++ b/docs/source/getting_started/examples.rst @@ -53,13 +53,13 @@ Simple synthesis script ~~~~~~~~~~~~~~~~~~~~~~~ This section covers an example project available in -``docs/resources/PRESENTATION_Intro/*``. The project contains a simple ASIC +``docs/source/code_examples/intro/*``. The project contains a simple ASIC synthesis script (``counter.ys``), a digital design written in Verilog (``counter.v``), and a simple CMOS cell library (``mycells.lib``). -.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys +.. literalinclude:: /code_examples/intro/counter.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_Intro/counter.ys`` + :caption: ``docs/source/code_examples/intro/counter.ys`` .. role:: yoscrypt(code) :language: yoscrypt @@ -89,18 +89,18 @@ synthesis script (``counter.ys``), a digital design written in Verilog Running the script ^^^^^^^^^^^^^^^^^^ -.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.v +.. literalinclude:: /code_examples/intro/counter.v :language: Verilog - :caption: ``docs/resources/PRESENTATION_Intro/counter.v`` + :caption: ``docs/source/code_examples/intro/counter.v`` -.. literalinclude:: ../../resources/PRESENTATION_Intro/mycells.lib +.. literalinclude:: /code_examples/intro/mycells.lib :language: Liberty - :caption: ``docs/resources/PRESENTATION_Intro/mycells.lib`` + :caption: ``docs/source/code_examples/intro/mycells.lib`` Step 1 """""" -.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys +.. literalinclude:: /code_examples/intro/counter.ys :language: yoscrypt :lines: 1-3 @@ -112,7 +112,7 @@ Result: Step 2 """""" -.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys +.. literalinclude:: /code_examples/intro/counter.ys :language: yoscrypt :lines: 5-6 @@ -124,7 +124,7 @@ Result: Step 3 """""" -.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys +.. literalinclude:: /code_examples/intro/counter.ys :language: yoscrypt :lines: 8-9 @@ -136,7 +136,7 @@ Result: Step 4 """""" -.. literalinclude:: ../../resources/PRESENTATION_Intro/counter.ys +.. literalinclude:: /code_examples/intro/counter.ys :language: yoscrypt :lines: 11-18 diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index a06ee1e17..d04419ec1 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -86,13 +86,13 @@ after design elaboration. Example ^^^^^^^ -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_01.v +.. literalinclude:: /code_examples/synth_flow/proc_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/proc_01.v`` + :caption: ``docs/source/code_examples/synth_flow/proc_01.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_01.ys +.. literalinclude:: /code_examples/synth_flow/proc_01.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/proc_01.ys`` + :caption: ``docs/source/code_examples/synth_flow/proc_01.ys`` .. figure:: /_images/res/PRESENTATION_ExSyn/proc_01.* :class: width-helper @@ -100,24 +100,24 @@ Example .. figure:: /_images/res/PRESENTATION_ExSyn/proc_02.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_02.v +.. literalinclude:: /code_examples/synth_flow/proc_02.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/proc_02.v`` + :caption: ``docs/source/code_examples/synth_flow/proc_02.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_02.ys +.. literalinclude:: /code_examples/synth_flow/proc_02.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/proc_02.ys`` + :caption: ``docs/source/code_examples/synth_flow/proc_02.ys`` .. figure:: /_images/res/PRESENTATION_ExSyn/proc_03.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_03.ys +.. literalinclude:: /code_examples/synth_flow/proc_03.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/proc_03.ys`` + :caption: ``docs/source/code_examples/synth_flow/proc_03.ys`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/proc_03.v +.. literalinclude:: /code_examples/synth_flow/proc_03.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/proc_03.v`` + :caption: ``docs/source/code_examples/synth_flow/proc_03.v`` The :cmd:ref:`opt` command @@ -153,46 +153,46 @@ Example .. figure:: /_images/res/PRESENTATION_ExSyn/opt_01.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_01.ys +.. literalinclude:: /code_examples/synth_flow/opt_01.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_01.ys`` + :caption: ``docs/source/code_examples/synth_flow/opt_01.ys`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_01.v +.. literalinclude:: /code_examples/synth_flow/opt_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_01.v`` + :caption: ``docs/source/code_examples/synth_flow/opt_01.v`` .. figure:: /_images/res/PRESENTATION_ExSyn/opt_02.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_02.ys +.. literalinclude:: /code_examples/synth_flow/opt_02.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_02.ys`` + :caption: ``docs/source/code_examples/synth_flow/opt_02.ys`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_02.v +.. literalinclude:: /code_examples/synth_flow/opt_02.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_02.v`` + :caption: ``docs/source/code_examples/synth_flow/opt_02.v`` .. figure:: /_images/res/PRESENTATION_ExSyn/opt_03.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_03.ys +.. literalinclude:: /code_examples/synth_flow/opt_03.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_03.ys`` + :caption: ``docs/source/code_examples/synth_flow/opt_03.ys`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_03.v +.. literalinclude:: /code_examples/synth_flow/opt_03.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_03.v`` + :caption: ``docs/source/code_examples/synth_flow/opt_03.v`` .. figure:: /_images/res/PRESENTATION_ExSyn/opt_04.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_04.v +.. literalinclude:: /code_examples/synth_flow/opt_04.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_04.v`` + :caption: ``docs/source/code_examples/synth_flow/opt_04.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/opt_04.ys +.. literalinclude:: /code_examples/synth_flow/opt_04.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/opt_04.ys`` + :caption: ``docs/source/code_examples/synth_flow/opt_04.ys`` When to use :cmd:ref:`opt` or :cmd:ref:`clean` @@ -249,24 +249,24 @@ Example .. figure:: /_images/res/PRESENTATION_ExSyn/memory_01.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_01.ys +.. literalinclude:: /code_examples/synth_flow/memory_01.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/memory_01.ys`` + :caption: ``docs/source/code_examples/synth_flow/memory_01.ys`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_01.v +.. literalinclude:: /code_examples/synth_flow/memory_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/memory_01.v`` + :caption: ``docs/source/code_examples/synth_flow/memory_01.v`` .. figure:: /_images/res/PRESENTATION_ExSyn/memory_02.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_02.v +.. literalinclude:: /code_examples/synth_flow/memory_02.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/memory_02.v`` + :caption: ``docs/source/code_examples/synth_flow/memory_02.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/memory_02.ys +.. literalinclude:: /code_examples/synth_flow/memory_02.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/memory_02.ys`` + :caption: ``docs/source/code_examples/synth_flow/memory_02.ys`` The :cmd:ref:`fsm` command @@ -321,17 +321,17 @@ The :cmd:ref:`techmap` command The :cmd:ref:`techmap` command replaces cells with implementations given as verilog source. For example implementing a 32 bit adder using 16 bit adders: -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01_map.v +.. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01_map.v`` + :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.v +.. literalinclude:: /code_examples/synth_flow/techmap_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.v`` + :caption: ``docs/source/code_examples/synth_flow/techmap_01.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.ys +.. literalinclude:: /code_examples/synth_flow/techmap_01.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.ys`` + :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` stdcell mapping ^^^^^^^^^^^^^^^ @@ -378,13 +378,13 @@ advanced ABC features. It is also possible to write the design with Example ^^^^^^^ -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/abc_01.v +.. literalinclude:: /code_examples/synth_flow/abc_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/abc_01.v`` + :caption: ``docs/source/code_examples/synth_flow/abc_01.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/abc_01.ys +.. literalinclude:: /code_examples/synth_flow/abc_01.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/abc_01.ys`` + :caption: ``docs/source/code_examples/synth_flow/abc_01.ys`` .. figure:: /_images/res/PRESENTATION_ExSyn/abc_01.* :class: width-helper diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index 7d4243faf..a16d3cd57 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -18,9 +18,9 @@ A simple circuit :numref:`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:: /APPNOTE_011_Design_Investigation/example.v +.. literalinclude:: /code_examples/show/example.v :language: Verilog - :caption: ``docs/source/APPNOTE_011_Design_Investigation/example.v`` + :caption: ``docs/source/code_examples/show/example.v`` :name: example_v The Yosys synthesis script we will be running is included as @@ -31,7 +31,7 @@ interactive shell to further investigate the circuit before continuing synthesis. .. code-block:: yoscrypt - :caption: ``docs/source/APPNOTE_011_Design_Investigation/example.ys`` + :caption: ``docs/source/code_examples/show/example.ys`` :name: example_ys read_verilog example.v @@ -115,8 +115,8 @@ Break-out boxes for signal vectors The code listing below shows a simple circuit which uses a lot of spliced signal accesses. -.. literalinclude:: /APPNOTE_011_Design_Investigation/splice.v - :caption: ``splice.v`` +.. literalinclude:: /code_examples/show/splice.v + :caption: ``docs/source/code_examples/show/splice.v`` :name: splice_src Notice how the output for this circuit from the :cmd:ref:`show` command @@ -341,20 +341,14 @@ 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:: ../../../resources/PRESENTATION_ExOth/scrambler.v +.. literalinclude:: /code_examples/scrambler/scrambler.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExOth/scrambler.v`` + :caption: ``docs/source/code_examples/scrambler/scrambler.v`` -.. code:: yoscrypt - - 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 +.. literalinclude:: /code_examples/scrambler/scrambler.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/scrambler/scrambler.ys`` + :end-before: cd .. .. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p01.* :class: width-helper @@ -446,17 +440,13 @@ 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``. -.. code-block:: yoscrypt - :caption: The circuit from ``memdemo.v`` broken up using :cmd:ref:`submod` +.. literalinclude:: /code_examples/selections/submod.ys + :language: yoscrypt + :caption: Using :cmd:ref:`submod` to break up the circuit from ``memdemo.v`` + :start-after: cd memdemo + :end-at: @selstage :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 - 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. @@ -584,7 +574,7 @@ 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:: /APPNOTE_011_Design_Investigation/primetest.v +.. literalinclude:: /code_examples/primetest.v :language: verilog :caption: ``primetest.v``, a simple miter circuit for testing if a number is prime. But it has a problem. diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 78b20ea35..b0fcb7b18 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -103,7 +103,7 @@ 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:: /APPNOTE_011_Design_Investigation/foobaraddsub.v +.. literalinclude:: /code_examples/selections/foobaraddsub.v :caption: Test module for operations on selections :name: foobaraddsub :language: verilog @@ -146,7 +146,7 @@ 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.) -.. literalinclude:: /APPNOTE_011_Design_Investigation/sumprod.v +.. literalinclude:: /code_examples/selections/sumprod.v :caption: Another test module for operations on selections :name: sumprod :language: verilog @@ -233,7 +233,7 @@ 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. -.. literalinclude:: /APPNOTE_011_Design_Investigation/memdemo.v +.. literalinclude:: /code_examples/selections/memdemo.v :caption: Demo circuit for demonstrating some advanced Yosys features :name: memdemo_src :language: verilog @@ -370,13 +370,13 @@ those cases selection variables must be used to capture more complex selections. Example: -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.v +.. literalinclude:: /code_examples/selections/select.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/select.v`` + :caption: ``docs/source/code_examples/selections/select.v`` -.. literalinclude:: ../../../resources/PRESENTATION_ExAdv/select.ys +.. literalinclude:: /code_examples/selections/select.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/select.ys`` + :caption: ``docs/source/code_examples/selections/select.ys`` :name: select_ys .. figure:: /_images/res/PRESENTATION_ExAdv/select.* diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 0bd824b20..88e7a1479 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -51,13 +51,13 @@ The extract pass after `extract` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test.v +.. literalinclude:: /code_examples/macc/macc_simple_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test.v`` + :caption: ``docs/source/code_examples/macc/macc_simple_test.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_xmap.v +.. literalinclude:: /code_examples/macc/macc_simple_xmap.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_xmap.v`` + :caption: ``docs/source/code_examples/macc/macc_simple_xmap.v`` .. code:: yoscrypt @@ -66,9 +66,9 @@ The extract pass extract -map macc_simple_xmap.v;; -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test_01.v +.. literalinclude:: /code_examples/macc/macc_simple_test_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_01.v`` + :caption: ``docs/source/code_examples/macc/macc_simple_test_01.v`` .. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* :class: width-helper @@ -76,9 +76,9 @@ The extract pass .. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_simple_test_02.v +.. literalinclude:: /code_examples/macc/macc_simple_test_02.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_simple_test_02.v`` + :caption: ``docs/source/code_examples/macc/macc_simple_test_02.v`` .. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* :class: width-helper @@ -123,51 +123,51 @@ Make sure ``A`` is the smaller port on all multipliers .. todo:: add/expand supporting text -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v +.. literalinclude:: /code_examples/macc/macc_xilinx_swap_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_swap_map.v`` + :caption: ``docs/source/code_examples/macc/macc_xilinx_swap_map.v`` Wrapping multipliers: ``macc_xilinx_wrap_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v +.. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v :language: verilog :lines: 1-46 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` + :caption: ``docs/source/code_examples/macc/macc_xilinx_wrap_map.v`` Wrapping adders: ``macc_xilinx_wrap_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v +.. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v :language: verilog :lines: 48-89 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v`` + :caption: ``docs/source/code_examples/macc/macc_xilinx_wrap_map.v`` Extract: ``macc_xilinx_xmap.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v +.. literalinclude:: /code_examples/macc/macc_xilinx_xmap.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_xmap.v`` + :caption: ``docs/source/code_examples/macc/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: ``macc_xilinx_unwrap_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v +.. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v :language: verilog :lines: 1-30 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` + :caption: ``docs/source/code_examples/macc/macc_xilinx_unwrap_map.v`` Unwrapping adders: ``macc_xilinx_unwrap_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v +.. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v :language: verilog :lines: 32-61 - :caption: ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v`` + :caption: ``docs/source/code_examples/macc/macc_xilinx_unwrap_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v +.. literalinclude:: /code_examples/macc/macc_xilinx_test.v :language: verilog :lines: 1-6 - :caption: ``test1`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` + :caption: ``test1`` of ``docs/source/code_examples/macc/macc_xilinx_test.v`` .. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* :class: width-helper @@ -175,10 +175,10 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` .. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/macc_xilinx_test.v +.. literalinclude:: /code_examples/macc/macc_xilinx_test.v :language: verilog :lines: 8-13 - :caption: ``test2`` of ``docs/resources/PRESENTATION_ExAdv/macc_xilinx_test.v`` + :caption: ``test2`` of ``docs/source/code_examples/macc/macc_xilinx_test.v`` .. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* :class: width-helper @@ -303,17 +303,17 @@ Checking techmap Remember the following example from :doc:`/getting_started/typical_phases`? -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01_map.v +.. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01_map.v`` + :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.v +.. literalinclude:: /code_examples/synth_flow/techmap_01.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.v`` + :caption: ``docs/source/code_examples/synth_flow/techmap_01.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExSyn/techmap_01.ys +.. literalinclude:: /code_examples/synth_flow/techmap_01.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExSyn/techmap_01.ys`` + :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` Lets see if it is correct.. @@ -355,22 +355,17 @@ values for ``tready`` that yield the incorrect behavior. .. todo:: add/expand supporting text -.. literalinclude:: ../../resources/PRESENTATION_ExOth/axis_master.v +.. literalinclude:: /code_examples/axis/axis_master.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExOth/axis_master.v`` + :caption: ``docs/source/code_examples/axis/axis_master.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExOth/axis_test.v +.. literalinclude:: /code_examples/axis/axis_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExOth/axis_test.v`` + :caption: ``docs/source/code_examples/axis/axis_test.v`` - -.. code:: yoscrypt - - read_verilog -sv axis_master.v axis_test.v - hierarchy -top axis_test - - proc; flatten;; - sat -seq 50 -prove-asserts +.. literalinclude:: /code_examples/axis/axis_test.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/axis/test.ys`` Result with unmodified ``axis_master.v``: diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index ec9f2b8d0..06ab9a820 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -26,22 +26,22 @@ 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``. +``docs/source/code_examples/stubnets/stubnets.cc``. -.. literalinclude:: ../CHAPTER_Prog/stubnets.cc +.. literalinclude:: /code_examples/stubnets/stubnets.cc :language: c++ :linenos: - :caption: docs/source/CHAPTER_Prog/stubnets.cc + :caption: docs/source/code_examples/stubnets/stubnets.cc -.. literalinclude:: ../CHAPTER_Prog/Makefile +.. literalinclude:: /code_examples/stubnets/Makefile :language: makefile :linenos: - :caption: docs/source/CHAPTER_Prog/Makefile + :caption: docs/source/code_examples/stubnets/Makefile -.. literalinclude:: ../CHAPTER_Prog/test.v +.. literalinclude:: /code_examples/stubnets/test.v :language: verilog :linenos: - :caption: docs/source/CHAPTER_Prog/test.v + :caption: docs/source/code_examples/stubnets/test.v Quick guide ----------- @@ -83,15 +83,13 @@ using these commands. Creating modules from scratch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: add/expand supporting text +.. todo:: add/expand supporting text, also use files in docs/resources/PRESENTATION_Prog Let's create the following module using the RTLIL API: -.. code:: Verilog - - module absval(input signed [3:0] a, output [3:0] y); - assign y = a[3] ? -a : a; - endmodule +.. literalinclude:: ../../resources/PRESENTATION_Prog/absval_ref.v + :language: Verilog + :caption: docs/resources/PRESENTATION_Prog/absval_ref.v .. code:: C++ diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index b89ca9cb9..a2f360a2c 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -130,20 +130,20 @@ Mapping OR3X1 This is a simple example for demonstration only. Techmap shouldn't be used to implement basic logic optimization. -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_map.v +.. literalinclude:: /code_examples/techmap/red_or3x1_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/red_or3x1_map.v`` + :caption: ``docs/source/code_examples/techmap/red_or3x1_map.v`` .. figure:: /_images/res/PRESENTATION_ExAdv/red_or3x1.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_test.ys +.. literalinclude:: /code_examples/techmap/red_or3x1_test.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/red_or3x1_test.ys`` + :caption: ``docs/source/code_examples/techmap/red_or3x1_test.ys`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/red_or3x1_test.v +.. literalinclude:: /code_examples/techmap/red_or3x1_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/red_or3x1_test.v`` + :caption: ``docs/source/code_examples/techmap/red_or3x1_test.v`` Conditional techmap ~~~~~~~~~~~~~~~~~~~ @@ -163,17 +163,17 @@ Example: .. figure:: /_images/res/PRESENTATION_ExAdv/sym_mul.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_map.v +.. literalinclude:: /code_examples/techmap/sym_mul_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/sym_mul_map.v`` + :caption: ``docs/source/code_examples/techmap/sym_mul_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_test.v +.. literalinclude:: /code_examples/techmap/sym_mul_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/sym_mul_test.v`` + :caption: ``docs/source/code_examples/techmap/sym_mul_test.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/sym_mul_test.ys +.. literalinclude:: /code_examples/techmap/sym_mul_test.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/sym_mul_test.ys`` + :caption: ``docs/source/code_examples/techmap/sym_mul_test.ys`` Scripting in map modules @@ -202,17 +202,17 @@ Example: .. figure:: /_images/res/PRESENTATION_ExAdv/mymul.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_map.v +.. literalinclude:: /code_examples/techmap/mymul_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/mymul_map.v`` + :caption: ``docs/source/code_examples/techmap/mymul_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_test.v +.. literalinclude:: /code_examples/techmap/mymul_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/mymul_test.v`` + :caption: ``docs/source/code_examples/techmap/mymul_test.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mymul_test.ys +.. literalinclude:: /code_examples/techmap/mymul_test.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/mymul_test.ys`` + :caption: ``docs/source/code_examples/techmap/mymul_test.ys`` Handling constant inputs ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -232,17 +232,17 @@ Example: .. figure:: /_images/res/PRESENTATION_ExAdv/mulshift.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_map.v +.. literalinclude:: /code_examples/techmap/mulshift_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/mulshift_map.v`` + :caption: ``docs/source/code_examples/techmap/mulshift_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_test.v +.. literalinclude:: /code_examples/techmap/mulshift_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/mulshift_test.v`` + :caption: ``docs/source/code_examples/techmap/mulshift_test.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/mulshift_test.ys +.. literalinclude:: /code_examples/techmap/mulshift_test.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/mulshift_test.ys`` + :caption: ``docs/source/code_examples/techmap/mulshift_test.ys`` Handling shorted inputs ~~~~~~~~~~~~~~~~~~~~~~~ @@ -263,17 +263,17 @@ Example: .. figure:: /_images/res/PRESENTATION_ExAdv/addshift.* :class: width-helper -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_map.v +.. literalinclude:: /code_examples/techmap/addshift_map.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/addshift_map.v`` + :caption: ``docs/source/code_examples/techmap/addshift_map.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_test.v +.. literalinclude:: /code_examples/techmap/addshift_test.v :language: verilog - :caption: ``docs/resources/PRESENTATION_ExAdv/addshift_test.v`` + :caption: ``docs/source/code_examples/techmap/addshift_test.v`` -.. literalinclude:: ../../resources/PRESENTATION_ExAdv/addshift_test.ys +.. literalinclude:: /code_examples/techmap/addshift_test.ys :language: yoscrypt - :caption: ``docs/resources/PRESENTATION_ExAdv/addshift_test.ys`` + :caption: ``docs/source/code_examples/techmap/addshift_test.ys`` Notes on using techmap ~~~~~~~~~~~~~~~~~~~~~~ From b6e61c16b148c4441a97f31726f4f14c042dd511 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 14 Nov 2023 18:54:16 +1300 Subject: [PATCH 041/108] docs: restructuring images directory see also previous commit Also updates `scripting_intro.rst` to use literal includes, and uses individual image outputs to avoid the intermediary `.tex` file to join them all. --- docs/.gitignore | 5 +- docs/source/_images/011/example_out.tex | 18 ---- docs/source/_images/011/select_prod.tex | 19 ---- docs/source/_images/011/splitnets_libfile.tex | 15 ---- docs/source/_images/011/submod_dots.tex | 27 ------ docs/source/_images/Makefile | 82 +++++++----------- docs/source/_images/approach_flow.png | Bin 9709 -> 0 bytes docs/source/_images/basics_abstractions.png | Bin 29158 -> 0 bytes docs/source/_images/basics_ast.png | Bin 9478 -> 0 bytes docs/source/_images/basics_flow.png | Bin 12540 -> 0 bytes docs/source/_images/basics_parsetree.png | Bin 23196 -> 0 bytes .../_images/{ => internals}/approach_flow.tex | 0 .../_images/{ => internals}/overview_flow.tex | 0 .../{ => internals}/overview_rtlil.tex | 0 .../{ => internals}/simplified_rtlil.tex | 0 .../_images/{ => internals}/verilog_flow.tex | 0 docs/source/_images/overview_flow.png | Bin 17668 -> 0 bytes docs/source/_images/overview_rtlil.png | Bin 16034 -> 0 bytes .../{ => primer}/basics_abstractions.tex | 0 .../_images/{ => primer}/basics_ast.tex | 0 .../_images/{ => primer}/basics_flow.tex | 0 .../_images/{ => primer}/basics_parsetree.tex | 0 .../{ => primer}/levels_of_abstraction.tex | 0 docs/source/_images/verilog_flow.png | Bin 15934 -> 0 bytes docs/source/appendix/primer.rst | 8 +- docs/source/code_examples/intro/Makefile | 13 ++- docs/source/code_examples/macc/Makefile | 10 ++- .../code_examples/macc/macc_xilinx_test.ys | 22 ++--- docs/source/code_examples/scrambler/Makefile | 4 +- docs/source/code_examples/selections/Makefile | 18 ++-- docs/source/code_examples/show/Makefile | 6 +- docs/source/code_examples/show/example.ys | 5 -- docs/source/code_examples/stubnets/Makefile | 2 + docs/source/code_examples/synth_flow/Makefile | 15 ++-- docs/source/code_examples/techmap/Makefile | 5 +- .../getting_started/scripting_intro.rst | 40 ++++----- docs/source/introduction.rst | 2 +- .../interactive_investigation.rst | 24 ++--- .../using_yosys/more_scripting/selections.rst | 18 ++-- docs/source/yosys_internals/extensions.rst | 2 +- .../yosys_internals/flow/control_and_data.rst | 2 +- docs/source/yosys_internals/flow/overview.rst | 2 +- .../yosys_internals/flow/verilog_frontend.rst | 2 +- .../yosys_internals/formats/rtlil_rep.rst | 2 +- 44 files changed, 131 insertions(+), 237 deletions(-) delete mode 100644 docs/source/_images/011/example_out.tex delete mode 100644 docs/source/_images/011/select_prod.tex delete mode 100644 docs/source/_images/011/splitnets_libfile.tex delete mode 100644 docs/source/_images/011/submod_dots.tex delete mode 100644 docs/source/_images/approach_flow.png delete mode 100644 docs/source/_images/basics_abstractions.png delete mode 100644 docs/source/_images/basics_ast.png delete mode 100644 docs/source/_images/basics_flow.png delete mode 100644 docs/source/_images/basics_parsetree.png rename docs/source/_images/{ => internals}/approach_flow.tex (100%) rename docs/source/_images/{ => internals}/overview_flow.tex (100%) rename docs/source/_images/{ => internals}/overview_rtlil.tex (100%) rename docs/source/_images/{ => internals}/simplified_rtlil.tex (100%) rename docs/source/_images/{ => internals}/verilog_flow.tex (100%) delete mode 100644 docs/source/_images/overview_flow.png delete mode 100644 docs/source/_images/overview_rtlil.png rename docs/source/_images/{ => primer}/basics_abstractions.tex (100%) rename docs/source/_images/{ => primer}/basics_ast.tex (100%) rename docs/source/_images/{ => primer}/basics_flow.tex (100%) rename docs/source/_images/{ => primer}/basics_parsetree.tex (100%) rename docs/source/_images/{ => primer}/levels_of_abstraction.tex (100%) delete mode 100644 docs/source/_images/verilog_flow.png diff --git a/docs/.gitignore b/docs/.gitignore index 50f03d13c..d7bfd8e95 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,12 +1,9 @@ /build/ /source/cmd /source/temp -/source/_images/*.log -/source/_images/*.aux -/source/_images/*.pdf -/source/_images/*.svg /source/_images/**/*.log /source/_images/**/*.aux /source/_images/**/*.pdf /source/_images/**/*.svg /source/_images/**/*.dot +/source/_images/code_examples diff --git a/docs/source/_images/011/example_out.tex b/docs/source/_images/011/example_out.tex deleted file mode 100644 index 831b036e9..000000000 --- a/docs/source/_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/source/_images/011/select_prod.tex b/docs/source/_images/011/select_prod.tex deleted file mode 100644 index c4a3c6e37..000000000 --- a/docs/source/_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/source/_images/011/splitnets_libfile.tex b/docs/source/_images/011/splitnets_libfile.tex deleted file mode 100644 index 9669ef841..000000000 --- a/docs/source/_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/source/_images/011/submod_dots.tex b/docs/source/_images/011/submod_dots.tex deleted file mode 100644 index 3d48b46e5..000000000 --- a/docs/source/_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/source/_images/Makefile b/docs/source/_images/Makefile index f0a7795b6..955805f9c 100644 --- a/docs/source/_images/Makefile +++ b/docs/source/_images/Makefile @@ -1,62 +1,46 @@ -all: resources dots tex svg tidy +all: examples all_tex tidy -RES_LIST:= PRESENTATION_Intro/ PRESENTATION_ExSyn/ PRESENTATION_ExAdv/ PRESENTATION_ExOth/ -RES_DIRS:= $(addprefix ../../resources/,$(RES_LIST)) -.PHONY: resources -resources: $(RES_DIRS) +# 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: -../../resources/%: FORCE - @$(MAKE) -C $@ - @mkdir -p res/$* - @cp --update -t res/$* $@*.dot +../%/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="{}" -TEX_SOURCE:= $(wildcard *.tex) -DOT_LOC:= ../APPNOTE_011_Design_Investigation -DOT_SOURCE:= $(wildcard $(DOT_LOC)/*.dot) +# find and build all tex files +.PHONY: all_tex +TEX_FILES := $(wildcard **/*.tex) +all_tex: $(TEX_FILES:.tex=.pdf) $(TEX_FILES:.tex=.svg) -RES_DOTS:= $(wildcard res/*/*.dot) -RES_DIRS:= $(sort $(dir $(RES_DOTS))) -RES_PDF:= $(RES_DOTS:%.dot=%.pdf) - -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) $(RES_PDF)) - -dots: $(DOT_PDF) $(RES_PDF) -tex: $(TEX_PDF) -svg: $(SVG_OUTPUT) - -011/%.pdf: $(DOT_LOC)/%.dot - TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< - -res/%.pdf: res/%.dot - TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< - -011/%.pdf: 011/%.tex - cd 011 && TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' pdflatex $(<F) --interaction=nonstopmode +%.pdf: %.dot + $(FAKETIME) dot -Tpdf -o $@ $< %.pdf: %.tex - pdflatex $< --interaction=nonstopmode + cd $(@D) && $(FAKETIME) pdflatex $(<F) --interaction=nonstopmode %.svg: %.pdf pdf2svg $< $@ .PHONY: clean tidy tidy: - rm -f *.log - rm -f *.aux - rm -f 011/*.log 011/*.aux + rm -f **/*.log **/*.aux + clean: tidy - rm -f *.pdf - rm -f *.svg - rm -f 011/*.pdf 011/*.svg - rm -rf $(RES_DIRS) + rm -rf code_examples + rm -f **/*.pdf **/*.svg diff --git a/docs/source/_images/approach_flow.png b/docs/source/_images/approach_flow.png deleted file mode 100644 index a5fc53b08aa5f84ae7a5126ff11df1a5f351814e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9709 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 JDs_j5{{iZXWUc@J diff --git a/docs/source/_images/basics_abstractions.png b/docs/source/_images/basics_abstractions.png deleted file mode 100644 index a735fbd3b5e03065def0ea9aa54ab543ee8f2691..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29158 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 W6;nPo4tsy&J6TC3i7GLppZ^P;t#1(k diff --git a/docs/source/_images/basics_ast.png b/docs/source/_images/basics_ast.png deleted file mode 100644 index c2d95c844a93b0284ca934d1716d44d1d42f7cba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9478 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 diff --git a/docs/source/_images/basics_flow.png b/docs/source/_images/basics_flow.png deleted file mode 100644 index a027b5eac3e37db661962a9827dd67212bbcb665..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12540 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 diff --git a/docs/source/_images/basics_parsetree.png b/docs/source/_images/basics_parsetree.png deleted file mode 100644 index ff7a17e2bd2f55c2a53bcc0567f44ca640fccca0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23196 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 S?SN7Gg1(NScA4h$cmD$=#RHW9 diff --git a/docs/source/_images/approach_flow.tex b/docs/source/_images/internals/approach_flow.tex similarity index 100% rename from docs/source/_images/approach_flow.tex rename to docs/source/_images/internals/approach_flow.tex diff --git a/docs/source/_images/overview_flow.tex b/docs/source/_images/internals/overview_flow.tex similarity index 100% rename from docs/source/_images/overview_flow.tex rename to docs/source/_images/internals/overview_flow.tex diff --git a/docs/source/_images/overview_rtlil.tex b/docs/source/_images/internals/overview_rtlil.tex similarity index 100% rename from docs/source/_images/overview_rtlil.tex rename to docs/source/_images/internals/overview_rtlil.tex diff --git a/docs/source/_images/simplified_rtlil.tex b/docs/source/_images/internals/simplified_rtlil.tex similarity index 100% rename from docs/source/_images/simplified_rtlil.tex rename to docs/source/_images/internals/simplified_rtlil.tex diff --git a/docs/source/_images/verilog_flow.tex b/docs/source/_images/internals/verilog_flow.tex similarity index 100% rename from docs/source/_images/verilog_flow.tex rename to docs/source/_images/internals/verilog_flow.tex diff --git a/docs/source/_images/overview_flow.png b/docs/source/_images/overview_flow.png deleted file mode 100644 index c1b13a000b6e20751cb7a59bb0958f15fa2ccbff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17668 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 diff --git a/docs/source/_images/overview_rtlil.png b/docs/source/_images/overview_rtlil.png deleted file mode 100644 index f79c667e8b4c4c043bca4085c02dd6292dd3dc03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16034 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 diff --git a/docs/source/_images/basics_abstractions.tex b/docs/source/_images/primer/basics_abstractions.tex similarity index 100% rename from docs/source/_images/basics_abstractions.tex rename to docs/source/_images/primer/basics_abstractions.tex diff --git a/docs/source/_images/basics_ast.tex b/docs/source/_images/primer/basics_ast.tex similarity index 100% rename from docs/source/_images/basics_ast.tex rename to docs/source/_images/primer/basics_ast.tex diff --git a/docs/source/_images/basics_flow.tex b/docs/source/_images/primer/basics_flow.tex similarity index 100% rename from docs/source/_images/basics_flow.tex rename to docs/source/_images/primer/basics_flow.tex diff --git a/docs/source/_images/basics_parsetree.tex b/docs/source/_images/primer/basics_parsetree.tex similarity index 100% rename from docs/source/_images/basics_parsetree.tex rename to docs/source/_images/primer/basics_parsetree.tex diff --git a/docs/source/_images/levels_of_abstraction.tex b/docs/source/_images/primer/levels_of_abstraction.tex similarity index 100% rename from docs/source/_images/levels_of_abstraction.tex rename to docs/source/_images/primer/levels_of_abstraction.tex diff --git a/docs/source/_images/verilog_flow.png b/docs/source/_images/verilog_flow.png deleted file mode 100644 index 1f3d82780f34c2682013eda28b36a05fc27d940e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15934 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 G`2PUd9DMKq diff --git a/docs/source/appendix/primer.rst b/docs/source/appendix/primer.rst index 9a905c6f2..b8c3e5ae7 100644 --- a/docs/source/appendix/primer.rst +++ b/docs/source/appendix/primer.rst @@ -23,7 +23,7 @@ circuit to a functionally equivalent low-level representation of a circuit. :numref:`Figure %s <fig:Basics_abstractions>` 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 @@ -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 <fig:Basics_flow>`. -.. figure:: /_images/basics_flow.* +.. figure:: /_images/primer/basics_flow.* :class: width-helper :name: fig:Basics_flow @@ -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 @@ -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/code_examples/intro/Makefile b/docs/source/code_examples/intro/Makefile index 2c5fdcf4c..3b7bbfe7f 100644 --- a/docs/source/code_examples/intro/Makefile +++ b/docs/source/code_examples/intro/Makefile @@ -1,13 +1,10 @@ PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -all: counter_00.dot counter_01.dot counter_02.dot counter_03.dot +DOTS = counter_00.dot counter_01.dot counter_02.dot counter_03.dot -counter_00.dot: counter.v counter.ys mycells.lib +dots: $(DOTS) + +$(DOTS): counter.v counter.ys mycells.lib $(YOSYS) counter_outputs.ys - -counter_01.dot: counter_00.dot -counter_02.dot: counter_00.dot -counter_03.dot: counter_00.dot - diff --git a/docs/source/code_examples/macc/Makefile b/docs/source/code_examples/macc/Makefile index 91ec83288..27b8166f8 100644 --- a/docs/source/code_examples/macc/Makefile +++ b/docs/source/code_examples/macc/Makefile @@ -1,12 +1,14 @@ PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -all: macc_simple_xmap.pdf macc_xilinx_xmap.pdf +DOTS = macc_simple_xmap.dot macc_xilinx_xmap.dot -macc_simple_xmap.pdf: macc_simple_*.v macc_simple_test.ys +dots: $(DOTS) + +macc_simple_xmap.dot: macc_simple_*.v macc_simple_test.ys $(YOSYS) macc_simple_test.ys -macc_xilinx_xmap.pdf: macc_xilinx_*.v macc_xilinx_test.ys +macc_xilinx_xmap.dot: macc_xilinx_*.v macc_xilinx_test.ys $(YOSYS) macc_xilinx_test.ys diff --git a/docs/source/code_examples/macc/macc_xilinx_test.ys b/docs/source/code_examples/macc/macc_xilinx_test.ys index f3e8af4f0..6e91a04ff 100644 --- a/docs/source/code_examples/macc/macc_xilinx_test.ys +++ b/docs/source/code_examples/macc/macc_xilinx_test.ys @@ -3,21 +3,21 @@ 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 +show -prefix macc_xilinx_test1a -format dot -notitle test1 +show -prefix macc_xilinx_test2a -format dot -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 +show -prefix macc_xilinx_test1b -format dot -notitle test1 +show -prefix macc_xilinx_test2b -format dot -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 +show -prefix macc_xilinx_test1c -format dot -notitle test1 +show -prefix macc_xilinx_test2c -format dot -notitle test2 design -push read_verilog macc_xilinx_xmap.v @@ -30,14 +30,14 @@ 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 +show -prefix macc_xilinx_test1d -format dot -notitle test1 +show -prefix macc_xilinx_test2d -format dot -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 +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 pdf -notitle +show -prefix macc_xilinx_xmap -format dot -notitle diff --git a/docs/source/code_examples/scrambler/Makefile b/docs/source/code_examples/scrambler/Makefile index 1e9425558..e1b1d2979 100644 --- a/docs/source/code_examples/scrambler/Makefile +++ b/docs/source/code_examples/scrambler/Makefile @@ -1,8 +1,8 @@ PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -all: scrambler_p01.dot scrambler_p02.dot +dots: scrambler_p01.dot scrambler_p02.dot scrambler_p01.dot scrambler_p02.dot: scrambler.ys scrambler.v $(YOSYS) scrambler.ys diff --git a/docs/source/code_examples/selections/Makefile b/docs/source/code_examples/selections/Makefile index 384ce12a9..0ec85bb20 100644 --- a/docs/source/code_examples/selections/Makefile +++ b/docs/source/code_examples/selections/Makefile @@ -11,22 +11,22 @@ MEMDEMO_DOTS := $(addsuffix .dot,$(MEMDEMO)) SUBMOD = submod_00 submod_01 submod_02 submod_03 SUBMOD_DOTS := $(addsuffix .dot,$(SUBMOD)) -all: select.dot $(SUMPROD_DOTS) $(MEMDEMO_DOTS) +dots: select.dot $(SUMPROD_DOTS) $(MEMDEMO_DOTS) $(SUBMOD_DOTS) select.dot: select.v select.ys $(YOSYS) select.ys $(SUMPROD_DOTS): sumprod.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 'read_verilog sumprod.v; opt; cd sumprod; select a:sumstuff; show -format dot -prefix sumprod_00' + $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select a:sumstuff %x; show -format dot -prefix sumprod_01' + $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod; show -format dot -prefix sumprod_02' + $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod %ci; show -format dot -prefix sumprod_03' + $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod %ci2; show -format dot -prefix sumprod_04' + $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod %ci3; show -format dot -prefix sumprod_05' $(MEMDEMO_DOTS): memdemo.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) -p 'read_verilog memdemo.v; proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_00' + $(YOSYS) -p 'read_verilog memdemo.v; proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_01 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff' $(SUBMOD_DOTS): submod.ys memdemo.v $(YOSYS) submod.ys diff --git a/docs/source/code_examples/show/Makefile b/docs/source/code_examples/show/Makefile index 9cc4fc58d..18da74d6a 100644 --- a/docs/source/code_examples/show/Makefile +++ b/docs/source/code_examples/show/Makefile @@ -2,16 +2,16 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -EXAMPLE = example_00 example_01 example_02 example_03 +EXAMPLE = example_00 example_01 example_02 EXAMPLE_DOTS := $(addsuffix .dot,$(EXAMPLE)) CMOS = cmos_00 cmos_01 CMOS_DOTS := $(addsuffix .dot,$(CMOS)) -all: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) +dots: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) splice.dot: splice.v - $(YOSYS) -p 'proc; opt; show -format dot -prefix splice' splice.v + $(YOSYS) -p 'read_verilog splice.v; proc; opt; show -format dot -prefix splice' $(EXAMPLE_DOTS): example.v example.ys $(YOSYS) example.ys diff --git a/docs/source/code_examples/show/example.ys b/docs/source/code_examples/show/example.ys index b1e956088..6c9ff7983 100644 --- a/docs/source/code_examples/show/example.ys +++ b/docs/source/code_examples/show/example.ys @@ -4,8 +4,3 @@ 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/code_examples/stubnets/Makefile b/docs/source/code_examples/stubnets/Makefile index 8e326bdc2..cbcd71113 100644 --- a/docs/source/code_examples/stubnets/Makefile +++ b/docs/source/code_examples/stubnets/Makefile @@ -1,3 +1,5 @@ +dots: + 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" diff --git a/docs/source/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index a9015e8d5..25763ef03 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -7,18 +7,15 @@ TARGETS += abc_01 PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -all: $(addsuffix .pdf,$(TARGETS)) +DOTS = $(addsuffix .dot,$(TARGETS)) -define make_pdf_template -$(1).pdf: $(1)*.v $(1)*.ys - $(YOSYS) -p 'script $(1).ys; show -notitle -prefix $(1) -format pdf' -endef +dots: $(DOTS) -$(foreach trg,$(TARGETS),$(eval $(call make_pdf_template,$(trg)))) +%.dot: %.v %.ys + $(YOSYS) -p 'script $*.ys; show -notitle -prefix $* -format dot' clean: - rm -f $(addsuffix .pdf,$(TARGETS)) - rm -f $(addsuffix .dot,$(TARGETS)) + rm -f $(DOTS) diff --git a/docs/source/code_examples/techmap/Makefile b/docs/source/code_examples/techmap/Makefile index b48972fd9..531fab085 100644 --- a/docs/source/code_examples/techmap/Makefile +++ b/docs/source/code_examples/techmap/Makefile @@ -1,8 +1,8 @@ PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -all: red_or3x1.dot sym_mul.dot mymul.dot mulshift.dot addshift.dot +dots: red_or3x1.dot sym_mul.dot mymul.dot mulshift.dot addshift.dot red_or3x1.dot: red_or3x1_* $(YOSYS) red_or3x1_test.ys @@ -18,4 +18,3 @@ mulshift.dot: mulshift_* addshift.dot: addshift_* $(YOSYS) addshift_test.ys - diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 35015ceb9..d5877917c 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -128,31 +128,31 @@ different stages of the yosys tool flow. .. _xdot: https://github.com/jrfonseca/xdot.py -.. code-block:: console - :caption: Yosys script with :cmd:ref:`show` commands and example design - :name: show_src +.. literalinclude:: /code_examples/show/example.ys + :language: yoscrypt + :caption: docs/source/code_examples/show/example.ys - $ cat example.ys - read_verilog example.v - show -pause - proc - show -pause - opt - show -pause +.. literalinclude:: /code_examples/show/example.v + :language: Verilog + :caption: docs/source/code_examples/show/example.v - $ 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 +.. role:: yoscrypt(code) + :language: yoscrypt -.. figure:: /_images/011/example_out.* +.. figure:: /_images/code_examples/show/example_00.* :class: width-helper - :name: show_out - Output of the three :cmd:ref:`show` commands from :numref:`show_src` + ``example_00`` - shown after :yoscrypt:`read_verilog example.v` + +.. figure:: /_images/code_examples/show/example_01.* + :class: width-helper + + ``example_01`` - shown after :yoscrypt:`proc` + +.. figure:: /_images/code_examples/show/example_02.* + :class: width-helper + + ``example_02`` - shown after :yoscrypt:`opt` A circuit diagram is generated for the design in its current state. Various options can be used to change the appearance of the circuit diagram, set the diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 62c76584d..727426fa8 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -37,7 +37,7 @@ 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/levels_of_abstraction.* +.. figure:: /_images/primer/levels_of_abstraction.* :class: width-helper :name: fig:Levels_of_abstraction diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index a16d3cd57..5b312d4e1 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -45,7 +45,7 @@ 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. -.. figure:: /_images/011/example_00.* +.. figure:: /_images/code_examples/show/example_00.* :class: width-helper Output of the first :cmd:ref:`show` command in :numref:`example_ys` @@ -77,7 +77,7 @@ original ``always``-block in the second line. Note how the multiplexer from the 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/011/example_01.* +.. figure:: /_images/code_examples/show/example_01.* :class: width-helper Output of the second :cmd:ref:`show` command in :numref:`example_ys` @@ -99,7 +99,7 @@ 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/011/example_02.* +.. figure:: /_images/code_examples/show/example_02.* :class: width-helper :name: example_out @@ -126,7 +126,7 @@ 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/011/splice.* +.. figure:: /_images/code_examples/show/splice.* :class: width-helper :name: splice_dia @@ -154,7 +154,7 @@ Gate level netlists :numref:`first_pitfall` shows two common pitfalls when working with designs mapped to a cell library: -.. figure:: /_images/011/cmos_00.* +.. figure:: /_images/code_examples/show/cmos_00.* :class: width-helper :name: first_pitfall @@ -167,7 +167,7 @@ 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/011/cmos_01.* +.. figure:: /_images/code_examples/show/cmos_01.* :class: width-helper :name: second_pitfall @@ -350,10 +350,10 @@ reorganizing a module in Yosys and checking the resulting circuit. :caption: ``docs/source/code_examples/scrambler/scrambler.ys`` :end-before: cd .. -.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p01.* +.. figure:: /_images/code_examples/scrambler/scrambler_p01.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExOth/scrambler_p02.* +.. figure:: /_images/code_examples/scrambler/scrambler_p02.* :class: width-helper Analyzing the resulting circuit with :doc:`/cmd/eval`: @@ -430,7 +430,7 @@ if the circuit under investigation is encapsulated in a separate module. Recall the ``memdemo`` design from :ref:`advanced_logic_cones`: -.. figure:: /_images/011/memdemo_00.* +.. figure:: /_images/code_examples/selections/memdemo_00.* :class: width-helper ``memdemo`` @@ -451,18 +451,18 @@ 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/011/submod_02.* +.. figure:: /_images/code_examples/selections/submod_02.* :class: width-helper ``outstage`` -.. figure:: /_images/011/submod_03.* +.. figure:: /_images/code_examples/selections/submod_03.* :class: width-helper :name: selstage ``selstage`` -.. figure:: /_images/011/submod_01.* +.. figure:: /_images/code_examples/selections/submod_01.* :class: width-helper ``scramble`` diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index b0fcb7b18..879ceb7e8 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -154,7 +154,7 @@ to mark portions of code for analysis.) Selecting ``a:sumstuff`` in this module will yield the following circuit diagram: -.. figure:: /_images/011/sumprod_00.* +.. figure:: /_images/code_examples/selections/sumprod_00.* :class: width-helper :name: sumprod_00 @@ -171,7 +171,7 @@ 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/011/sumprod_01.* +.. figure:: /_images/code_examples/selections/sumprod_01.* :class: width-helper :name: sumprod_01 @@ -192,22 +192,22 @@ input ports. The following sequence of diagrams demonstrates this step-wise expansion: -.. figure:: /_images/011/sumprod_02.* +.. figure:: /_images/code_examples/selections/sumprod_02.* :class: width-helper Output of ``show prod`` on :numref:`sumprod` -.. figure:: /_images/011/sumprod_03.* +.. figure:: /_images/code_examples/selections/sumprod_03.* :class: width-helper Output of ``show prod %ci`` on :numref:`sumprod` -.. figure:: /_images/011/sumprod_04.* +.. figure:: /_images/code_examples/selections/sumprod_04.* :class: width-helper Output of ``show prod %ci %ci`` on :numref:`sumprod` -.. figure:: /_images/011/sumprod_05.* +.. figure:: /_images/code_examples/selections/sumprod_05.* :class: width-helper Output of ``show prod %ci %ci %ci`` on :numref:`sumprod` @@ -242,7 +242,7 @@ We synthesize the circuit using ``proc; opt; memory; opt`` and change to the ``memdemo`` module with ``cd memdemo``. If we type :cmd:ref:`show` now we see the diagram shown in :numref:`memdemo_00`. -.. figure:: /_images/011/memdemo_00.* +.. figure:: /_images/code_examples/selections/memdemo_00.* :class: width-helper :name: memdemo_00 @@ -287,7 +287,7 @@ Or we could decide to tell the ``%ci`` action to not follow the ``CLK`` input: show y %ci2:-[CLK] -.. figure:: /_images/011/memdemo_01.* +.. figure:: /_images/code_examples/selections/memdemo_01.* :class: width-helper :name: memdemo_01 @@ -379,7 +379,7 @@ Example: :caption: ``docs/source/code_examples/selections/select.ys`` :name: select_ys -.. figure:: /_images/res/PRESENTATION_ExAdv/select.* +.. figure:: /_images/code_examples/selections/select.* :class: width-helper Circuit diagram produced by :numref:`select_ys` diff --git a/docs/source/yosys_internals/extensions.rst b/docs/source/yosys_internals/extensions.rst index 06ab9a820..4eaf41def 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extensions.rst @@ -58,7 +58,7 @@ provides. This document will focus on the much simpler version of RTLIL left after the commands :cmd:ref:`proc` and :cmd:ref:`memory` (or ``memory -nomap``): -.. figure:: /_images/simplified_rtlil.* +.. figure:: /_images/internals/simplified_rtlil.* :class: width-helper :name: fig:Simplified_RTLIL diff --git a/docs/source/yosys_internals/flow/control_and_data.rst b/docs/source/yosys_internals/flow/control_and_data.rst index b2ec418ad..5dcbe0730 100644 --- a/docs/source/yosys_internals/flow/control_and_data.rst +++ b/docs/source/yosys_internals/flow/control_and_data.rst @@ -9,7 +9,7 @@ a predetermined order, each consuming the data generated by the last subsystem and generating the data for the next subsystem (see :numref:`Fig. %s <fig:approach_flow>`). -.. figure:: /_images/approach_flow.* +.. figure:: /_images/internals/approach_flow.* :class: width-helper :name: fig:approach_flow diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst index 1c2adc01c..08ead2570 100644 --- a/docs/source/yosys_internals/flow/overview.rst +++ b/docs/source/yosys_internals/flow/overview.rst @@ -40,7 +40,7 @@ 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.* +.. figure:: /_images/internals/overview_flow.* :class: width-helper :name: fig:Overview_flow diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index 72907c121..6a0389f20 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -9,7 +9,7 @@ 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 <fig:Verilog_flow>`. -.. figure:: /_images/verilog_flow.* +.. figure:: /_images/internals/verilog_flow.* :class: width-helper :name: fig:Verilog_flow diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index b6b437b90..aefa11496 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -23,7 +23,7 @@ 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.* +.. figure:: /_images/internals/overview_rtlil.* :class: width-helper :name: fig:Overview_RTLIL From 2b270b227010b95841527d8452155a54a453f950 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 15 Nov 2023 17:39:37 +1300 Subject: [PATCH 042/108] docs: Tidying image generation Makefiles now have `clean` target. Also fixed top level makefile calls to images directory. More yosys scripts instead of inline yosys commands in makefiles (which also means they can be included in the accompanying document when talking about the image generated). Fixed another couple image generators that were still outputting pdf directly. Fixed some hanging image references which hadn't been updated. Adjusted some text related to images, and included a couple more intermediate images on `memdemo`. --- Makefile | 1 - docs/source/code_examples/intro/Makefile | 6 +- docs/source/code_examples/macc/Makefile | 4 + .../code_examples/macc/macc_simple_test.ys | 14 +-- docs/source/code_examples/scrambler/Makefile | 4 + docs/source/code_examples/selections/Makefile | 20 ++-- .../code_examples/selections/memdemo.ys | 9 ++ .../source/code_examples/selections/select.ys | 4 +- .../source/code_examples/selections/submod.ys | 2 +- .../code_examples/selections/sumprod.ys | 10 ++ docs/source/code_examples/show/Makefile | 11 +- docs/source/code_examples/show/cmos.ys | 17 +++ docs/source/code_examples/synth_flow/Makefile | 3 +- docs/source/code_examples/techmap/Makefile | 4 + docs/source/getting_started/examples.rst | 8 +- .../source/getting_started/typical_phases.rst | 24 ++-- .../interactive_investigation.rst | 18 ++- .../using_yosys/more_scripting/selections.rst | 106 ++++++++++-------- docs/source/using_yosys/yosys_flows.rst | 40 +++---- docs/source/yosys_internals/techmap.rst | 10 +- 20 files changed, 197 insertions(+), 118 deletions(-) create mode 100644 docs/source/code_examples/selections/memdemo.ys create mode 100644 docs/source/code_examples/selections/sumprod.ys create mode 100644 docs/source/code_examples/show/cmos.ys diff --git a/Makefile b/Makefile index 8418aefde..0b8cb96dd 100644 --- a/Makefile +++ b/Makefile @@ -971,7 +971,6 @@ docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS) PHONY: docs/gen_images docs/guidelines docs/usage docs/gen_images: - $(Q) $(MAKE) -C docs/source/_images resources $(Q) $(MAKE) -C docs/source/_images all DOCS_GUIDELINE_FILES := GettingStarted CodingStyle diff --git a/docs/source/code_examples/intro/Makefile b/docs/source/code_examples/intro/Makefile index 3b7bbfe7f..c7507e934 100644 --- a/docs/source/code_examples/intro/Makefile +++ b/docs/source/code_examples/intro/Makefile @@ -6,5 +6,9 @@ DOTS = counter_00.dot counter_01.dot counter_02.dot counter_03.dot dots: $(DOTS) -$(DOTS): counter.v counter.ys mycells.lib +$(DOTS): counter.v counter_outputs.ys mycells.lib $(YOSYS) counter_outputs.ys + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/code_examples/macc/Makefile b/docs/source/code_examples/macc/Makefile index 27b8166f8..57ba455bb 100644 --- a/docs/source/code_examples/macc/Makefile +++ b/docs/source/code_examples/macc/Makefile @@ -12,3 +12,7 @@ macc_simple_xmap.dot: macc_simple_*.v 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/docs/source/code_examples/macc/macc_simple_test.ys b/docs/source/code_examples/macc/macc_simple_test.ys index 8d106a28c..70496c057 100644 --- a/docs/source/code_examples/macc/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/docs/source/code_examples/scrambler/Makefile b/docs/source/code_examples/scrambler/Makefile index e1b1d2979..4fdb0610a 100644 --- a/docs/source/code_examples/scrambler/Makefile +++ b/docs/source/code_examples/scrambler/Makefile @@ -6,3 +6,7 @@ dots: scrambler_p01.dot scrambler_p02.dot scrambler_p01.dot scrambler_p02.dot: scrambler.ys scrambler.v $(YOSYS) scrambler.ys + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/code_examples/selections/Makefile b/docs/source/code_examples/selections/Makefile index 0ec85bb20..06abd2a3e 100644 --- a/docs/source/code_examples/selections/Makefile +++ b/docs/source/code_examples/selections/Makefile @@ -16,17 +16,15 @@ dots: select.dot $(SUMPROD_DOTS) $(MEMDEMO_DOTS) $(SUBMOD_DOTS) select.dot: select.v select.ys $(YOSYS) select.ys -$(SUMPROD_DOTS): sumprod.v - $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select a:sumstuff; show -format dot -prefix sumprod_00' - $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select a:sumstuff %x; show -format dot -prefix sumprod_01' - $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod; show -format dot -prefix sumprod_02' - $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod %ci; show -format dot -prefix sumprod_03' - $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod %ci2; show -format dot -prefix sumprod_04' - $(YOSYS) -p 'read_verilog sumprod.v; opt; cd sumprod; select prod %ci3; show -format dot -prefix sumprod_05' +$(SUMPROD_DOTS): sumprod.v sumprod.ys + $(YOSYS) sumprod.ys -$(MEMDEMO_DOTS): memdemo.v - $(YOSYS) -p 'read_verilog memdemo.v; proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_00' - $(YOSYS) -p 'read_verilog memdemo.v; proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_01 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff' +$(MEMDEMO_DOTS): memdemo.v memdemo.ys + $(YOSYS) memdemo.ys -$(SUBMOD_DOTS): submod.ys memdemo.v +$(SUBMOD_DOTS): memdemo.v submod.ys $(YOSYS) submod.ys + +.PHONY: clean +clean: + rm -rf *.dot diff --git a/docs/source/code_examples/selections/memdemo.ys b/docs/source/code_examples/selections/memdemo.ys new file mode 100644 index 000000000..e240f1621 --- /dev/null +++ b/docs/source/code_examples/selections/memdemo.ys @@ -0,0 +1,9 @@ +read_verilog memdemo.v +prep -top memdemo; memory; opt + +cd memdemo +show -format dot -prefix memdemo_00 +show -format dot -prefix memdemo_01 y %ci2 +show -format dot -prefix memdemo_02 y %ci2:+$dff[Q,D] +show -format dot -prefix memdemo_03 y %ci2:-[CLK] %ci2 +show -format dot -prefix memdemo_04 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff diff --git a/docs/source/code_examples/selections/select.ys b/docs/source/code_examples/selections/select.ys index 565ce90a3..e9a775f1f 100644 --- a/docs/source/code_examples/selections/select.ys +++ b/docs/source/code_examples/selections/select.ys @@ -1,6 +1,6 @@ read_verilog select.v -hierarchy -check -top test -proc; opt +prep -top test + cd test select -set cone_a state_a %ci*:-$dff select -set cone_b state_b %ci*:-$dff diff --git a/docs/source/code_examples/selections/submod.ys b/docs/source/code_examples/selections/submod.ys index 29ad61076..c252153c6 100644 --- a/docs/source/code_examples/selections/submod.ys +++ b/docs/source/code_examples/selections/submod.ys @@ -1,5 +1,5 @@ read_verilog memdemo.v -proc; opt; memory; opt +prep -top memdemo; memory; opt cd memdemo select -set outstage y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff diff --git a/docs/source/code_examples/selections/sumprod.ys b/docs/source/code_examples/selections/sumprod.ys new file mode 100644 index 000000000..1e687fa4e --- /dev/null +++ b/docs/source/code_examples/selections/sumprod.ys @@ -0,0 +1,10 @@ +read_verilog sumprod.v +prep -top sumprod +cd sumprod + +show -format dot -prefix sumprod_00 a:sumstuff +show -format dot -prefix sumprod_01 a:sumstuff %x +show -format dot -prefix sumprod_02 prod +show -format dot -prefix sumprod_03 prod %ci +show -format dot -prefix sumprod_04 prod %ci2 +show -format dot -prefix sumprod_05 prod %ci3 diff --git a/docs/source/code_examples/show/Makefile b/docs/source/code_examples/show/Makefile index 18da74d6a..c57012f92 100644 --- a/docs/source/code_examples/show/Makefile +++ b/docs/source/code_examples/show/Makefile @@ -11,13 +11,14 @@ CMOS_DOTS := $(addsuffix .dot,$(CMOS)) dots: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) splice.dot: splice.v - $(YOSYS) -p 'read_verilog splice.v; proc; opt; show -format dot -prefix splice' + $(YOSYS) -p 'prep -top splice_demo; show -format dot -prefix splice' splice.v $(EXAMPLE_DOTS): example.v example.ys $(YOSYS) example.ys -cmos_00.dot: cmos.v - $(YOSYS) -p 'read_verilog cmos.v; techmap; abc -liberty ../intro/mycells.lib;; show -format dot -prefix cmos_00' +$(CMOS_DOTS): cmos.v cmos.ys + $(YOSYS) cmos.ys -cmos_01.dot: cmos.v - $(YOSYS) -p 'read_verilog cmos.v; techmap; splitnets -ports; abc -liberty ../intro/mycells.lib;; show -lib ../intro/mycells.v -format dot -prefix cmos_01' +.PHONY: clean +clean: + rm -rf *.dot diff --git a/docs/source/code_examples/show/cmos.ys b/docs/source/code_examples/show/cmos.ys new file mode 100644 index 000000000..7158de1d0 --- /dev/null +++ b/docs/source/code_examples/show/cmos.ys @@ -0,0 +1,17 @@ +# pitfall +read_verilog cmos.v +prep -top cmos_demo +techmap +abc -liberty ../intro/mycells.lib;; +show -format dot -prefix cmos_00 + +# reset +design -reset + +# fixed output +read_verilog cmos.v +prep -top cmos_demo +techmap +splitnets -ports +abc -liberty ../intro/mycells.lib;; +show -lib ../intro/mycells.v -format dot -prefix cmos_01 diff --git a/docs/source/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index 25763ef03..804f6da37 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -16,6 +16,7 @@ dots: $(DOTS) %.dot: %.v %.ys $(YOSYS) -p 'script $*.ys; show -notitle -prefix $* -format dot' +.PHONY: clean clean: - rm -f $(DOTS) + rm -f *.dot diff --git a/docs/source/code_examples/techmap/Makefile b/docs/source/code_examples/techmap/Makefile index 531fab085..e4e0ac745 100644 --- a/docs/source/code_examples/techmap/Makefile +++ b/docs/source/code_examples/techmap/Makefile @@ -18,3 +18,7 @@ mulshift.dot: mulshift_* addshift.dot: addshift_* $(YOSYS) addshift_test.ys + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/getting_started/examples.rst b/docs/source/getting_started/examples.rst index 8fecb4985..5e1b0e429 100644 --- a/docs/source/getting_started/examples.rst +++ b/docs/source/getting_started/examples.rst @@ -106,7 +106,7 @@ Step 1 Result: -.. figure:: /_images/res/PRESENTATION_Intro/counter_00.* +.. figure:: /_images/code_examples/intro/counter_00.* :class: width-helper Step 2 @@ -118,7 +118,7 @@ Step 2 Result: -.. figure:: /_images/res/PRESENTATION_Intro/counter_01.* +.. figure:: /_images/code_examples/intro/counter_01.* :class: width-helper Step 3 @@ -130,7 +130,7 @@ Step 3 Result: -.. figure:: /_images/res/PRESENTATION_Intro/counter_02.* +.. figure:: /_images/code_examples/intro/counter_02.* :class: width-helper Step 4 @@ -142,5 +142,5 @@ Step 4 Result: -.. figure:: /_images/res/PRESENTATION_Intro/counter_03.* +.. figure:: /_images/code_examples/intro/counter_03.* :class: width-helper diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index d04419ec1..2fce9215c 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -94,10 +94,10 @@ Example :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/proc_01.ys`` -.. figure:: /_images/res/PRESENTATION_ExSyn/proc_01.* +.. figure:: /_images/code_examples/synth_flow/proc_01.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExSyn/proc_02.* +.. figure:: /_images/code_examples/synth_flow/proc_02.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/proc_02.v @@ -108,7 +108,7 @@ Example :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/proc_02.ys`` -.. figure:: /_images/res/PRESENTATION_ExSyn/proc_03.* +.. figure:: /_images/code_examples/synth_flow/proc_03.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/proc_03.ys @@ -145,12 +145,12 @@ The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And .. code-block:: yoscrypt - proc; opt; memory; opt_expr;; fsm;; + hierarchy; proc; opt; memory; opt_expr;; fsm;; Example ^^^^^^^ -.. figure:: /_images/res/PRESENTATION_ExSyn/opt_01.* +.. figure:: /_images/code_examples/synth_flow/opt_01.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_01.ys @@ -161,7 +161,7 @@ Example :language: verilog :caption: ``docs/source/code_examples/synth_flow/opt_01.v`` -.. figure:: /_images/res/PRESENTATION_ExSyn/opt_02.* +.. figure:: /_images/code_examples/synth_flow/opt_02.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_02.ys @@ -172,7 +172,7 @@ Example :language: verilog :caption: ``docs/source/code_examples/synth_flow/opt_02.v`` -.. figure:: /_images/res/PRESENTATION_ExSyn/opt_03.* +.. figure:: /_images/code_examples/synth_flow/opt_03.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_03.ys @@ -183,7 +183,7 @@ Example :language: verilog :caption: ``docs/source/code_examples/synth_flow/opt_03.v`` -.. figure:: /_images/res/PRESENTATION_ExSyn/opt_04.* +.. figure:: /_images/code_examples/synth_flow/opt_04.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_04.v @@ -246,7 +246,7 @@ For example: Example ^^^^^^^ -.. figure:: /_images/res/PRESENTATION_ExSyn/memory_01.* +.. figure:: /_images/code_examples/synth_flow/memory_01.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/memory_01.ys @@ -257,7 +257,7 @@ Example :language: verilog :caption: ``docs/source/code_examples/synth_flow/memory_01.v`` -.. figure:: /_images/res/PRESENTATION_ExSyn/memory_02.* +.. figure:: /_images/code_examples/synth_flow/memory_02.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/memory_02.v @@ -315,7 +315,7 @@ Finally the :cmd:ref:`fsm_map` command can be used to convert the (optimized) The :cmd:ref:`techmap` command ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. figure:: /_images/res/PRESENTATION_ExSyn/techmap_01.* +.. figure:: /_images/code_examples/synth_flow/techmap_01.* :class: width-helper The :cmd:ref:`techmap` command replaces cells with implementations given as @@ -386,7 +386,7 @@ Example :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/abc_01.ys`` -.. figure:: /_images/res/PRESENTATION_ExSyn/abc_01.* +.. figure:: /_images/code_examples/synth_flow/abc_01.* :class: width-helper Other special-purpose mapping commands diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index 5b312d4e1..fe78c66c5 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -130,7 +130,7 @@ when the individual bits of of a signal vector are accessed. :class: width-helper :name: splice_dia - Output of ``yosys -p 'proc; opt; show' splice.v`` + 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 ``<MSB_LEFT>:<LSB_LEFT> - @@ -152,7 +152,7 @@ Gate level netlists ^^^^^^^^^^^^^^^^^^^ :numref:`first_pitfall` shows two common pitfalls when working with designs -mapped to a cell library: +mapped to a cell library: .. figure:: /_images/code_examples/show/cmos_00.* :class: width-helper @@ -160,6 +160,13 @@ mapped to a cell library: 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 @@ -174,6 +181,13 @@ individual bits, resulting in an unnecessary complex diagram. 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 diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 879ceb7e8..eb3f66d6c 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -177,6 +177,8 @@ selected wire it selects all cells connected to the wire and vice versa. So Output of ``show a:sumstuff %x`` on :numref:`sumprod` +.. _selecting_logic_cones: + Selecting logic cones ^^^^^^^^^^^^^^^^^^^^^ @@ -231,16 +233,29 @@ 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. +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: Demo circuit for demonstrating some advanced Yosys features + :caption: ``memdemo.v`` :name: memdemo_src :language: verilog -We synthesize the circuit using ``proc; opt; memory; opt`` and change to the -``memdemo`` module with ``cd memdemo``. If we type :cmd:ref:`show` now we see -the diagram shown in :numref:`memdemo_00`. +The script ``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 ``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 @@ -248,13 +263,19 @@ the diagram shown in :numref:`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: +.. todo:: :ref:`memdemo_01` and :ref:`memdemo_02` are the same, probably change + the example so they aren't. -.. code-block:: yoscrypt +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`: - 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 @@ -262,12 +283,14 @@ connected to the output port ``Q``, that the ``clk`` signal goes into the 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: +``%ci`` action :yoscrypt:`show y %ci2:+$dff[Q,D]`, that tells it to only follow +ports ``Q`` and ``D`` of ``$dff`` cells: -.. code-block:: yoscrypt - - show y %ci2:+$dff[Q,D] +.. figure:: /_images/code_examples/selections/memdemo_02.* + :class: width-helper + :name: memdemo_02 + + Output of :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 itself starts with ``-`` or ``+``, indicating if it is an include or @@ -275,43 +298,32 @@ 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/code_examples/selections/memdemo_01.* - :class: width-helper - :name: memdemo_01 - - Output of ``show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff`` +could as well only specify the port names, :yoscrypt:`show y %ci2:+[Q,D]`. Or we +could decide to tell the ``%ci`` action to not follow the ``CLK`` input, +:yoscrypt:`show y %ci2:-[CLK]`. Next we would investigate the next logic level by adding another ``%ci2`` to the -command: +command, :yoscrypt:`show y %ci2:-[CLK] %ci2`: -.. code-block:: yoscrypt - - show y %ci2:-[CLK] %ci2 +.. figure:: /_images/code_examples/selections/memdemo_03.* + :class: width-helper + :name: memdemo_03 + + Output of :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 +an additional pattern to narrow the selection on the path we are interested. In +the end we would end up with 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. The diagram produced by this +command is shown in :numref:`memdemo_04`. -.. 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`. +.. figure:: /_images/code_examples/selections/memdemo_04.* + :class: width-helper + :name: memdemo_04 + + Output of ``show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff`` Similar to ``%ci`` exists an action ``%co`` to select output cones that accepts the same syntax for pattern and repetition. The ``%x`` action mentioned @@ -350,6 +362,8 @@ on the stack. Storing and recalling selections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. todo:: reflow for not presentation + The current selection can be stored in memory with the command ``select -set <name>``. It can later be recalled using ``select @<name>``. In fact, the ``@<name>`` expression pushes the stored selection on the stack maintained by diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 88e7a1479..b73ee59db 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -41,12 +41,12 @@ The extract pass .. todo:: add/expand supporting text -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_00a.* +.. figure:: /_images/code_examples/macc/macc_simple_test_00a.* :class: width-helper before `extract` -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_00b.* +.. figure:: /_images/code_examples/macc/macc_simple_test_00b.* :class: width-helper after `extract` @@ -70,20 +70,20 @@ The extract pass :language: verilog :caption: ``docs/source/code_examples/macc/macc_simple_test_01.v`` -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_01a.* +.. figure:: /_images/code_examples/macc/macc_simple_test_01a.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_01b.* +.. figure:: /_images/code_examples/macc/macc_simple_test_01b.* :class: width-helper .. literalinclude:: /code_examples/macc/macc_simple_test_02.v :language: verilog :caption: ``docs/source/code_examples/macc/macc_simple_test_02.v`` -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_02a.* +.. figure:: /_images/code_examples/macc/macc_simple_test_02a.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_simple_test_02b.* +.. figure:: /_images/code_examples/macc/macc_simple_test_02b.* :class: width-helper The wrap-extract-unwrap method @@ -169,10 +169,10 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` :lines: 1-6 :caption: ``test1`` of ``docs/source/code_examples/macc/macc_xilinx_test.v`` -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1a.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test1a.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.* :class: width-helper .. literalinclude:: /code_examples/macc/macc_xilinx_test.v @@ -180,15 +180,15 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` :lines: 8-13 :caption: ``test2`` of ``docs/source/code_examples/macc/macc_xilinx_test.v`` -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2a.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2a.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.* :class: width-helper Wrapping in ``test1``: -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1b.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.* :class: width-helper .. code:: yoscrypt @@ -200,12 +200,12 @@ Wrapping in ``test1``: -unsigned $__add_wrapper \ Y Y_WIDTH ;; -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.* :class: width-helper Wrapping in ``test2``: -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2b.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.* :class: width-helper .. code:: yoscrypt @@ -217,7 +217,7 @@ Wrapping in ``test2``: -unsigned $__add_wrapper \ Y Y_WIDTH ;; -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.* :class: width-helper Extract in ``test1``: @@ -235,10 +235,10 @@ Extract in ``test1``: -map %__macc_xilinx_xmap \ -swap $__add_wrapper A,B ;; -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1c.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test1d.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test1d.* :class: width-helper Extract in ``test2``: @@ -256,18 +256,18 @@ Extract in ``test2``: -map %__macc_xilinx_xmap \ -swap $__add_wrapper A,B ;; -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2c.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.* :class: width-helper Unwrap in ``test2``: -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2d.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.* :class: width-helper -.. figure:: /_images/res/PRESENTATION_ExAdv/macc_xilinx_test2e.* +.. figure:: /_images/code_examples/macc/macc_xilinx_test2e.* :class: width-helper .. code:: yoscrypt diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index a2f360a2c..3bbda4c38 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -134,7 +134,7 @@ Mapping OR3X1 :language: verilog :caption: ``docs/source/code_examples/techmap/red_or3x1_map.v`` -.. figure:: /_images/res/PRESENTATION_ExAdv/red_or3x1.* +.. figure:: /_images/code_examples/techmap/red_or3x1.* :class: width-helper .. literalinclude:: /code_examples/techmap/red_or3x1_test.ys @@ -160,7 +160,7 @@ Conditional techmap Example: -.. figure:: /_images/res/PRESENTATION_ExAdv/sym_mul.* +.. figure:: /_images/code_examples/techmap/sym_mul.* :class: width-helper .. literalinclude:: /code_examples/techmap/sym_mul_map.v @@ -199,7 +199,7 @@ Scripting in map modules Example: -.. figure:: /_images/res/PRESENTATION_ExAdv/mymul.* +.. figure:: /_images/code_examples/techmap/mymul.* :class: width-helper .. literalinclude:: /code_examples/techmap/mymul_map.v @@ -229,7 +229,7 @@ Handling constant inputs Example: -.. figure:: /_images/res/PRESENTATION_ExAdv/mulshift.* +.. figure:: /_images/code_examples/techmap/mulshift.* :class: width-helper .. literalinclude:: /code_examples/techmap/mulshift_map.v @@ -260,7 +260,7 @@ Handling shorted inputs Example: -.. figure:: /_images/res/PRESENTATION_ExAdv/addshift.* +.. figure:: /_images/code_examples/techmap/addshift.* :class: width-helper .. literalinclude:: /code_examples/techmap/addshift_map.v From bb7ebec38cc78f398eecc2a10df1f64b278e5564 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:11:53 +1300 Subject: [PATCH 043/108] guidelines: fix paths to moved files --- guidelines/GettingStarted | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guidelines/GettingStarted b/guidelines/GettingStarted index d27b285fc..110f63185 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 From 0fb511905a22987d929507e2c58e00c59ed03292 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:46:47 +1300 Subject: [PATCH 044/108] docs: more tidying Fix 010 pdf link. Swap yosys script code blocks for literal includes. Fix broken example code. --- .../appendix/APPNOTE_010_Verilog_to_BLIF.rst | 2 +- .../code_examples/macc/macc_xilinx_test.ys | 20 +++-- .../interactive_investigation.rst | 2 +- docs/source/using_yosys/yosys_flows.rst | 88 +++++++------------ 4 files changed, 50 insertions(+), 62 deletions(-) diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index cc658f03f..ff404cb53 100644 --- a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst +++ b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst @@ -29,7 +29,7 @@ Download ======== This document was originally published in April 2015: -:download:`Converting Verilog to BLIF PDF</_downloads/APPNOTE_012_Verilog_to_BTOR.pdf>` +:download:`Converting Verilog to BLIF PDF</_downloads/APPNOTE_010_Verilog_to_BLIF.pdf>` .. Installation diff --git a/docs/source/code_examples/macc/macc_xilinx_test.ys b/docs/source/code_examples/macc/macc_xilinx_test.ys index 6e91a04ff..47bf399b2 100644 --- a/docs/source/code_examples/macc/macc_xilinx_test.ys +++ b/docs/source/code_examples/macc/macc_xilinx_test.ys @@ -1,24 +1,32 @@ +# ============================================================================ +# 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 @@ -29,12 +37,14 @@ 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 diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index fe78c66c5..ad7b9613d 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -424,7 +424,7 @@ Yosys script for ASIC synthesis of the Amber ARMv2 CPU. if (ARST) Q <= ARST_VALUE; else - <= D; + Q <= D; endmodule diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index b73ee59db..170db416c 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -41,15 +41,23 @@ The extract pass .. todo:: add/expand supporting text +.. 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 `extract` + 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 `extract` + after :cmd:ref:`extract` .. literalinclude:: /code_examples/macc/macc_simple_test.v :language: verilog @@ -59,13 +67,6 @@ The extract pass :language: verilog :caption: ``docs/source/code_examples/macc/macc_simple_xmap.v`` -.. code:: yoscrypt - - read_verilog macc_simple_test.v - hierarchy -check -top test - - extract -map macc_simple_xmap.v;; - .. literalinclude:: /code_examples/macc/macc_simple_test_01.v :language: verilog :caption: ``docs/source/code_examples/macc/macc_simple_test_01.v`` @@ -191,14 +192,10 @@ Wrapping in ``test1``: .. figure:: /_images/code_examples/macc/macc_xilinx_test1b.* :class: width-helper -.. code:: yoscrypt - - techmap -map macc_xilinx_wrap_map.v - - connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; +.. 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 @@ -208,57 +205,37 @@ Wrapping in ``test2``: .. figure:: /_images/code_examples/macc/macc_xilinx_test2b.* :class: width-helper -.. code:: yoscrypt - - techmap -map macc_xilinx_wrap_map.v - - connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; +.. 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``: -.. code:: yoscrypt - - 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 ;; - .. 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``: -.. code:: yoscrypt - - 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 ;; - .. 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 @@ -267,13 +244,14 @@ 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 -.. code:: yoscrypt - - techmap -map macc_xilinx_unwrap_map.v ;; - Symbolic model checking ----------------------- From a8b2525b08fead32c5205b7dea992450970ddbf0 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:21:39 +1300 Subject: [PATCH 045/108] typical phases: Expand/split sections More consistent indentation and section headings. Convert yoscrypt blocks to lists of cmdrefs (so they link to the commands in question). Also update said lists. Add other common optimizations/mapping commands. Remove example synth script in favour of the examples on the next page. --- .../source/getting_started/typical_phases.rst | 277 +++++++++--------- 1 file changed, 145 insertions(+), 132 deletions(-) diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index 2fce9215c..64f76cd4e 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -1,7 +1,13 @@ Typical phases of a synthesis flow ---------------------------------- -.. todo:: expand text +.. role:: yoscrypt(code) + :language: yoscrypt + +.. todo:: should e.g. :yoscrypt:`proc` and :yoscrypt:`memory` examples be + included here (typical phases) or examples + +.. todo:: expand bullet points - Reading and elaborating the design - Higher-level synthesis and optimization @@ -16,10 +22,11 @@ Typical phases of a synthesis flow - Map bit-level logic gates and registers to cell library - Write results to output file - Reading the design ~~~~~~~~~~~~~~~~~~ +.. todo:: include ``read_verilog <<EOF`` when discussing how to read designs? + .. code-block:: yoscrypt read_verilog file1.v @@ -45,6 +52,13 @@ 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. +.. todo:: hierarchy without ``-top`` is bad + - resolve non-module-specific references (sub modules, interfaces et al) + - check sub modules exist, discarding unused + - set top attribute + - also mention failure modes + - also prep? + .. code-block:: yoscrypt # simplest form. at least this version should be used after reading all input files @@ -57,27 +71,31 @@ needed variations of parametric modules. hierarchy -check -top top_module -The :cmd:ref:`proc` command -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Converting process blocks +~~~~~~~~~~~~~~~~~~~~~~~~~ The Verilog frontend converts ``always``-blocks to RTL netlists for the -expressions and "processess" for the control- and memory elements. +expressions and "processess" for the control- and memory elements. The +:cmd:ref:`proc` command then transforms these "processess" to netlists of RTL +multiplexer and register cells. It also is a macro command that calls the other +``proc_*`` commands in a sensible order: -The :cmd:ref:`proc` command transforms this "processess" to netlists of RTL -multiplexer and register cells. +#. :cmd:ref:`proc_clean` removes empty branches and processes. +#. :cmd:ref:`proc_rmdead` removes unreachable branches. +#. :cmd:ref:`proc_prune` +#. :cmd:ref:`proc_init` special handling of "initial" blocks. +#. :cmd:ref:`proc_arst` identifies modeling of async resets. +#. :cmd:ref:`proc_rom` +#. :cmd:ref:`proc_mux` converts decision trees to multiplexer networks. +#. :cmd:ref:`proc_dlatch` +#. :cmd:ref:`proc_dff` extracts registers from processes. +#. :cmd:ref:`proc_memwr` +#. :cmd:ref:`proc_clean` this should remove all the processes, provided all went + fine. -The :cmd:ref:`proc` command is actually a macro-command that calls the following -other commands: - -.. code-block:: yoscrypt - - 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 +After all the ``proc_*`` commands, :yoscrypt:`opt_expr` is called. This can be +disabled by calling :yoscrypt:`proc -noopt`. For more information about +:cmd:ref:`proc`, such as disabling certain sub commands, see :doc:`/cmd/proc`. Many commands can not operate on modules with "processess" in them. Usually a call to :cmd:ref:`proc` is the first command in the actual synthesis procedure @@ -86,6 +104,8 @@ after design elaboration. Example ^^^^^^^ +.. todo:: describe ``proc`` images + .. literalinclude:: /code_examples/synth_flow/proc_01.v :language: verilog :caption: ``docs/source/code_examples/synth_flow/proc_01.v`` @@ -95,10 +115,10 @@ Example :caption: ``docs/source/code_examples/synth_flow/proc_01.ys`` .. figure:: /_images/code_examples/synth_flow/proc_01.* - :class: width-helper + :class: width-helper .. figure:: /_images/code_examples/synth_flow/proc_02.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/proc_02.v :language: verilog @@ -109,7 +129,7 @@ Example :caption: ``docs/source/code_examples/synth_flow/proc_02.ys`` .. figure:: /_images/code_examples/synth_flow/proc_03.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/proc_03.ys :language: yoscrypt @@ -120,8 +140,8 @@ Example :caption: ``docs/source/code_examples/synth_flow/proc_03.v`` -The :cmd:ref:`opt` command -~~~~~~~~~~~~~~~~~~~~~~~~~~ +Optimizations +~~~~~~~~~~~~~ The :cmd:ref:`opt` command implements a series of simple optimizations. It also is a macro command that calls other commands: @@ -148,10 +168,12 @@ The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And hierarchy; proc; opt; memory; opt_expr;; fsm;; Example -^^^^^^^ +""""""" + +.. todo:: describe ``opt`` images .. figure:: /_images/code_examples/synth_flow/opt_01.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_01.ys :language: yoscrypt @@ -162,7 +184,7 @@ Example :caption: ``docs/source/code_examples/synth_flow/opt_01.v`` .. figure:: /_images/code_examples/synth_flow/opt_02.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_02.ys :language: yoscrypt @@ -173,7 +195,7 @@ Example :caption: ``docs/source/code_examples/synth_flow/opt_02.v`` .. figure:: /_images/code_examples/synth_flow/opt_03.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_03.ys :language: yoscrypt @@ -184,7 +206,7 @@ Example :caption: ``docs/source/code_examples/synth_flow/opt_03.v`` .. figure:: /_images/code_examples/synth_flow/opt_04.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/opt_04.v :language: verilog @@ -194,20 +216,16 @@ Example :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/opt_04.ys`` - When to use :cmd:ref:`opt` or :cmd:ref:`clean` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +"""""""""""""""""""""""""""""""""""""""""""""" Usually it does not hurt to call :cmd:ref:`opt` after each regular command in the synthesis script. But it increases the synthesis time, so it is favourable to only call :cmd:ref:`opt` when an improvement can be achieved. -The designs in ``yosys-bigsim`` are a good playground for experimenting with the -effects of calling :cmd:ref:`opt` in various places of the flow. - -It generally is a good idea to call :cmd:ref:`opt` before inherently expensive +It is generally a good idea to call :cmd:ref:`opt` before inherently expensive commands such as :cmd:ref:`sat` or :cmd:ref:`freduce`, as the possible gain is -much higher in this cases as the possible loss. +much higher in these cases as the possible loss. The :cmd:ref:`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 @@ -215,26 +233,44 @@ 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 ``;;`` is a good idea in every synthesis script. -The :cmd:ref:`memory` command -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Other common optimization commands +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. todo:: fill out descriptions for other optimization commands + +:cmd:ref:`wreduce` + Reduces the word size of operations. + +:cmd:ref:`peepopt` + Applies a collection of peephole optimizers to the current design. + +:cmd:ref:`share` + Merges shareable resources into a single resource using a SAT solver to + determine if two resources are shareable. + +Memory handling +~~~~~~~~~~~~~~~ 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` 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: +decoders and registers. It also is a macro command that calls the other +``memory_*`` commands in a sensible order: -.. code-block:: yoscrypt +.. todo:: fill out missing :cmd:ref:`memory` subcommands descriptions - # this merges registers into the memory read- and write cells. - memory_dff +#. :cmd:ref:`memory_bmux2rom` +#. :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. +#. :cmd:ref:`memory_share` +#. :cmd:ref:`memory_memx` +#. :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_bram` +#. :cmd:ref:`memory_map` takes the multi-port memory cell and transforms it to + address decoder logic and registers. - # 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 +.. todo:: is :yoscrypt:`memory -nomap; techmap -map my_memory_map.v; memory_map` + superceded by :yoscrypt:`memory_libmap`? Usually it is preferred to use architecture-specific RAM resources for memory. For example: @@ -243,11 +279,16 @@ For example: memory -nomap; techmap -map my_memory_map.v; memory_map +For more information about :cmd:ref:`memory`, such as disabling certain sub +commands, see :doc:`/cmd/memory`. + Example ^^^^^^^ +.. todo:: describe ``memory`` images + .. figure:: /_images/code_examples/synth_flow/memory_01.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/memory_01.ys :language: yoscrypt @@ -258,7 +299,7 @@ Example :caption: ``docs/source/code_examples/synth_flow/memory_01.v`` .. figure:: /_images/code_examples/synth_flow/memory_02.* - :class: width-helper + :class: width-helper .. literalinclude:: /code_examples/synth_flow/memory_02.v :language: verilog @@ -268,59 +309,49 @@ Example :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/memory_02.ys`` +The :cmd:ref:`memory_libmap` command +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The :cmd:ref:`fsm` command -~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. todo:: :cmd:ref:`memory_libmap` description + +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: -.. code-block:: yoscrypt +#. :cmd:ref:`fsm_detect` identifies FSM state registers and marks them + with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the + ``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" + *)`` to disable FSM optimization for a register. +#. :cmd:ref:`fsm_extract` replaces the entire FSM (logic and state registers) + with a ``$fsm`` cell. +#. :cmd:ref:`fsm_opt` optimizes the FSM. Called multiple times. +#. :cmd:ref:`fsm_expand` optionally merges additional auxilliary gates into the + ``$fsm`` cell. +#. :cmd:ref:`fsm_recode` also optimizes the FSM. +#. :cmd:ref:`fsm_info` logs internal FSM information. +#. :cmd:ref:`fsm_export` optionally exports each FSM to KISS2 files. +#. :cmd:ref:`fsm_map` converts the (optimized) ``$fsm`` cell back to logic and + registers. - fsm_detect # unless got option -nodetect - fsm_extract +See also :doc:`/cmd/fsm`. - fsm_opt - clean - fsm_opt +DSP handling +~~~~~~~~~~~~ - fsm_expand # if got option -expand - clean # if got option -expand - fsm_opt # if got option -expand +.. todo:: add info about dsp handling - fsm_recode # unless got option -norecode - - fsm_info - - fsm_export # if got option -export - fsm_map # unless got option -nomap - -Some details on the most important commands from the ``fsm_*`` group: - -The :cmd:ref:`fsm_detect` command identifies FSM state registers and marks them -with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the -``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" -*)`` to disable FSM optimization for a register. - -The :cmd:ref:`fsm_extract` command replaces the entire FSM (logic and state -registers) with a ``$fsm`` cell. - -The commands :cmd:ref:`fsm_opt` and :cmd:ref:`fsm_recode` can be used to -optimize the FSM. - -Finally the :cmd:ref:`fsm_map` command can be used to convert the (optimized) -``$fsm`` cell back to logic and registers. - -The :cmd:ref:`techmap` command -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. figure:: /_images/code_examples/synth_flow/techmap_01.* - :class: width-helper +Technology mapping +~~~~~~~~~~~~~~~~~~ The :cmd:ref:`techmap` command replaces cells with implementations given as verilog source. For example implementing a 32 bit adder using 16 bit adders: +.. figure:: /_images/code_examples/synth_flow/techmap_01.* + :class: width-helper + .. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` @@ -333,6 +364,8 @@ verilog source. For example implementing a 32 bit adder using 16 bit adders: :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` +See :doc:`/yosys_internals/techmap` for more. + stdcell mapping ^^^^^^^^^^^^^^^ @@ -378,6 +411,8 @@ advanced ABC features. It is also possible to write the design with Example ^^^^^^^ +.. todo:: describe ``abc`` images + .. literalinclude:: /code_examples/synth_flow/abc_01.v :language: verilog :caption: ``docs/source/code_examples/synth_flow/abc_01.v`` @@ -387,58 +422,36 @@ Example :caption: ``docs/source/code_examples/synth_flow/abc_01.ys`` .. figure:: /_images/code_examples/synth_flow/abc_01.* - :class: width-helper + :class: width-helper Other special-purpose mapping commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The commands below may be used depending on the targeted architecture for +compatibility with, or to take advantage of, resources available. + :cmd:ref:`dfflibmap` - This command maps the internal register cell types to the register types - described in a liberty file. + This command maps the internal register cell types to the register types + described in a liberty file. :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. + 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 this cells to the design. + Top-level input/outputs must usually be implemented using special I/O-pad + cells. This command inserts such cells to the design. -Example Synthesis Script -~~~~~~~~~~~~~~~~~~~~~~~~ +:cmd:ref:`alumacc` + Translate arithmetic operations like $add, $mul, $lt, etc. to $alu and $macc + cells. -.. code-block:: yoscrypt +:cmd:ref:`dfflegalize` + Specify a set of supported FF cells/cell groups and convert all FFs to them. - # 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 +:cmd:ref:`deminout` + Convert inout ports to input or output ports, if possible. - # 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 - -The weird :cmd:ref:`select` expressions at the end of this script are discussed -later in -:doc:`using_yosys/more_scripting/selections</using_yosys/more_scripting/selections>`. +:cmd:ref:`pmuxtree` + Transforms parallel mux cells, ``$pmux``, to trees of ``$mux`` cells. From bad8dba2cd047afd295c1acea377c003173d421a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:22:00 +1300 Subject: [PATCH 046/108] Correcting plurals --- .../interactive_investigation.rst | 24 +++++++++---------- .../using_yosys/more_scripting/selections.rst | 4 ++-- docs/source/yosys_internals/flow/index.rst | 2 +- docs/source/yosys_internals/techmap.rst | 6 ++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index ad7b9613d..08d41702d 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -134,12 +134,12 @@ when the individual bits of of a signal vector are accessed. The key elements in understanding this circuit diagram are of course the boxes with round corners and rows labeled ``<MSB_LEFT>:<LSB_LEFT> - -<MSB_RIGHT>:<LSB_RIGHT>``. Each of this boxes has one signal per row on one side -and a common signal for all rows on the other side. The ``<MSB>:<LSB>`` 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``. +<MSB_RIGHT>:<LSB_RIGHT>``. Each of these boxes have one signal per row on one +side and a common signal for all rows on the other side. The ``<MSB>:<LSB>`` +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 @@ -213,11 +213,11 @@ 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 :cmd:ref:`show` -with the ``-colors <integer>`` 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. +individual signal wires. For these cases it can be useful to call +:cmd:ref:`show` with the ``-colors <integer>`` 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 :cmd:ref:`show` command. @@ -531,7 +531,7 @@ 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 this commands can be applied. +modules before these commands can be applied. Solving combinatorial SAT problems ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index eb3f66d6c..6504bc0bb 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -187,7 +187,7 @@ 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, this commands broadens the selection by one "step". +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. @@ -329,7 +329,7 @@ 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 +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. diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst index e2b5b658c..7733ec855 100644 --- a/docs/source/yosys_internals/flow/index.rst +++ b/docs/source/yosys_internals/flow/index.rst @@ -4,7 +4,7 @@ Internal flow A (usually short) synthesis script controls Yosys. -This scripts contain three types of commands: +These scripts contain three types of commands: - **Frontends**, that read input files (usually Verilog); - **Passes**, that perform transformations on the design in memory; diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index 3bbda4c38..973aca39f 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -279,9 +279,9 @@ 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 this cells. +- 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 From f9ce3d1c26bd8c23645fed91f00a649309df6e37 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:04:46 +1300 Subject: [PATCH 047/108] WIP merging synth phases with example Replace `typical_phases.rst` and `examples.rst` with a single `example_synth.rst`. Also updating the counter example to match. Aims to reduce redundancy, and simplify the getting started section. Details on things like `proc`, `memory` and `fsm` should instead be in the advanced section (under the new `synth` subsection). --- docs/source/code_examples/intro/Makefile | 2 +- .../code_examples/intro/counter_outputs.ys | 9 +- docs/source/getting_started/example_synth.rst | 217 ++++++++++++++++++ docs/source/getting_started/examples.rst | 146 ------------ docs/source/getting_started/index.rst | 9 +- .../getting_started/scripting_intro.rst | 3 +- .../source/getting_started/typical_phases.rst | 4 +- docs/source/using_yosys/index.rst | 2 +- .../using_yosys/more_scripting/index.rst | 2 - docs/source/using_yosys/synthesis/index.rst | 10 + .../{ => synthesis}/memory_mapping.rst | 0 .../opt_passes.rst | 0 docs/source/using_yosys/synthesis/proc.rst | 4 + .../{more_scripting => synthesis}/synth.rst | 0 14 files changed, 245 insertions(+), 163 deletions(-) create mode 100644 docs/source/getting_started/example_synth.rst delete mode 100644 docs/source/getting_started/examples.rst create mode 100644 docs/source/using_yosys/synthesis/index.rst rename docs/source/using_yosys/{ => synthesis}/memory_mapping.rst (100%) rename docs/source/using_yosys/{more_scripting => synthesis}/opt_passes.rst (100%) create mode 100644 docs/source/using_yosys/synthesis/proc.rst rename docs/source/using_yosys/{more_scripting => synthesis}/synth.rst (100%) diff --git a/docs/source/code_examples/intro/Makefile b/docs/source/code_examples/intro/Makefile index c7507e934..90b91d7a5 100644 --- a/docs/source/code_examples/intro/Makefile +++ b/docs/source/code_examples/intro/Makefile @@ -2,7 +2,7 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -DOTS = counter_00.dot counter_01.dot counter_02.dot counter_03.dot +DOTS = counter_00.dot counter_proc.dot counter_01.dot counter_02.dot counter_03.dot dots: $(DOTS) diff --git a/docs/source/code_examples/intro/counter_outputs.ys b/docs/source/code_examples/intro/counter_outputs.ys index a35c83d6f..d52934b3f 100644 --- a/docs/source/code_examples/intro/counter_outputs.ys +++ b/docs/source/code_examples/intro/counter_outputs.ys @@ -1,12 +1,13 @@ -# read design +# read 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 +# elaborate +proc +show -notitle -format dot -prefix counter_proc +opt show -notitle -format dot -prefix counter_01 # mapping to internal cell library diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst new file mode 100644 index 000000000..9f61e9180 --- /dev/null +++ b/docs/source/getting_started/example_synth.rst @@ -0,0 +1,217 @@ +Synthesis starter +----------------- + +A simple counter +~~~~~~~~~~~~~~~~ + +.. role:: yoscrypt(code) + :language: yoscrypt + +This section covers an example project available in +``docs/source/code_examples/intro/*``. The project contains a simple ASIC +synthesis script (``counter.ys``), a digital design written in Verilog +(``counter.v``), and a simple CMOS cell library (``mycells.lib``). + +First, let's quickly look at the design: + +.. literalinclude:: /code_examples/intro/counter.v + :language: Verilog + :caption: ``docs/source/code_examples/intro/counter.v`` + :linenos: + :name: 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 +~~~~~~~~~~~~~~~~~~ + +Let's load the design into Yosys. From the command line, we can call ``yosys +counter.v``. This will open an interactive Yosys shell session and immediately +parse the code from ``counter.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: + +.. code:: console + + $ yosys counter.v + + -- Parsing `counter.v' using frontend ` -vlog2k' -- + + 1. Executing Verilog-2005 frontend: counter.v + Parsing Verilog input from `counter.v' to AST representation. + Storing AST representation for module `$abstract\counter'. + Successfully finished Verilog frontend. + +Now that we are in the interactive shell, we can call Yosys commands directly. +Let's run :yoscrypt:`hierarchy -check -top counter`. This command declares that +the top level module is ``counter``, and that we want to expand it and any other +modules it may use. Any other modules which were loaded are then discarded, +stopping the following commands from trying to work on them. 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. + +.. todo:: more on why :cmd:ref:`hierarchy` is important + +.. note:: + + :cmd:ref:`hierarchy` should always be the first command after the design has + been read. + +.. use doscon for a console-like display that supports the `yosys> [command]` format. + +.. code:: doscon + + yosys> hierarchy -check -top counter + + 2. Executing HIERARCHY pass (managing design hierarchy). + + 3. Executing AST frontend in derive mode using pre-parsed AST for module `\counter'. + Generating RTLIL representation for module `\counter'. + + 3.1. Analyzing design hierarchy.. + Top module: \counter + + 3.2. Analyzing design hierarchy.. + Top module: \counter + Removing unused module `$abstract\counter'. + Removed 1 unused modules. + +Our circuit now looks like this: + +.. figure:: /_images/code_examples/intro/counter_00.* + :class: width-helper + :name: counter-hierarchy + + ``counter`` module after :cmd:ref:`hierarchy` + +Elaboration +~~~~~~~~~~~ + +Notice that block that says "PROC" in :ref:`counter-hierarchy`? Simple +operations like ``count + 2'd1`` can be extracted from our ``always @`` block in +:ref:`counter-v`. This gives us the ``$add`` cell we see. But control logic, +like the ``if .. else``; and memory elements, like the ``count <='2d0``; are not +so straightforward. To handle these, let us now introduce a new command: +:doc:`/cmd/proc`. + +:cmd:ref:`proc` is a macro command; running a series of other commands which +work to convert the behavioral logic of processes into multiplexers and +registers. We go into more detail on :cmd:ref:`proc` later in +:doc:`/using_yosys/synthesis/proc`, but for now let's see what happens when we +run it. + +.. figure:: /_images/code_examples/intro/counter_proc.* + :class: width-helper + + ``counter`` module after :cmd:ref:`proc` + +The ``if`` statements are now modeled with ``$mux`` cells, and the memory +consists of a ``$dff`` cell. That's getting a bit messy now, so let's chuck in +a call to :cmd:ref:`opt`. + +.. figure:: /_images/code_examples/intro/counter_01.* + :class: width-helper + + ``counter`` module after :cmd:ref:`opt` + +Much better. We can now see that the ``$dff`` and ``$mux`` cells have been +replaced with a single ``$sdffe``, using the built-in enable and reset ports +instead. + +.. todo:: a bit more on :cmd:ref:`opt` here + +At this stage of a synthesis flow there are a few other commands we could run. +First off is :cmd:ref:`flatten`. If we had any modules within our ``counter``, +this would replace them with their implementation. Flattening the design like +this can allow for optimizations between modules which would otherwise be +missed. Next is :doc:`/cmd/check`. + +Depending on the target architecture, we might also run 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. + +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. +There isn't much else we can do for our ``counter`` example, but 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. + +.. todo:: talk more about DSPs (and their associated commands) + +Some of the commands we might use here are: + +- :doc:`/cmd/fsm`, +- :doc:`/cmd/memory`, +- :doc:`/cmd/wreduce`, +- :doc:`/cmd/peepopt`, +- :doc:`/cmd/alumacc`, and +- :doc:`/cmd/share`. + +Techmap +~~~~~~~ + +:yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain +logic gates (AND, OR, NOT, etc.). + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 8-9 + +Result: + +.. figure:: /_images/code_examples/intro/counter_02.* + :class: width-helper + + ``counter`` after :cmd:ref:`techmap` + +Mapping to hardware +~~~~~~~~~~~~~~~~~~~ + +:ref:`cmos_lib` + +#. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available + hardware flip-flops. +#. :yoscrypt:`abc -liberty mycells.lib` - Map logic to available hardware gates. + +.. figure:: /_images/code_examples/intro/counter_03.* + :class: width-helper + + ``counter`` after hardware cell mapping + +.. _cmos_lib: + +The CMOS cell library +^^^^^^^^^^^^^^^^^^^^^ + +.. literalinclude:: /code_examples/intro/mycells.lib + :language: Liberty + :caption: ``docs/source/code_examples/intro/mycells.lib`` + +The script file +~~~~~~~~~~~~~~~ + +#. :yoscrypt:`read_verilog -defer counter.v` +#. :yoscrypt:`clean` - Clean up the design (just the last step of + :cmd:ref:`opt`). +#. :yoscrypt:`write_verilog synth.v` - Write final synthesis result to output + file. + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/intro/counter.ys`` + diff --git a/docs/source/getting_started/examples.rst b/docs/source/getting_started/examples.rst deleted file mode 100644 index 5e1b0e429..000000000 --- a/docs/source/getting_started/examples.rst +++ /dev/null @@ -1,146 +0,0 @@ -Example(s) ----------- - -.. _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`. - -Simple synthesis script -~~~~~~~~~~~~~~~~~~~~~~~ - -This section covers an example project available in -``docs/source/code_examples/intro/*``. The project contains a simple ASIC -synthesis script (``counter.ys``), a digital design written in Verilog -(``counter.v``), and a simple CMOS cell library (``mycells.lib``). - -.. literalinclude:: /code_examples/intro/counter.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/intro/counter.ys`` - -.. role:: yoscrypt(code) - :language: yoscrypt - -#. :yoscrypt:`read_verilog counter.v` - Read Verilog source file and convert to - internal representation. -#. :yoscrypt:`hierarchy -check -top counter` - Elaborate the design hierarchy. - Should always be the first command after reading the design. Can re-run AST front-end. -#. :yoscrypt:`proc` - Convert ``processes`` (the internal representation of - behavioral Verilog code) into multiplexers and registers. -#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. -#. :yoscrypt:`fsm` - Analyze and optimize finite state machines. -#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. -#. :yoscrypt:`memory` - Analyze memories and create circuits to implement them. -#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. -#. :yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain - logic gates (AND, OR, NOT, etc.). -#. :yoscrypt:`opt` - Perform some basic optimizations and cleanups. -#. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available - hardware flip-flops. -#. :yoscrypt:`abc -liberty mycells.lib` - Map logic to available hardware gates. -#. :yoscrypt:`clean` - Clean up the design (just the last step of - :cmd:ref:`opt`). -#. :yoscrypt:`write_verilog synth.v` - Write final synthesis result to output - file. - -Running the script -^^^^^^^^^^^^^^^^^^ - -.. literalinclude:: /code_examples/intro/counter.v - :language: Verilog - :caption: ``docs/source/code_examples/intro/counter.v`` - -.. literalinclude:: /code_examples/intro/mycells.lib - :language: Liberty - :caption: ``docs/source/code_examples/intro/mycells.lib`` - -Step 1 -"""""" - -.. literalinclude:: /code_examples/intro/counter.ys - :language: yoscrypt - :lines: 1-3 - -Result: - -.. figure:: /_images/code_examples/intro/counter_00.* - :class: width-helper - -Step 2 -"""""" - -.. literalinclude:: /code_examples/intro/counter.ys - :language: yoscrypt - :lines: 5-6 - -Result: - -.. figure:: /_images/code_examples/intro/counter_01.* - :class: width-helper - -Step 3 -"""""" - -.. literalinclude:: /code_examples/intro/counter.ys - :language: yoscrypt - :lines: 8-9 - -Result: - -.. figure:: /_images/code_examples/intro/counter_02.* - :class: width-helper - -Step 4 -"""""" - -.. literalinclude:: /code_examples/intro/counter.ys - :language: yoscrypt - :lines: 11-18 - -Result: - -.. figure:: /_images/code_examples/intro/counter_03.* - :class: width-helper diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index 0828adf39..2f89a71cd 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -2,9 +2,8 @@ Getting started with Yosys ========================== .. toctree:: - :maxdepth: 3 + :maxdepth: 3 - installation - scripting_intro - typical_phases - examples + installation + scripting_intro + example_synth diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index d5877917c..fd2aeee88 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -7,8 +7,7 @@ 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 :ref:`sec:typusecase` for an -example synthesis script. +starting with the hash sign (#) are ignored. Also see :doc:`example_synth`. The command :cmd:ref:`help` can be used to access the command reference manual, with ``help <command>`` providing details for a specific command. ``yosys -H`` diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst index 64f76cd4e..d6cf89be5 100644 --- a/docs/source/getting_started/typical_phases.rst +++ b/docs/source/getting_started/typical_phases.rst @@ -168,7 +168,7 @@ The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And hierarchy; proc; opt; memory; opt_expr;; fsm;; Example -""""""" +^^^^^^^ .. todo:: describe ``opt`` images @@ -217,7 +217,7 @@ Example :caption: ``docs/source/code_examples/synth_flow/opt_04.ys`` When to use :cmd:ref:`opt` or :cmd:ref:`clean` -"""""""""""""""""""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Usually it does not hurt to call :cmd:ref:`opt` after each regular command in the synthesis script. But it increases the synthesis time, so it is favourable diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst index fd8b2171f..d254df76f 100644 --- a/docs/source/using_yosys/index.rst +++ b/docs/source/using_yosys/index.rst @@ -4,6 +4,6 @@ Using Yosys (advanced) .. toctree:: :maxdepth: 2 + synthesis/index more_scripting/index - memory_mapping yosys_flows diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 8fb460613..f16298ce0 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -4,8 +4,6 @@ More scripting .. toctree:: :maxdepth: 3 - opt_passes selections interactive_investigation - synth troubleshooting diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst new file mode 100644 index 000000000..b8dba55e9 --- /dev/null +++ b/docs/source/using_yosys/synthesis/index.rst @@ -0,0 +1,10 @@ +Synthesis in detail +------------------- + +.. toctree:: + :maxdepth: 3 + + synth + opt_passes + proc + memory_mapping diff --git a/docs/source/using_yosys/memory_mapping.rst b/docs/source/using_yosys/synthesis/memory_mapping.rst similarity index 100% rename from docs/source/using_yosys/memory_mapping.rst rename to docs/source/using_yosys/synthesis/memory_mapping.rst diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/synthesis/opt_passes.rst similarity index 100% rename from docs/source/using_yosys/more_scripting/opt_passes.rst rename to docs/source/using_yosys/synthesis/opt_passes.rst diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst new file mode 100644 index 000000000..1d7b823be --- /dev/null +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -0,0 +1,4 @@ +The :cmd:ref:`proc` command +--------------------------- + +text diff --git a/docs/source/using_yosys/more_scripting/synth.rst b/docs/source/using_yosys/synthesis/synth.rst similarity index 100% rename from docs/source/using_yosys/more_scripting/synth.rst rename to docs/source/using_yosys/synthesis/synth.rst From 1e3b90ae56ab504f6de39979a06090c047a82907 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 7 Dec 2023 17:14:21 +1300 Subject: [PATCH 048/108] Removing typical phases doc Moved remaining content into relevant places. Added `load_design.rst` to more scripting. Split fsm handling and abc out of optimization passes. Also moved things around to match the general flow previously described. Changed generic `synth` for `prep` instead. --- docs/source/getting_started/example_synth.rst | 58 ++- .../source/getting_started/typical_phases.rst | 457 ------------------ .../using_yosys/more_scripting/index.rst | 9 +- .../more_scripting/load_design.rst | 37 ++ docs/source/using_yosys/synthesis/abc.rst | 39 ++ .../synthesis/{opt_passes.rst => fsm.rst} | 186 +------ docs/source/using_yosys/synthesis/index.rst | 7 +- .../{memory_mapping.rst => memory.rst} | 108 ++++- docs/source/using_yosys/synthesis/opt.rst | 233 +++++++++ docs/source/using_yosys/synthesis/proc.rst | 69 ++- docs/source/using_yosys/synthesis/synth.rst | 31 +- 11 files changed, 568 insertions(+), 666 deletions(-) delete mode 100644 docs/source/getting_started/typical_phases.rst create mode 100644 docs/source/using_yosys/more_scripting/load_design.rst create mode 100644 docs/source/using_yosys/synthesis/abc.rst rename docs/source/using_yosys/synthesis/{opt_passes.rst => fsm.rst} (52%) rename docs/source/using_yosys/synthesis/{memory_mapping.rst => memory.rst} (86%) create mode 100644 docs/source/using_yosys/synthesis/opt.rst diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 9f61e9180..d155d41c9 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -1,17 +1,35 @@ Synthesis starter ----------------- +.. + Typical phases of a synthesis flow are as follows: + + - Reading and elaborating the design + - Higher-level synthesis and optimization + + - Converting ``always``-blocks to logic and registers + - Perform coarse-grain optimizations (resource sharing, const folding, ...) + - Handling of memories and other coarse-grain blocks + - Extracting and optimizing finite state machines + + - Convert remaining logic to bit-level logic functions + - Perform optimizations on bit-level logic functions + - Map bit-level logic gates and registers to cell library + - Write results to output file + A simple counter ~~~~~~~~~~~~~~~~ .. role:: yoscrypt(code) :language: yoscrypt -This section covers an example project available in -``docs/source/code_examples/intro/*``. The project contains a simple ASIC +This section covers an `example project`_ available in +``docs/source/code_examples/intro/``. The project contains a simple ASIC synthesis script (``counter.ys``), a digital design written in Verilog (``counter.v``), and a simple CMOS cell library (``mycells.lib``). +.. _example project: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/intro + First, let's quickly look at the design: .. literalinclude:: /code_examples/intro/counter.v @@ -159,20 +177,27 @@ Some of the commands we might use here are: - :doc:`/cmd/memory`, - :doc:`/cmd/wreduce`, - :doc:`/cmd/peepopt`, +- :doc:`/cmd/pmuxtree`, - :doc:`/cmd/alumacc`, and - :doc:`/cmd/share`. -Techmap -~~~~~~~ +We could have also + +Logic gate mapping +~~~~~~~~~~~~~~~~~~ :yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain logic gates (AND, OR, NOT, etc.). -.. literalinclude:: /code_examples/intro/counter.ys - :language: yoscrypt - :lines: 8-9 +When :cmd:ref:`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. -Result: +The built-in logic gate types are: ``$_NOT_``, ``$_AND_``, ``$_OR_``, +``$_XOR_``, and ``$_MUX_``. + +See :doc:`/yosys_internals/formats/cell_library` for more about the internal +cells used. .. figure:: /_images/code_examples/intro/counter_02.* :class: width-helper @@ -193,6 +218,22 @@ Mapping to hardware ``counter`` after hardware cell mapping +:cmd:ref:`dfflibmap` + This command maps the internal register cell types to the register types + described in a liberty file. + +: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. + +:cmd:ref:`dfflegalize` + Specify a set of supported FF cells/cell groups and convert all FFs to them. + .. _cmos_lib: The CMOS cell library @@ -215,3 +256,4 @@ The script file :language: yoscrypt :caption: ``docs/source/code_examples/intro/counter.ys`` +See also :doc:`/using_yosys/synthesis/synth`. diff --git a/docs/source/getting_started/typical_phases.rst b/docs/source/getting_started/typical_phases.rst deleted file mode 100644 index d6cf89be5..000000000 --- a/docs/source/getting_started/typical_phases.rst +++ /dev/null @@ -1,457 +0,0 @@ -Typical phases of a synthesis flow ----------------------------------- - -.. role:: yoscrypt(code) - :language: yoscrypt - -.. todo:: should e.g. :yoscrypt:`proc` and :yoscrypt:`memory` examples be - included here (typical phases) or examples - -.. todo:: expand bullet points - -- Reading and elaborating the design -- Higher-level synthesis and optimization - - - Converting ``always``-blocks to logic and registers - - Perform coarse-grain optimizations (resource sharing, const folding, ...) - - Handling of memories and other coarse-grain blocks - - Extracting and optimizing finite state machines - -- Convert remaining logic to bit-level logic functions -- Perform optimizations on bit-level logic functions -- Map bit-level logic gates and registers to cell library -- Write results to output file - -Reading the design -~~~~~~~~~~~~~~~~~~ - -.. todo:: include ``read_verilog <<EOF`` when discussing how to read designs? - -.. code-block:: yoscrypt - - 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 - - -Design elaboration -~~~~~~~~~~~~~~~~~~ - -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. - -.. todo:: hierarchy without ``-top`` is bad - - resolve non-module-specific references (sub modules, interfaces et al) - - check sub modules exist, discarding unused - - set top attribute - - also mention failure modes - - also prep? - -.. code-block:: yoscrypt - - # 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 - - -Converting process blocks -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Verilog frontend converts ``always``-blocks to RTL netlists for the -expressions and "processess" for the control- and memory elements. The -:cmd:ref:`proc` command then transforms these "processess" to netlists of RTL -multiplexer and register cells. It also is a macro command that calls the other -``proc_*`` commands in a sensible order: - -#. :cmd:ref:`proc_clean` removes empty branches and processes. -#. :cmd:ref:`proc_rmdead` removes unreachable branches. -#. :cmd:ref:`proc_prune` -#. :cmd:ref:`proc_init` special handling of "initial" blocks. -#. :cmd:ref:`proc_arst` identifies modeling of async resets. -#. :cmd:ref:`proc_rom` -#. :cmd:ref:`proc_mux` converts decision trees to multiplexer networks. -#. :cmd:ref:`proc_dlatch` -#. :cmd:ref:`proc_dff` extracts registers from processes. -#. :cmd:ref:`proc_memwr` -#. :cmd:ref:`proc_clean` this should remove all the processes, provided all went - fine. - -After all the ``proc_*`` commands, :yoscrypt:`opt_expr` is called. This can be -disabled by calling :yoscrypt:`proc -noopt`. For more information about -:cmd:ref:`proc`, such as disabling certain sub commands, see :doc:`/cmd/proc`. - -Many commands can not operate on modules with "processess" in them. Usually a -call to :cmd:ref:`proc` is the first command in the actual synthesis procedure -after design elaboration. - -Example -^^^^^^^ - -.. todo:: describe ``proc`` images - -.. literalinclude:: /code_examples/synth_flow/proc_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/proc_01.v`` - -.. literalinclude:: /code_examples/synth_flow/proc_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/proc_01.ys`` - -.. figure:: /_images/code_examples/synth_flow/proc_01.* - :class: width-helper - -.. figure:: /_images/code_examples/synth_flow/proc_02.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/proc_02.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/proc_02.v`` - -.. literalinclude:: /code_examples/synth_flow/proc_02.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/proc_02.ys`` - -.. figure:: /_images/code_examples/synth_flow/proc_03.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/proc_03.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/proc_03.ys`` - -.. literalinclude:: /code_examples/synth_flow/proc_03.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/proc_03.v`` - - -Optimizations -~~~~~~~~~~~~~ - -The :cmd:ref:`opt` command implements a series of simple optimizations. It also -is a macro command that calls other commands: - -.. code-block:: yoscrypt - - 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] - -The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And -``;;`` can be used as shortcut for :cmd:ref:`clean`. For example: - -.. code-block:: yoscrypt - - hierarchy; proc; opt; memory; opt_expr;; fsm;; - -Example -^^^^^^^ - -.. todo:: describe ``opt`` images - -.. figure:: /_images/code_examples/synth_flow/opt_01.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_01.ys`` - -.. literalinclude:: /code_examples/synth_flow/opt_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_01.v`` - -.. figure:: /_images/code_examples/synth_flow/opt_02.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_02.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_02.ys`` - -.. literalinclude:: /code_examples/synth_flow/opt_02.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_02.v`` - -.. figure:: /_images/code_examples/synth_flow/opt_03.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_03.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_03.ys`` - -.. literalinclude:: /code_examples/synth_flow/opt_03.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_03.v`` - -.. figure:: /_images/code_examples/synth_flow/opt_04.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_04.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_04.v`` - -.. literalinclude:: /code_examples/synth_flow/opt_04.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_04.ys`` - -When to use :cmd:ref:`opt` or :cmd:ref:`clean` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Usually it does not hurt to call :cmd:ref:`opt` after each regular command in -the synthesis script. But it increases the synthesis time, so it is favourable -to only call :cmd:ref:`opt` when an improvement can be achieved. - -It is generally a good idea to call :cmd:ref:`opt` before inherently expensive -commands such as :cmd:ref:`sat` or :cmd:ref:`freduce`, as the possible gain is -much higher in these cases as the possible loss. - -The :cmd:ref:`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 -``;;`` is a good idea in every synthesis script. - -Other common optimization commands -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. todo:: fill out descriptions for other optimization commands - -:cmd:ref:`wreduce` - Reduces the word size of operations. - -:cmd:ref:`peepopt` - Applies a collection of peephole optimizers to the current design. - -:cmd:ref:`share` - Merges shareable resources into a single resource using a SAT solver to - determine if two resources are shareable. - -Memory handling -~~~~~~~~~~~~~~~ - -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` -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 -``memory_*`` commands in a sensible order: - -.. todo:: fill out missing :cmd:ref:`memory` subcommands descriptions - -#. :cmd:ref:`memory_bmux2rom` -#. :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. -#. :cmd:ref:`memory_share` -#. :cmd:ref:`memory_memx` -#. :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_bram` -#. :cmd:ref:`memory_map` takes the multi-port memory cell and transforms it to - address decoder logic and registers. - -.. todo:: is :yoscrypt:`memory -nomap; techmap -map my_memory_map.v; memory_map` - superceded by :yoscrypt:`memory_libmap`? - -Usually it is preferred to use architecture-specific RAM resources for memory. -For example: - -.. code-block:: yoscrypt - - memory -nomap; techmap -map my_memory_map.v; memory_map - -For more information about :cmd:ref:`memory`, such as disabling certain sub -commands, see :doc:`/cmd/memory`. - -Example -^^^^^^^ - -.. todo:: describe ``memory`` images - -.. figure:: /_images/code_examples/synth_flow/memory_01.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/memory_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/memory_01.ys`` - -.. literalinclude:: /code_examples/synth_flow/memory_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/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: ``docs/source/code_examples/synth_flow/memory_02.v`` - -.. literalinclude:: /code_examples/synth_flow/memory_02.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/memory_02.ys`` - -The :cmd:ref:`memory_libmap` command -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. todo:: :cmd:ref:`memory_libmap` description - -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: - -#. :cmd:ref:`fsm_detect` identifies FSM state registers and marks them - with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the - ``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" - *)`` to disable FSM optimization for a register. -#. :cmd:ref:`fsm_extract` replaces the entire FSM (logic and state registers) - with a ``$fsm`` cell. -#. :cmd:ref:`fsm_opt` optimizes the FSM. Called multiple times. -#. :cmd:ref:`fsm_expand` optionally merges additional auxilliary gates into the - ``$fsm`` cell. -#. :cmd:ref:`fsm_recode` also optimizes the FSM. -#. :cmd:ref:`fsm_info` logs internal FSM information. -#. :cmd:ref:`fsm_export` optionally exports each FSM to KISS2 files. -#. :cmd:ref:`fsm_map` converts the (optimized) ``$fsm`` cell back to logic and - registers. - -See also :doc:`/cmd/fsm`. - -DSP handling -~~~~~~~~~~~~ - -.. todo:: add info about dsp handling - -Technology mapping -~~~~~~~~~~~~~~~~~~ - -The :cmd:ref:`techmap` command replaces cells with implementations given as -verilog source. For example implementing a 32 bit adder using 16 bit adders: - -.. figure:: /_images/code_examples/synth_flow/techmap_01.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/techmap_01_map.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` - -.. literalinclude:: /code_examples/synth_flow/techmap_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/techmap_01.v`` - -.. literalinclude:: /code_examples/synth_flow/techmap_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` - -See :doc:`/yosys_internals/techmap` for more. - -stdcell mapping -^^^^^^^^^^^^^^^ - -When :cmd:ref:`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. - -The built-in logic gate types are: ``$_NOT_``, ``$_AND_``, ``$_OR_``, -``$_XOR_``, and ``$_MUX_``. - -The register types are: ``$_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_``, and ``$_DLATCH_P_``. - -See :doc:`/yosys_internals/formats/cell_library` for more about the internal -cells used. - -The :cmd:ref:`abc` command -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The :cmd:ref:`abc` command provides an interface to ABC_, an open source tool -for low-level logic synthesis. - -.. _ABC: http://www.eecs.berkeley.edu/~alanmi/abc/ - -The :cmd:ref:`abc` command processes a netlist of internal gate types and can -perform: - -- logic minimization (optimization) -- mapping of logic to standard cell library (liberty format) -- mapping of logic to k-LUTs (for FPGA synthesis) - -Optionally :cmd:ref:`abc` can process registers from one clock domain and -perform sequential optimization (such as register balancing). - -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 -:cmd:ref:`write_blif` and load the output file into ABC outside of Yosys. - -Example -^^^^^^^ - -.. todo:: describe ``abc`` images - -.. literalinclude:: /code_examples/synth_flow/abc_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/abc_01.v`` - -.. literalinclude:: /code_examples/synth_flow/abc_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/abc_01.ys`` - -.. figure:: /_images/code_examples/synth_flow/abc_01.* - :class: width-helper - -Other special-purpose mapping commands -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The commands below may be used depending on the targeted architecture for -compatibility with, or to take advantage of, resources available. - -:cmd:ref:`dfflibmap` - This command maps the internal register cell types to the register types - described in a liberty file. - -: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. - -:cmd:ref:`alumacc` - Translate arithmetic operations like $add, $mul, $lt, etc. to $alu and $macc - cells. - -:cmd:ref:`dfflegalize` - Specify a set of supported FF cells/cell groups and convert all FFs to them. - -:cmd:ref:`deminout` - Convert inout ports to input or output ports, if possible. - -:cmd:ref:`pmuxtree` - Transforms parallel mux cells, ``$pmux``, to trees of ``$mux`` cells. diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index f16298ce0..976de0cbd 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -2,8 +2,9 @@ More scripting -------------- .. toctree:: - :maxdepth: 3 + :maxdepth: 3 - selections - interactive_investigation - troubleshooting + load_design + selections + interactive_investigation + troubleshooting 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 000000000..91da5b538 --- /dev/null +++ b/docs/source/using_yosys/more_scripting/load_design.rst @@ -0,0 +1,37 @@ +Loading a design +~~~~~~~~~~~~~~~~ + +keyword: Frontends + +- :doc:`/cmd/read_verilog` + +.. todo:: include ``read_verilog <<EOF``, also other methods of loading designs + +.. code-block:: yoscrypt + + 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 + +Others: + +- :doc:`/cmd/read` +- `GHDL plugin`_ for VHDL +- :doc:`/cmd/read_rtlil` (direct textual representation of Yosys internal state) +- :doc:`/cmd/read_aiger` +- :doc:`/cmd/read_blif` +- :doc:`/cmd/read_json` +- :doc:`/cmd/read_liberty` + +.. _GHDL plugin: https://github.com/ghdl/ghdl-yosys-plugin diff --git a/docs/source/using_yosys/synthesis/abc.rst b/docs/source/using_yosys/synthesis/abc.rst new file mode 100644 index 000000000..a46072fee --- /dev/null +++ b/docs/source/using_yosys/synthesis/abc.rst @@ -0,0 +1,39 @@ +The :cmd:ref:`abc` command +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: discuss abc (more stable) vs abc9 (newer, possibly better) + +The :cmd:ref:`abc` command provides an interface to ABC_, an open source tool +for low-level logic synthesis. + +.. _ABC: http://www.eecs.berkeley.edu/~alanmi/abc/ + +The :cmd:ref:`abc` command processes a netlist of internal gate types and can +perform: + +- logic minimization (optimization) +- mapping of logic to standard cell library (liberty format) +- mapping of logic to k-LUTs (for FPGA synthesis) + +Optionally :cmd:ref:`abc` can process registers from one clock domain and +perform sequential optimization (such as register balancing). + +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 +:cmd:ref:`write_blif` and load the output file into ABC outside of Yosys. + +Example +^^^^^^^ + +.. todo:: describe ``abc`` images + +.. literalinclude:: /code_examples/synth_flow/abc_01.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/abc_01.v`` + +.. literalinclude:: /code_examples/synth_flow/abc_01.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/abc_01.ys`` + +.. figure:: /_images/code_examples/synth_flow/abc_01.* + :class: width-helper diff --git a/docs/source/using_yosys/synthesis/opt_passes.rst b/docs/source/using_yosys/synthesis/fsm.rst similarity index 52% rename from docs/source/using_yosys/synthesis/opt_passes.rst rename to docs/source/using_yosys/synthesis/fsm.rst index f3c9c92f9..11da17eba 100644 --- a/docs/source/using_yosys/synthesis/opt_passes.rst +++ b/docs/source/using_yosys/synthesis/fsm.rst @@ -1,160 +1,26 @@ -.. _chapter:opt: +FSM handling +============ -Optimization passes -=================== +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: -.. todo:: check text context, also check the optimization passes still do what they say +#. :cmd:ref:`fsm_detect` identifies FSM state registers and marks them + with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the + ``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" + *)`` to disable FSM optimization for a register. +#. :cmd:ref:`fsm_extract` replaces the entire FSM (logic and state registers) + with a ``$fsm`` cell. +#. :cmd:ref:`fsm_opt` optimizes the FSM. Called multiple times. +#. :cmd:ref:`fsm_expand` optionally merges additional auxilliary gates into the + ``$fsm`` cell. +#. :cmd:ref:`fsm_recode` also optimizes the FSM. +#. :cmd:ref:`fsm_info` logs internal FSM information. +#. :cmd:ref:`fsm_export` optionally exports each FSM to KISS2 files. +#. :cmd:ref:`fsm_map` converts the (optimized) ``$fsm`` cell back to logic and + registers. -Yosys employs a number of optimizations to generate better and cleaner results. -This chapter outlines these optimizations. - -Simple optimizations --------------------- - -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. At the time of -this writing the :cmd:ref:`opt` pass executes the following passes that each -perform a simple optimization: - -- Once at the beginning of :cmd:ref:`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 :cmd:ref:`opt_expr` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This pass performs const 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` - ========= ========= =========== - -.. todo:: How to format table? - -:numref:`Table %s <tab:opt_expr_and>` 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. - -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. - -The :cmd:ref:`opt_muxtree` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This pass optimizes trees of multiplexer cells by analyzing the select inputs. -Consider the following simple example: - -.. code:: verilog - - 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 :cmd:ref:`opt_muxtree` pass -detects this contradiction and replaces the inner multiplexer with a constant 1, -yielding the logic for ``y = a ? 1 : 3``. - -The :cmd:ref:`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 -~~~~~~~~~~~~~~~~~~~~~~ - -.. todo:: Update to ``opt_dff`` - -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 :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`opt_muxtree` to identify -possible optimizations. - -FSM extraction and encoding ---------------------------- +See also :doc:`/cmd/fsm`. The fsm pass performs finite-state-machine (FSM) extraction and recoding. The fsm pass simply executes the following other passes: @@ -328,14 +194,4 @@ 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 :ref:`sec:techmap_extern` -for details). +Formality. diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst index b8dba55e9..007fd555d 100644 --- a/docs/source/using_yosys/synthesis/index.rst +++ b/docs/source/using_yosys/synthesis/index.rst @@ -5,6 +5,9 @@ Synthesis in detail :maxdepth: 3 synth - opt_passes proc - memory_mapping + fsm + memory + opt + abc + diff --git a/docs/source/using_yosys/synthesis/memory_mapping.rst b/docs/source/using_yosys/synthesis/memory.rst similarity index 86% rename from docs/source/using_yosys/synthesis/memory_mapping.rst rename to docs/source/using_yosys/synthesis/memory.rst index 7fd0a3eb9..721a86672 100644 --- a/docs/source/using_yosys/synthesis/memory_mapping.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -1,20 +1,88 @@ -.. _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 the other common +``memory_*`` commands in a sensible order: + +.. todo:: fill out missing :cmd:ref:`memory` subcommands descriptions + +#. :cmd:ref:`memory_bmux2rom` +#. :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. +#. :cmd:ref:`memory_share` +#. :cmd:ref:`memory_memx` +#. :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_bram` +#. :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 + +.. figure:: /_images/code_examples/synth_flow/memory_01.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/memory_01.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/memory_01.ys`` + +.. literalinclude:: /code_examples/synth_flow/memory_01.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/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: ``docs/source/code_examples/synth_flow/memory_02.v`` + +.. literalinclude:: /code_examples/synth_flow/memory_02.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/memory_02.ys`` + +.. _memory_map: Memory mapping -============== +^^^^^^^^^^^^^^ -Documentation for the Yosys :cmd:ref:`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. +.. todo:: :cmd:ref:`memory_libmap` description + +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 + +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. See also: `passes/memory/memlib.md <https://github.com/YosysHQ/yosys/blob/master/passes/memory/memlib.md>`_ -Additional notes ----------------- +Notes +----- Memory kind selection ~~~~~~~~~~~~~~~~~~~~~ @@ -95,7 +163,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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -128,6 +198,8 @@ Write port with byte enables Simple dual port (SDP) memory patterns -------------------------------------- +.. todo:: assorted enables, e.g. cen, wen+ren + Asynchronous-read SDP ~~~~~~~~~~~~~~~~~~~~~ @@ -219,6 +291,8 @@ Synchronous SDP with undefined collision behavior read_data <= mem[read_addr]; end +.. _sdp_wf: + Synchronous SDP with write-first behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -335,6 +409,8 @@ Synchronous single-port RAM with write-first behavior read_data <= mem[addr]; end +.. _sr_init: + Synchronous read port with initial value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -436,6 +512,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 ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -597,7 +675,7 @@ Patterns only supported with Verific Synchronous SDP with write-first behavior via blocking assignments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Use `Synchronous SDP with write-first behavior`_ for compatibility with Yosys +- Use `sdp_wf`_ for compatibility with Yosys Verilog frontend. .. code:: verilog @@ -615,8 +693,8 @@ Synchronous SDP with write-first behavior via blocking assignments Asymmetric memories via part selection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Build wide ports out of narrow ports instead (see `Wide synchronous read - port`_) for compatibility with Yosys Verilog frontend. +- 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 000000000..7851e78be --- /dev/null +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -0,0 +1,233 @@ +Optimization passes +=================== + +.. todo:: check text context, also check the optimization passes still do what they say + +Yosys employs a number of optimizations to generate better and cleaner results. +This chapter outlines these optimizations. + +The :cmd:ref:`opt` pass +-------------------------- + +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. At the time of +this writing the :cmd:ref:`opt` pass executes the following passes that each +perform a simple optimization: + +.. code-block:: yoscrypt + + 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] + +The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And +``;;`` can be used as shortcut for :cmd:ref:`clean`. For example: + +.. code-block:: yoscrypt + + hierarchy; proc; opt; memory; opt_expr;; fsm;; + +The :cmd:ref:`opt_expr` pass +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This pass performs const 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` + ========= ========= =========== + +.. todo:: How to format table? + +:numref:`Table %s <tab:opt_expr_and>` 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. + +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. + +The :cmd:ref:`opt_muxtree` pass +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This pass optimizes trees of multiplexer cells by analyzing the select inputs. +Consider the following simple example: + +.. code:: verilog + + 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 :cmd:ref:`opt_muxtree` pass +detects this contradiction and replaces the inner multiplexer with a constant 1, +yielding the logic for ``y = a ? 1 : 3``. + +The :cmd:ref:`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 +~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: Update to ``opt_dff`` + +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 :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`opt_muxtree` to identify +possible optimizations. + +Example +~~~~~~~ + +.. todo:: describe ``opt`` images + +.. figure:: /_images/code_examples/synth_flow/opt_01.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/opt_01.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/opt_01.ys`` + +.. literalinclude:: /code_examples/synth_flow/opt_01.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/opt_01.v`` + +.. figure:: /_images/code_examples/synth_flow/opt_02.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/opt_02.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/opt_02.ys`` + +.. literalinclude:: /code_examples/synth_flow/opt_02.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/opt_02.v`` + +.. figure:: /_images/code_examples/synth_flow/opt_03.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/opt_03.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/opt_03.ys`` + +.. literalinclude:: /code_examples/synth_flow/opt_03.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/opt_03.v`` + +.. figure:: /_images/code_examples/synth_flow/opt_04.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/opt_04.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/opt_04.v`` + +.. literalinclude:: /code_examples/synth_flow/opt_04.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/opt_04.ys`` + +When to use :cmd:ref:`opt` or :cmd:ref:`clean` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually it does not hurt to call :cmd:ref:`opt` after each regular command in +the synthesis script. But it increases the synthesis time, so it is favourable +to only call :cmd:ref:`opt` when an improvement can be achieved. + +It is generally a good idea to call :cmd:ref:`opt` before inherently expensive +commands such as :cmd:ref:`sat` or :cmd:ref:`freduce`, as the possible gain is +much higher in these cases as the possible loss. + +The :cmd:ref:`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 +``;;`` is a good idea in every synthesis script. + +Other optimizations +------------------- + +.. todo:: more on the other optimizations + +- :doc:`/cmd/wreduce` +- :doc:`/cmd/peepopt` +- :doc:`/cmd/share` +- :cmd:ref:`abc` and :cmd:ref:`abc9`, see also: :doc:`abc`. diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst index 1d7b823be..498e1264a 100644 --- a/docs/source/using_yosys/synthesis/proc.rst +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -1,4 +1,67 @@ -The :cmd:ref:`proc` command ---------------------------- +Converting process blocks +~~~~~~~~~~~~~~~~~~~~~~~~~ -text +The Verilog frontend converts ``always``-blocks to RTL netlists for the +expressions and "processess" for the control- and memory elements. The +:cmd:ref:`proc` command then transforms these "processess" to netlists of RTL +multiplexer and register cells. It also is a macro command that calls the other +``proc_*`` commands in a sensible order: + +#. :cmd:ref:`proc_clean` removes empty branches and processes. +#. :cmd:ref:`proc_rmdead` removes unreachable branches. +#. :cmd:ref:`proc_prune` +#. :cmd:ref:`proc_init` special handling of "initial" blocks. +#. :cmd:ref:`proc_arst` identifies modeling of async resets. +#. :cmd:ref:`proc_rom` +#. :cmd:ref:`proc_mux` converts decision trees to multiplexer networks. +#. :cmd:ref:`proc_dlatch` +#. :cmd:ref:`proc_dff` extracts registers from processes. +#. :cmd:ref:`proc_memwr` +#. :cmd:ref:`proc_clean` this should remove all the processes, provided all went + fine. + +After all the ``proc_*`` commands, :yoscrypt:`opt_expr` is called. This can be +disabled by calling :yoscrypt:`proc -noopt`. For more information about +:cmd:ref:`proc`, such as disabling certain sub commands, see :doc:`/cmd/proc`. + +Many commands can not operate on modules with "processess" in them. Usually a +call to :cmd:ref:`proc` is the first command in the actual synthesis procedure +after design elaboration. + +Example +^^^^^^^ + +.. todo:: describe ``proc`` images + +.. literalinclude:: /code_examples/synth_flow/proc_01.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/proc_01.v`` + +.. literalinclude:: /code_examples/synth_flow/proc_01.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/proc_01.ys`` + +.. figure:: /_images/code_examples/synth_flow/proc_01.* + :class: width-helper + +.. figure:: /_images/code_examples/synth_flow/proc_02.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/proc_02.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/proc_02.v`` + +.. literalinclude:: /code_examples/synth_flow/proc_02.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/proc_02.ys`` + +.. figure:: /_images/code_examples/synth_flow/proc_03.* + :class: width-helper + +.. literalinclude:: /code_examples/synth_flow/proc_03.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/proc_03.ys`` + +.. literalinclude:: /code_examples/synth_flow/proc_03.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/proc_03.v`` diff --git a/docs/source/using_yosys/synthesis/synth.rst b/docs/source/using_yosys/synthesis/synth.rst index 2ac717f05..62cac991b 100644 --- a/docs/source/using_yosys/synthesis/synth.rst +++ b/docs/source/using_yosys/synthesis/synth.rst @@ -1,15 +1,5 @@ -Introduction to synthesis -------------------------- - -The generic ``synth`` -~~~~~~~~~~~~~~~~~~~~~ - -The following commands are executed by the :cmd:ref:`synth` command: - -.. literalinclude:: /cmd/synth.rst - :start-at: begin: - :end-before: .. raw:: latex - :dedent: +Synth commands +-------------- Packaged ``synth_*`` commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -38,3 +28,20 @@ being targeted. - :doc:`/cmd/synth_quicklogic` - :doc:`/cmd/synth_sf2` - :doc:`/cmd/synth_xilinx` + +General synthesis +~~~~~~~~~~~~~~~~~ + +In addition to the above hardware-specific synth commands, there is also +:doc:`/cmd/prep`. This command is limited to coarse-grain synthesis, without +getting into any architecture-specific mappings or optimizations. Among other +things, this is useful for design verification. + +The following commands are executed by the :cmd:ref:`prep` command: + +.. literalinclude:: /cmd/prep.rst + :start-at: begin: + :end-before: .. raw:: latex + :dedent: + +The following sections will get more into what each of these commands do. From aef9921fc9866ee6c28627f4ea0599fe05b4c70b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 8 Dec 2023 09:46:02 +1300 Subject: [PATCH 049/108] Tidying TODOs --- docs/source/getting_started/example_synth.rst | 9 +++++++-- docs/source/introduction.rst | 13 +++++++++++-- .../using_yosys/more_scripting/load_design.rst | 3 +++ docs/source/using_yosys/yosys_flows.rst | 5 +++-- .../yosys_internals/flow/verilog_frontend.rst | 4 +--- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index d155d41c9..b3d4aa679 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -23,6 +23,9 @@ A simple counter .. role:: yoscrypt(code) :language: yoscrypt +.. todo:: consider changing simple counter example for something with memory + using e.g. synth_ice40 to cover more of the synth flow + This section covers an `example project`_ available in ``docs/source/code_examples/intro/``. The project contains a simple ASIC synthesis script (``counter.ys``), a digital design written in Verilog @@ -181,11 +184,11 @@ Some of the commands we might use here are: - :doc:`/cmd/alumacc`, and - :doc:`/cmd/share`. -We could have also - Logic gate mapping ~~~~~~~~~~~~~~~~~~ +.. todo:: example_synth mapping to gates + :yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain logic gates (AND, OR, NOT, etc.). @@ -207,6 +210,8 @@ cells used. Mapping to hardware ~~~~~~~~~~~~~~~~~~~ +.. todo:: example_synth mapping to hardware + :ref:`cmos_lib` #. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 727426fa8..7f5f1e106 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -117,13 +117,22 @@ Benefits of open source HDL synthesis The extended Yosys universe --------------------------- -.. todo:: links and add SCY - In no particular order: - SBY for formal verification + - https://github.com/YosysHQ/sby + - https://yosyshq.readthedocs.io/projects/sby + - EQY for equivalence checking + - https://github.com/YosysHQ/eqy + - https://yosyshq.readthedocs.io/projects/eqy + - MCY for mutation coverage + - https://github.com/YosysHQ/mcy + - https://yosyshq.readthedocs.io/projects/mcy + +- SCY for deep formal traces + - https://github.com/YosysHQ/scy History of Yosys ---------------- diff --git a/docs/source/using_yosys/more_scripting/load_design.rst b/docs/source/using_yosys/more_scripting/load_design.rst index 91da5b538..d64c50959 100644 --- a/docs/source/using_yosys/more_scripting/load_design.rst +++ b/docs/source/using_yosys/more_scripting/load_design.rst @@ -24,6 +24,9 @@ keyword: Frontends read_verilog file6.v verilog_defaults -pop +.. todo:: more info on other ``read_*`` commands, also is this the first time we + mention verific? + Others: - :doc:`/cmd/read` diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 170db416c..a3fae32a4 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -39,7 +39,8 @@ The extract pass 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 +.. todo:: add/expand supporting text, also mention custom pattern matching and + pmgen .. literalinclude:: /code_examples/macc/macc_simple_test.ys :language: yoscrypt @@ -277,7 +278,7 @@ Checking. Checking techmap ~~~~~~~~~~~~~~~~ -.. todo:: add/expand supporting text +.. todo:: add/expand supporting text, reference no longer exists Remember the following example from :doc:`/getting_started/typical_phases`? diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index 6a0389f20..b36eb3bbf 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -409,9 +409,7 @@ 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. - -.. todo:: The ``proc_adff`` pass doesn't exist anymore? +is done by the ``proc_arst`` pass. The ProcessGenerator algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 25f6a98f520e346c882c574ed0a3a9be6df64b81 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:46:05 +1300 Subject: [PATCH 050/108] Updating the intro Based on the Ignite presentation and github. Adds links for the extended Yosys universe. Moves the original thesis stuff further down (and labels it as such). --- docs/source/introduction.rst | 154 ++++++++++++++++++++++------------- 1 file changed, 98 insertions(+), 56 deletions(-) diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 7f5f1e106..b4934ad78 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -1,47 +1,46 @@ What is Yosys ============= -.. todo:: rewrite to not be a thesis abstract +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. -:Abstract: - Most of today's digital design is done in HDL code (mostly Verilog or - VHDL) and with the help of HDL synthesis tools. +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. - 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. +.. _open source: https://github.com/YosysHQ/yosys - 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. +.. note:: Yosys is released under the ISC License: - 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. + 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. - This document was originally published as bachelor thesis at the Vienna - University of Technology :cite:p:`BACC`. +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`_. -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. +.. _nextpnr: https://github.com/YosysHQ/nextpnr +.. _OpenLane flow: https://github.com/The-OpenROAD-Project/OpenLane +.. _SMT2: https://smtlib.cs.uiowa.edu/ -.. figure:: /_images/primer/levels_of_abstraction.* +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 - :name: fig:Levels_of_abstraction - - Where Yosys exists in the layers of abstraction What you can do with Yosys -------------------------- @@ -72,8 +71,71 @@ Things you can't do .. _nextpnr: https://github.com/YosysHQ/nextpnr +The extended Yosys universe +--------------------------- + +In no particular order: + +- SBY for formal verification + - https://github.com/YosysHQ/sby + - https://yosyshq.readthedocs.io/projects/sby + +- EQY for equivalence checking + - https://github.com/YosysHQ/eqy + - https://yosyshq.readthedocs.io/projects/eqy + +- MCY for mutation coverage + - https://github.com/YosysHQ/mcy + - https://yosyshq.readthedocs.io/projects/mcy + +- SCY for deep formal traces + - 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): @@ -114,30 +176,10 @@ Benefits of open source HDL synthesis purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. -The extended Yosys universe ---------------------------- - -In no particular order: - -- SBY for formal verification - - https://github.com/YosysHQ/sby - - https://yosyshq.readthedocs.io/projects/sby - -- EQY for equivalence checking - - https://github.com/YosysHQ/eqy - - https://yosyshq.readthedocs.io/projects/eqy - -- MCY for mutation coverage - - https://github.com/YosysHQ/mcy - - https://yosyshq.readthedocs.io/projects/mcy - -- SCY for deep formal traces - - https://github.com/YosysHQ/scy - History of Yosys ----------------- +~~~~~~~~~~~~~~~~ -.. todo:: make less academic +.. 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 From f949579cf3aac26b35ad16138717dae90104c50c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:19:12 +1300 Subject: [PATCH 051/108] Testing latexpdf build Also added `seealso` blocks to example synth. --- docs/source/getting_started/example_synth.rst | 11 +++++++++- docs/source/index.rst | 20 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index b3d4aa679..c4da2dd8c 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -111,6 +111,8 @@ Our circuit now looks like this: ``counter`` module after :cmd:ref:`hierarchy` +.. seealso:: Advanced usage docs for :doc:`/using_yosys/more_scripting/load_design` + Elaboration ~~~~~~~~~~~ @@ -158,6 +160,8 @@ Depending on the target architecture, we might also run commands such as remove tristate and inout constructs respectively, replacing them with logic suitable for mapping to an FPGA. +.. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/proc` + The coarse-grain representation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -184,6 +188,9 @@ Some of the commands we might use here are: - :doc:`/cmd/alumacc`, and - :doc:`/cmd/share`. +.. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/fsm`, and + :doc:`/using_yosys/synthesis/memory` + Logic gate mapping ~~~~~~~~~~~~~~~~~~ @@ -239,6 +246,8 @@ Mapping to hardware :cmd:ref:`dfflegalize` Specify a set of supported FF cells/cell groups and convert all FFs to them. +.. seealso:: Advanced usage docs for :doc:`/yosys_internals/techmap` + .. _cmos_lib: The CMOS cell library @@ -261,4 +270,4 @@ The script file :language: yoscrypt :caption: ``docs/source/code_examples/intro/counter.ys`` -See also :doc:`/using_yosys/synthesis/synth`. +.. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/synth` diff --git a/docs/source/index.rst b/docs/source/index.rst index 0a776393a..c19036f81 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,6 +2,16 @@ Yosys Open SYnthesis Suite ================================================================================ +.. todo:: better landing page + + Consider adding something here that isn't just table of contents since this + *is* the root page and is where the logo links to. + +.. only:: html + + Table of contents + ----------------- + .. toctree:: :maxdepth: 3 @@ -13,11 +23,13 @@ Yosys Open SYnthesis Suite appendix -Indices -------- +.. only:: html -- :ref:`commandindex` -- :ref:`tagindex` + Indices + ------- + + - :ref:`commandindex` + - :ref:`tagindex` TODOs ----- From 4ecceaed44573e080a98f787626e38deb50c64b3 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:44:05 +1300 Subject: [PATCH 052/108] Updates to install and tests Includes CAD suite info and details on the OSS CAD suite nightly build targets. Instructions for building from source, largely based on the readme but with some minor modifications. Tests are still WIP, but we replaced the old test suites with a brief comment on the github workflow tests. Still needs more on the tests themselves and how to run them locally. Also an extra todo on the index page. --- docs/source/getting_started/installation.rst | 138 ++++++++++++++++++- docs/source/index.rst | 6 + docs/source/test_suites.rst | 57 ++------ 3 files changed, 152 insertions(+), 49 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 1677445fa..f32cdf69d 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -1,14 +1,148 @@ Installation ------------ -.. todo:: update and finish installation instructions +This document will guide you through the process of installing Yosys. + +CAD suite(s) +~~~~~~~~~~~~ + +Yosys is part of the `Tabby CAD Suite +<https://www.yosyshq.com/tabby-cad-datasheet>`_ and the `OSS CAD Suite +<https://github.com/YosysHQ/oss-cad-suite-build>`_! The easiest way to use yosys +is to install the binary software suite, which contains all required +dependencies and related tools. + +* `Contact YosysHQ <https://www.yosyshq.com/contact>`_ for a `Tabby CAD Suite + <https://www.yosyshq.com/tabby-cad-datasheet>`_ 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 + <https://github.com/YosysHQ/oss-cad-suite-build#installation>`_ + +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: + +- linux-x64 |linux-x64| + - Most personal Linux based computers + +- darwin-x64 |darwin-x64| + - macOS 10.14 or later with Intel CPU + +- darwin-arm64 |darwin-arm64| + - macOS 11.00 or later with M1 CPU + +- windows-x64 |windows-x64| + - Targeted for Windows 10 and 11, but older 64-bit version of Windows 7, 8, + or 8.1 should work + +- linux-arm |linux-arm| +- linux-arm64 |linux-arm64| +- linux-riscv64 (untested) |linux-riscv64| + +.. _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-arm| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-arm.yml/badge.svg +.. |linux-arm64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-arm64.yml/badge.svg +.. |linux-riscv64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-riscv64.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, libffi, and Python3.6 or later. Some +additional tools: readline, Tcl and zlib; are optional but enabled by default +(see ``ENABLE_*`` settings in Makefile). Xdot (graphviz) is optional unless +using the :cmd:ref:`show` command to display schematics. + +.. + unclear if libffi is required now or still optional + readme says optional, but I can't find a corresponding ENABLE_* + +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 +^^^^^^^^^^^^^^^^^^^^^^^^ + +To configure the build system to use a specific compiler, use one of the +following: + +.. code:: console + + make config-clang + make config-gcc + +Then, simply run ``make`` in this directory. + +.. code:: console + + make + sudo make install + +Note that this also downloads, builds, and installs ABC (using yosys-abc as the +executable name). + +.. seealso:: + + Refer to :doc:`/test_suites` for details on testing Yosys once compiled. Source tree and build system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. todo:: check if source tree/build system details need updating + The Yosys source tree is organized into the following top-level directories: diff --git a/docs/source/index.rst b/docs/source/index.rst index c19036f81..17e12f123 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -7,6 +7,12 @@ Yosys Open SYnthesis Suite Consider adding something here that isn't just table of contents since this *is* the root page and is where the logo links to. +.. todo:: look into command ref improvements + + - Search bar with live drop down suggestions for matching on title / + autocompleting commands + - Scroll the left sidebar to the current location on page load + .. only:: html Table of contents diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index fde337b28..3fa84ad3e 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -1,55 +1,18 @@ Test suites =========== -.. note:: Potentially significantly out of date information - last updated circa 2015 +.. todo:: more about the included test suite -.. todo:: update content from 2015 +Automatic testing +----------------- -Continuously checking the correctness of Yosys and making sure that new features -do not break old ones is a high priority in Yosys. Two external test suites -have been built for Yosys: VlogHammer and yosys-bigsim. In addition to that, -yosys comes with approx 200 test cases used in ``make test``. A debug build of -Yosys also contains a lot of asserts and checks the integrity of the internal -state after each command. +The `Yosys Git repo`_ has automatic testing of builds and running of the +included test suite on the following platforms: -VlogHammer ----------- +- Ubuntu 20.04 (Focal Fossa) |test-linux| +- macOS 11 (Big Sur) |test-macos| -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, ...). +.. _Yosys Git repo: https://github.com/YosysHQ/yosys -Yosys Subsystems tested: Verilog frontend, const folding, const eval, technology -mapping, simulation models, SAT models. - -Thousands of auto-generated test cases containing code such as: - -.. code-block:: 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}))))})); - -Some bugs in Yosys were found and fixed thanks to VlogHammer. Over 50 bugs in -the other tools used as external reference where found and reported so far. - -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. - -The following designs are included in yosys-bigsim (excerpt): - -- ``openmsp430`` -- an MSP430 compatible 16 bit CPU -- ``aes_5cycle_2stage`` -- an AES encryption core -- ``softusb_navre`` -- an AVR compatible 8 bit CPU -- ``amber23`` -- an ARMv2 compatible 32 bit CPU -- ``lm32`` -- another 32 bit CPU from Lattice Semiconductor -- ``verilog-pong`` -- a hardware pong game with VGA output -- ``elliptic_curve_group`` -- ECG point-add and point-scalar-mul core -- ``reed_solomon_decoder`` -- a Reed-Solomon Error Correction Decoder - -Code available at https://github.com/YosysHQ/yosys-bigsim +.. |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 From e34a25ea273ab11b268e666589d9b5b5e073515f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:05:45 +1300 Subject: [PATCH 053/108] TODOs Blocking tasks are now capital TODO (compared to non-blocking todo). Updated some of the todos. Added note about which intel synth does which families. Rename extended Yosys universe to Yosys family. Added brief text to landing page, and also a note about the restructure and where to find old docs. Moved todolist above ToC in preparation for disabling it in the config (so that it doesn't need it's own header). Fixed pdf build, was previously breaking on trying to include the svg badges. --- docs/source/appendix/auxlibs.rst | 2 +- docs/source/appendix/auxprogs.rst | 2 +- docs/source/getting_started/example_synth.rst | 15 ++++---- docs/source/getting_started/index.rst | 2 ++ docs/source/getting_started/installation.rst | 28 ++++++++------- .../getting_started/scripting_intro.rst | 2 +- docs/source/index.rst | 35 ++++++++++--------- docs/source/introduction.rst | 15 +++++--- docs/source/test_suites.rst | 6 ++-- docs/source/using_yosys/index.rst | 2 ++ .../using_yosys/more_scripting/index.rst | 2 ++ .../interactive_investigation.rst | 2 +- .../using_yosys/more_scripting/selections.rst | 2 +- docs/source/using_yosys/synthesis/abc.rst | 2 +- docs/source/using_yosys/synthesis/index.rst | 2 ++ docs/source/using_yosys/synthesis/memory.rst | 2 +- docs/source/using_yosys/synthesis/opt.rst | 4 +-- docs/source/using_yosys/synthesis/synth.rst | 9 +++-- docs/source/using_yosys/yosys_flows.rst | 2 +- .../yosys_internals/formats/rtlil_rep.rst | 2 +- 20 files changed, 78 insertions(+), 60 deletions(-) diff --git a/docs/source/appendix/auxlibs.rst b/docs/source/appendix/auxlibs.rst index a77eb8b3f..4c845f197 100644 --- a/docs/source/appendix/auxlibs.rst +++ b/docs/source/appendix/auxlibs.rst @@ -4,7 +4,7 @@ Auxiliary libraries The Yosys source distribution contains some auxiliary libraries that are compiled into Yosys and can be used in plugins. -.. todo:: fill out the newer auxiliary libs +.. TODO:: fill out the newer auxiliary libs BigInt ------ diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index 6b2d04d71..2235bbd89 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -19,7 +19,7 @@ Yosys. See :doc:`/yosys_internals/extensions` for details. yosys-filterlib --------------- -.. todo:: how does a filterlib rules-file work? is this still supported? +.. 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 diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index c4da2dd8c..6dac3a9a9 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -23,8 +23,9 @@ A simple counter .. role:: yoscrypt(code) :language: yoscrypt -.. todo:: consider changing simple counter example for something with memory - using e.g. synth_ice40 to cover more of the synth flow +.. TODO:: move current example synth as mapping to cell libraries + + replace with a walk through of synth_ice40 This section covers an `example project`_ available in ``docs/source/code_examples/intro/``. The project contains a simple ASIC @@ -77,7 +78,7 @@ stopping the following commands from trying to work on them. By passing the that if the design includes any non-blackbox modules without an implementation it should return an error. -.. todo:: more on why :cmd:ref:`hierarchy` is important +.. TODO:: more on why :cmd:ref:`hierarchy` is important .. note:: @@ -147,7 +148,7 @@ Much better. We can now see that the ``$dff`` and ``$mux`` cells have been replaced with a single ``$sdffe``, using the built-in enable and reset ports instead. -.. todo:: a bit more on :cmd:ref:`opt` here +.. TODO:: a bit more on :cmd:ref:`opt` here At this stage of a synthesis flow there are a few other commands we could run. First off is :cmd:ref:`flatten`. If we had any modules within our ``counter``, @@ -176,7 +177,7 @@ 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. -.. todo:: talk more about DSPs (and their associated commands) +.. TODO:: talk more about DSPs (and their associated commands) Some of the commands we might use here are: @@ -194,7 +195,7 @@ Some of the commands we might use here are: Logic gate mapping ~~~~~~~~~~~~~~~~~~ -.. todo:: example_synth mapping to gates +.. TODO:: example_synth mapping to gates :yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain logic gates (AND, OR, NOT, etc.). @@ -217,7 +218,7 @@ cells used. Mapping to hardware ~~~~~~~~~~~~~~~~~~~ -.. todo:: example_synth mapping to hardware +.. TODO:: example_synth mapping to hardware :ref:`cmos_lib` diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index 2f89a71cd..a3c4a265b 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -1,6 +1,8 @@ Getting started with Yosys ========================== +.. todo:: brief overview for the getting started index + .. toctree:: :maxdepth: 3 diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index f32cdf69d..66c5a3335 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -34,22 +34,24 @@ Targeted architectures The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures: -- linux-x64 |linux-x64| - - Most personal Linux based computers +.. only:: html -- darwin-x64 |darwin-x64| - - macOS 10.14 or later with Intel CPU + - linux-x64 |linux-x64| + - Most personal Linux based computers -- darwin-arm64 |darwin-arm64| - - macOS 11.00 or later with M1 CPU + - darwin-x64 |darwin-x64| + - macOS 10.14 or later with Intel CPU -- windows-x64 |windows-x64| - - Targeted for Windows 10 and 11, but older 64-bit version of Windows 7, 8, - or 8.1 should work + - darwin-arm64 |darwin-arm64| + - macOS 11.00 or later with M1 CPU -- linux-arm |linux-arm| -- linux-arm64 |linux-arm64| -- linux-riscv64 (untested) |linux-riscv64| + - windows-x64 |windows-x64| + - Targeted for Windows 10 and 11, but older 64-bit version of Windows 7, + 8, or 8.1 should work + + - linux-arm |linux-arm| + - linux-arm64 |linux-arm64| + - linux-riscv64 (untested) |linux-riscv64| .. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build .. _nightly builds: https://github.com/YosysHQ/oss-cad-suite-build/releases/latest @@ -141,7 +143,7 @@ executable name). Source tree and build system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: check if source tree/build system details need updating +.. TODO:: check if source tree/build system details need updating The Yosys source tree is organized into the following top-level directories: diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index fd2aeee88..d065a6485 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -1,7 +1,7 @@ Scripting in Yosys ------------------ -.. todo:: check logical consistency +.. TODO:: logical consistency, esp with example_synth Yosys reads and processes commands from synthesis scripts, command line arguments and an interactive command prompt. Yosys commands consist of a command diff --git a/docs/source/index.rst b/docs/source/index.rst index 17e12f123..bbefa521f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,16 +2,30 @@ Yosys Open SYnthesis Suite ================================================================================ -.. todo:: better landing page - - Consider adding something here that isn't just table of contents since this - *is* the root page and is where the logo links to. +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`. + +.. note:: + + 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. + +.. _let us know: https://github.com/YosysHQ/yosys/issues/new/choose +.. _version 0.36: https://yosyshq.readthedocs.io/projects/yosys/en/0.36/ .. todo:: look into command ref improvements - 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 + +.. todolist:: .. only:: html @@ -28,16 +42,3 @@ Yosys Open SYnthesis Suite test_suites appendix - -.. only:: html - - Indices - ------- - - - :ref:`commandindex` - - :ref:`tagindex` - -TODOs ------ - -.. todolist:: diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index b4934ad78..292c6ceec 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -7,8 +7,8 @@ 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`_, Yosys finds use across hobbyist and commercial applications as +well as academic. .. _open source: https://github.com/YosysHQ/yosys @@ -71,8 +71,15 @@ Things you can't do .. _nextpnr: https://github.com/YosysHQ/nextpnr -The extended Yosys universe ---------------------------- +The Yosys family +---------------- + +As mentioned above, `YosysHQ`_ maintains not just Yosys but an entire family of +tools built around it. + +.. _YosysHQ: https://github.com/YosysHQ + +.. TODO:: Yosys family descriptions In no particular order: diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index 3fa84ad3e..b37263144 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -9,8 +9,10 @@ Automatic testing The `Yosys Git repo`_ has automatic testing of builds and running of the included test suite on the following platforms: -- Ubuntu 20.04 (Focal Fossa) |test-linux| -- macOS 11 (Big Sur) |test-macos| +.. only:: html + + - Ubuntu 20.04 (Focal Fossa) |test-linux| + - macOS 11 (Big Sur) |test-macos| .. _Yosys Git repo: https://github.com/YosysHQ/yosys diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst index d254df76f..91d34bfe4 100644 --- a/docs/source/using_yosys/index.rst +++ b/docs/source/using_yosys/index.rst @@ -1,6 +1,8 @@ Using Yosys (advanced) ====================== +.. todo:: brief overview for the using Yosys index + .. toctree:: :maxdepth: 2 diff --git a/docs/source/using_yosys/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 976de0cbd..7c3f2ae56 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -1,6 +1,8 @@ More scripting -------------- +.. todo:: brief overview for the more scripting index + .. toctree:: :maxdepth: 3 diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index 08d41702d..baa4b7e03 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -260,7 +260,7 @@ switch back). Now the `ls` command lists the objects within that module. :numref:`lscd` below demonstrates this using the ``example.v`` from `A simple circuit`_ -.. todo:: update yosys output with $ternary$example.v$3 +.. TODO:: update yosys output with $ternary$example.v$3 .. code-block:: none :caption: Demonstration of :cmd:ref:`ls` and :cmd:ref:`cd` having run ``yosys example.v`` diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 6504bc0bb..0db716ccc 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -263,7 +263,7 @@ diagram in :numref:`memdemo_00`. Complete circuit diagram for the design shown in :numref:`memdemo_src` -.. todo:: :ref:`memdemo_01` and :ref:`memdemo_02` are the same, probably change +.. TODO:: :ref:`memdemo_01` and :ref:`memdemo_02` are the same, probably change the example so they aren't. There's a lot going on there, but maybe we are only interested in the tree of diff --git a/docs/source/using_yosys/synthesis/abc.rst b/docs/source/using_yosys/synthesis/abc.rst index a46072fee..e703b8986 100644 --- a/docs/source/using_yosys/synthesis/abc.rst +++ b/docs/source/using_yosys/synthesis/abc.rst @@ -1,7 +1,7 @@ The :cmd:ref:`abc` command ~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: discuss abc (more stable) vs abc9 (newer, possibly better) +.. TODO:: discuss abc, consider using https://github.com/Ravenslofty/yosys-cookbook/blob/master/misc/abc9.md The :cmd:ref:`abc` command provides an interface to ABC_, an open source tool for low-level logic synthesis. diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst index 007fd555d..d062c1c3d 100644 --- a/docs/source/using_yosys/synthesis/index.rst +++ b/docs/source/using_yosys/synthesis/index.rst @@ -1,6 +1,8 @@ Synthesis in detail ------------------- +.. todo:: brief overview for the synthesis index + .. toctree:: :maxdepth: 3 diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 721a86672..499f73d5a 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -57,7 +57,7 @@ Example Memory mapping ^^^^^^^^^^^^^^ -.. todo:: :cmd:ref:`memory_libmap` description +.. TODO:: :cmd:ref:`memory_libmap` description Usually it is preferred to use architecture-specific RAM resources for memory. For example: diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index 7851e78be..407308a29 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -66,8 +66,6 @@ In some cases this pass can also optimize cells with some constant inputs. 1 :math:`b` :math:`b` ========= ========= =========== -.. todo:: How to format table? - :numref:`Table %s <tab:opt_expr_and>` 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 @@ -131,7 +129,7 @@ is produced. The ``opt_rmdff`` pass ~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: Update to ``opt_dff`` +.. TODO:: Update to ``opt_dff`` 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 diff --git a/docs/source/using_yosys/synthesis/synth.rst b/docs/source/using_yosys/synthesis/synth.rst index 62cac991b..c9ec45b8a 100644 --- a/docs/source/using_yosys/synthesis/synth.rst +++ b/docs/source/using_yosys/synthesis/synth.rst @@ -4,11 +4,10 @@ Synth commands Packaged ``synth_*`` commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: are all these synth commands supported? - The following is a list of all synth commands included in Yosys for different platforms. Each command runs a script of sub commands specific to the platform -being targeted. +being targeted. Note that not all of these scripts are actively maintained and +may not be up-to-date. - :doc:`/cmd/synth_achronix` - :doc:`/cmd/synth_anlogic` @@ -21,8 +20,8 @@ being targeted. - :doc:`/cmd/synth_gowin` - :doc:`/cmd/synth_greenpak4` - :doc:`/cmd/synth_ice40` -- :doc:`/cmd/synth_intel` -- :doc:`/cmd/synth_intel_alm` +- :doc:`/cmd/synth_intel` (MAX10, Cyclone IV) +- :doc:`/cmd/synth_intel_alm` (Cyclone V, Arria V, Cyclone 10 GX) - :doc:`/cmd/synth_lattice` - :doc:`/cmd/synth_nexus` - :doc:`/cmd/synth_quicklogic` diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index a3fae32a4..bafdb4c08 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -4,7 +4,7 @@ Flows, command types, and order Command order ------------- -.. todo:: check text is coherent +.. TODO:: check text is coherent Intro to coarse-grain synthesis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index aefa11496..ce373ce6c 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -74,7 +74,7 @@ This has three advantages: - First, it is impossible that an auto-generated identifier collides with an identifier that was provided by the user. -.. todo:: ``opt_clean`` (or clean), also ``-purge`` +.. TODO:: ``opt_clean`` (or clean), also ``-purge`` - Second, the information about which identifiers were originally provided by the user is always available which can help guide some optimizations. For From 1733a76273bcd7ca46fd47ab2ab706b8eb13bdf4 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:08:45 +1300 Subject: [PATCH 054/108] Updated ABC info Includes comparison of `abc` v `abc9`. Also creates a new subsection of the yosys internals for extending yosys (moving the previous extensions.rst into it). Co-authored-by: Lofty <dan.ravensloft@gmail.com> --- docs/source/appendix/auxprogs.rst | 2 +- docs/source/using_yosys/synthesis/abc.rst | 136 +++++++++++++----- .../extending_yosys/abc_flow.rst | 76 ++++++++++ .../{ => extending_yosys}/extensions.rst | 6 +- .../yosys_internals/extending_yosys/index.rst | 11 ++ docs/source/yosys_internals/index.rst | 10 +- 6 files changed, 196 insertions(+), 45 deletions(-) create mode 100644 docs/source/yosys_internals/extending_yosys/abc_flow.rst rename docs/source/yosys_internals/{ => extending_yosys}/extensions.rst (97%) create mode 100644 docs/source/yosys_internals/extending_yosys/index.rst diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index 2235bbd89..752d4a0c8 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -9,7 +9,7 @@ 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/extensions` for details. +Yosys. See :doc:`/yosys_internals/extending_yosys/extensions` for details. .. literalinclude:: /temp/yosys-config :start-at: Usage diff --git a/docs/source/using_yosys/synthesis/abc.rst b/docs/source/using_yosys/synthesis/abc.rst index e703b8986..928b32018 100644 --- a/docs/source/using_yosys/synthesis/abc.rst +++ b/docs/source/using_yosys/synthesis/abc.rst @@ -1,39 +1,103 @@ -The :cmd:ref:`abc` command -~~~~~~~~~~~~~~~~~~~~~~~~~~ +The ABC toolbox +--------------- -.. TODO:: discuss abc, consider using https://github.com/Ravenslofty/yosys-cookbook/blob/master/misc/abc9.md - -The :cmd:ref:`abc` command provides an interface to ABC_, an open source tool -for low-level logic synthesis. - -.. _ABC: http://www.eecs.berkeley.edu/~alanmi/abc/ - -The :cmd:ref:`abc` command processes a netlist of internal gate types and can -perform: - -- logic minimization (optimization) -- mapping of logic to standard cell library (liberty format) -- mapping of logic to k-LUTs (for FPGA synthesis) - -Optionally :cmd:ref:`abc` can process registers from one clock domain and -perform sequential optimization (such as register balancing). - -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 -:cmd:ref:`write_blif` and load the output file into ABC outside of Yosys. - -Example -^^^^^^^ - -.. todo:: describe ``abc`` images - -.. literalinclude:: /code_examples/synth_flow/abc_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/abc_01.v`` - -.. literalinclude:: /code_examples/synth_flow/abc_01.ys +.. role:: yoscrypt(code) :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/abc_01.ys`` -.. figure:: /_images/code_examples/synth_flow/abc_01.* - :class: width-helper +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/yosys_internals/extending_yosys/abc_flow.rst b/docs/source/yosys_internals/extending_yosys/abc_flow.rst new file mode 100644 index 000000000..e55c87870 --- /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 ``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 ``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/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst similarity index 97% rename from docs/source/yosys_internals/extensions.rst rename to docs/source/yosys_internals/extending_yosys/extensions.rst index 4eaf41def..346eb5265 100644 --- a/docs/source/yosys_internals/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -13,11 +13,11 @@ 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 +.. literalinclude:: /temp/GettingStarted :language: none :caption: guidelines/GettingStarted -.. literalinclude:: ../temp/CodingStyle +.. literalinclude:: /temp/CodingStyle :language: none :caption: guidelines/CodingStyle @@ -87,7 +87,7 @@ Creating modules from scratch Let's create the following module using the RTLIL API: -.. literalinclude:: ../../resources/PRESENTATION_Prog/absval_ref.v +.. literalinclude:: ../../../resources/PRESENTATION_Prog/absval_ref.v :language: Verilog :caption: docs/resources/PRESENTATION_Prog/absval_ref.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 000000000..c2dc6cd2b --- /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/index.rst b/docs/source/yosys_internals/index.rst index 001e2536c..d349f6f1b 100644 --- a/docs/source/yosys_internals/index.rst +++ b/docs/source/yosys_internals/index.rst @@ -32,9 +32,9 @@ 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 + :maxdepth: 3 - flow/index - formats/index - techmap - extensions + flow/index + formats/index + extending_yosys/index + techmap From 7f24ef37f82d5f0f51afb544ed972400778c18ae Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:15:51 +1300 Subject: [PATCH 055/108] Add todo --- docs/source/bib.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/bib.rst b/docs/source/bib.rst index 21f85a869..2675cec16 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 From f44e8d01243a11242586df03fdfdac8a7e4294ec Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:34:42 +1300 Subject: [PATCH 056/108] Working on extensions doc Moved the last files out of the resources directory. Some tidy up/reformatting of the extensions to allow literalincludes from `my_cmd.cc`. Most (all?) of the getting started guidelines file is either in the quick guide section, or sections referenced by it. Instead of including it verbatim, we'll instead just leave a reference to it but then jump straight into the quick guide. Include an image for the absval generated module. Still needs more surrounding text but it's good enough for now. Also includes some other minor tidying, including removing the no longer used abc_01 code example. --- .../code_examples/extensions}/.gitignore | 0 .../code_examples/extensions}/Makefile | 7 +- .../code_examples/extensions}/absval_ref.v | 2 +- .../code_examples/extensions}/my_cmd.cc | 2 +- .../code_examples/extensions}/sigmap_test.v | 2 +- docs/source/code_examples/synth_flow/Makefile | 1 - docs/source/code_examples/synth_flow/abc_01.v | 10 - .../source/code_examples/synth_flow/abc_01.ys | 5 - .../code_examples/synth_flow/abc_01_cells.lib | 54 ----- .../code_examples/synth_flow/abc_01_cells.v | 40 ---- docs/source/using_yosys/yosys_flows.rst | 4 +- .../extending_yosys/extensions.rst | 219 +++++++++--------- 12 files changed, 120 insertions(+), 226 deletions(-) rename docs/{resources/PRESENTATION_Prog => source/code_examples/extensions}/.gitignore (100%) rename docs/{resources/PRESENTATION_Prog => source/code_examples/extensions}/Makefile (82%) rename docs/{resources/PRESENTATION_Prog => source/code_examples/extensions}/absval_ref.v (69%) rename docs/{resources/PRESENTATION_Prog => source/code_examples/extensions}/my_cmd.cc (97%) rename docs/{resources/PRESENTATION_Prog => source/code_examples/extensions}/sigmap_test.v (67%) delete mode 100644 docs/source/code_examples/synth_flow/abc_01.v delete mode 100644 docs/source/code_examples/synth_flow/abc_01.ys delete mode 100644 docs/source/code_examples/synth_flow/abc_01_cells.lib delete mode 100644 docs/source/code_examples/synth_flow/abc_01_cells.v diff --git a/docs/resources/PRESENTATION_Prog/.gitignore b/docs/source/code_examples/extensions/.gitignore similarity index 100% rename from docs/resources/PRESENTATION_Prog/.gitignore rename to docs/source/code_examples/extensions/.gitignore diff --git a/docs/resources/PRESENTATION_Prog/Makefile b/docs/source/code_examples/extensions/Makefile similarity index 82% rename from docs/resources/PRESENTATION_Prog/Makefile rename to docs/source/code_examples/extensions/Makefile index 60ca513a8..bec29369c 100644 --- a/docs/resources/PRESENTATION_Prog/Makefile +++ b/docs/source/code_examples/extensions/Makefile @@ -1,9 +1,11 @@ PROGRAM_PREFIX := -YOSYS ?= ../../../$(PROGRAM_PREFIX)yosys +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys all: test0.log test1.log test2.log +dots: test1.dot + CXXFLAGS=$(shell $(YOSYS)-config --cxxflags) DATDIR=$(shell $(YOSYS)-config --datdir) @@ -18,6 +20,9 @@ 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: + $(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 diff --git a/docs/resources/PRESENTATION_Prog/absval_ref.v b/docs/source/code_examples/extensions/absval_ref.v similarity index 69% rename from docs/resources/PRESENTATION_Prog/absval_ref.v rename to docs/source/code_examples/extensions/absval_ref.v index ca0a115a0..3f547b50b 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_Prog/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc similarity index 97% rename from docs/resources/PRESENTATION_Prog/my_cmd.cc rename to docs/source/code_examples/extensions/my_cmd.cc index 9cb4b8e38..36ddbe175 100644 --- a/docs/resources/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/docs/resources/PRESENTATION_Prog/sigmap_test.v b/docs/source/code_examples/extensions/sigmap_test.v similarity index 67% rename from docs/resources/PRESENTATION_Prog/sigmap_test.v rename to docs/source/code_examples/extensions/sigmap_test.v index 18dcf5eb7..8d0b43836 100644 --- a/docs/resources/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/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index 804f6da37..b6c83f05d 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -3,7 +3,6 @@ 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 PROGRAM_PREFIX := diff --git a/docs/source/code_examples/synth_flow/abc_01.v b/docs/source/code_examples/synth_flow/abc_01.v deleted file mode 100644 index 3bc686353..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/abc_01.ys b/docs/source/code_examples/synth_flow/abc_01.ys deleted file mode 100644 index bb0b3780f..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/abc_01_cells.lib b/docs/source/code_examples/synth_flow/abc_01_cells.lib deleted file mode 100644 index bf6b34788..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/abc_01_cells.v b/docs/source/code_examples/synth_flow/abc_01_cells.v deleted file mode 100644 index 444094798..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index bafdb4c08..22f964a02 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -278,7 +278,9 @@ Checking. Checking techmap ~~~~~~~~~~~~~~~~ -.. todo:: add/expand supporting text, reference no longer exists +.. todo:: add/expand supporting text + +.. TODO:: reference no longer exists Remember the following example from :doc:`/getting_started/typical_phases`? diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 346eb5265..ab8cf0cb6 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -1,52 +1,25 @@ Writing extensions ================== +.. role:: yoscrypt(code) + :language: yoscrypt + .. todo:: check text is coherent This chapter contains some bits and pieces of information about programming yosys extensions. Don't be afraid to ask questions on the YosysHQ Slack. -Guidelines ----------- +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. -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/code_examples/stubnets/stubnets.cc``. - -.. literalinclude:: /code_examples/stubnets/stubnets.cc - :language: c++ - :linenos: - :caption: docs/source/code_examples/stubnets/stubnets.cc - -.. literalinclude:: /code_examples/stubnets/Makefile - :language: makefile - :linenos: - :caption: docs/source/code_examples/stubnets/Makefile - -.. literalinclude:: /code_examples/stubnets/test.v - :language: verilog - :linenos: - :caption: docs/source/code_examples/stubnets/test.v +.. todo:: what's in guidelines/GettingStarted that's missing from the manual? Quick guide ----------- -See also: ``docs/resources/PRESENTATION_Prog/*``. +Code examples from this section are included in the +``docs/code_examples/extensions/`` directory of the Yosys source code. Program components and data formats ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -76,39 +49,90 @@ It is possible to only work on this simpler version: 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. The -:doc:`/using_yosys/more_scripting/selections` document has more information on -using these commands. +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 ``my_cmd.cc`` + +Note that we are making a global instance of a class derived from +``Yosys::Pass``, which we get by including ``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: + +.. 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. todo:: add/expand supporting text, also use files in docs/resources/PRESENTATION_Prog - Let's create the following module using the RTLIL API: -.. literalinclude:: ../../../resources/PRESENTATION_Prog/absval_ref.v - :language: Verilog - :caption: docs/resources/PRESENTATION_Prog/absval_ref.v +.. literalinclude:: /code_examples/extensions/absval_ref.v + :language: Verilog + :caption: absval_ref.v -.. code:: C++ +We'll do the same as before and format it as a a ``Yosys::Pass``. - RTLIL::Module *module = new RTLIL::Module; - module->name = "\\absval"; +.. literalinclude:: /code_examples/extensions/my_cmd.cc + :language: c++ + :lines: 23-47 + :caption: :yoscrypt:`test1` - creating the absval module, from ``my_cmd.cc`` - RTLIL::Wire *a = module->addWire("\\a", 4); - a->port_input = true; - a->port_id = 1; +.. code:: shell-session - RTLIL::Wire *y = module->addWire("\\y", 4); - y->port_output = true; - y->port_id = 2; + $ yosys -m ./my_cmd.so -p 'test1' -Q - 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); + -- Running command `test1' -- + Name of this module: absval - module->fixup_ports(); +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 ~~~~~~~~~~~~~~~~~ @@ -124,7 +148,6 @@ When modifying existing modules, stick to the following DOs and DON'Ts: - 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. @@ -133,13 +156,14 @@ Using the SigMap helper class Consider the following module: -.. code:: Verilog +.. literalinclude:: /code_examples/extensions/sigmap_test.v + :language: Verilog + :caption: sigmap_test.v - module test(input a, output x, y); - assign x = a, y = a; - endmodule +In this case ``a``, ``x``, and ``y`` are all different names for the same +signal. However: -In this case ``a``, ``x``, and ``y`` are all different names for the same signal. However: +.. todo:: use my_cmd.cc literalincludes .. code:: C++ @@ -148,7 +172,8 @@ In this case ``a``, ``x``, and ``y`` are all different names for the same signal 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). +unique signal from the group (usually the wire that is directly driven by a cell +or port). .. code:: C++ @@ -159,7 +184,8 @@ unique signal from the group (usually the wire that is directly driven by a cell Printing log messages ~~~~~~~~~~~~~~~~~~~~~ -The ``log()`` function is a ``printf()``-like function that can be used to create 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: @@ -206,53 +232,24 @@ Use ``log_cmd_error()`` to report a recoverable error: Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``. -Creating a command -~~~~~~~~~~~~~~~~~~ +The "stubnets" example module +------------------------------ -Simply create a global instance of a class derived from ``Pass`` to create -a new yosys command: +The following is the complete code of the "stubnets" example module. It is +included in the Yosys source distribution as +``docs/source/code_examples/stubnets/stubnets.cc``. -.. code:: C++ +.. literalinclude:: /code_examples/stubnets/stubnets.cc + :language: c++ + :linenos: + :caption: docs/source/code_examples/stubnets/stubnets.cc - #include "kernel/yosys.h" - USING_YOSYS_NAMESPACE +.. literalinclude:: /code_examples/stubnets/Makefile + :language: makefile + :linenos: + :caption: docs/source/code_examples/stubnets/Makefile - struct MyPass : public Pass { - MyPass() : Pass("my_cmd", "just a simple test") { } - virtual void execute(std::vector<std::string> 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; - -Creating a plugin -~~~~~~~~~~~~~~~~~ - -Yosys can be extended by adding additional C++ code to the Yosys code base, or -by loading plugins into Yosys. - -Use the following command to compile a Yosys plugin: - -.. code:: - - yosys-config --exec --cxx --cxxflags --ldflags \ - -o my_cmd.so -shared my_cmd.cc --ldlibs - -Or shorter: - -.. code:: - - yosys-config --build my_cmd.so my_cmd.cc - -Load the plugin using the yosys ``-m`` option: - -.. code:: - - yosys -m ./my_cmd.so -p 'my_cmd foo bar' +.. literalinclude:: /code_examples/stubnets/test.v + :language: verilog + :linenos: + :caption: docs/source/code_examples/stubnets/test.v From 3a153f99db4f23616fcf2b9a69b58bb4fcafb755 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:08:46 +1300 Subject: [PATCH 057/108] Add cell_libs.rst Updates code examples, removing `counter_outputs.ys` in favour of a single script. Also adds a .gitignore for the output file `synth.v`. `example_synth.rst` still pending updated example. --- docs/source/code_examples/intro/.gitignore | 1 + docs/source/code_examples/intro/Makefile | 6 +- docs/source/code_examples/intro/counter.ys | 12 +- .../code_examples/intro/counter_outputs.ys | 28 ---- .../using_yosys/synthesis/cell_libs.rst | 129 ++++++++++++++++++ docs/source/using_yosys/synthesis/index.rst | 1 + 6 files changed, 145 insertions(+), 32 deletions(-) create mode 100644 docs/source/code_examples/intro/.gitignore delete mode 100644 docs/source/code_examples/intro/counter_outputs.ys create mode 100644 docs/source/using_yosys/synthesis/cell_libs.rst diff --git a/docs/source/code_examples/intro/.gitignore b/docs/source/code_examples/intro/.gitignore new file mode 100644 index 000000000..9f8173c6d --- /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 index 90b91d7a5..e6509681f 100644 --- a/docs/source/code_examples/intro/Makefile +++ b/docs/source/code_examples/intro/Makefile @@ -2,12 +2,12 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -DOTS = counter_00.dot counter_proc.dot counter_01.dot counter_02.dot counter_03.dot +DOTS = counter_00.dot counter_01.dot counter_02.dot counter_03.dot dots: $(DOTS) -$(DOTS): counter.v counter_outputs.ys mycells.lib - $(YOSYS) counter_outputs.ys +$(DOTS): counter.v counter.ys mycells.lib + $(YOSYS) counter.ys .PHONY: clean clean: diff --git a/docs/source/code_examples/intro/counter.ys b/docs/source/code_examples/intro/counter.ys index 5582f1b78..e327a6f6b 100644 --- a/docs/source/code_examples/intro/counter.ys +++ b/docs/source/code_examples/intro/counter.ys @@ -2,12 +2,20 @@ 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 +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 @@ -17,5 +25,7 @@ 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/docs/source/code_examples/intro/counter_outputs.ys b/docs/source/code_examples/intro/counter_outputs.ys deleted file mode 100644 index d52934b3f..000000000 --- a/docs/source/code_examples/intro/counter_outputs.ys +++ /dev/null @@ -1,28 +0,0 @@ -# read -read_verilog counter.v -hierarchy -check -top counter -show -notitle -format dot -prefix counter_00 - -# elaborate -proc -show -notitle -format dot -prefix counter_proc - -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 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 000000000..5f54b894f --- /dev/null +++ b/docs/source/using_yosys/synthesis/cell_libs.rst @@ -0,0 +1,129 @@ +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 as ``docs/source/code_examples/intro/*``. The project contains a +simple ASIC synthesis script (``counter.ys``), a digital design written in +Verilog (``counter.v``), and a simple CMOS cell library (``mycells.lib``). Many +of the early steps here are already covered in more detail in the +:doc:`/getting_started/example_synth` document. + +.. note:: + + The ``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: ``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: ``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: ``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 +~~~~~~~~~~~~~~~~~~ + +.. TODO:: comment on similarities and/or differences with example_synth + +.. literalinclude:: /code_examples/intro/counter.ys + :language: yoscrypt + :lines: 14-15 + :lineno-match: + :caption: ``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 +~~~~~~~~~~~~~~~~~~~ + +.. todo:: are we recalling or is this new information + +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: ``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: ``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: ``counter.ys`` - write synthesized design diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst index d062c1c3d..19d302fcc 100644 --- a/docs/source/using_yosys/synthesis/index.rst +++ b/docs/source/using_yosys/synthesis/index.rst @@ -12,4 +12,5 @@ Synthesis in detail memory opt abc + cell_libs From 6d1caf61340217db6fdb53a0793be7e696f4f1d2 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 14 Dec 2023 11:30:51 +1300 Subject: [PATCH 058/108] Initial synth_ice40 example Overall structure in place to match the iCE40 flow. Still needs a new example design, and more text for the later sections (which the counter doesn't cover). --- docs/source/getting_started/example_synth.rst | 270 ++++++++++-------- docs/source/yosys_internals/techmap.rst | 2 + 2 files changed, 155 insertions(+), 117 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 6dac3a9a9..6bc5be967 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -1,21 +1,17 @@ Synthesis starter ----------------- -.. - Typical phases of a synthesis flow are as follows: +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. - - Reading and elaborating the design - - Higher-level synthesis and optimization - - - Converting ``always``-blocks to logic and registers - - Perform coarse-grain optimizations (resource sharing, const folding, ...) - - Handling of memories and other coarse-grain blocks - - Extracting and optimizing finite state machines - - - Convert remaining logic to bit-level logic functions - - Perform optimizations on bit-level logic functions - - Map bit-level logic gates and registers to cell library - - Write results to output file +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/synth` A simple counter ~~~~~~~~~~~~~~~~ @@ -23,24 +19,15 @@ A simple counter .. role:: yoscrypt(code) :language: yoscrypt -.. TODO:: move current example synth as mapping to cell libraries +.. TODO:: replace counter.v with a (slightly) more complex design + which includes hard blocks and maybe an FSM - replace with a walk through of synth_ice40 - -This section covers an `example project`_ available in -``docs/source/code_examples/intro/``. The project contains a simple ASIC -synthesis script (``counter.ys``), a digital design written in Verilog -(``counter.v``), and a simple CMOS cell library (``mycells.lib``). - -.. _example project: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/intro - -First, let's quickly look at the design: +First, let's quickly look at the design we'll be synthesizing: .. literalinclude:: /code_examples/intro/counter.v :language: Verilog :caption: ``docs/source/code_examples/intro/counter.v`` :linenos: - :name: 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, @@ -69,14 +56,40 @@ should see something like the following: Storing AST representation for module `$abstract\counter'. Successfully finished Verilog frontend. +.. 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. -Let's run :yoscrypt:`hierarchy -check -top counter`. This command declares that -the top level module is ``counter``, and that we want to expand it and any other -modules it may use. Any other modules which were loaded are then discarded, -stopping the following commands from trying to work on them. 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. +Our overall goal is to call :yoscrypt:`synth_ice40 -top counter`, but for now we +can run each of the commands individually for a better sense of how each part +contributes to the flow. 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 + +: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 safely +skip this command. + +Let's instead start with run :yoscrypt:`hierarchy -check -top counter`. This +command declares that the top level module is ``counter``, and that we want to +expand it and any other modules it may use. Any other modules which were loaded +are then discarded, preventing the subsequent commands from trying to work on +them. 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. .. TODO:: more on why :cmd:ref:`hierarchy` is important @@ -108,27 +121,22 @@ Our circuit now looks like this: .. figure:: /_images/code_examples/intro/counter_00.* :class: width-helper - :name: counter-hierarchy ``counter`` module after :cmd:ref:`hierarchy` -.. seealso:: Advanced usage docs for :doc:`/using_yosys/more_scripting/load_design` - -Elaboration -~~~~~~~~~~~ - Notice that block that says "PROC" in :ref:`counter-hierarchy`? Simple operations like ``count + 2'd1`` can be extracted from our ``always @`` block in -:ref:`counter-v`. This gives us the ``$add`` cell we see. But control logic, -like the ``if .. else``; and memory elements, like the ``count <='2d0``; are not -so straightforward. To handle these, let us now introduce a new command: +:ref:`counter-v`. This gives us the ``$add`` cell we see. But control logic +(like the ``if .. else``) and memory elements (like the ``count <='2d0``) are +not so straightforward. To handle these, let us now introduce the next command: :doc:`/cmd/proc`. -:cmd:ref:`proc` is a macro command; running a series of other commands which -work to convert the behavioral logic of processes into multiplexers and -registers. We go into more detail on :cmd:ref:`proc` later in -:doc:`/using_yosys/synthesis/proc`, but for now let's see what happens when we -run it. +:cmd:ref:`proc` is a macro command like :cmd:ref:`synth_ice40`. Rather than +processing our design itself, 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. We go into more detail on +:cmd:ref:`proc` later in :doc:`/using_yosys/synthesis/proc`, but for now let's +see what happens when we run it. .. figure:: /_images/code_examples/intro/counter_proc.* :class: width-helper @@ -136,40 +144,42 @@ run it. ``counter`` module after :cmd:ref:`proc` The ``if`` statements are now modeled with ``$mux`` cells, and the memory -consists of a ``$dff`` cell. That's getting a bit messy now, so let's chuck in -a call to :cmd:ref:`opt`. +consists of a ``$dff`` cell. -.. figure:: /_images/code_examples/intro/counter_01.* - :class: width-helper +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/proc` - ``counter`` module after :cmd:ref:`opt` - -Much better. We can now see that the ``$dff`` and ``$mux`` cells have been -replaced with a single ``$sdffe``, using the built-in enable and reset ports -instead. - -.. TODO:: a bit more on :cmd:ref:`opt` here +Flattening +~~~~~~~~~~ At this stage of a synthesis flow there are a few other commands we could run. First off is :cmd:ref:`flatten`. If we had any modules within our ``counter``, this would replace them with their implementation. Flattening the design like this can allow for optimizations between modules which would otherwise be -missed. Next is :doc:`/cmd/check`. +missed. Depending on the target architecture, we might also run 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. -.. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/proc` +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: flatten: + :end-before: coarse: + :dedent: + :name: flatten + :caption: ``flatten`` section + +The iCE40 flow puts these commands into thier own :ref:`flatten`, +while some synthesis scripts will instead include them in the next section. 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. -There isn't much else we can do for our ``counter`` example, but this is the -stage of synthesis where we do things like const propagation, expression +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. @@ -177,59 +187,90 @@ 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. +In the iCE40 flow we get all the following commands: + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: coarse: + :end-before: map_ram: + :dedent: + :caption: ``coarse`` section + .. TODO:: talk more about DSPs (and their associated commands) +.. TODO:: example_syth ``coarse`` section + Some of the commands we might use here are: +- :doc:`/cmd/opt_expr`, +- :doc:`/cmd/opt_clean`, +- :doc:`/cmd/check`, +- :doc:`/cmd/opt`, - :doc:`/cmd/fsm`, -- :doc:`/cmd/memory`, - :doc:`/cmd/wreduce`, - :doc:`/cmd/peepopt`, +- :doc:`/cmd/memory`, - :doc:`/cmd/pmuxtree`, - :doc:`/cmd/alumacc`, and - :doc:`/cmd/share`. -.. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/fsm`, and - :doc:`/using_yosys/synthesis/memory` +.. seealso:: Advanced usage docs for + :doc:`/using_yosys/synthesis/fsm`, + :doc:`/using_yosys/synthesis/memory`, and + :doc:`/using_yosys/synthesis/opt` -Logic gate mapping -~~~~~~~~~~~~~~~~~~ +Hardware mapping +~~~~~~~~~~~~~~~~ -.. TODO:: example_synth mapping to gates +.. TODO:: example_synth hardware mapping sections -:yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain -logic gates (AND, OR, NOT, etc.). +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_ram: + :end-before: map_ffram: + :dedent: + :name: map_ram + :caption: ``map_ram`` section -When :cmd:ref:`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. +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_ffram: + :end-before: map_gates: + :dedent: + :name: map_ffram + :caption: ``map_ffram`` section -The built-in logic gate types are: ``$_NOT_``, ``$_AND_``, ``$_OR_``, -``$_XOR_``, and ``$_MUX_``. +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_gates: + :end-before: map_ffs: + :dedent: + :name: map_gates + :caption: ``map_gates`` section -See :doc:`/yosys_internals/formats/cell_library` for more about the internal -cells used. +.. 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/intro/counter_02.* - :class: width-helper +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_luts: + :end-before: map_cells: + :dedent: + :name: map_luts + :caption: ``map_luts`` section - ``counter`` after :cmd:ref:`techmap` - -Mapping to hardware -~~~~~~~~~~~~~~~~~~~ - -.. TODO:: example_synth mapping to hardware - -:ref:`cmos_lib` - -#. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available - hardware flip-flops. -#. :yoscrypt:`abc -liberty mycells.lib` - Map logic to available hardware gates. - -.. figure:: /_images/code_examples/intro/counter_03.* - :class: width-helper - - ``counter`` after hardware cell mapping +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-after: map_cells: + :end-before: check: + :dedent: + :name: map_cells + :caption: ``map_cells`` section :cmd:ref:`dfflibmap` This command maps the internal register cell types to the register types @@ -247,28 +288,23 @@ Mapping to hardware :cmd:ref:`dfflegalize` Specify a set of supported FF cells/cell groups and convert all FFs to them. -.. seealso:: Advanced usage docs for :doc:`/yosys_internals/techmap` +.. seealso:: Advanced usage docs for + :doc:`/yosys_internals/techmap`, and + :doc:`/using_yosys/synthesis/memory`. -.. _cmos_lib: +Final steps +~~~~~~~~~~~~ -The CMOS cell library -^^^^^^^^^^^^^^^^^^^^^ +.. TODO:: example_synth final steps (check section and outputting) -.. literalinclude:: /code_examples/intro/mycells.lib - :language: Liberty - :caption: ``docs/source/code_examples/intro/mycells.lib`` - -The script file -~~~~~~~~~~~~~~~ - -#. :yoscrypt:`read_verilog -defer counter.v` -#. :yoscrypt:`clean` - Clean up the design (just the last step of - :cmd:ref:`opt`). -#. :yoscrypt:`write_verilog synth.v` - Write final synthesis result to output - file. - -.. literalinclude:: /code_examples/intro/counter.ys +.. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt - :caption: ``docs/source/code_examples/intro/counter.ys`` + :start-after: check: + :end-before: blif: + :dedent: + :name: check + :caption: ``check`` section -.. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/synth` +- :doc:`/cmd/check` +- :doc:`/cmd/autoname` +- :doc:`/cmd/stat` diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index 973aca39f..d7186ab6c 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -2,6 +2,8 @@ .. todo:: less academic, check text is coherent +.. TODO:: can we split some of this into synthesis/techmap ? + Technology mapping ================== From 80c78aaad64bd25ee52d7ba8475c91bcc38f8cf7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:21:52 +1300 Subject: [PATCH 059/108] New example_synth code `example_synth.rst` updated down to coarse-grain representation. --- .../code_examples/example_synth/Makefile | 15 ++ .../code_examples/example_synth/example.out | 147 +++++++++++++ .../code_examples/example_synth/example.v | 76 +++++++ .../code_examples/example_synth/example.ys | 17 ++ docs/source/getting_started/example_synth.rst | 206 +++++++++++------- 5 files changed, 388 insertions(+), 73 deletions(-) create mode 100644 docs/source/code_examples/example_synth/Makefile create mode 100644 docs/source/code_examples/example_synth/example.out create mode 100644 docs/source/code_examples/example_synth/example.v create mode 100644 docs/source/code_examples/example_synth/example.ys diff --git a/docs/source/code_examples/example_synth/Makefile b/docs/source/code_examples/example_synth/Makefile new file mode 100644 index 000000000..4446c2099 --- /dev/null +++ b/docs/source/code_examples/example_synth/Makefile @@ -0,0 +1,15 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOTS = control_hier.dot control_proc.dot +DOTS += example_hier.dot + +dots: $(DOTS) example.out + +$(DOTS) example.out: example.v example.ys + $(YOSYS) example.ys -l example.out -Q + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/code_examples/example_synth/example.out b/docs/source/code_examples/example_synth/example.out new file mode 100644 index 000000000..f2c4bfafa --- /dev/null +++ b/docs/source/code_examples/example_synth/example.out @@ -0,0 +1,147 @@ + +-- Executing script file `example.ys' -- +echo on + +yosys> read_verilog -defer example.v + +1. Executing Verilog-2005 frontend: example.v +Parsing Verilog input from `example.v' to AST representation. +Storing AST representation for module `$abstract\example'. +Storing AST representation for module `$abstract\control'. +Storing AST representation for module `$abstract\data'. +Successfully finished Verilog frontend. + +yosys> hierarchy -top control + +2. Executing HIERARCHY pass (managing design hierarchy). + +3. Executing AST frontend in derive mode using pre-parsed AST for module `\control'. +Generating RTLIL representation for module `\control'. + +3.1. Analyzing design hierarchy.. +Top module: \control + +3.2. Analyzing design hierarchy.. +Top module: \control +Removing unused module `$abstract\data'. +Removing unused module `$abstract\control'. +Removing unused module `$abstract\example'. +Removed 3 unused modules. + +yosys> show -notitle -format dot -prefix control_hier + +4. Generating Graphviz representation of design. +Writing dot description to `control_hier.dot'. +Dumping module control to page 1. + +yosys> proc + +5. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 1 switch rules as full_case in process $proc$example.v:43$1 in module control. +Removed a total of 0 dead cases. + +yosys> proc_prune + +5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 1 redundant assignment. +Promoted 0 assignments to connections. + +yosys> proc_init + +5.4. Executing PROC_INIT pass (extract init attributes). + +yosys> proc_arst + +5.5. Executing PROC_ARST pass (detect async resets in processes). + +yosys> proc_rom + +5.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. +<suppressed ~2 debug messages> + +yosys> proc_mux + +5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\control.$proc$example.v:43$1'. + 1/2: $0\addr[7:0] + 2/2: $0\state[1:0] + +yosys> proc_dlatch + +5.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +5.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\control.\state' using process `\control.$proc$example.v:43$1'. + created $dff cell `$procdff$12' with positive edge clock. +Creating register for signal `\control.\addr' using process `\control.$proc$example.v:43$1'. + created $dff cell `$procdff$13' with positive edge clock. + +yosys> proc_memwr + +5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Found and cleaned up 2 empty switches in `\control.$proc$example.v:43$1'. +Removing empty process `control.$proc$example.v:43$1'. +Cleaned up 2 empty switches. + +yosys> opt_expr -keepdc + +5.12. Executing OPT_EXPR pass (perform const folding). +Optimizing module control. + +yosys> show -notitle -format dot -prefix control_proc + +6. Generating Graphviz representation of design. +Writing dot description to `control_proc.dot'. +Dumping module control to page 1. + +yosys> design -reset + +yosys> read_verilog example.v + +7. Executing Verilog-2005 frontend: example.v +Parsing Verilog input from `example.v' to AST representation. +Generating RTLIL representation for module `\example'. +Generating RTLIL representation for module `\control'. +Generating RTLIL representation for module `\data'. +Successfully finished Verilog frontend. + +yosys> hierarchy -check -top example + +8. Executing HIERARCHY pass (managing design hierarchy). + +8.1. Analyzing design hierarchy.. +Top module: \example +Used module: \data +Used module: \control + +8.2. Analyzing design hierarchy.. +Top module: \example +Used module: \data +Used module: \control +Removed 0 unused modules. + +yosys> show -notitle -format dot -prefix example_hier example + +9. Generating Graphviz representation of design. +Writing dot description to `example_hier.dot'. +Dumping module example to page 1. + +End of script. Logfile hash: b45465606c, CPU: user 0.01s system 0.00s, MEM: 11.86 MB peak +Yosys 0.35+39 (git sha1 0cd4a10c8, clang 10.0.0-4ubuntu1 -fPIC -Os) +Time spent: 37% 4x read_verilog (0 sec), 23% 3x show (0 sec), ... diff --git a/docs/source/code_examples/example_synth/example.v b/docs/source/code_examples/example_synth/example.v new file mode 100644 index 000000000..f0fc5cdb5 --- /dev/null +++ b/docs/source/code_examples/example_synth/example.v @@ -0,0 +1,76 @@ +module example ( + input clk, + input rst, + input inc, + input [7:0] a, + input [7:0] b, + output [15:0] c +); + +wire [1:0] state; +wire [7:0] addr; + +control ctrl ( + .clk(clk), + .rst(rst), + .inc(inc), + .addr_o(addr), + .state_o(state) +); + +data dat ( + .clk(clk), + .addr_i(addr), + .state_i(state), + .a(a), + .b(b), + .c(c) +); + +endmodule + +module control ( + input clk, + input rst, + input inc, + output [7:0] addr_o, + output [1:0] state_o +); + +reg [1:0] state; +reg [7:0] addr; + +always @(posedge clk) begin + if (rst) begin + state <= 2'b00; + addr <= 0; + end else begin + if (inc) state <= state + 1'b1; + addr <= addr + 1'b1; + end +end + +endmodule //control + +module data ( + input clk, + input [7:0] addr_i, + input [1:0] state_i, + input [7:0] a, + input [7:0] b, + output reg [15:0] c +); + +reg [15:0] mem[255:0]; + +always @(posedge clk) begin + case (state_i) + 2'b00: mem[addr_i] <= a*b; + 2'b01: mem[addr_i] <= a+b; + 2'b10: mem[addr_i] <= a-b; + 2'b11: mem[addr_i] <= addr_i; + endcase + c <= mem[addr_i]; +end + +endmodule //data diff --git a/docs/source/code_examples/example_synth/example.ys b/docs/source/code_examples/example_synth/example.ys new file mode 100644 index 000000000..b8745dac5 --- /dev/null +++ b/docs/source/code_examples/example_synth/example.ys @@ -0,0 +1,17 @@ +# turn command echoes on to use the log output as a console session +echo on + +# ======================================================== +read_verilog -defer example.v +hierarchy -top control +show -notitle -format dot -prefix control_hier + +# ======================================================== +proc +show -notitle -format dot -prefix control_proc + +# ======================================================== +design -reset +read_verilog example.v +hierarchy -check -top example +show -notitle -format dot -prefix example_hier example diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 6bc5be967..bedaa035c 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -13,33 +13,30 @@ used. .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/synth` -A simple counter -~~~~~~~~~~~~~~~~ +Demo design +~~~~~~~~~~~ .. role:: yoscrypt(code) :language: yoscrypt -.. TODO:: replace counter.v with a (slightly) more complex design - which includes hard blocks and maybe an FSM - First, let's quickly look at the design we'll be synthesizing: -.. literalinclude:: /code_examples/intro/counter.v - :language: Verilog - :caption: ``docs/source/code_examples/intro/counter.v`` - :linenos: +.. todo:: reconsider including the whole (~77 line) design like this -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``. +.. literalinclude:: /code_examples/example_synth/example.v + :language: Verilog + :linenos: + :caption: ``example.v`` + :name: example-v + +.. todo:: example.v description Loading the design ~~~~~~~~~~~~~~~~~~ Let's load the design into Yosys. From the command line, we can call ``yosys -counter.v``. This will open an interactive Yosys shell session and immediately -parse the code from ``counter.v`` and convert it into an Abstract Syntax Tree +example.v``. This will open an interactive Yosys shell session and immediately +parse the code from ``example.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 @@ -47,13 +44,15 @@ should see something like the following: .. code:: console - $ yosys counter.v + $ yosys example.v - -- Parsing `counter.v' using frontend ` -vlog2k' -- + -- Parsing `example.v' using frontend ` -vlog2k' -- - 1. Executing Verilog-2005 frontend: counter.v - Parsing Verilog input from `counter.v' to AST representation. - Storing AST representation for module `$abstract\counter'. + 1. Executing Verilog-2005 frontend: example.v + Parsing Verilog input from `example.v' to AST representation. + Storing AST representation for module `$abstract\example'. + Storing AST representation for module `$abstract\control'. + Storing AST representation for module `$abstract\data'. Successfully finished Verilog frontend. .. seealso:: Advanced usage docs for @@ -63,9 +62,12 @@ 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 counter`, but for now we +Our overall goal is to call :yoscrypt:`synth_ice40 -top example`, but for now we can run each of the commands individually for a better sense of how each part -contributes to the flow. At the bottom of the :cmd:ref:`help` output for +contributes to the flow. We will also start with just a single module; +``control``. + +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``: @@ -75,6 +77,7 @@ Let's start with the section labeled ``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 @@ -83,15 +86,20 @@ design. PLLs are a common example of this, where we might need to reference later. Since our simple design doesn't use any of these IP blocks, we can safely skip this command. -Let's instead start with run :yoscrypt:`hierarchy -check -top counter`. This -command declares that the top level module is ``counter``, and that we want to -expand it and any other modules it may use. Any other modules which were loaded -are then discarded, preventing the subsequent commands from trying to work on -them. 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. +The control module +^^^^^^^^^^^^^^^^^^ -.. TODO:: more on why :cmd:ref:`hierarchy` is important +Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy +-top control`. This command declares that the top level module is ``control``, +and everything else can be discarded. + +.. literalinclude:: /code_examples/example_synth/example.v + :language: Verilog + :start-at: module control + :end-at: endmodule //control + :lineno-match: + :caption: ``control`` module source + :name: control-v .. note:: @@ -100,51 +108,95 @@ modules without an implementation it should return an error. .. use doscon for a console-like display that supports the `yosys> [command]` format. -.. code:: doscon +.. literalinclude:: /code_examples/example_synth/example.out + :language: doscon + :start-at: yosys> hierarchy -top control + :end-before: yosys> show + :caption: :yoscrypt:`hierarchy -top control` output - yosys> hierarchy -check -top counter +Our ``control`` circuit now looks like this: - 2. Executing HIERARCHY pass (managing design hierarchy). - - 3. Executing AST frontend in derive mode using pre-parsed AST for module `\counter'. - Generating RTLIL representation for module `\counter'. - - 3.1. Analyzing design hierarchy.. - Top module: \counter - - 3.2. Analyzing design hierarchy.. - Top module: \counter - Removing unused module `$abstract\counter'. - Removed 1 unused modules. - -Our circuit now looks like this: - -.. figure:: /_images/code_examples/intro/counter_00.* +.. figure:: /_images/code_examples/example_synth/control_hier.* :class: width-helper + :name: control_hier - ``counter`` module after :cmd:ref:`hierarchy` + ``control`` module after :cmd:ref:`hierarchy` -Notice that block that says "PROC" in :ref:`counter-hierarchy`? Simple -operations like ``count + 2'd1`` can be extracted from our ``always @`` block in -:ref:`counter-v`. This gives us the ``$add`` cell we see. But control logic -(like the ``if .. else``) and memory elements (like the ``count <='2d0``) are +Notice that block that says "PROC" in :ref:`control_hier`? Simple operations +like ``addr + 1'b1`` can be extracted from our ``always @`` block in +:ref:`control-v`. This gives us the two ``$add`` cells we see. But control +logic (like the ``if .. else``) and memory elements (like the ``addr <= 0``) are not so straightforward. 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 -processing our design itself, it instead calls a series of other commands. In +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. We go into more detail on -:cmd:ref:`proc` later in :doc:`/using_yosys/synthesis/proc`, but for now let's -see what happens when we run it. +logic of processes into multiplexers and registers. Let's see what happens when +we run it. -.. figure:: /_images/code_examples/intro/counter_proc.* +.. figure:: /_images/code_examples/example_synth/control_proc.* :class: width-helper - ``counter`` module after :cmd:ref:`proc` + ``control`` module after :cmd:ref:`proc` -The ``if`` statements are now modeled with ``$mux`` cells, and the memory -consists of a ``$dff`` cell. +The ``if`` statements are now modeled with ``$mux`` cells, while the registers +use ``$dff`` cells. 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`. + +The full example +^^^^^^^^^^^^^^^^ + +Let's now go back and check on our full design by using :yoscrypt:`hierarchy +-check -top example`. 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 ``control``. 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/example_synth/example.out + :language: doscon + :start-at: design -reset + :end-before: yosys> show + :caption: reloading ``example.v`` and running :yoscrypt:`hierarchy -check -top example` + +Notice how this time we didn't see any of those `$abstract` modules? That's +because when we ran ``yosys example.v``, the first command Yosys called was +:yoscrypt:`read_verilog -defer example.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 or not synthesizable code, +which is why Yosys does this 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``. + +.. 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 ``example.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 ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys + interactive terminal. + +.. figure:: /_images/code_examples/example_synth/example_hier.* + :class: width-helper + :name: example_hier + + ``example`` module after :cmd:ref:`hierarchy` + +We can also run :cmd:ref:`proc` now, although we won't actually see any change +in this top view. + +.. TODO:: more on why :cmd:ref:`hierarchy` is important .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/proc` @@ -153,26 +205,27 @@ Flattening ~~~~~~~~~~ At this stage of a synthesis flow there are a few other commands we could run. -First off is :cmd:ref:`flatten`. If we had any modules within our ``counter``, -this would replace them with their implementation. Flattening the design like -this can allow for optimizations between modules which would otherwise be -missed. - -Depending on the target architecture, we might also run 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. +In :cmd:ref:`synth_ice40` we get these: .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: flatten: :end-before: coarse: :dedent: - :name: flatten + :name: synth_flatten :caption: ``flatten`` section -The iCE40 flow puts these commands into thier own :ref:`flatten`, -while some synthesis scripts will instead include them in the next section. +First off is :cmd:ref:`synth_flatten`. Flattening the design like this can +allow for optimizations between modules which would otherwise be missed. We +will skip this command for now because it makes the design schematic quite +large. If you would like to see 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 example`. + +Depending on the target architecture, we 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. The coarse-grain representation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -195,6 +248,13 @@ In the iCE40 flow we get all the following commands: :end-before: map_ram: :dedent: :caption: ``coarse`` section + :name: synth_coarse + +.. 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 + the :ref:`synth_coarse` section. .. TODO:: talk more about DSPs (and their associated commands) From 742ec78ca3b0b9d92bd38d92a75abbb08e4a16c7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 18 Dec 2023 13:19:01 +1300 Subject: [PATCH 060/108] Switching example synth to fifo Fifo code based on SBY quick start. Instead of showing the full design we are (currently) focusing on a single output (rdata), using `%ci*` to get the subcircuit it relies on. --- .../code_examples/example_synth/Makefile | 15 - .../code_examples/example_synth/example.out | 147 -- .../code_examples/example_synth/example.v | 76 - .../code_examples/example_synth/example.ys | 17 - docs/source/code_examples/fifo/Makefile | 16 + docs/source/code_examples/fifo/fifo.out | 2331 +++++++++++++++++ docs/source/code_examples/fifo/fifo.v | 73 + docs/source/code_examples/fifo/fifo.ys | 39 + docs/source/getting_started/example_synth.rst | 150 +- 9 files changed, 2538 insertions(+), 326 deletions(-) delete mode 100644 docs/source/code_examples/example_synth/Makefile delete mode 100644 docs/source/code_examples/example_synth/example.out delete mode 100644 docs/source/code_examples/example_synth/example.v delete mode 100644 docs/source/code_examples/example_synth/example.ys create mode 100644 docs/source/code_examples/fifo/Makefile create mode 100644 docs/source/code_examples/fifo/fifo.out create mode 100644 docs/source/code_examples/fifo/fifo.v create mode 100644 docs/source/code_examples/fifo/fifo.ys diff --git a/docs/source/code_examples/example_synth/Makefile b/docs/source/code_examples/example_synth/Makefile deleted file mode 100644 index 4446c2099..000000000 --- a/docs/source/code_examples/example_synth/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -PROGRAM_PREFIX := - -YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys - -DOTS = control_hier.dot control_proc.dot -DOTS += example_hier.dot - -dots: $(DOTS) example.out - -$(DOTS) example.out: example.v example.ys - $(YOSYS) example.ys -l example.out -Q - -.PHONY: clean -clean: - rm -f *.dot diff --git a/docs/source/code_examples/example_synth/example.out b/docs/source/code_examples/example_synth/example.out deleted file mode 100644 index f2c4bfafa..000000000 --- a/docs/source/code_examples/example_synth/example.out +++ /dev/null @@ -1,147 +0,0 @@ - --- Executing script file `example.ys' -- -echo on - -yosys> read_verilog -defer example.v - -1. Executing Verilog-2005 frontend: example.v -Parsing Verilog input from `example.v' to AST representation. -Storing AST representation for module `$abstract\example'. -Storing AST representation for module `$abstract\control'. -Storing AST representation for module `$abstract\data'. -Successfully finished Verilog frontend. - -yosys> hierarchy -top control - -2. Executing HIERARCHY pass (managing design hierarchy). - -3. Executing AST frontend in derive mode using pre-parsed AST for module `\control'. -Generating RTLIL representation for module `\control'. - -3.1. Analyzing design hierarchy.. -Top module: \control - -3.2. Analyzing design hierarchy.. -Top module: \control -Removing unused module `$abstract\data'. -Removing unused module `$abstract\control'. -Removing unused module `$abstract\example'. -Removed 3 unused modules. - -yosys> show -notitle -format dot -prefix control_hier - -4. Generating Graphviz representation of design. -Writing dot description to `control_hier.dot'. -Dumping module control to page 1. - -yosys> proc - -5. Executing PROC pass (convert processes to netlists). - -yosys> proc_clean - -5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -yosys> proc_rmdead - -5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Marked 1 switch rules as full_case in process $proc$example.v:43$1 in module control. -Removed a total of 0 dead cases. - -yosys> proc_prune - -5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 1 redundant assignment. -Promoted 0 assignments to connections. - -yosys> proc_init - -5.4. Executing PROC_INIT pass (extract init attributes). - -yosys> proc_arst - -5.5. Executing PROC_ARST pass (detect async resets in processes). - -yosys> proc_rom - -5.6. Executing PROC_ROM pass (convert switches to ROMs). -Converted 0 switches. -<suppressed ~2 debug messages> - -yosys> proc_mux - -5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). -Creating decoders for process `\control.$proc$example.v:43$1'. - 1/2: $0\addr[7:0] - 2/2: $0\state[1:0] - -yosys> proc_dlatch - -5.8. Executing PROC_DLATCH pass (convert process syncs to latches). - -yosys> proc_dff - -5.9. Executing PROC_DFF pass (convert process syncs to FFs). -Creating register for signal `\control.\state' using process `\control.$proc$example.v:43$1'. - created $dff cell `$procdff$12' with positive edge clock. -Creating register for signal `\control.\addr' using process `\control.$proc$example.v:43$1'. - created $dff cell `$procdff$13' with positive edge clock. - -yosys> proc_memwr - -5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). - -yosys> proc_clean - -5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Found and cleaned up 2 empty switches in `\control.$proc$example.v:43$1'. -Removing empty process `control.$proc$example.v:43$1'. -Cleaned up 2 empty switches. - -yosys> opt_expr -keepdc - -5.12. Executing OPT_EXPR pass (perform const folding). -Optimizing module control. - -yosys> show -notitle -format dot -prefix control_proc - -6. Generating Graphviz representation of design. -Writing dot description to `control_proc.dot'. -Dumping module control to page 1. - -yosys> design -reset - -yosys> read_verilog example.v - -7. Executing Verilog-2005 frontend: example.v -Parsing Verilog input from `example.v' to AST representation. -Generating RTLIL representation for module `\example'. -Generating RTLIL representation for module `\control'. -Generating RTLIL representation for module `\data'. -Successfully finished Verilog frontend. - -yosys> hierarchy -check -top example - -8. Executing HIERARCHY pass (managing design hierarchy). - -8.1. Analyzing design hierarchy.. -Top module: \example -Used module: \data -Used module: \control - -8.2. Analyzing design hierarchy.. -Top module: \example -Used module: \data -Used module: \control -Removed 0 unused modules. - -yosys> show -notitle -format dot -prefix example_hier example - -9. Generating Graphviz representation of design. -Writing dot description to `example_hier.dot'. -Dumping module example to page 1. - -End of script. Logfile hash: b45465606c, CPU: user 0.01s system 0.00s, MEM: 11.86 MB peak -Yosys 0.35+39 (git sha1 0cd4a10c8, clang 10.0.0-4ubuntu1 -fPIC -Os) -Time spent: 37% 4x read_verilog (0 sec), 23% 3x show (0 sec), ... diff --git a/docs/source/code_examples/example_synth/example.v b/docs/source/code_examples/example_synth/example.v deleted file mode 100644 index f0fc5cdb5..000000000 --- a/docs/source/code_examples/example_synth/example.v +++ /dev/null @@ -1,76 +0,0 @@ -module example ( - input clk, - input rst, - input inc, - input [7:0] a, - input [7:0] b, - output [15:0] c -); - -wire [1:0] state; -wire [7:0] addr; - -control ctrl ( - .clk(clk), - .rst(rst), - .inc(inc), - .addr_o(addr), - .state_o(state) -); - -data dat ( - .clk(clk), - .addr_i(addr), - .state_i(state), - .a(a), - .b(b), - .c(c) -); - -endmodule - -module control ( - input clk, - input rst, - input inc, - output [7:0] addr_o, - output [1:0] state_o -); - -reg [1:0] state; -reg [7:0] addr; - -always @(posedge clk) begin - if (rst) begin - state <= 2'b00; - addr <= 0; - end else begin - if (inc) state <= state + 1'b1; - addr <= addr + 1'b1; - end -end - -endmodule //control - -module data ( - input clk, - input [7:0] addr_i, - input [1:0] state_i, - input [7:0] a, - input [7:0] b, - output reg [15:0] c -); - -reg [15:0] mem[255:0]; - -always @(posedge clk) begin - case (state_i) - 2'b00: mem[addr_i] <= a*b; - 2'b01: mem[addr_i] <= a+b; - 2'b10: mem[addr_i] <= a-b; - 2'b11: mem[addr_i] <= addr_i; - endcase - c <= mem[addr_i]; -end - -endmodule //data diff --git a/docs/source/code_examples/example_synth/example.ys b/docs/source/code_examples/example_synth/example.ys deleted file mode 100644 index b8745dac5..000000000 --- a/docs/source/code_examples/example_synth/example.ys +++ /dev/null @@ -1,17 +0,0 @@ -# turn command echoes on to use the log output as a console session -echo on - -# ======================================================== -read_verilog -defer example.v -hierarchy -top control -show -notitle -format dot -prefix control_hier - -# ======================================================== -proc -show -notitle -format dot -prefix control_proc - -# ======================================================== -design -reset -read_verilog example.v -hierarchy -check -top example -show -notitle -format dot -prefix example_hier example diff --git a/docs/source/code_examples/fifo/Makefile b/docs/source/code_examples/fifo/Makefile new file mode 100644 index 000000000..e0287eab4 --- /dev/null +++ b/docs/source/code_examples/fifo/Makefile @@ -0,0 +1,16 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOTS = addr_gen_hier.dot addr_gen_proc.dot +DOTS += rdata_proc.dot rdata_flat.dot +DOTS += fifo_flat.dot fifo_synth.dot + +dots: $(DOTS) fifo.out + +$(DOTS) fifo.out: fifo.v fifo.ys + $(YOSYS) fifo.ys -l fifo.out -Q + +.PHONY: clean +clean: + rm -f *.dot diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out new file mode 100644 index 000000000..5a4215e5c --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.out @@ -0,0 +1,2331 @@ + +-- 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> show -notitle -format dot -prefix addr_gen_hier + +4. Generating Graphviz representation of design. +Writing dot description to `addr_gen_hier.dot'. +Dumping module addr_gen to page 1. + +yosys> proc + +5. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 2 switch rules as full_case in process $proc$fifo.v:13$1 in module addr_gen. +Removed a total of 0 dead cases. + +yosys> proc_prune + +5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 1 assignment to connection. + +yosys> proc_init + +5.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 + +5.5. Executing PROC_ARST pass (detect async resets in processes). +Found async reset \rst in `\addr_gen.$proc$fifo.v:13$1'. + +yosys> proc_rom + +5.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. +<suppressed ~2 debug messages> + +yosys> proc_mux + +5.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:13$1'. + 1/1: $0\addr[7:0] + +yosys> proc_dlatch + +5.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +5.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\addr_gen.\addr' using process `\addr_gen.$proc$fifo.v:13$1'. + created $adff cell `$procdff$10' with positive edge clock and positive level reset. + +yosys> proc_memwr + +5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +5.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:13$1'. +Removing empty process `addr_gen.$proc$fifo.v:13$1'. +Cleaned up 2 empty switches. + +yosys> opt_expr -keepdc + +5.12. Executing OPT_EXPR pass (perform const folding). +Optimizing module addr_gen. + +yosys> show -notitle -format dot -prefix addr_gen_proc + +6. Generating Graphviz representation of design. +Writing dot description to `addr_gen_proc.dot'. +Dumping module addr_gen to page 1. + +yosys> design -reset + +yosys> read_verilog fifo.v + +7. 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 + +8. Executing HIERARCHY pass (managing design hierarchy). + +8.1. Analyzing design hierarchy.. +Top module: \fifo +Used module: \addr_gen +Parameter \MAX_DATA = 256 + +8.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'. + +8.3. Analyzing design hierarchy.. +Top module: \fifo +Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 + +8.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 + +9. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +9.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +9.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 2 switch rules as full_case in process $proc$fifo.v:64$24 in module fifo. +Marked 1 switch rules as full_case in process $proc$fifo.v:38$16 in module fifo. +Marked 2 switch rules as full_case in process $proc$fifo.v:13$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +Removed a total of 0 dead cases. + +yosys> proc_prune + +9.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 6 assignments to connections. + +yosys> proc_init + +9.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 + +9.5. Executing PROC_ARST pass (detect async resets in processes). +Found async reset \rst in `\fifo.$proc$fifo.v:64$24'. +Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. + +yosys> proc_rom + +9.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. +<suppressed ~5 debug messages> + +yosys> proc_mux + +9.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:64$24'. + 1/1: $0\count[8:0] +Creating decoders for process `\fifo.$proc$fifo.v:38$16'. + 1/3: $1$memwr$\data$fifo.v:40$15_EN[7:0]$22 + 2/3: $1$memwr$\data$fifo.v:40$15_DATA[7:0]$21 + 3/3: $1$memwr$\data$fifo.v:40$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:13$32'. + 1/1: $0\addr[7:0] + +yosys> proc_dlatch + +9.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +9.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$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:38$16'. + created $dff cell `$procdff$56' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$15_ADDR' using process `\fifo.$proc$fifo.v:38$16'. + created $dff cell `$procdff$57' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$15_DATA' using process `\fifo.$proc$fifo.v:38$16'. + created $dff cell `$procdff$58' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$15_EN' using process `\fifo.$proc$fifo.v:38$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:13$32'. + created $adff cell `$procdff$60' with positive edge clock and positive level reset. + +yosys> proc_memwr + +9.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +9.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:64$24'. +Removing empty process `fifo.$proc$fifo.v:64$24'. +Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:38$16'. +Removing empty process `fifo.$proc$fifo.v:38$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:13$32'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. +Cleaned up 5 empty switches. + +yosys> opt_expr -keepdc + +9.12. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. + +yosys> show -notitle -format dot -prefix rdata_proc o:rdata %ci* + +10. Generating Graphviz representation of design. +Writing dot description to `rdata_proc.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> flatten + +11. Executing FLATTEN pass (flatten design). +Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +<suppressed ~2 debug messages> + +yosys> show -notitle -format dot -prefix rdata_flat o:rdata %ci* + +12. Generating Graphviz representation of design. +Writing dot description to `rdata_flat.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> opt_clean + +13. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 3 unused cells and 25 unused wires. +<suppressed ~4 debug messages> + +yosys> show -notitle -format dot -prefix fifo_flat + +14. Generating Graphviz representation of design. +Writing dot description to `fifo_flat.dot'. +Dumping module fifo to page 1. + +yosys> design -reset + +yosys> read_verilog fifo.v + +15. 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> synth_ice40 -dsp -top fifo + +16. Executing SYNTH_ICE40 pass. + +yosys> read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v + +16.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_sim.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/cells_sim.v' to AST representation. +Generating RTLIL representation for module `\SB_IO'. +Generating RTLIL representation for module `\SB_GB_IO'. +Generating RTLIL representation for module `\SB_GB'. +Generating RTLIL representation for module `\SB_LUT4'. +Generating RTLIL representation for module `\SB_CARRY'. +Generating RTLIL representation for module `\SB_DFF'. +Generating RTLIL representation for module `\SB_DFFE'. +Generating RTLIL representation for module `\SB_DFFSR'. +Generating RTLIL representation for module `\SB_DFFR'. +Generating RTLIL representation for module `\SB_DFFSS'. +Generating RTLIL representation for module `\SB_DFFS'. +Generating RTLIL representation for module `\SB_DFFESR'. +Generating RTLIL representation for module `\SB_DFFER'. +Generating RTLIL representation for module `\SB_DFFESS'. +Generating RTLIL representation for module `\SB_DFFES'. +Generating RTLIL representation for module `\SB_DFFN'. +Generating RTLIL representation for module `\SB_DFFNE'. +Generating RTLIL representation for module `\SB_DFFNSR'. +Generating RTLIL representation for module `\SB_DFFNR'. +Generating RTLIL representation for module `\SB_DFFNSS'. +Generating RTLIL representation for module `\SB_DFFNS'. +Generating RTLIL representation for module `\SB_DFFNESR'. +Generating RTLIL representation for module `\SB_DFFNER'. +Generating RTLIL representation for module `\SB_DFFNESS'. +Generating RTLIL representation for module `\SB_DFFNES'. +Generating RTLIL representation for module `\SB_RAM40_4K'. +Generating RTLIL representation for module `\SB_RAM40_4KNR'. +Generating RTLIL representation for module `\SB_RAM40_4KNW'. +Generating RTLIL representation for module `\SB_RAM40_4KNRNW'. +Generating RTLIL representation for module `\ICESTORM_LC'. +Generating RTLIL representation for module `\SB_PLL40_CORE'. +Generating RTLIL representation for module `\SB_PLL40_PAD'. +Generating RTLIL representation for module `\SB_PLL40_2_PAD'. +Generating RTLIL representation for module `\SB_PLL40_2F_CORE'. +Generating RTLIL representation for module `\SB_PLL40_2F_PAD'. +Generating RTLIL representation for module `\SB_WARMBOOT'. +Generating RTLIL representation for module `\SB_SPRAM256KA'. +Generating RTLIL representation for module `\SB_HFOSC'. +Generating RTLIL representation for module `\SB_LFOSC'. +Generating RTLIL representation for module `\SB_RGBA_DRV'. +Generating RTLIL representation for module `\SB_LED_DRV_CUR'. +Generating RTLIL representation for module `\SB_RGB_DRV'. +Generating RTLIL representation for module `\SB_I2C'. +Generating RTLIL representation for module `\SB_SPI'. +Generating RTLIL representation for module `\SB_LEDDA_IP'. +Generating RTLIL representation for module `\SB_FILTER_50NS'. +Generating RTLIL representation for module `\SB_IO_I3C'. +Generating RTLIL representation for module `\SB_IO_OD'. +Generating RTLIL representation for module `\SB_MAC16'. +Generating RTLIL representation for module `\ICESTORM_RAM'. +Successfully finished Verilog frontend. + +yosys> hierarchy -check -top fifo + +16.2. Executing HIERARCHY pass (managing design hierarchy). + +16.2.1. Analyzing design hierarchy.. +Top module: \fifo +Used module: \addr_gen +Parameter \MAX_DATA = 256 + +16.2.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'. + +16.2.3. Analyzing design hierarchy.. +Top module: \fifo +Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 + +16.2.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 + +16.3. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +16.3.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +16.3.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323 in module SB_DFFNES. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316 in module SB_DFFNESS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312 in module SB_DFFNER. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305 in module SB_DFFNESR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302 in module SB_DFFNS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299 in module SB_DFFNSS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296 in module SB_DFFNR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293 in module SB_DFFNSR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285 in module SB_DFFES. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278 in module SB_DFFESS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274 in module SB_DFFER. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267 in module SB_DFFESR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264 in module SB_DFFS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261 in module SB_DFFSS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258 in module SB_DFFR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255 in module SB_DFFSR. +Marked 2 switch rules as full_case in process $proc$fifo.v:64$75 in module fifo. +Marked 1 switch rules as full_case in process $proc$fifo.v:38$67 in module fifo. +Marked 2 switch rules as full_case in process $proc$fifo.v:13$463 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +Removed a total of 0 dead cases. + +yosys> proc_prune + +16.3.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 8 redundant assignments. +Promoted 28 assignments to connections. + +yosys> proc_init + +16.3.4. Executing PROC_INIT pass (extract init attributes). +Found init rule in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$326'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$322'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$315'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$311'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$304'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$301'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$298'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$295'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$290'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$288'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$284'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$277'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$273'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$266'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$263'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$260'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$257'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$254'. + Set init value: \Q = 1'0 +Found init rule in `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$252'. + Set init value: \Q = 1'0 +Found init rule in `\fifo.$proc$fifo.v:0$82'. + Set init value: \count = 9'000000000 +Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$466'. + Set init value: \addr = 8'00000000 + +yosys> proc_arst + +16.3.5. Executing PROC_ARST pass (detect async resets in processes). +Found async reset \S in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. +Found async reset \R in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. +Found async reset \S in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. +Found async reset \R in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. +Found async reset \S in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. +Found async reset \R in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. +Found async reset \S in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. +Found async reset \R in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. +Found async reset \rst in `\fifo.$proc$fifo.v:64$75'. +Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. + +yosys> proc_rom + +16.3.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. +<suppressed ~23 debug messages> + +yosys> proc_mux + +16.3.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$326'. +Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$322'. +Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$315'. +Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$311'. +Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$304'. +Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$301'. +Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$298'. +Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$295'. +Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. +Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$290'. +Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$289'. +Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$288'. +Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$284'. +Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$277'. +Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$273'. +Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$266'. +Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$263'. +Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$260'. +Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$257'. +Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$254'. +Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. + 1/1: $0\Q[0:0] +Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$252'. +Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$251'. +Creating decoders for process `\fifo.$proc$fifo.v:0$82'. +Creating decoders for process `\fifo.$proc$fifo.v:64$75'. + 1/1: $0\count[8:0] +Creating decoders for process `\fifo.$proc$fifo.v:38$67'. + 1/3: $1$memwr$\data$fifo.v:40$66_EN[7:0]$73 + 2/3: $1$memwr$\data$fifo.v:40$66_DATA[7:0]$72 + 3/3: $1$memwr$\data$fifo.v:40$66_ADDR[7:0]$71 +Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$466'. +Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. + 1/1: $0\addr[7:0] + +yosys> proc_dlatch + +16.3.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +16.3.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\SB_DFFNES.\Q' using process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. + created $adff cell `$procdff$530' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNESS.\Q' using process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. + created $dff cell `$procdff$531' with negative edge clock. +Creating register for signal `\SB_DFFNER.\Q' using process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. + created $adff cell `$procdff$532' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNESR.\Q' using process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. + created $dff cell `$procdff$533' with negative edge clock. +Creating register for signal `\SB_DFFNS.\Q' using process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. + created $adff cell `$procdff$534' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNSS.\Q' using process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. + created $dff cell `$procdff$535' with negative edge clock. +Creating register for signal `\SB_DFFNR.\Q' using process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. + created $adff cell `$procdff$536' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNSR.\Q' using process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. + created $dff cell `$procdff$537' with negative edge clock. +Creating register for signal `\SB_DFFNE.\Q' using process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. + created $dff cell `$procdff$538' with negative edge clock. +Creating register for signal `\SB_DFFN.\Q' using process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$289'. + created $dff cell `$procdff$539' with negative edge clock. +Creating register for signal `\SB_DFFES.\Q' using process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. + created $adff cell `$procdff$540' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFESS.\Q' using process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. + created $dff cell `$procdff$541' with positive edge clock. +Creating register for signal `\SB_DFFER.\Q' using process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. + created $adff cell `$procdff$542' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFESR.\Q' using process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. + created $dff cell `$procdff$543' with positive edge clock. +Creating register for signal `\SB_DFFS.\Q' using process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. + created $adff cell `$procdff$544' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFSS.\Q' using process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. + created $dff cell `$procdff$545' with positive edge clock. +Creating register for signal `\SB_DFFR.\Q' using process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. + created $adff cell `$procdff$546' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFSR.\Q' using process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. + created $dff cell `$procdff$547' with positive edge clock. +Creating register for signal `\SB_DFFE.\Q' using process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. + created $dff cell `$procdff$548' with positive edge clock. +Creating register for signal `\SB_DFF.\Q' using process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$251'. + created $dff cell `$procdff$549' with positive edge clock. +Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$75'. + created $adff cell `$procdff$550' with positive edge clock and positive level reset. +Creating register for signal `\fifo.\rdata' using process `\fifo.$proc$fifo.v:38$67'. + created $dff cell `$procdff$551' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$66_ADDR' using process `\fifo.$proc$fifo.v:38$67'. + created $dff cell `$procdff$552' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$66_DATA' using process `\fifo.$proc$fifo.v:38$67'. + created $dff cell `$procdff$553' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$66_EN' using process `\fifo.$proc$fifo.v:38$67'. + created $dff cell `$procdff$554' 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:13$463'. + created $adff cell `$procdff$555' with positive edge clock and positive level reset. + +yosys> proc_memwr + +16.3.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +16.3.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$326'. +Found and cleaned up 1 empty switch in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. +Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. +Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$322'. +Found and cleaned up 2 empty switches in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. +Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. +Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$315'. +Found and cleaned up 1 empty switch in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. +Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. +Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$311'. +Found and cleaned up 2 empty switches in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. +Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. +Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$304'. +Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. +Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$301'. +Found and cleaned up 1 empty switch in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. +Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. +Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$298'. +Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. +Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$295'. +Found and cleaned up 1 empty switch in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. +Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. +Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. +Found and cleaned up 1 empty switch in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. +Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. +Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$290'. +Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$289'. +Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$288'. +Found and cleaned up 1 empty switch in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. +Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. +Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$284'. +Found and cleaned up 2 empty switches in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. +Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. +Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$277'. +Found and cleaned up 1 empty switch in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. +Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. +Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$273'. +Found and cleaned up 2 empty switches in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. +Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. +Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$266'. +Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. +Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$263'. +Found and cleaned up 1 empty switch in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. +Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. +Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$260'. +Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. +Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$257'. +Found and cleaned up 1 empty switch in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. +Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. +Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$254'. +Found and cleaned up 1 empty switch in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. +Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. +Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$252'. +Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$251'. +Removing empty process `fifo.$proc$fifo.v:0$82'. +Found and cleaned up 2 empty switches in `\fifo.$proc$fifo.v:64$75'. +Removing empty process `fifo.$proc$fifo.v:64$75'. +Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:38$67'. +Removing empty process `fifo.$proc$fifo.v:38$67'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$466'. +Found and cleaned up 2 empty switches in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. +Cleaned up 23 empty switches. + +yosys> opt_expr -keepdc + +16.3.12. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. + +yosys> flatten + +16.4. Executing FLATTEN pass (flatten design). +Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +<suppressed ~2 debug messages> + +yosys> tribuf -logic + +16.5. Executing TRIBUF pass. + +yosys> deminout + +16.6. Executing DEMINOUT pass (demote inout ports to input or output). + +yosys> opt_expr + +16.7. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_clean + +16.8. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 3 unused cells and 25 unused wires. +<suppressed ~4 debug messages> + +yosys> check + +16.9. Executing CHECK pass (checking for obvious problems). +Checking module fifo... +Found and reported 0 problems. + +yosys> opt -nodffe -nosdff + +16.10. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr + +16.10.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge -nomux + +16.10.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_muxtree + +16.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~6 debug messages> + +yosys> opt_reduce + +16.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. + Consolidated identical input bits for $mux cell $procmux$517: + Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\data$fifo.v:40$66_EN[7:0]$70 + New ports: A=1'0, B=1'1, Y=$0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] + New connections: $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [7:1] = { $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] } + Optimizing cells in module \fifo. +Performed a total of 1 changes. + +yosys> opt_merge + +16.10.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff -nodffe -nosdff + +16.10.6. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> opt_expr + +16.10.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.10.9. Rerunning OPT passes. (Maybe there is more to do..) + +yosys> opt_muxtree + +16.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~6 debug messages> + +yosys> opt_reduce + +16.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.10.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff -nodffe -nosdff + +16.10.13. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> opt_expr + +16.10.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.10.16. Finished OPT passes. (There is nothing left to do.) + +yosys> fsm + +16.11. Executing FSM pass (extract and optimize FSM). + +yosys> fsm_detect + +16.11.1. Executing FSM_DETECT pass (finding FSMs in design). + +yosys> fsm_extract + +16.11.2. Executing FSM_EXTRACT pass (extracting FSM from design). + +yosys> fsm_opt + +16.11.3. Executing FSM_OPT pass (simple optimizations of FSMs). + +yosys> opt_clean + +16.11.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> fsm_opt + +16.11.5. Executing FSM_OPT pass (simple optimizations of FSMs). + +yosys> fsm_recode + +16.11.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). + +yosys> fsm_info + +16.11.7. Executing FSM_INFO pass (dumping all available information on FSM cells). + +yosys> fsm_map + +16.11.8. Executing FSM_MAP pass (mapping FSMs to basic logic). + +yosys> opt + +16.12. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr + +16.12.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge -nomux + +16.12.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_muxtree + +16.12.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~6 debug messages> + +yosys> opt_reduce + +16.12.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.12.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.12.6. Executing OPT_DFF pass (perform DFF optimizations). +Adding EN signal on $procdff$550 ($adff) from module fifo (D = $0\count[8:0], Q = \count). +Adding EN signal on $flatten\fifo_writer.$procdff$555 ($adff) from module fifo (D = $flatten\fifo_writer.$procmux$526_Y, Q = \fifo_writer.addr). +Adding EN signal on $flatten\fifo_reader.$procdff$555 ($adff) from module fifo (D = $flatten\fifo_reader.$procmux$526_Y, Q = \fifo_reader.addr). + +yosys> opt_clean + +16.12.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 2 unused cells and 2 unused wires. +<suppressed ~3 debug messages> + +yosys> opt_expr + +16.12.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +<suppressed ~1 debug messages> + +16.12.9. Rerunning OPT passes. (Maybe there is more to do..) + +yosys> opt_muxtree + +16.12.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~6 debug messages> + +yosys> opt_reduce + +16.12.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.12.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.12.13. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.12.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> opt_expr + +16.12.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.12.16. Finished OPT passes. (There is nothing left to do.) + +yosys> wreduce + +16.13. Executing WREDUCE pass (reducing word size of cells). +Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$78 ($add). +Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$78 ($add). +Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$81 ($sub). +Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:70$81 ($sub). +Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$465 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$465 ($add). +Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$465 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$465 ($add). +Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$78_Y. +Removed top 23 bits (of 32) from wire fifo.$sub$fifo.v:70$81_Y. + +yosys> peepopt + +16.14. Executing PEEPOPT pass (run peephole optimizers). + +yosys> opt_clean + +16.15. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 0 unused cells and 2 unused wires. +<suppressed ~1 debug messages> + +yosys> share + +16.16. Executing SHARE pass (SAT-based resource sharing). + +yosys> techmap -map +/cmp2lut.v -D LUT_WIDTH=4 + +16.17. Executing TECHMAP pass (map to technology primitives). + +16.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/cmp2lut.v +Parsing Verilog input from `/home/dawn/yosys/share/cmp2lut.v' to AST representation. +Generating RTLIL representation for module `\_90_lut_cmp_'. +Successfully finished Verilog frontend. + +16.17.2. Continuing TECHMAP pass. +No more expansions possible. +<suppressed ~6 debug messages> + +yosys> opt_expr + +16.18. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_clean + +16.19. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> memory_dff + +16.20. 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> wreduce t:$mul + +16.21. Executing WREDUCE pass (reducing word size of cells). + +yosys> techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 -D DSP_NAME=$__MUL16X16 + +16.22. Executing TECHMAP pass (map to technology primitives). + +16.22.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/mul2dsp.v +Parsing Verilog input from `/home/dawn/yosys/share/mul2dsp.v' to AST representation. +Generating RTLIL representation for module `\_80_mul'. +Generating RTLIL representation for module `\_90_soft_mul'. +Successfully finished Verilog frontend. + +16.22.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/dsp_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/dsp_map.v' to AST representation. +Generating RTLIL representation for module `\$__MUL16X16'. +Successfully finished Verilog frontend. + +16.22.3. Continuing TECHMAP pass. +No more expansions possible. +<suppressed ~5 debug messages> + +yosys> select a:mul2dsp + +yosys*> setattr -unset mul2dsp + +yosys*> opt_expr -fine + +16.23. Executing OPT_EXPR pass (perform const folding). + +yosys*> wreduce + +16.24. Executing WREDUCE pass (reducing word size of cells). + +yosys*> select -clear + +yosys> ice40_dsp + +16.25. Executing ICE40_DSP pass (map multipliers). + +yosys> chtype -set $mul t:$__soft_mul + +yosys> alumacc + +16.26. Executing ALUMACC pass (create $alu and $macc cells). +Extracting $alu and $macc cells in module fifo: + creating $macc model for $add$fifo.v:68$78 ($add). + creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$465 ($add). + creating $macc model for $flatten\fifo_writer.$add$fifo.v:20$465 ($add). + creating $macc model for $sub$fifo.v:70$81 ($sub). + creating $alu model for $macc $sub$fifo.v:70$81. + creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$465. + creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$465. + creating $alu model for $macc $add$fifo.v:68$78. + creating $alu cell for $add$fifo.v:68$78: $auto$alumacc.cc:485:replace_alu$574 + creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$465: $auto$alumacc.cc:485:replace_alu$577 + creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$465: $auto$alumacc.cc:485:replace_alu$580 + creating $alu cell for $sub$fifo.v:70$81: $auto$alumacc.cc:485:replace_alu$583 + created 4 $alu and 0 $macc cells. + +yosys> opt + +16.27. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr + +16.27.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge -nomux + +16.27.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_muxtree + +16.27.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~6 debug messages> + +yosys> opt_reduce + +16.27.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.27.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.27.6. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.27.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 1 unused cells and 9 unused wires. +<suppressed ~2 debug messages> + +yosys> opt_expr + +16.27.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.27.9. Rerunning OPT passes. (Maybe there is more to do..) + +yosys> opt_muxtree + +16.27.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~6 debug messages> + +yosys> opt_reduce + +16.27.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.27.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.27.13. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.27.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> opt_expr + +16.27.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.27.16. Finished OPT passes. (There is nothing left to do.) + +yosys> memory -nomap + +16.28. Executing MEMORY pass. + +yosys> opt_mem + +16.28.1. Executing OPT_MEM pass (optimize memories). +Performed a total of 0 transformations. + +yosys> opt_mem_priority + +16.28.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). +Performed a total of 0 transformations. + +yosys> opt_mem_feedback + +16.28.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). + +yosys> memory_bmux2rom + +16.28.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). + +yosys> memory_dff + +16.28.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). + +yosys> opt_clean + +16.28.6. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> memory_share + +16.28.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). + +yosys> opt_mem_widen + +16.28.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). +Performed a total of 0 transformations. + +yosys> opt_clean + +16.28.9. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> memory_collect + +16.28.10. Executing MEMORY_COLLECT pass (generating $mem cells). + +yosys> opt_clean + +16.29. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt -no-auto-huge + +16.30. Executing MEMORY_LIBMAP pass (mapping memories to cells). +mapping memory fifo.data via $__ICE40_RAM4K_ +<suppressed ~68 debug messages> + +yosys> techmap -map +/ice40/brams_map.v -map +/ice40/spram_map.v + +16.31. Executing TECHMAP pass (map to technology primitives). + +16.31.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/brams_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/brams_map.v' to AST representation. +Generating RTLIL representation for module `\$__ICE40_RAM4K_'. +Successfully finished Verilog frontend. + +16.31.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/spram_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/spram_map.v' to AST representation. +Generating RTLIL representation for module `\$__ICE40_SPRAM_'. +Successfully finished Verilog frontend. + +16.31.3. Continuing TECHMAP pass. +Using template $paramod$13b3947419e62b7bbba1b93c77e4155efbe69a94\$__ICE40_RAM4K_ for cells of type $__ICE40_RAM4K_. +No more expansions possible. +<suppressed ~26 debug messages> + +yosys> ice40_braminit + +16.32. Executing ICE40_BRAMINIT pass. + +yosys> opt -fast -mux_undef -undriven -fine + +16.33. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr -mux_undef -undriven -fine + +16.33.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +<suppressed ~13 debug messages> + +yosys> opt_merge + +16.33.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.33.3. Executing OPT_DFF pass (perform DFF optimizations). +Removing always-active EN on $auto$mem.cc:1146:emulate_transparency$593 ($dffe) from module fifo. + +yosys> opt_clean + +16.33.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 0 unused cells and 18 unused wires. +<suppressed ~1 debug messages> + +16.33.5. Rerunning OPT passes. (Removed registers in this run.) + +yosys> opt_expr -mux_undef -undriven -fine + +16.33.6. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge + +16.33.7. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.33.8. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.33.9. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +16.33.10. Finished fast OPT passes. + +yosys> memory_map + +16.34. Executing MEMORY_MAP pass (converting memories to logic and flip-flops). + +yosys> opt -undriven -fine + +16.35. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr -undriven -fine + +16.35.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge -nomux + +16.35.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_muxtree + +16.35.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + Evaluating internal representation of mux trees. + Analyzing evaluation results. +Removed 0 multiplexer ports. +<suppressed ~4 debug messages> + +yosys> opt_reduce -fine + +16.35.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.35.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.35.6. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.35.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> opt_expr -undriven -fine + +16.35.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.35.9. Finished OPT passes. (There is nothing left to do.) + +yosys> ice40_wrapcarry + +16.36. Executing ICE40_WRAPCARRY pass (wrap carries). + +yosys> techmap -map +/techmap.v -map +/ice40/arith_map.v + +16.37. Executing TECHMAP pass (map to technology primitives). + +16.37.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v +Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod_trunc'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\$__div_mod_floor'. +Generating RTLIL representation for module `\_90_divfloor'. +Generating RTLIL representation for module `\_90_modfloor'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_demux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +16.37.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/arith_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/arith_map.v' to AST representation. +Generating RTLIL representation for module `\_80_ice40_alu'. +Successfully finished Verilog frontend. + +16.37.3. Continuing TECHMAP pass. +Using template $paramod$c3cd1564c35d873179656addd6052d7ea8b6d991\_80_ice40_alu for cells of type $alu. +Using extmapper simplemap for cells of type $dff. +Using extmapper simplemap for cells of type $logic_not. +Using extmapper simplemap for cells of type $logic_and. +Using extmapper simplemap for cells of type $mux. +Using extmapper simplemap for cells of type $eq. +Using extmapper simplemap for cells of type $and. +Using extmapper simplemap for cells of type $adffe. +Using template $paramod$53700bbee849b2010ad0b60a61ccd204a10e24ca\_80_ice40_alu for cells of type $alu. +Using extmapper simplemap for cells of type $reduce_bool. +Using template $paramod$6f67705c43e5e94c02b6ebb52209ce5aa5ade4c1\_80_ice40_alu for cells of type $alu. +Using extmapper simplemap for cells of type $xor. +Using extmapper simplemap for cells of type $not. +Using extmapper simplemap for cells of type $pos. +No more expansions possible. +<suppressed ~175 debug messages> + +yosys> opt -fast + +16.38. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr + +16.38.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +<suppressed ~109 debug messages> + +yosys> opt_merge + +16.38.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +<suppressed ~81 debug messages> +Removed a total of 27 cells. + +yosys> opt_dff + +16.38.3. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.38.4. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 11 unused cells and 83 unused wires. +<suppressed ~12 debug messages> + +16.38.5. Finished fast OPT passes. + +yosys> ice40_opt + +16.39. Executing ICE40_OPT pass (performing simple optimizations). + +16.39.1. Running ICE40 specific optimizations. +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$574.slice[0].carry: CO=\count [0] +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$577.slice[0].carry: CO=\fifo_reader.addr [0] +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$580.slice[0].carry: CO=\fifo_writer.addr [0] +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$583.slice[0].carry: CO=\count [0] + +yosys> opt_expr -mux_undef -undriven + +16.39.2. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge + +16.39.3. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.39.4. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.39.5. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +16.39.6. Rerunning OPT passes. (Removed registers in this run.) + +16.39.7. Running ICE40 specific optimizations. + +yosys> opt_expr -mux_undef -undriven + +16.39.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge + +16.39.9. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.39.10. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.39.11. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +16.39.12. Finished OPT passes. (There is nothing left to do.) + +yosys> dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_SDFF_?P?_ 0 -cell $_SDFFCE_?P?P_ 0 -cell $_DLATCH_?_ x -mince -1 + +16.40. Executing DFFLEGALIZE pass (convert FFs to types supported by the target). + +yosys> techmap -map +/ice40/ff_map.v + +16.41. Executing TECHMAP pass (map to technology primitives). + +16.41.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/ff_map.v' to AST representation. +Generating RTLIL representation for module `\$_DFF_N_'. +Generating RTLIL representation for module `\$_DFF_P_'. +Generating RTLIL representation for module `\$_DFFE_NP_'. +Generating RTLIL representation for module `\$_DFFE_PP_'. +Generating RTLIL representation for module `\$_DFF_NP0_'. +Generating RTLIL representation for module `\$_DFF_NP1_'. +Generating RTLIL representation for module `\$_DFF_PP0_'. +Generating RTLIL representation for module `\$_DFF_PP1_'. +Generating RTLIL representation for module `\$_DFFE_NP0P_'. +Generating RTLIL representation for module `\$_DFFE_NP1P_'. +Generating RTLIL representation for module `\$_DFFE_PP0P_'. +Generating RTLIL representation for module `\$_DFFE_PP1P_'. +Generating RTLIL representation for module `\$_SDFF_NP0_'. +Generating RTLIL representation for module `\$_SDFF_NP1_'. +Generating RTLIL representation for module `\$_SDFF_PP0_'. +Generating RTLIL representation for module `\$_SDFF_PP1_'. +Generating RTLIL representation for module `\$_SDFFCE_NP0P_'. +Generating RTLIL representation for module `\$_SDFFCE_NP1P_'. +Generating RTLIL representation for module `\$_SDFFCE_PP0P_'. +Generating RTLIL representation for module `\$_SDFFCE_PP1P_'. +Successfully finished Verilog frontend. + +16.41.2. Continuing TECHMAP pass. +Using template \$_DFFE_PP0P_ for cells of type $_DFFE_PP0P_. +Using template \$_DFF_P_ for cells of type $_DFF_P_. +No more expansions possible. +<suppressed ~73 debug messages> + +yosys> opt_expr -mux_undef + +16.42. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> simplemap + +16.43. Executing SIMPLEMAP pass (map simple cells to gate primitives). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$577.slice[0].carry ($lut). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$580.slice[0].carry ($lut). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$583.slice[0].carry ($lut). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$574.slice[0].carry ($lut). + +yosys> ice40_opt -full + +16.44. Executing ICE40_OPT pass (performing simple optimizations). + +16.44.1. Running ICE40 specific optimizations. + +yosys> opt_expr -mux_undef -undriven -full + +16.44.2. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +<suppressed ~71 debug messages> + +yosys> opt_merge + +16.44.3. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +<suppressed ~12 debug messages> +Removed a total of 4 cells. + +yosys> opt_dff + +16.44.4. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.44.5. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 0 unused cells and 270 unused wires. +<suppressed ~1 debug messages> + +16.44.6. Rerunning OPT passes. (Removed registers in this run.) + +16.44.7. Running ICE40 specific optimizations. + +yosys> opt_expr -mux_undef -undriven -full + +16.44.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +<suppressed ~1 debug messages> + +yosys> opt_merge + +16.44.9. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.44.10. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.44.11. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +16.44.12. Rerunning OPT passes. (Removed registers in this run.) + +16.44.13. Running ICE40 specific optimizations. + +yosys> opt_expr -mux_undef -undriven -full + +16.44.14. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +yosys> opt_merge + +16.44.15. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.44.16. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.44.17. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +16.44.18. Finished OPT passes. (There is nothing left to do.) + +yosys> techmap -map +/ice40/latches_map.v + +16.45. Executing TECHMAP pass (map to technology primitives). + +16.45.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/latches_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/latches_map.v' to AST representation. +Generating RTLIL representation for module `\$_DLATCH_N_'. +Generating RTLIL representation for module `\$_DLATCH_P_'. +Successfully finished Verilog frontend. + +16.45.2. Continuing TECHMAP pass. +No more expansions possible. +<suppressed ~4 debug messages> + +yosys> read_verilog -D ICE40_HX -icells -lib -specify +/ice40/abc9_model.v + +16.46. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/abc9_model.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/abc9_model.v' to AST representation. +Generating RTLIL representation for module `$__ICE40_CARRY_WRAPPER'. +Successfully finished Verilog frontend. + +yosys> abc9 -W 250 + +16.47. Executing ABC9 pass. + +yosys> abc9_ops -check + +16.47.1. Executing ABC9_OPS pass (helper functions for ABC9). + +yosys> abc9_ops -prep_hier + +16.47.2. Executing ABC9_OPS pass (helper functions for ABC9). + +yosys> scc -specify -set_attr abc9_scc_id {} + +16.47.3. Executing SCC pass (detecting logic loops). +Found 0 SCCs in module fifo. +Found 0 SCCs. + +yosys> abc9_ops -prep_bypass + +16.47.4. Executing ABC9_OPS pass (helper functions for ABC9). + +yosys> design -stash $abc9 + +yosys> design -load $abc9_map + +yosys> proc + +16.47.5. Executing PROC pass (convert processes to netlists). + +yosys> proc_clean + +16.47.5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> proc_rmdead + +16.47.5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Removed a total of 0 dead cases. + +yosys> proc_prune + +16.47.5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +Removed 0 redundant assignments. +Promoted 0 assignments to connections. + +yosys> proc_init + +16.47.5.4. Executing PROC_INIT pass (extract init attributes). + +yosys> proc_arst + +16.47.5.5. Executing PROC_ARST pass (detect async resets in processes). + +yosys> proc_rom + +16.47.5.6. Executing PROC_ROM pass (convert switches to ROMs). +Converted 0 switches. + +yosys> proc_mux + +16.47.5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). + +yosys> proc_dlatch + +16.47.5.8. Executing PROC_DLATCH pass (convert process syncs to latches). + +yosys> proc_dff + +16.47.5.9. Executing PROC_DFF pass (convert process syncs to FFs). + +yosys> proc_memwr + +16.47.5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). + +yosys> proc_clean + +16.47.5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Cleaned up 0 empty switches. + +yosys> opt_expr -keepdc + +16.47.5.12. Executing OPT_EXPR pass (perform const folding). + +yosys> wbflip + +yosys> techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop + +16.47.6. Executing TECHMAP pass (map to technology primitives). + +16.47.6.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v +Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod_trunc'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\$__div_mod_floor'. +Generating RTLIL representation for module `\_90_divfloor'. +Generating RTLIL representation for module `\_90_modfloor'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_demux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +16.47.6.2. Continuing TECHMAP pass. +No more expansions possible. +<suppressed ~128 debug messages> + +yosys> opt -nodffe -nosdff + +16.47.7. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr + +16.47.7.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module SB_DFFER. + +yosys> opt_merge -nomux + +16.47.7.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\SB_DFFER'. +Removed a total of 0 cells. + +yosys> opt_muxtree + +16.47.7.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \SB_DFFER.. + Creating internal representation of mux trees. + No muxes found in this module. +Removed 0 multiplexer ports. + +yosys> opt_reduce + +16.47.7.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \SB_DFFER. +Performed a total of 0 changes. + +yosys> opt_merge + +16.47.7.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\SB_DFFER'. +Removed a total of 0 cells. + +yosys> opt_dff -nodffe -nosdff + +16.47.7.6. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean + +16.47.7.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \SB_DFFER.. + +yosys> opt_expr + +16.47.7.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module SB_DFFER. + +16.47.7.9. Finished OPT passes. (There is nothing left to do.) + +yosys> design -stash $abc9_map + +yosys> design -load $abc9 + +yosys> design -delete $abc9 + +yosys> techmap -wb -max_iter 1 -map %$abc9_map -map +/abc9_map.v a:abc9_scc_id %n + +16.47.8. Executing TECHMAP pass (map to technology primitives). + +16.47.8.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_map.v +Parsing Verilog input from `/home/dawn/yosys/share/abc9_map.v' to AST representation. +Successfully finished Verilog frontend. + +16.47.8.2. Continuing TECHMAP pass. +Using template SB_DFFER for cells of type SB_DFFER. +No more expansions possible. +<suppressed ~28 debug messages> + +yosys> design -delete $abc9_map + +yosys> read_verilog -icells -lib -specify +/abc9_model.v + +16.47.9. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_model.v +Parsing Verilog input from `/home/dawn/yosys/share/abc9_model.v' to AST representation. +Generating RTLIL representation for module `$__ABC9_DELAY'. +Generating RTLIL representation for module `$__ABC9_SCC_BREAKER'. +Generating RTLIL representation for module `$__DFF_N__$abc9_flop'. +Generating RTLIL representation for module `$__DFF_P__$abc9_flop'. +Successfully finished Verilog frontend. + +yosys> abc9_ops -break_scc -prep_delays -prep_xaiger + +16.47.10. Executing ABC9_OPS pass (helper functions for ABC9). +<suppressed ~86 debug messages> + +yosys> abc9_ops -prep_lut 0 + +16.47.11. Executing ABC9_OPS pass (helper functions for ABC9). + +yosys> abc9_ops -prep_box + +16.47.12. Executing ABC9_OPS pass (helper functions for ABC9). +<suppressed ~2 debug messages> + +yosys> design -stash $abc9 + +yosys> design -load $abc9_holes + +yosys> techmap -wb -map %$abc9 -map +/techmap.v + +16.47.13. Executing TECHMAP pass (map to technology primitives). + +16.47.13.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v +Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. +Generating RTLIL representation for module `\_90_simplemap_bool_ops'. +Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. +Generating RTLIL representation for module `\_90_simplemap_logic_ops'. +Generating RTLIL representation for module `\_90_simplemap_compare_ops'. +Generating RTLIL representation for module `\_90_simplemap_various'. +Generating RTLIL representation for module `\_90_simplemap_registers'. +Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. +Generating RTLIL representation for module `\_90_shift_shiftx'. +Generating RTLIL representation for module `\_90_fa'. +Generating RTLIL representation for module `\_90_lcu'. +Generating RTLIL representation for module `\_90_alu'. +Generating RTLIL representation for module `\_90_macc'. +Generating RTLIL representation for module `\_90_alumacc'. +Generating RTLIL representation for module `\$__div_mod_u'. +Generating RTLIL representation for module `\$__div_mod_trunc'. +Generating RTLIL representation for module `\_90_div'. +Generating RTLIL representation for module `\_90_mod'. +Generating RTLIL representation for module `\$__div_mod_floor'. +Generating RTLIL representation for module `\_90_divfloor'. +Generating RTLIL representation for module `\_90_modfloor'. +Generating RTLIL representation for module `\_90_pow'. +Generating RTLIL representation for module `\_90_pmux'. +Generating RTLIL representation for module `\_90_demux'. +Generating RTLIL representation for module `\_90_lut'. +Successfully finished Verilog frontend. + +16.47.13.2. Continuing TECHMAP pass. +Using template $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 for cells of type $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1. +Using template $paramod\SB_LUT4\LUT_INIT=16'0110100110010110 for cells of type SB_LUT4. +Using template SB_CARRY for cells of type SB_CARRY. +Using extmapper simplemap for cells of type $mux. +Using extmapper simplemap for cells of type $logic_and. +Using extmapper simplemap for cells of type $logic_or. +No more expansions possible. +<suppressed ~155 debug messages> + +yosys> opt -purge + +16.47.14. Executing OPT pass (performing simple optimizations). + +yosys> opt_expr + +16.47.14.1. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. +<suppressed ~4 debug messages> + +yosys> opt_merge -nomux + +16.47.14.2. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +<suppressed ~29 debug messages> +Removed a total of 12 cells. + +yosys> opt_muxtree + +16.47.14.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + No muxes found in this module. +Removed 0 multiplexer ports. + +yosys> opt_reduce + +16.47.14.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.47.14.5. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.47.14.6. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean -purge + +16.47.14.7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 0 unused cells and 24 unused wires. +<suppressed ~1 debug messages> + +yosys> opt_expr + +16.47.14.8. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.47.14.9. Rerunning OPT passes. (Maybe there is more to do..) + +yosys> opt_muxtree + +16.47.14.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +Running muxtree optimizer on module \fifo.. + Creating internal representation of mux trees. + No muxes found in this module. +Removed 0 multiplexer ports. + +yosys> opt_reduce + +16.47.14.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). + Optimizing cells in module \fifo. +Performed a total of 0 changes. + +yosys> opt_merge + +16.47.14.12. Executing OPT_MERGE pass (detect identical cells). +Finding identical cells in module `\fifo'. +Removed a total of 0 cells. + +yosys> opt_dff + +16.47.14.13. Executing OPT_DFF pass (perform DFF optimizations). + +yosys> opt_clean -purge + +16.47.14.14. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. + +yosys> opt_expr + +16.47.14.15. Executing OPT_EXPR pass (perform const folding). +Optimizing module fifo. + +16.47.14.16. Finished OPT passes. (There is nothing left to do.) + +yosys> aigmap + +16.47.15. Executing AIGMAP pass (map logic to AIG). +Module fifo: replaced 7 cells with 43 new cells, skipped 11 cells. + replaced 2 cell types: + 2 $_OR_ + 5 $_MUX_ + not replaced 3 cell types: + 8 $specify2 + 1 $_NOT_ + 2 $_AND_ + +yosys> design -stash $abc9_holes + +yosys> design -load $abc9 + +yosys> design -delete $abc9 + +yosys> aigmap + +16.47.16. Executing AIGMAP pass (map logic to AIG). +Module fifo: replaced 46 cells with 256 new cells, skipped 230 cells. + replaced 3 cell types: + 22 $_OR_ + 8 $_XOR_ + 16 $_MUX_ + not replaced 15 cell types: + 20 $_NOT_ + 19 $_AND_ + 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011100000 + 26 SB_DFF + 25 SB_DFFER + 30 $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 + 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011001011 + 25 SB_DFFER_$abc9_byp + 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000001100010 + 2 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100001011 + 16 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000010100001 + 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000010000101 + 1 $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K + 16 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100010010 + 26 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000000010101 + +yosys*> abc9_ops -write_lut /tmp/yosys-abc-Sf9BQI/input.lut + +16.47.16.1. Executing ABC9_OPS pass (helper functions for ABC9). + +yosys*> abc9_ops -write_box /tmp/yosys-abc-Sf9BQI/input.box + +16.47.16.2. Executing ABC9_OPS pass (helper functions for ABC9). + +yosys*> write_xaiger -map /tmp/yosys-abc-Sf9BQI/input.sym /tmp/yosys-abc-Sf9BQI/input.xaig + +16.47.16.3. Executing XAIGER backend. +<suppressed ~78 debug messages> +Extracted 113 AND gates and 562 wires from module `fifo' to a netlist network with 71 inputs and 127 outputs. + +yosys*> abc9_exe -W 250 -cwd /tmp/yosys-abc-Sf9BQI -lut /tmp/yosys-abc-Sf9BQI/input.lut -box /tmp/yosys-abc-Sf9BQI/input.box + +16.47.16.4. Executing ABC9_EXE pass (technology mapping using ABC9). + +16.47.16.5. Executing ABC9. +Running ABC command: "<yosys-exe-dir>/yosys-abc" -s -f <abc-temp-dir>/abc.script 2>&1 +ABC: ABC command line: "source <abc-temp-dir>/abc.script". +ABC: +ABC: + read_lut <abc-temp-dir>/input.lut +ABC: + read_box <abc-temp-dir>/input.box +ABC: + &read <abc-temp-dir>/input.xaig +ABC: + &ps +ABC: <abc-temp-dir>/input : i/o = 71/ 127 and = 113 lev = 6 (0.27) mem = 0.01 MB box = 139 bb = 109 +ABC: Warning: AIG with boxes has internal fanout in 0 complex flops and 20 carries. +ABC: + &scorr +ABC: Warning: The network is combinational. +ABC: + &sweep +ABC: + &dc2 +ABC: + &dch -f +ABC: + &ps +ABC: <abc-temp-dir>/input : i/o = 71/ 127 and = 160 lev = 6 (0.12) mem = 0.01 MB ch = 20 box = 139 bb = 109 +ABC: Warning: AIG with boxes has internal fanout in 0 complex flops and 20 carries. +ABC: + &if -W 250 -v +ABC: K = 4. Memory (bytes): Truth = 0. Cut = 48. Obj = 128. Set = 528. CutMin = no +ABC: Node = 160. Ch = 19. Total mem = 0.11 MB. Peak cut mem = 0.01 MB. +ABC: P: Del = 2712.00. Ar = 28.0. Edge = 81. Cut = 569. T = 0.00 sec +ABC: P: Del = 2712.00. Ar = 27.0. Edge = 87. Cut = 564. T = 0.00 sec +ABC: P: Del = 2712.00. Ar = 26.0. Edge = 86. Cut = 565. T = 0.00 sec +ABC: F: Del = 2712.00. Ar = 26.0. Edge = 88. Cut = 554. T = 0.00 sec +ABC: A: Del = 2712.00. Ar = 26.0. Edge = 86. Cut = 537. T = 0.00 sec +ABC: A: Del = 2712.00. Ar = 26.0. Edge = 86. Cut = 545. T = 0.00 sec +ABC: Total time = 0.00 sec +ABC: + &write -n <abc-temp-dir>/output.aig +ABC: + &mfs +ABC: The network is not changed by "&mfs". +ABC: + &ps -l +ABC: <abc-temp-dir>/input : i/o = 71/ 127 and = 91 lev = 6 (0.12) mem = 0.01 MB box = 139 bb = 109 +ABC: Mapping (K=4) : lut = 26 edge = 86 lev = 3 (0.05) levB = 10 mem = 0.00 MB +ABC: LUT = 26 : 2=4 15.4 % 3=10 38.5 % 4=12 46.2 % Ave = 3.31 +ABC: Warning: AIG with boxes has internal fanout in 0 complex flops and 20 carries. +ABC: + &write -n <abc-temp-dir>/output.aig +ABC: + time +ABC: elapse: 0.01 seconds, total: 0.01 seconds + +yosys*> read_aiger -xaiger -wideports -module_name fifo$abc9 -map /tmp/yosys-abc-Sf9BQI/input.sym /tmp/yosys-abc-Sf9BQI/output.aig + +16.47.16.6. Executing AIGER frontend. + +yosys> clean +<suppressed ~408 debug messages> +Removed 175 unused cells and 883 unused wires. + +yosys*> abc9_ops -reintegrate + +16.47.16.7. Executing ABC9_OPS pass (helper functions for ABC9). +ABC RESULTS: $lut cells: 29 +ABC RESULTS: $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 cells: 30 +ABC RESULTS: \SB_DFFER_$abc9_byp cells: 25 +ABC RESULTS: input signals: 36 +ABC RESULTS: output signals: 91 +Removing temp directory. + +yosys> techmap -wb -map %$abc9_unmap -map +/abc9_unmap.v + +16.47.17. Executing TECHMAP pass (map to technology primitives). + +16.47.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_unmap.v +Parsing Verilog input from `/home/dawn/yosys/share/abc9_unmap.v' to AST representation. +Generating RTLIL representation for module `\$__DFF_x__$abc9_flop'. +Generating RTLIL representation for module `\$__ABC9_SCC_BREAKER'. +Successfully finished Verilog frontend. + +16.47.17.2. Continuing TECHMAP pass. +Using template SB_DFFER_$abc9_byp for cells of type SB_DFFER_$abc9_byp. +Using template $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K for cells of type $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K. +Using template $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 for cells of type $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1. +No more expansions possible. +<suppressed ~64 debug messages> + +yosys> design -delete $abc9_unmap + +yosys> design -delete $abc9_holes + +yosys> delete =*_$abc9_byp + +yosys> setattr -mod -unset abc9_box_id + +yosys> ice40_wrapcarry -unwrap + +16.48. Executing ICE40_WRAPCARRY pass (wrap carries). + +yosys> techmap -map +/ice40/ff_map.v + +16.49. Executing TECHMAP pass (map to technology primitives). + +16.49.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/ff_map.v' to AST representation. +Generating RTLIL representation for module `\$_DFF_N_'. +Generating RTLIL representation for module `\$_DFF_P_'. +Generating RTLIL representation for module `\$_DFFE_NP_'. +Generating RTLIL representation for module `\$_DFFE_PP_'. +Generating RTLIL representation for module `\$_DFF_NP0_'. +Generating RTLIL representation for module `\$_DFF_NP1_'. +Generating RTLIL representation for module `\$_DFF_PP0_'. +Generating RTLIL representation for module `\$_DFF_PP1_'. +Generating RTLIL representation for module `\$_DFFE_NP0P_'. +Generating RTLIL representation for module `\$_DFFE_NP1P_'. +Generating RTLIL representation for module `\$_DFFE_PP0P_'. +Generating RTLIL representation for module `\$_DFFE_PP1P_'. +Generating RTLIL representation for module `\$_SDFF_NP0_'. +Generating RTLIL representation for module `\$_SDFF_NP1_'. +Generating RTLIL representation for module `\$_SDFF_PP0_'. +Generating RTLIL representation for module `\$_SDFF_PP1_'. +Generating RTLIL representation for module `\$_SDFFCE_NP0P_'. +Generating RTLIL representation for module `\$_SDFFCE_NP1P_'. +Generating RTLIL representation for module `\$_SDFFCE_PP0P_'. +Generating RTLIL representation for module `\$_SDFFCE_PP1P_'. +Successfully finished Verilog frontend. + +16.49.2. Continuing TECHMAP pass. +No more expansions possible. +<suppressed ~22 debug messages> + +yosys> clean +Removed 7 unused cells and 1055 unused wires. + +yosys> opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 -dlogic SB_CARRY:CO=3 + +16.50. Executing OPT_LUT pass (optimize LUTs). +Discovering LUTs. +Number of LUTs: 58 + 1-LUT 3 + 2-LUT 8 + 3-LUT 35 + 4-LUT 12 + with \SB_CARRY (#0) 25 + with \SB_CARRY (#1) 26 + +Eliminating LUTs. +Number of LUTs: 58 + 1-LUT 3 + 2-LUT 8 + 3-LUT 35 + 4-LUT 12 + with \SB_CARRY (#0) 25 + with \SB_CARRY (#1) 26 + +Combining LUTs. +Number of LUTs: 58 + 1-LUT 3 + 2-LUT 8 + 3-LUT 35 + 4-LUT 12 + with \SB_CARRY (#0) 25 + with \SB_CARRY (#1) 26 + +Eliminated 0 LUTs. +Combined 0 LUTs. +<suppressed ~334 debug messages> + +yosys> techmap -map +/ice40/cells_map.v + +16.51. Executing TECHMAP pass (map to technology primitives). + +16.51.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_map.v +Parsing Verilog input from `/home/dawn/yosys/share/ice40/cells_map.v' to AST representation. +Generating RTLIL representation for module `\$lut'. +Successfully finished Verilog frontend. + +16.51.2. Continuing TECHMAP pass. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10111000 for cells of type $lut. +Using template $paramod$fd904e9e35cfd343a9df248824bd3f1408724879\$lut for cells of type $lut. +Using template $paramod$e87f431398fe61dc3cef677df705fdf1c11aa0f7\$lut for cells of type $lut. +Using template $paramod$8d7a8d6e3356de09670738ba85f2c6b874f6b06d\$lut for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10010000 for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0100 for cells of type $lut. +Using template $paramod$2b29ccbd5fb8b9c557f92ddec1023c75686f32ae\$lut for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0010 for cells of type $lut. +Using template $paramod$ba7c22fadfbf9ee7abcb895a21403114111dd201\$lut for cells of type $lut. +Using template $paramod$5c7d886f3b88971ac55fed4bca034a87bf180f7d\$lut for cells of type $lut. +Using template $paramod$571404c0889eaf57f492cb5e37f8acb5df5852f9\$lut for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0110 for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000001\LUT=2'01 for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'01001011 for cells of type $lut. +No more expansions possible. +<suppressed ~243 debug messages> + +yosys> clean +Removed 0 unused cells and 130 unused wires. + +yosys> autoname + +16.52. Executing AUTONAME pass. +Renamed 1254 objects in module fifo (21 iterations). +<suppressed ~213 debug messages> + +yosys> hierarchy -check + +16.53. Executing HIERARCHY pass (managing design hierarchy). + +16.53.1. Analyzing design hierarchy.. +Top module: \fifo + +16.53.2. Analyzing design hierarchy.. +Top module: \fifo +Removed 0 unused modules. + +yosys> stat + +16.54. Printing statistics. + +=== fifo === + + Number of wires: 91 + Number of wire bits: 246 + Number of public wires: 91 + Number of public wire bits: 246 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 136 + SB_CARRY 26 + SB_DFF 26 + SB_DFFER 25 + SB_LUT4 58 + SB_RAM40_4K 1 + + +yosys> check -noinit + +16.55. Executing CHECK pass (checking for obvious problems). +Checking module fifo... +Found and reported 0 problems. + +yosys> blackbox =A:whitebox + +yosys> show -notitle -format dot -prefix fifo_synth + +17. Generating Graphviz representation of design. +Writing dot description to `fifo_synth.dot'. +Dumping module fifo to page 1. + +yosys> stat + +18. Printing statistics. + +=== fifo === + + Number of wires: 91 + Number of wire bits: 246 + Number of public wires: 91 + Number of public wire bits: 246 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 136 + SB_CARRY 26 + SB_DFF 26 + SB_DFFER 25 + SB_LUT4 58 + SB_RAM40_4K 1 + +End of script. Logfile hash: 7fbdf4b991, CPU: user 0.68s system 0.01s, MEM: 29.84 MB peak +Yosys 0.35+39 (git sha1 0cd4a10c8, clang 10.0.0-4ubuntu1 -fPIC -Os) +Time spent: 37% 27x read_verilog (0 sec), 33% 12x techmap (0 sec), ... diff --git a/docs/source/code_examples/fifo/fifo.v b/docs/source/code_examples/fifo/fifo.v new file mode 100644 index 000000000..e70005765 --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.v @@ -0,0 +1,73 @@ +// address generator/counter +module addr_gen +#( parameter MAX_DATA=256 +) ( input en, clk, rst, + output reg [AWIDTH-1:0] addr +); + localparam AWIDTH = $clog2(MAX_DATA); + + 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 +) ( input wen, ren, clk, rst, + input [7:0] wdata, + output reg [7:0] rdata, + output reg [AWIDTH:0] count +); + localparam AWIDTH = $clog2(MAX_DATA); + + // 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 000000000..d0274e38b --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.ys @@ -0,0 +1,39 @@ +# ======================================================== +# 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 +show -notitle -format dot -prefix addr_gen_hier + +# ======================================================== +proc +show -notitle -format dot -prefix addr_gen_proc + +# ======================================================== +design -reset +read_verilog fifo.v +hierarchy -check -top fifo +proc +show -notitle -format dot -prefix rdata_proc o:rdata %ci* + +# ======================================================== + +flatten +show -notitle -format dot -prefix rdata_flat o:rdata %ci* + +# ======================================================== + +opt_clean +show -notitle -format dot -prefix fifo_flat + +design -reset +read_verilog fifo.v +synth_ice40 -dsp -top fifo +show -notitle -format dot -prefix fifo_synth +stat diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index bedaa035c..3c43be269 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -23,37 +23,29 @@ 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/example_synth/example.v +.. literalinclude:: /code_examples/fifo/fifo.v :language: Verilog :linenos: - :caption: ``example.v`` - :name: example-v + :caption: ``fifo.v`` + :name: fifo-v -.. todo:: example.v description +.. todo:: fifo.v description Loading the design ~~~~~~~~~~~~~~~~~~ Let's load the design into Yosys. From the command line, we can call ``yosys -example.v``. This will open an interactive Yosys shell session and immediately -parse the code from ``example.v`` and convert it into an Abstract Syntax Tree +fifo.v``. This will open an interactive Yosys shell session and immediately +parse the code from ``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: -.. code:: console - - $ yosys example.v - - -- Parsing `example.v' using frontend ` -vlog2k' -- - - 1. Executing Verilog-2005 frontend: example.v - Parsing Verilog input from `example.v' to AST representation. - Storing AST representation for module `$abstract\example'. - Storing AST representation for module `$abstract\control'. - Storing AST representation for module `$abstract\data'. - Successfully finished Verilog frontend. +.. 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` @@ -62,10 +54,10 @@ 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 example`, but for now we +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; -``control``. +``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. @@ -86,20 +78,20 @@ design. PLLs are a common example of this, where we might need to reference later. Since our simple design doesn't use any of these IP blocks, we can safely skip this command. -The control module -^^^^^^^^^^^^^^^^^^ +The addr_gen module +^^^^^^^^^^^^^^^^^^^ Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy --top control`. This command declares that the top level module is ``control``, +-top addr_gen`. This command declares that the top level module is ``addr_gen``, and everything else can be discarded. -.. literalinclude:: /code_examples/example_synth/example.v +.. literalinclude:: /code_examples/fifo/fifo.v :language: Verilog - :start-at: module control - :end-at: endmodule //control + :start-at: module addr_gen + :end-at: endmodule //addr_gen :lineno-match: - :caption: ``control`` module source - :name: control-v + :caption: ``addr_gen`` module source + :name: addr_gen-v .. note:: @@ -108,26 +100,26 @@ and everything else can be discarded. .. use doscon for a console-like display that supports the `yosys> [command]` format. -.. literalinclude:: /code_examples/example_synth/example.out +.. literalinclude:: /code_examples/fifo/fifo.out :language: doscon - :start-at: yosys> hierarchy -top control + :start-at: yosys> hierarchy -top addr_gen :end-before: yosys> show - :caption: :yoscrypt:`hierarchy -top control` output + :caption: :yoscrypt:`hierarchy -top addr_gen` output -Our ``control`` circuit now looks like this: +Our ``addr_gen`` circuit now looks like this: -.. figure:: /_images/code_examples/example_synth/control_hier.* +.. figure:: /_images/code_examples/fifo/addr_gen_hier.* :class: width-helper - :name: control_hier + :name: addr_gen_hier - ``control`` module after :cmd:ref:`hierarchy` + ``addr_gen`` module after :cmd:ref:`hierarchy` -Notice that block that says "PROC" in :ref:`control_hier`? Simple operations -like ``addr + 1'b1`` can be extracted from our ``always @`` block in -:ref:`control-v`. This gives us the two ``$add`` cells we see. But control -logic (like the ``if .. else``) and memory elements (like the ``addr <= 0``) are -not so straightforward. To handle these, let us now introduce the next command: -:doc:`/cmd/proc`. +Notice that block that says "PROC" in :ref:`addr_gen_hier`? 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 ``$add`` and ``$eq`` cells we +see. But control logic (like the ``if .. else``) and memory elements (like the +``addr <= 0``) are not so straightforward. 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 @@ -135,68 +127,81 @@ 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. -.. figure:: /_images/code_examples/example_synth/control_proc.* +.. figure:: /_images/code_examples/fifo/addr_gen_proc.* :class: width-helper + :name: addr_gen_proc - ``control`` module after :cmd:ref:`proc` + ``addr_gen`` module after :cmd:ref:`proc` -The ``if`` statements are now modeled with ``$mux`` cells, while the registers -use ``$dff`` cells. 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`. +The ``if`` statements are now modeled with ``$mux`` cells, while the register +uses an ``$adff`` cells. 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`. + +.. todo:: consider a brief glossary for terms like adff The full example ^^^^^^^^^^^^^^^^ Let's now go back and check on our full design by using :yoscrypt:`hierarchy --check -top example`. By passing the ``-check`` option there we are also +-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 ``control``. We +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/example_synth/example.out +.. literalinclude:: /code_examples/fifo/fifo.out :language: doscon :start-at: design -reset - :end-before: yosys> show - :caption: reloading ``example.v`` and running :yoscrypt:`hierarchy -check -top example` + :end-before: yosys> proc + :caption: reloading ``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 example.v``, the first command Yosys called was -:yoscrypt:`read_verilog -defer example.v`. The ``-defer`` option there tells +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 or not synthesizable code, -which is why Yosys does this 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``. +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:: more on why :cmd:ref:`hierarchy` is important .. 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 ``example.ys``. There are extra commands being run + included in the source as ``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 ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys interactive terminal. -.. figure:: /_images/code_examples/example_synth/example_hier.* +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`. + +.. figure:: /_images/code_examples/fifo/rdata_proc.* :class: width-helper - :name: example_hier + :name: rdata_proc - ``example`` module after :cmd:ref:`hierarchy` + ``rdata`` output after :cmd:ref:`proc` -We can also run :cmd:ref:`proc` now, although we won't actually see any change -in this top view. +The ``fifo_reader`` block we can see there is the same as the +:ref:`addr_gen_proc` that we looked at earlier. -.. TODO:: more on why :cmd:ref:`hierarchy` is important +.. TODO:: comment on ``$memrd`` .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/proc` @@ -215,12 +220,14 @@ In :cmd:ref:`synth_ice40` we get these: :name: synth_flatten :caption: ``flatten`` section -First off is :cmd:ref:`synth_flatten`. Flattening the design like this can -allow for optimizations between modules which would otherwise be missed. We -will skip this command for now because it makes the design schematic quite -large. If you would like to see 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 example`. +First off is :cmd:ref:`flatten`. Flattening the design like this can +allow for optimizations between modules which would otherwise be missed. + +.. figure:: /_images/code_examples/fifo/rdata_flat.* + :class: width-helper + :name: rdata_flat + + ``rdata`` module after :cmd:ref:`flatten` Depending on the target architecture, we might also see commands such as :cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`. These @@ -244,6 +251,7 @@ In the iCE40 flow we get all the following commands: .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt + :linenos: :start-after: coarse: :end-before: map_ram: :dedent: From a33b1b60591e4aa7495ee891b7fe24b230bc9497 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 18 Dec 2023 17:49:15 +1300 Subject: [PATCH 061/108] More work on example_synth Added highlighting in (most) schematics. Written down to end of coarse-grain, with a couple of TODOs for filling in gaps. Includes `techmap_synth.rst` stub. --- docs/source/code_examples/fifo/fifo.ys | 41 +++- docs/source/getting_started/example_synth.rst | 195 ++++++++++++++---- docs/source/using_yosys/synthesis/index.rst | 1 + .../using_yosys/synthesis/techmap_synth.rst | 4 + 4 files changed, 196 insertions(+), 45 deletions(-) create mode 100644 docs/source/using_yosys/synthesis/techmap_synth.rst diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index d0274e38b..576704838 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -9,31 +9,54 @@ read_verilog -defer fifo.v # turn command echoes on to use the log output as a console session echo on hierarchy -top addr_gen -show -notitle -format dot -prefix addr_gen_hier +select -set new_cells t:* +show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_hier # ======================================================== proc -show -notitle -format dot -prefix addr_gen_proc +select -set new_cells t:$mux t:*dff +show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc + +# ======================================================== +opt_clean +show -notitle -format dot -prefix addr_gen_clean # ======================================================== design -reset read_verilog fifo.v hierarchy -check -top fifo proc -show -notitle -format dot -prefix rdata_proc o:rdata %ci* +show -color maroon3 c:fifo_reader -notitle -format dot -prefix rdata_proc o:rdata %ci* # ======================================================== -flatten +flatten;; show -notitle -format dot -prefix rdata_flat o:rdata %ci* # ======================================================== -opt_clean -show -notitle -format dot -prefix fifo_flat +opt_dff +select -set new_cells t:$adffe +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* + +# ======================================================== + +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* + +# ======================================================== design -reset read_verilog fifo.v -synth_ice40 -dsp -top fifo -show -notitle -format dot -prefix fifo_synth -stat +synth_ice40 -top fifo -run begin:map_ram +# memory_collect +# opt +select -set new_cells t:$mem_v2 +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse o:rdata %ci* diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 3c43be269..a22ea1bf9 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -103,7 +103,7 @@ and everything else can be discarded. .. literalinclude:: /code_examples/fifo/fifo.out :language: doscon :start-at: yosys> hierarchy -top addr_gen - :end-before: yosys> show + :end-before: yosys> select :caption: :yoscrypt:`hierarchy -top addr_gen` output Our ``addr_gen`` circuit now looks like this: @@ -114,13 +114,19 @@ Our ``addr_gen`` circuit now looks like this: ``addr_gen`` module after :cmd:ref:`hierarchy` -Notice that block that says "PROC" in :ref:`addr_gen_hier`? 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 ``$add`` and ``$eq`` cells we -see. But control logic (like the ``if .. else``) and memory elements (like the -``addr <= 0``) are not so straightforward. To handle these, let us now introduce -the next command: :doc:`/cmd/proc`. +.. todo:: how to highlight PROC blocks? + They seem to be replaced in ``show``, so the selection never matches +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 @@ -133,10 +139,35 @@ we run it. ``addr_gen`` module after :cmd:ref:`proc` -The ``if`` statements are now modeled with ``$mux`` cells, while the register -uses an ``$adff`` cells. 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`. +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`. + +.. TODO:: intro ``opt_expr`` + :doc:`/cmd/opt_expr` + + - by default called at the end of :cmd:ref:`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:`opt_clean`: + +.. figure:: /_images/code_examples/fifo/addr_gen_clean.* + :class: width-helper + :name: addr_gen_clean + + ``addr_gen`` module after :cmd:ref:`opt_clean` + +.. TODO:: more on opt_clean + :doc:`/cmd/opt_clean` + + - :cmd:ref:`clean` for short, ``;;`` for even shorter + - final command of :cmd:ref:`opt` + - can run at any time .. todo:: consider a brief glossary for terms like adff @@ -198,8 +229,11 @@ command only works with a single module, so you may need to call it with ``rdata`` output after :cmd:ref:`proc` -The ``fifo_reader`` block we can see there is the same as the -:ref:`addr_gen_proc` that we looked at earlier. +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`` set to the given +value. .. TODO:: comment on ``$memrd`` @@ -220,14 +254,28 @@ In :cmd:ref:`synth_ice40` we get these: :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. +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> show + :name: flat_clean + :caption: output of :yoscrypt:`flatten;;` .. figure:: /_images/code_examples/fifo/rdata_flat.* :class: width-helper :name: rdata_flat - ``rdata`` module after :cmd:ref:`flatten` + ``rdata`` output after :yoscrypt:`flatten;;` + +We can now see both :ref:`rdata_proc` and :ref:`addr_gen_proc` together. Note +that in the :ref:`flat_clean` we see above has two separate calls: one to +:cmd:ref:`flatten` and one to :cmd:ref:`clean`. In an interactive terminal the +output of both commands will be combined into the single `yosys> flatten;;` +output. Depending on the target architecture, we might also see commands such as :cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`. These @@ -247,6 +295,12 @@ 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 + the :ref:`synth_coarse`. + In the iCE40 flow we get all the following commands: .. literalinclude:: /cmd/synth_ice40.rst @@ -258,34 +312,103 @@ In the iCE40 flow we get all the following commands: :caption: ``coarse`` section :name: synth_coarse -.. note:: +The first few commands are relatively straightforward. We've already come +across :cmd:ref:`opt_clean` and :cmd:ref:`opt_expr`. 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. - 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 - the :ref:`synth_coarse` section. +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/fsm` and +:doc:`/using_yosys/synthesis/opt` respectively. -.. TODO:: talk more about DSPs (and their associated commands) +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: -.. TODO:: example_syth ``coarse`` section +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> opt_dff + :end-before: yosys> select + :caption: output of :cmd:ref:`opt_dff` -Some of the commands we might use here are: +.. figure:: /_images/code_examples/fifo/rdata_adffe.* + :class: width-helper + :name: rdata_adffe -- :doc:`/cmd/opt_expr`, -- :doc:`/cmd/opt_clean`, -- :doc:`/cmd/check`, -- :doc:`/cmd/opt`, -- :doc:`/cmd/fsm`, -- :doc:`/cmd/wreduce`, -- :doc:`/cmd/peepopt`, -- :doc:`/cmd/memory`, -- :doc:`/cmd/pmuxtree`, -- :doc:`/cmd/alumacc`, and -- :doc:`/cmd/share`. + ``rdata`` output after :cmd:ref:`opt_dff` + +The next three (new) commands are :doc:`/cmd/wreduce`, :doc:`/cmd/peepopt`, and +:doc:`/cmd/share`. None of these affect our design either, 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). +Following this is a series of commands for mapping to DSPs. + +.. TODO:: more on DSP mapping + +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 be +mapped to hard blocks. 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` + +That brings us to the last commands, and a look at ``rdata`` at the end of the +:ref:`synth_coarse`. We could also have gotten here by running +:yoscrypt:`synth_ice40 -top fifo -run begin:map_ram` after loading the design. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-at: memory -nomap + :end-before: map_ram: + :dedent: + +.. figure:: /_images/code_examples/fifo/rdata_coarse.* + :class: width-helper + :name: rdata_coarse + + ``rdata`` output after :yoscrypt:`memory -nomap` + +.. TODO:: discuss :cmd:ref:`memory_collect` and ``$mem_v2`` .. seealso:: Advanced usage docs for - :doc:`/using_yosys/synthesis/fsm`, - :doc:`/using_yosys/synthesis/memory`, and + :doc:`/using_yosys/synthesis/fsm` :doc:`/using_yosys/synthesis/opt` + :doc:`/using_yosys/synthesis/techmap_synth` + :doc:`/using_yosys/synthesis/memory` Hardware mapping ~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst index 19d302fcc..095dd4b61 100644 --- a/docs/source/using_yosys/synthesis/index.rst +++ b/docs/source/using_yosys/synthesis/index.rst @@ -11,6 +11,7 @@ Synthesis in detail fsm memory opt + techmap_synth abc cell_libs diff --git a/docs/source/using_yosys/synthesis/techmap_synth.rst b/docs/source/using_yosys/synthesis/techmap_synth.rst new file mode 100644 index 000000000..db1d0c96a --- /dev/null +++ b/docs/source/using_yosys/synthesis/techmap_synth.rst @@ -0,0 +1,4 @@ +techmap_synth +------------- + +.. TODO:: techmap_synth From 50d8c1b25866a2b8d1b341d8c170c5f7eb860d91 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:08:06 +1300 Subject: [PATCH 062/108] First pass example_synth done Split coarse grain representation into 4 parts, loosely: fsm/opt, other optimizations/techmap/memory_dff, DSPs, alumacc/memory -nomap. Split hardware mapping into subsections as well: memory blocks (map_ram and map_ffram), arithmetic (map_gates), FFs (map_ffs), LUTs (map_luts and briefly abc), and other (map_cells and a note on hilomap and iopadmap). Also add `-T` flag to Yosys call to remove footer from log output. --- docs/source/code_examples/fifo/Makefile | 11 +- docs/source/code_examples/fifo/fifo.out | 1657 +++++++---------- docs/source/code_examples/fifo/fifo.ys | 50 +- docs/source/getting_started/example_synth.rst | 193 +- 4 files changed, 899 insertions(+), 1012 deletions(-) diff --git a/docs/source/code_examples/fifo/Makefile b/docs/source/code_examples/fifo/Makefile index e0287eab4..795853f81 100644 --- a/docs/source/code_examples/fifo/Makefile +++ b/docs/source/code_examples/fifo/Makefile @@ -2,14 +2,17 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -DOTS = addr_gen_hier.dot addr_gen_proc.dot -DOTS += rdata_proc.dot rdata_flat.dot -DOTS += fifo_flat.dot fifo_synth.dot +DOT_NAMES = addr_gen_hier addr_gen_proc addr_gen_clean +DOT_NAMES += rdata_proc rdata_flat rdata_adffe rdata_memrdv2 rdata_alumacc +DOT_NAMES += rdata_coarse rdata_map_ram rdata_map_ffram rdata_map_gates +DOT_NAMES += rdata_map_ffs rdata_map_luts rdata_map_cells + +DOTS := $(addsuffix .dot,$(DOT_NAMES)) dots: $(DOTS) fifo.out $(DOTS) fifo.out: fifo.v fifo.ys - $(YOSYS) fifo.ys -l fifo.out -Q + $(YOSYS) fifo.ys -l fifo.out -Q -T .PHONY: clean clean: diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index 5a4215e5c..d747247c5 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -27,7 +27,9 @@ Removing unused module `$abstract\fifo'. Removing unused module `$abstract\addr_gen'. Removed 2 unused modules. -yosys> show -notitle -format dot -prefix addr_gen_hier +yosys> select -set new_cells t:* + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_hier 4. Generating Graphviz representation of design. Writing dot description to `addr_gen_hier.dot'. @@ -105,17 +107,32 @@ yosys> opt_expr -keepdc 5.12. Executing OPT_EXPR pass (perform const folding). Optimizing module addr_gen. -yosys> show -notitle -format dot -prefix addr_gen_proc +yosys> select -set new_cells t:$mux t:*dff + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc 6. Generating Graphviz representation of design. Writing dot description to `addr_gen_proc.dot'. Dumping module addr_gen to page 1. +yosys> opt_clean + +7. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \addr_gen.. +Removed 0 unused cells and 4 unused wires. +<suppressed ~1 debug messages> + +yosys> show -notitle -format dot -prefix addr_gen_clean + +8. 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 -7. Executing Verilog-2005 frontend: fifo.v +9. 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'. @@ -123,24 +140,24 @@ Successfully finished Verilog frontend. yosys> hierarchy -check -top fifo -8. Executing HIERARCHY pass (managing design hierarchy). +10. Executing HIERARCHY pass (managing design hierarchy). -8.1. Analyzing design hierarchy.. +10.1. Analyzing design hierarchy.. Top module: \fifo Used module: \addr_gen Parameter \MAX_DATA = 256 -8.2. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +10.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'. -8.3. Analyzing design hierarchy.. +10.3. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 -8.4. Analyzing design hierarchy.. +10.4. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 Removing unused module `\addr_gen'. @@ -148,16 +165,16 @@ Removed 1 unused modules. yosys> proc -9. Executing PROC pass (convert processes to netlists). +11. Executing PROC pass (convert processes to netlists). yosys> proc_clean -9.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +11.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. yosys> proc_rmdead -9.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +11.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Marked 2 switch rules as full_case in process $proc$fifo.v:64$24 in module fifo. Marked 1 switch rules as full_case in process $proc$fifo.v:38$16 in module fifo. Marked 2 switch rules as full_case in process $proc$fifo.v:13$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. @@ -165,13 +182,13 @@ Removed a total of 0 dead cases. yosys> proc_prune -9.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +11.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 6 assignments to connections. yosys> proc_init -9.4. Executing PROC_INIT pass (extract init attributes). +11.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'. @@ -179,19 +196,19 @@ Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000 yosys> proc_arst -9.5. Executing PROC_ARST pass (detect async resets in processes). +11.5. Executing PROC_ARST pass (detect async resets in processes). Found async reset \rst in `\fifo.$proc$fifo.v:64$24'. Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. yosys> proc_rom -9.6. Executing PROC_ROM pass (convert switches to ROMs). +11.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. <suppressed ~5 debug messages> yosys> proc_mux -9.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +11.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:64$24'. 1/1: $0\count[8:0] @@ -205,11 +222,11 @@ Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'000000000000000000 yosys> proc_dlatch -9.8. Executing PROC_DLATCH pass (convert process syncs to latches). +11.8. Executing PROC_DLATCH pass (convert process syncs to latches). yosys> proc_dff -9.9. Executing PROC_DFF pass (convert process syncs to FFs). +11.9. Executing PROC_DFF pass (convert process syncs to FFs). Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$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:38$16'. @@ -225,11 +242,11 @@ Creating register for signal `$paramod\addr_gen\MAX_DATA=s32'0000000000000000000 yosys> proc_memwr -9.10. Executing PROC_MEMWR pass (convert process memory writes to cells). +11.10. Executing PROC_MEMWR pass (convert process memory writes to cells). yosys> proc_clean -9.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +11.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:64$24'. Removing empty process `fifo.$proc$fifo.v:64$24'. @@ -242,58 +259,103 @@ Cleaned up 5 empty switches. yosys> opt_expr -keepdc -9.12. Executing OPT_EXPR pass (perform const folding). +11.12. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. -yosys> show -notitle -format dot -prefix rdata_proc o:rdata %ci* +yosys> show -color maroon3 c:fifo_reader -notitle -format dot -prefix rdata_proc o:rdata %ci* -10. Generating Graphviz representation of design. +12. Generating Graphviz representation of design. Writing dot description to `rdata_proc.dot'. Dumping selected parts of module fifo to page 1. yosys> flatten -11. Executing FLATTEN pass (flatten design). +13. Executing FLATTEN pass (flatten design). Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. <suppressed ~2 debug messages> +yosys> clean +Removed 3 unused cells and 25 unused wires. + yosys> show -notitle -format dot -prefix rdata_flat o:rdata %ci* -12. Generating Graphviz representation of design. +14. Generating Graphviz representation of design. Writing dot description to `rdata_flat.dot'. Dumping selected parts of module fifo to page 1. -yosys> opt_clean +yosys> opt_dff -13. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 3 unused cells and 25 unused wires. -<suppressed ~4 debug messages> +15. 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> show -notitle -format dot -prefix fifo_flat +yosys> select -set new_cells t:$adffe -14. Generating Graphviz representation of design. -Writing dot description to `fifo_flat.dot'. -Dumping module fifo to page 1. +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* + +16. Generating Graphviz representation of design. +Writing dot description to `rdata_adffe.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> memory_dff + +17. 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* + +18. Generating Graphviz representation of design. +Writing dot description to `rdata_memrdv2.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> alumacc + +19. Executing ALUMACC pass (create $alu and $macc cells). +Extracting $alu and $macc cells in module fifo: + creating $macc model for $add$fifo.v:68$27 ($add). + creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$34 ($add). + creating $macc model for $flatten\fifo_writer.$add$fifo.v:20$34 ($add). + creating $macc model for $sub$fifo.v:70$30 ($sub). + creating $alu model for $macc $sub$fifo.v:70$30. + creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$34. + creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$34. + creating $alu model for $macc $add$fifo.v:68$27. + creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$76 + creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$79 + creating $alu cell for $add$fifo.v:68$27: $auto$alumacc.cc:485:replace_alu$82 + creating $alu cell for $sub$fifo.v:70$30: $auto$alumacc.cc:485:replace_alu$85 + 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* + +20. Generating Graphviz representation of design. +Writing dot description to `rdata_alumacc.dot'. +Dumping selected parts of module fifo to page 1. yosys> design -reset yosys> read_verilog fifo.v -15. Executing Verilog-2005 frontend: fifo.v +21. 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> synth_ice40 -dsp -top fifo +yosys> synth_ice40 -top fifo -run begin:map_ram -16. Executing SYNTH_ICE40 pass. +22. Executing SYNTH_ICE40 pass. yosys> read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v -16.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_sim.v +22.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_sim.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/cells_sim.v' to AST representation. Generating RTLIL representation for module `\SB_IO'. Generating RTLIL representation for module `\SB_GB_IO'. @@ -349,24 +411,24 @@ Successfully finished Verilog frontend. yosys> hierarchy -check -top fifo -16.2. Executing HIERARCHY pass (managing design hierarchy). +22.2. Executing HIERARCHY pass (managing design hierarchy). -16.2.1. Analyzing design hierarchy.. +22.2.1. Analyzing design hierarchy.. Top module: \fifo Used module: \addr_gen Parameter \MAX_DATA = 256 -16.2.2. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +22.2.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'. -16.2.3. Analyzing design hierarchy.. +22.2.3. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 -16.2.4. Analyzing design hierarchy.. +22.2.4. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 Removing unused module `\addr_gen'. @@ -374,370 +436,370 @@ Removed 1 unused modules. yosys> proc -16.3. Executing PROC pass (convert processes to netlists). +22.3. Executing PROC pass (convert processes to netlists). yosys> proc_clean -16.3.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +22.3.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. yosys> proc_rmdead -16.3.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323 in module SB_DFFNES. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316 in module SB_DFFNESS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312 in module SB_DFFNER. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305 in module SB_DFFNESR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302 in module SB_DFFNS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299 in module SB_DFFNSS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296 in module SB_DFFNR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293 in module SB_DFFNSR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285 in module SB_DFFES. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278 in module SB_DFFESS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274 in module SB_DFFER. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267 in module SB_DFFESR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264 in module SB_DFFS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261 in module SB_DFFSS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258 in module SB_DFFR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255 in module SB_DFFSR. -Marked 2 switch rules as full_case in process $proc$fifo.v:64$75 in module fifo. -Marked 1 switch rules as full_case in process $proc$fifo.v:38$67 in module fifo. -Marked 2 switch rules as full_case in process $proc$fifo.v:13$463 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +22.3.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349 in module SB_DFFNES. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342 in module SB_DFFNESS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338 in module SB_DFFNER. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331 in module SB_DFFNESR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328 in module SB_DFFNS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325 in module SB_DFFNSS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322 in module SB_DFFNR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319 in module SB_DFFNSR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311 in module SB_DFFES. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304 in module SB_DFFESS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300 in module SB_DFFER. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293 in module SB_DFFESR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290 in module SB_DFFS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287 in module SB_DFFSS. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284 in module SB_DFFR. +Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281 in module SB_DFFSR. +Marked 2 switch rules as full_case in process $proc$fifo.v:64$101 in module fifo. +Marked 1 switch rules as full_case in process $proc$fifo.v:38$93 in module fifo. +Marked 2 switch rules as full_case in process $proc$fifo.v:13$489 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. Removed a total of 0 dead cases. yosys> proc_prune -16.3.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +22.3.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 8 redundant assignments. Promoted 28 assignments to connections. yosys> proc_init -16.3.4. Executing PROC_INIT pass (extract init attributes). -Found init rule in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$326'. +22.3.4. Executing PROC_INIT pass (extract init attributes). +Found init rule in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$352'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$322'. +Found init rule in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$348'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$315'. +Found init rule in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$341'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$311'. +Found init rule in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$337'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$304'. +Found init rule in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$330'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$301'. +Found init rule in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$327'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$298'. +Found init rule in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$324'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$295'. +Found init rule in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$321'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. +Found init rule in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$318'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$290'. +Found init rule in `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$316'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$288'. +Found init rule in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$314'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$284'. +Found init rule in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$310'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$277'. +Found init rule in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$303'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$273'. +Found init rule in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$299'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$266'. +Found init rule in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$263'. +Found init rule in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$289'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$260'. +Found init rule in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$286'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$257'. +Found init rule in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$283'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$254'. +Found init rule in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$280'. Set init value: \Q = 1'0 -Found init rule in `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$252'. +Found init rule in `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$278'. Set init value: \Q = 1'0 -Found init rule in `\fifo.$proc$fifo.v:0$82'. +Found init rule in `\fifo.$proc$fifo.v:0$108'. Set init value: \count = 9'000000000 -Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$466'. +Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$492'. Set init value: \addr = 8'00000000 yosys> proc_arst -16.3.5. Executing PROC_ARST pass (detect async resets in processes). -Found async reset \S in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. -Found async reset \R in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. -Found async reset \S in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. -Found async reset \R in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. -Found async reset \S in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. -Found async reset \R in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. -Found async reset \S in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. -Found async reset \R in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. -Found async reset \rst in `\fifo.$proc$fifo.v:64$75'. -Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. +22.3.5. Executing PROC_ARST pass (detect async resets in processes). +Found async reset \S in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. +Found async reset \R in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. +Found async reset \S in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. +Found async reset \R in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. +Found async reset \S in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. +Found async reset \R in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. +Found async reset \S in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. +Found async reset \R in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. +Found async reset \rst in `\fifo.$proc$fifo.v:64$101'. +Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. yosys> proc_rom -16.3.6. Executing PROC_ROM pass (convert switches to ROMs). +22.3.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. <suppressed ~23 debug messages> yosys> proc_mux -16.3.7. Executing PROC_MUX pass (convert decision trees to multiplexers). -Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$326'. -Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. +22.3.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$352'. +Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$322'. -Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. +Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$348'. +Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$315'. -Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. +Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$341'. +Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$311'. -Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. +Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$337'. +Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$304'. -Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. +Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$330'. +Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$301'. -Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. +Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$327'. +Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$298'. -Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. +Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$324'. +Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$295'. -Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. +Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$321'. +Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. -Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. +Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$318'. +Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$290'. -Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$289'. -Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$288'. -Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. +Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$316'. +Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$315'. +Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$314'. +Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$284'. -Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. +Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$310'. +Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$277'. -Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. +Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$303'. +Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$273'. -Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. +Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$299'. +Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$266'. -Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. +Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. +Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$263'. -Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. +Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$289'. +Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$260'. -Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. +Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$286'. +Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$257'. -Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. +Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$283'. +Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$254'. -Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. +Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$280'. +Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$252'. -Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$251'. -Creating decoders for process `\fifo.$proc$fifo.v:0$82'. -Creating decoders for process `\fifo.$proc$fifo.v:64$75'. +Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$278'. +Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$277'. +Creating decoders for process `\fifo.$proc$fifo.v:0$108'. +Creating decoders for process `\fifo.$proc$fifo.v:64$101'. 1/1: $0\count[8:0] -Creating decoders for process `\fifo.$proc$fifo.v:38$67'. - 1/3: $1$memwr$\data$fifo.v:40$66_EN[7:0]$73 - 2/3: $1$memwr$\data$fifo.v:40$66_DATA[7:0]$72 - 3/3: $1$memwr$\data$fifo.v:40$66_ADDR[7:0]$71 -Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$466'. -Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. +Creating decoders for process `\fifo.$proc$fifo.v:38$93'. + 1/3: $1$memwr$\data$fifo.v:40$92_EN[7:0]$97 + 2/3: $1$memwr$\data$fifo.v:40$92_DATA[7:0]$98 + 3/3: $1$memwr$\data$fifo.v:40$92_ADDR[7:0]$99 +Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$492'. +Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. 1/1: $0\addr[7:0] yosys> proc_dlatch -16.3.8. Executing PROC_DLATCH pass (convert process syncs to latches). +22.3.8. Executing PROC_DLATCH pass (convert process syncs to latches). yosys> proc_dff -16.3.9. Executing PROC_DFF pass (convert process syncs to FFs). -Creating register for signal `\SB_DFFNES.\Q' using process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. - created $adff cell `$procdff$530' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNESS.\Q' using process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. - created $dff cell `$procdff$531' with negative edge clock. -Creating register for signal `\SB_DFFNER.\Q' using process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. - created $adff cell `$procdff$532' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNESR.\Q' using process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. - created $dff cell `$procdff$533' with negative edge clock. -Creating register for signal `\SB_DFFNS.\Q' using process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. - created $adff cell `$procdff$534' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNSS.\Q' using process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. - created $dff cell `$procdff$535' with negative edge clock. -Creating register for signal `\SB_DFFNR.\Q' using process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. - created $adff cell `$procdff$536' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNSR.\Q' using process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. - created $dff cell `$procdff$537' with negative edge clock. -Creating register for signal `\SB_DFFNE.\Q' using process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. - created $dff cell `$procdff$538' with negative edge clock. -Creating register for signal `\SB_DFFN.\Q' using process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$289'. - created $dff cell `$procdff$539' with negative edge clock. -Creating register for signal `\SB_DFFES.\Q' using process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. - created $adff cell `$procdff$540' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFESS.\Q' using process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. - created $dff cell `$procdff$541' with positive edge clock. -Creating register for signal `\SB_DFFER.\Q' using process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. - created $adff cell `$procdff$542' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFESR.\Q' using process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. - created $dff cell `$procdff$543' with positive edge clock. -Creating register for signal `\SB_DFFS.\Q' using process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. - created $adff cell `$procdff$544' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFSS.\Q' using process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. - created $dff cell `$procdff$545' with positive edge clock. -Creating register for signal `\SB_DFFR.\Q' using process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. - created $adff cell `$procdff$546' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFSR.\Q' using process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. - created $dff cell `$procdff$547' with positive edge clock. -Creating register for signal `\SB_DFFE.\Q' using process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. - created $dff cell `$procdff$548' with positive edge clock. -Creating register for signal `\SB_DFF.\Q' using process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$251'. - created $dff cell `$procdff$549' with positive edge clock. -Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$75'. - created $adff cell `$procdff$550' with positive edge clock and positive level reset. -Creating register for signal `\fifo.\rdata' using process `\fifo.$proc$fifo.v:38$67'. - created $dff cell `$procdff$551' with positive edge clock. -Creating register for signal `\fifo.$memwr$\data$fifo.v:40$66_ADDR' using process `\fifo.$proc$fifo.v:38$67'. - created $dff cell `$procdff$552' with positive edge clock. -Creating register for signal `\fifo.$memwr$\data$fifo.v:40$66_DATA' using process `\fifo.$proc$fifo.v:38$67'. - created $dff cell `$procdff$553' with positive edge clock. -Creating register for signal `\fifo.$memwr$\data$fifo.v:40$66_EN' using process `\fifo.$proc$fifo.v:38$67'. - created $dff cell `$procdff$554' 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:13$463'. - created $adff cell `$procdff$555' with positive edge clock and positive level reset. +22.3.9. Executing PROC_DFF pass (convert process syncs to FFs). +Creating register for signal `\SB_DFFNES.\Q' using process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. + created $adff cell `$procdff$556' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNESS.\Q' using process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. + created $dff cell `$procdff$557' with negative edge clock. +Creating register for signal `\SB_DFFNER.\Q' using process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. + created $adff cell `$procdff$558' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNESR.\Q' using process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. + created $dff cell `$procdff$559' with negative edge clock. +Creating register for signal `\SB_DFFNS.\Q' using process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. + created $adff cell `$procdff$560' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNSS.\Q' using process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. + created $dff cell `$procdff$561' with negative edge clock. +Creating register for signal `\SB_DFFNR.\Q' using process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. + created $adff cell `$procdff$562' with negative edge clock and positive level reset. +Creating register for signal `\SB_DFFNSR.\Q' using process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. + created $dff cell `$procdff$563' with negative edge clock. +Creating register for signal `\SB_DFFNE.\Q' using process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. + created $dff cell `$procdff$564' with negative edge clock. +Creating register for signal `\SB_DFFN.\Q' using process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$315'. + created $dff cell `$procdff$565' with negative edge clock. +Creating register for signal `\SB_DFFES.\Q' using process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. + created $adff cell `$procdff$566' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFESS.\Q' using process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. + created $dff cell `$procdff$567' with positive edge clock. +Creating register for signal `\SB_DFFER.\Q' using process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. + created $adff cell `$procdff$568' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFESR.\Q' using process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. + created $dff cell `$procdff$569' with positive edge clock. +Creating register for signal `\SB_DFFS.\Q' using process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. + created $adff cell `$procdff$570' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFSS.\Q' using process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. + created $dff cell `$procdff$571' with positive edge clock. +Creating register for signal `\SB_DFFR.\Q' using process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. + created $adff cell `$procdff$572' with positive edge clock and positive level reset. +Creating register for signal `\SB_DFFSR.\Q' using process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. + created $dff cell `$procdff$573' with positive edge clock. +Creating register for signal `\SB_DFFE.\Q' using process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. + created $dff cell `$procdff$574' with positive edge clock. +Creating register for signal `\SB_DFF.\Q' using process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$277'. + created $dff cell `$procdff$575' with positive edge clock. +Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$101'. + created $adff cell `$procdff$576' with positive edge clock and positive level reset. +Creating register for signal `\fifo.\rdata' using process `\fifo.$proc$fifo.v:38$93'. + created $dff cell `$procdff$577' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$92_EN' using process `\fifo.$proc$fifo.v:38$93'. + created $dff cell `$procdff$578' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$92_DATA' using process `\fifo.$proc$fifo.v:38$93'. + created $dff cell `$procdff$579' with positive edge clock. +Creating register for signal `\fifo.$memwr$\data$fifo.v:40$92_ADDR' using process `\fifo.$proc$fifo.v:38$93'. + created $dff cell `$procdff$580' 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:13$489'. + created $adff cell `$procdff$581' with positive edge clock and positive level reset. yosys> proc_memwr -16.3.10. Executing PROC_MEMWR pass (convert process memory writes to cells). +22.3.10. Executing PROC_MEMWR pass (convert process memory writes to cells). yosys> proc_clean -16.3.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$326'. -Found and cleaned up 1 empty switch in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. -Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$323'. -Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$322'. -Found and cleaned up 2 empty switches in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. -Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$316'. -Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$315'. -Found and cleaned up 1 empty switch in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. -Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$312'. -Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$311'. -Found and cleaned up 2 empty switches in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. -Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$305'. -Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$304'. -Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$302'. -Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$301'. -Found and cleaned up 1 empty switch in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. -Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$299'. -Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$298'. -Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$296'. -Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$295'. -Found and cleaned up 1 empty switch in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. -Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$293'. -Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. -Found and cleaned up 1 empty switch in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. -Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$291'. -Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$290'. -Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$289'. -Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$288'. -Found and cleaned up 1 empty switch in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. -Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$285'. -Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$284'. -Found and cleaned up 2 empty switches in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. -Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$278'. -Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$277'. -Found and cleaned up 1 empty switch in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. -Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$274'. -Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$273'. -Found and cleaned up 2 empty switches in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. -Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$267'. -Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$266'. -Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$264'. -Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$263'. -Found and cleaned up 1 empty switch in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. -Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$261'. -Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$260'. -Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$258'. -Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$257'. -Found and cleaned up 1 empty switch in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. -Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$255'. -Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$254'. -Found and cleaned up 1 empty switch in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. -Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$253'. -Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$252'. -Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$251'. -Removing empty process `fifo.$proc$fifo.v:0$82'. -Found and cleaned up 2 empty switches in `\fifo.$proc$fifo.v:64$75'. -Removing empty process `fifo.$proc$fifo.v:64$75'. -Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:38$67'. -Removing empty process `fifo.$proc$fifo.v:38$67'. -Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$466'. -Found and cleaned up 2 empty switches in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. -Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$463'. +22.3.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$352'. +Found and cleaned up 1 empty switch in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. +Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. +Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$348'. +Found and cleaned up 2 empty switches in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. +Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. +Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$341'. +Found and cleaned up 1 empty switch in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. +Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. +Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$337'. +Found and cleaned up 2 empty switches in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. +Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. +Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$330'. +Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. +Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$327'. +Found and cleaned up 1 empty switch in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. +Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. +Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$324'. +Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. +Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$321'. +Found and cleaned up 1 empty switch in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. +Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. +Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$318'. +Found and cleaned up 1 empty switch in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. +Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. +Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$316'. +Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$315'. +Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$314'. +Found and cleaned up 1 empty switch in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. +Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. +Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$310'. +Found and cleaned up 2 empty switches in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. +Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. +Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$303'. +Found and cleaned up 1 empty switch in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. +Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. +Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$299'. +Found and cleaned up 2 empty switches in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. +Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. +Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. +Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. +Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$289'. +Found and cleaned up 1 empty switch in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. +Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. +Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$286'. +Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. +Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$283'. +Found and cleaned up 1 empty switch in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. +Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. +Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$280'. +Found and cleaned up 1 empty switch in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. +Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. +Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$278'. +Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$277'. +Removing empty process `fifo.$proc$fifo.v:0$108'. +Found and cleaned up 2 empty switches in `\fifo.$proc$fifo.v:64$101'. +Removing empty process `fifo.$proc$fifo.v:64$101'. +Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:38$93'. +Removing empty process `fifo.$proc$fifo.v:38$93'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$492'. +Found and cleaned up 2 empty switches in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. +Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. Cleaned up 23 empty switches. yosys> opt_expr -keepdc -16.3.12. Executing OPT_EXPR pass (perform const folding). +22.3.12. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. yosys> flatten -16.4. Executing FLATTEN pass (flatten design). +22.4. Executing FLATTEN pass (flatten design). Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. <suppressed ~2 debug messages> yosys> tribuf -logic -16.5. Executing TRIBUF pass. +22.5. Executing TRIBUF pass. yosys> deminout -16.6. Executing DEMINOUT pass (demote inout ports to input or output). +22.6. Executing DEMINOUT pass (demote inout ports to input or output). yosys> opt_expr -16.7. Executing OPT_EXPR pass (perform const folding). +22.7. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. yosys> opt_clean -16.8. Executing OPT_CLEAN pass (remove unused cells and wires). +22.8. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 3 unused cells and 25 unused wires. <suppressed ~4 debug messages> yosys> check -16.9. Executing CHECK pass (checking for obvious problems). +22.9. Executing CHECK pass (checking for obvious problems). Checking module fifo... Found and reported 0 problems. yosys> opt -nodffe -nosdff -16.10. Executing OPT pass (performing simple optimizations). +22.10. Executing OPT pass (performing simple optimizations). yosys> opt_expr -16.10.1. Executing OPT_EXPR pass (perform const folding). +22.10.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. yosys> opt_merge -nomux -16.10.2. Executing OPT_MERGE pass (detect identical cells). +22.10.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_muxtree -16.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +22.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. Evaluating internal representation of mux trees. @@ -747,40 +809,40 @@ Removed 0 multiplexer ports. yosys> opt_reduce -16.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +22.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. - Consolidated identical input bits for $mux cell $procmux$517: - Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\data$fifo.v:40$66_EN[7:0]$70 - New ports: A=1'0, B=1'1, Y=$0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] - New connections: $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [7:1] = { $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] $0$memwr$\data$fifo.v:40$66_EN[7:0]$70 [0] } + Consolidated identical input bits for $mux cell $procmux$543: + Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\data$fifo.v:40$92_EN[7:0]$94 + New ports: A=1'0, B=1'1, Y=$0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] + New connections: $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [7:1] = { $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] } Optimizing cells in module \fifo. Performed a total of 1 changes. yosys> opt_merge -16.10.5. Executing OPT_MERGE pass (detect identical cells). +22.10.5. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_dff -nodffe -nosdff -16.10.6. Executing OPT_DFF pass (perform DFF optimizations). +22.10.6. Executing OPT_DFF pass (perform DFF optimizations). yosys> opt_clean -16.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). +22.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> opt_expr -16.10.8. Executing OPT_EXPR pass (perform const folding). +22.10.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.10.9. Rerunning OPT passes. (Maybe there is more to do..) +22.10.9. Rerunning OPT passes. (Maybe there is more to do..) yosys> opt_muxtree -16.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +22.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. Evaluating internal representation of mux trees. @@ -790,87 +852,87 @@ Removed 0 multiplexer ports. yosys> opt_reduce -16.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +22.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. yosys> opt_merge -16.10.12. Executing OPT_MERGE pass (detect identical cells). +22.10.12. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_dff -nodffe -nosdff -16.10.13. Executing OPT_DFF pass (perform DFF optimizations). +22.10.13. Executing OPT_DFF pass (perform DFF optimizations). yosys> opt_clean -16.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). +22.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> opt_expr -16.10.15. Executing OPT_EXPR pass (perform const folding). +22.10.15. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.10.16. Finished OPT passes. (There is nothing left to do.) +22.10.16. Finished OPT passes. (There is nothing left to do.) yosys> fsm -16.11. Executing FSM pass (extract and optimize FSM). +22.11. Executing FSM pass (extract and optimize FSM). yosys> fsm_detect -16.11.1. Executing FSM_DETECT pass (finding FSMs in design). +22.11.1. Executing FSM_DETECT pass (finding FSMs in design). yosys> fsm_extract -16.11.2. Executing FSM_EXTRACT pass (extracting FSM from design). +22.11.2. Executing FSM_EXTRACT pass (extracting FSM from design). yosys> fsm_opt -16.11.3. Executing FSM_OPT pass (simple optimizations of FSMs). +22.11.3. Executing FSM_OPT pass (simple optimizations of FSMs). yosys> opt_clean -16.11.4. Executing OPT_CLEAN pass (remove unused cells and wires). +22.11.4. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> fsm_opt -16.11.5. Executing FSM_OPT pass (simple optimizations of FSMs). +22.11.5. Executing FSM_OPT pass (simple optimizations of FSMs). yosys> fsm_recode -16.11.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). +22.11.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). yosys> fsm_info -16.11.7. Executing FSM_INFO pass (dumping all available information on FSM cells). +22.11.7. Executing FSM_INFO pass (dumping all available information on FSM cells). yosys> fsm_map -16.11.8. Executing FSM_MAP pass (mapping FSMs to basic logic). +22.11.8. Executing FSM_MAP pass (mapping FSMs to basic logic). yosys> opt -16.12. Executing OPT pass (performing simple optimizations). +22.12. Executing OPT pass (performing simple optimizations). yosys> opt_expr -16.12.1. Executing OPT_EXPR pass (perform const folding). +22.12.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. yosys> opt_merge -nomux -16.12.2. Executing OPT_MERGE pass (detect identical cells). +22.12.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_muxtree -16.12.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +22.12.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. Evaluating internal representation of mux trees. @@ -880,41 +942,41 @@ Removed 0 multiplexer ports. yosys> opt_reduce -16.12.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +22.12.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. yosys> opt_merge -16.12.5. Executing OPT_MERGE pass (detect identical cells). +22.12.5. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_dff -16.12.6. Executing OPT_DFF pass (perform DFF optimizations). -Adding EN signal on $procdff$550 ($adff) from module fifo (D = $0\count[8:0], Q = \count). -Adding EN signal on $flatten\fifo_writer.$procdff$555 ($adff) from module fifo (D = $flatten\fifo_writer.$procmux$526_Y, Q = \fifo_writer.addr). -Adding EN signal on $flatten\fifo_reader.$procdff$555 ($adff) from module fifo (D = $flatten\fifo_reader.$procmux$526_Y, Q = \fifo_reader.addr). +22.12.6. Executing OPT_DFF pass (perform DFF optimizations). +Adding EN signal on $procdff$576 ($adff) from module fifo (D = $0\count[8:0], Q = \count). +Adding EN signal on $flatten\fifo_writer.$procdff$581 ($adff) from module fifo (D = $flatten\fifo_writer.$procmux$552_Y, Q = \fifo_writer.addr). +Adding EN signal on $flatten\fifo_reader.$procdff$581 ($adff) from module fifo (D = $flatten\fifo_reader.$procmux$552_Y, Q = \fifo_reader.addr). yosys> opt_clean -16.12.7. Executing OPT_CLEAN pass (remove unused cells and wires). +22.12.7. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 2 unused cells and 2 unused wires. <suppressed ~3 debug messages> yosys> opt_expr -16.12.8. Executing OPT_EXPR pass (perform const folding). +22.12.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. <suppressed ~1 debug messages> -16.12.9. Rerunning OPT passes. (Maybe there is more to do..) +22.12.9. Rerunning OPT passes. (Maybe there is more to do..) yosys> opt_muxtree -16.12.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +22.12.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. Evaluating internal representation of mux trees. @@ -924,169 +986,120 @@ Removed 0 multiplexer ports. yosys> opt_reduce -16.12.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +22.12.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. yosys> opt_merge -16.12.12. Executing OPT_MERGE pass (detect identical cells). +22.12.12. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_dff -16.12.13. Executing OPT_DFF pass (perform DFF optimizations). +22.12.13. Executing OPT_DFF pass (perform DFF optimizations). yosys> opt_clean -16.12.14. Executing OPT_CLEAN pass (remove unused cells and wires). +22.12.14. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> opt_expr -16.12.15. Executing OPT_EXPR pass (perform const folding). +22.12.15. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.12.16. Finished OPT passes. (There is nothing left to do.) +22.12.16. Finished OPT passes. (There is nothing left to do.) yosys> wreduce -16.13. Executing WREDUCE pass (reducing word size of cells). -Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$78 ($add). -Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$78 ($add). -Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$81 ($sub). -Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:70$81 ($sub). -Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$465 ($add). -Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$465 ($add). -Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$465 ($add). -Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$465 ($add). -Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$78_Y. -Removed top 23 bits (of 32) from wire fifo.$sub$fifo.v:70$81_Y. +22.13. Executing WREDUCE pass (reducing word size of cells). +Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$107 ($sub). +Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:70$107 ($sub). +Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$104 ($add). +Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$104 ($add). +Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$491 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$491 ($add). +Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$491 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$491 ($add). +Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$104_Y. +Removed top 23 bits (of 32) from wire fifo.$sub$fifo.v:70$107_Y. yosys> peepopt -16.14. Executing PEEPOPT pass (run peephole optimizers). +22.14. Executing PEEPOPT pass (run peephole optimizers). yosys> opt_clean -16.15. Executing OPT_CLEAN pass (remove unused cells and wires). +22.15. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 0 unused cells and 2 unused wires. <suppressed ~1 debug messages> yosys> share -16.16. Executing SHARE pass (SAT-based resource sharing). +22.16. Executing SHARE pass (SAT-based resource sharing). yosys> techmap -map +/cmp2lut.v -D LUT_WIDTH=4 -16.17. Executing TECHMAP pass (map to technology primitives). +22.17. Executing TECHMAP pass (map to technology primitives). -16.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/cmp2lut.v +22.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/cmp2lut.v Parsing Verilog input from `/home/dawn/yosys/share/cmp2lut.v' to AST representation. Generating RTLIL representation for module `\_90_lut_cmp_'. Successfully finished Verilog frontend. -16.17.2. Continuing TECHMAP pass. +22.17.2. Continuing TECHMAP pass. No more expansions possible. <suppressed ~6 debug messages> yosys> opt_expr -16.18. Executing OPT_EXPR pass (perform const folding). +22.18. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. yosys> opt_clean -16.19. Executing OPT_CLEAN pass (remove unused cells and wires). +22.19. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -yosys> memory_dff - -16.20. 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> wreduce t:$mul - -16.21. Executing WREDUCE pass (reducing word size of cells). - -yosys> techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 -D DSP_NAME=$__MUL16X16 - -16.22. Executing TECHMAP pass (map to technology primitives). - -16.22.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/mul2dsp.v -Parsing Verilog input from `/home/dawn/yosys/share/mul2dsp.v' to AST representation. -Generating RTLIL representation for module `\_80_mul'. -Generating RTLIL representation for module `\_90_soft_mul'. -Successfully finished Verilog frontend. - -16.22.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/dsp_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/dsp_map.v' to AST representation. -Generating RTLIL representation for module `\$__MUL16X16'. -Successfully finished Verilog frontend. - -16.22.3. Continuing TECHMAP pass. -No more expansions possible. -<suppressed ~5 debug messages> - -yosys> select a:mul2dsp - -yosys*> setattr -unset mul2dsp - -yosys*> opt_expr -fine - -16.23. Executing OPT_EXPR pass (perform const folding). - -yosys*> wreduce - -16.24. Executing WREDUCE pass (reducing word size of cells). - -yosys*> select -clear - -yosys> ice40_dsp - -16.25. Executing ICE40_DSP pass (map multipliers). - -yosys> chtype -set $mul t:$__soft_mul - yosys> alumacc -16.26. Executing ALUMACC pass (create $alu and $macc cells). +22.20. Executing ALUMACC pass (create $alu and $macc cells). Extracting $alu and $macc cells in module fifo: - creating $macc model for $add$fifo.v:68$78 ($add). - creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$465 ($add). - creating $macc model for $flatten\fifo_writer.$add$fifo.v:20$465 ($add). - creating $macc model for $sub$fifo.v:70$81 ($sub). - creating $alu model for $macc $sub$fifo.v:70$81. - creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$465. - creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$465. - creating $alu model for $macc $add$fifo.v:68$78. - creating $alu cell for $add$fifo.v:68$78: $auto$alumacc.cc:485:replace_alu$574 - creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$465: $auto$alumacc.cc:485:replace_alu$577 - creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$465: $auto$alumacc.cc:485:replace_alu$580 - creating $alu cell for $sub$fifo.v:70$81: $auto$alumacc.cc:485:replace_alu$583 + creating $macc model for $add$fifo.v:68$104 ($add). + creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$491 ($add). + creating $macc model for $flatten\fifo_writer.$add$fifo.v:20$491 ($add). + creating $macc model for $sub$fifo.v:70$107 ($sub). + creating $alu model for $macc $sub$fifo.v:70$107. + creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$491. + creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$491. + creating $alu model for $macc $add$fifo.v:68$104. + creating $alu cell for $add$fifo.v:68$104: $auto$alumacc.cc:485:replace_alu$591 + creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$491: $auto$alumacc.cc:485:replace_alu$594 + creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$491: $auto$alumacc.cc:485:replace_alu$597 + creating $alu cell for $sub$fifo.v:70$107: $auto$alumacc.cc:485:replace_alu$600 created 4 $alu and 0 $macc cells. yosys> opt -16.27. Executing OPT pass (performing simple optimizations). +22.21. Executing OPT pass (performing simple optimizations). yosys> opt_expr -16.27.1. Executing OPT_EXPR pass (perform const folding). +22.21.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. yosys> opt_merge -nomux -16.27.2. Executing OPT_MERGE pass (detect identical cells). +22.21.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_muxtree -16.27.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +22.21.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. Evaluating internal representation of mux trees. @@ -1096,229 +1109,181 @@ Removed 0 multiplexer ports. yosys> opt_reduce -16.27.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +22.21.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. yosys> opt_merge -16.27.5. Executing OPT_MERGE pass (detect identical cells). +22.21.5. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. yosys> opt_dff -16.27.6. Executing OPT_DFF pass (perform DFF optimizations). +22.21.6. Executing OPT_DFF pass (perform DFF optimizations). yosys> opt_clean -16.27.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 1 unused cells and 9 unused wires. -<suppressed ~2 debug messages> - -yosys> opt_expr - -16.27.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -16.27.9. Rerunning OPT passes. (Maybe there is more to do..) - -yosys> opt_muxtree - -16.27.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~6 debug messages> - -yosys> opt_reduce - -16.27.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -yosys> opt_merge - -16.27.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_dff - -16.27.13. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.27.14. Executing OPT_CLEAN pass (remove unused cells and wires). +22.21.7. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> opt_expr -16.27.15. Executing OPT_EXPR pass (perform const folding). +22.21.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.27.16. Finished OPT passes. (There is nothing left to do.) +22.21.9. Finished OPT passes. (There is nothing left to do.) yosys> memory -nomap -16.28. Executing MEMORY pass. +22.22. Executing MEMORY pass. yosys> opt_mem -16.28.1. Executing OPT_MEM pass (optimize memories). +22.22.1. Executing OPT_MEM pass (optimize memories). Performed a total of 0 transformations. yosys> opt_mem_priority -16.28.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). +22.22.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). Performed a total of 0 transformations. yosys> opt_mem_feedback -16.28.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). +22.22.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). + Analyzing fifo.data write port 0. yosys> memory_bmux2rom -16.28.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). +22.22.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). yosys> memory_dff -16.28.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +22.22.5. 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> opt_clean -16.28.6. Executing OPT_CLEAN pass (remove unused cells and wires). +22.22.6. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. +Removed 1 unused cells and 9 unused wires. +<suppressed ~2 debug messages> yosys> memory_share -16.28.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). +22.22.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). yosys> opt_mem_widen -16.28.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). +22.22.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). Performed a total of 0 transformations. yosys> opt_clean -16.28.9. Executing OPT_CLEAN pass (remove unused cells and wires). +22.22.9. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> memory_collect -16.28.10. Executing MEMORY_COLLECT pass (generating $mem cells). +22.22.10. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> opt_clean -16.29. Executing OPT_CLEAN pass (remove unused cells and wires). +22.23. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -yosys> memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt -no-auto-huge +yosys> select -set new_cells t:$mem_v2 -16.30. Executing MEMORY_LIBMAP pass (mapping memories to cells). +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 + +23. Generating Graphviz representation of design. +Writing dot description to `rdata_coarse.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> echo off +echo off + +24. Executing SYNTH_ICE40 pass. + +24.1. Executing MEMORY_LIBMAP pass (mapping memories to cells). mapping memory fifo.data via $__ICE40_RAM4K_ <suppressed ~68 debug messages> -yosys> techmap -map +/ice40/brams_map.v -map +/ice40/spram_map.v +24.2. Executing TECHMAP pass (map to technology primitives). -16.31. Executing TECHMAP pass (map to technology primitives). - -16.31.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/brams_map.v +24.2.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/brams_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/brams_map.v' to AST representation. Generating RTLIL representation for module `\$__ICE40_RAM4K_'. Successfully finished Verilog frontend. -16.31.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/spram_map.v +24.2.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/spram_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/spram_map.v' to AST representation. Generating RTLIL representation for module `\$__ICE40_SPRAM_'. Successfully finished Verilog frontend. -16.31.3. Continuing TECHMAP pass. +24.2.3. Continuing TECHMAP pass. Using template $paramod$13b3947419e62b7bbba1b93c77e4155efbe69a94\$__ICE40_RAM4K_ for cells of type $__ICE40_RAM4K_. No more expansions possible. <suppressed ~26 debug messages> -yosys> ice40_braminit +24.3. Executing ICE40_BRAMINIT pass. -16.32. Executing ICE40_BRAMINIT pass. +25. Generating Graphviz representation of design. +Writing dot description to `rdata_map_ram.dot'. +Dumping selected parts of module fifo to page 1. -yosys> opt -fast -mux_undef -undriven -fine +26. Executing SYNTH_ICE40 pass. -16.33. Executing OPT pass (performing simple optimizations). +26.1. Executing OPT pass (performing simple optimizations). -yosys> opt_expr -mux_undef -undriven -fine - -16.33.1. Executing OPT_EXPR pass (perform const folding). +26.1.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. <suppressed ~13 debug messages> -yosys> opt_merge - -16.33.2. Executing OPT_MERGE pass (detect identical cells). +26.1.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +26.1.3. Executing OPT_DFF pass (perform DFF optimizations). +Removing always-active EN on $auto$mem.cc:1146:emulate_transparency$619 ($dffe) from module fifo. -16.33.3. Executing OPT_DFF pass (perform DFF optimizations). -Removing always-active EN on $auto$mem.cc:1146:emulate_transparency$593 ($dffe) from module fifo. - -yosys> opt_clean - -16.33.4. Executing OPT_CLEAN pass (remove unused cells and wires). +26.1.4. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 0 unused cells and 18 unused wires. <suppressed ~1 debug messages> -16.33.5. Rerunning OPT passes. (Removed registers in this run.) +26.1.5. Rerunning OPT passes. (Removed registers in this run.) -yosys> opt_expr -mux_undef -undriven -fine - -16.33.6. Executing OPT_EXPR pass (perform const folding). +26.1.6. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -yosys> opt_merge - -16.33.7. Executing OPT_MERGE pass (detect identical cells). +26.1.7. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +26.1.8. Executing OPT_DFF pass (perform DFF optimizations). -16.33.8. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.33.9. Executing OPT_CLEAN pass (remove unused cells and wires). +26.1.9. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -16.33.10. Finished fast OPT passes. +26.1.10. Finished fast OPT passes. -yosys> memory_map +26.2. Executing MEMORY_MAP pass (converting memories to logic and flip-flops). -16.34. Executing MEMORY_MAP pass (converting memories to logic and flip-flops). +26.3. Executing OPT pass (performing simple optimizations). -yosys> opt -undriven -fine - -16.35. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr -undriven -fine - -16.35.1. Executing OPT_EXPR pass (perform const folding). +26.3.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -yosys> opt_merge -nomux - -16.35.2. Executing OPT_MERGE pass (detect identical cells). +26.3.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_muxtree - -16.35.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +26.3.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. Evaluating internal representation of mux trees. @@ -1326,43 +1291,35 @@ Running muxtree optimizer on module \fifo.. Removed 0 multiplexer ports. <suppressed ~4 debug messages> -yosys> opt_reduce -fine - -16.35.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +26.3.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. -yosys> opt_merge - -16.35.5. Executing OPT_MERGE pass (detect identical cells). +26.3.5. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +26.3.6. Executing OPT_DFF pass (perform DFF optimizations). -16.35.6. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.35.7. Executing OPT_CLEAN pass (remove unused cells and wires). +26.3.7. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -yosys> opt_expr -undriven -fine - -16.35.8. Executing OPT_EXPR pass (perform const folding). +26.3.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.35.9. Finished OPT passes. (There is nothing left to do.) +26.3.9. Finished OPT passes. (There is nothing left to do.) -yosys> ice40_wrapcarry +27. Generating Graphviz representation of design. +Writing dot description to `rdata_map_ffram.dot'. +Dumping selected parts of module fifo to page 1. -16.36. Executing ICE40_WRAPCARRY pass (wrap carries). +28. Executing SYNTH_ICE40 pass. -yosys> techmap -map +/techmap.v -map +/ice40/arith_map.v +28.1. Executing ICE40_WRAPCARRY pass (wrap carries). -16.37. Executing TECHMAP pass (map to technology primitives). +28.2. Executing TECHMAP pass (map to technology primitives). -16.37.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v +28.2.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. Generating RTLIL representation for module `\_90_simplemap_bool_ops'. Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. @@ -1390,124 +1347,98 @@ Generating RTLIL representation for module `\_90_demux'. Generating RTLIL representation for module `\_90_lut'. Successfully finished Verilog frontend. -16.37.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/arith_map.v +28.2.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/arith_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/arith_map.v' to AST representation. Generating RTLIL representation for module `\_80_ice40_alu'. Successfully finished Verilog frontend. -16.37.3. Continuing TECHMAP pass. -Using template $paramod$c3cd1564c35d873179656addd6052d7ea8b6d991\_80_ice40_alu for cells of type $alu. +28.2.3. Continuing TECHMAP pass. +Using extmapper simplemap for cells of type $adffe. +Using template $paramod$53700bbee849b2010ad0b60a61ccd204a10e24ca\_80_ice40_alu for cells of type $alu. Using extmapper simplemap for cells of type $dff. Using extmapper simplemap for cells of type $logic_not. Using extmapper simplemap for cells of type $logic_and. +Using template $paramod$c3cd1564c35d873179656addd6052d7ea8b6d991\_80_ice40_alu for cells of type $alu. +Using extmapper simplemap for cells of type $reduce_bool. Using extmapper simplemap for cells of type $mux. +Using template $paramod$6f67705c43e5e94c02b6ebb52209ce5aa5ade4c1\_80_ice40_alu for cells of type $alu. Using extmapper simplemap for cells of type $eq. Using extmapper simplemap for cells of type $and. -Using extmapper simplemap for cells of type $adffe. -Using template $paramod$53700bbee849b2010ad0b60a61ccd204a10e24ca\_80_ice40_alu for cells of type $alu. -Using extmapper simplemap for cells of type $reduce_bool. -Using template $paramod$6f67705c43e5e94c02b6ebb52209ce5aa5ade4c1\_80_ice40_alu for cells of type $alu. Using extmapper simplemap for cells of type $xor. Using extmapper simplemap for cells of type $not. Using extmapper simplemap for cells of type $pos. No more expansions possible. <suppressed ~175 debug messages> -yosys> opt -fast +28.3. Executing OPT pass (performing simple optimizations). -16.38. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr - -16.38.1. Executing OPT_EXPR pass (perform const folding). +28.3.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. <suppressed ~109 debug messages> -yosys> opt_merge - -16.38.2. Executing OPT_MERGE pass (detect identical cells). +28.3.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. <suppressed ~81 debug messages> Removed a total of 27 cells. -yosys> opt_dff +28.3.3. Executing OPT_DFF pass (perform DFF optimizations). -16.38.3. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.38.4. Executing OPT_CLEAN pass (remove unused cells and wires). +28.3.4. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 11 unused cells and 83 unused wires. <suppressed ~12 debug messages> -16.38.5. Finished fast OPT passes. +28.3.5. Finished fast OPT passes. -yosys> ice40_opt +28.4. Executing ICE40_OPT pass (performing simple optimizations). -16.39. Executing ICE40_OPT pass (performing simple optimizations). +28.4.1. Running ICE40 specific optimizations. +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$591.slice[0].carry: CO=\count [0] +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$594.slice[0].carry: CO=\fifo_reader.addr [0] +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$597.slice[0].carry: CO=\fifo_writer.addr [0] +Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$600.slice[0].carry: CO=\count [0] -16.39.1. Running ICE40 specific optimizations. -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$574.slice[0].carry: CO=\count [0] -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$577.slice[0].carry: CO=\fifo_reader.addr [0] -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$580.slice[0].carry: CO=\fifo_writer.addr [0] -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$583.slice[0].carry: CO=\count [0] - -yosys> opt_expr -mux_undef -undriven - -16.39.2. Executing OPT_EXPR pass (perform const folding). +28.4.2. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -yosys> opt_merge - -16.39.3. Executing OPT_MERGE pass (detect identical cells). +28.4.3. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +28.4.4. Executing OPT_DFF pass (perform DFF optimizations). -16.39.4. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.39.5. Executing OPT_CLEAN pass (remove unused cells and wires). +28.4.5. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -16.39.6. Rerunning OPT passes. (Removed registers in this run.) +28.4.6. Rerunning OPT passes. (Removed registers in this run.) -16.39.7. Running ICE40 specific optimizations. +28.4.7. Running ICE40 specific optimizations. -yosys> opt_expr -mux_undef -undriven - -16.39.8. Executing OPT_EXPR pass (perform const folding). +28.4.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -yosys> opt_merge - -16.39.9. Executing OPT_MERGE pass (detect identical cells). +28.4.9. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +28.4.10. Executing OPT_DFF pass (perform DFF optimizations). -16.39.10. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.39.11. Executing OPT_CLEAN pass (remove unused cells and wires). +28.4.11. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -16.39.12. Finished OPT passes. (There is nothing left to do.) +28.4.12. Finished OPT passes. (There is nothing left to do.) -yosys> dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_SDFF_?P?_ 0 -cell $_SDFFCE_?P?P_ 0 -cell $_DLATCH_?_ x -mince -1 +29. Generating Graphviz representation of design. +Writing dot description to `rdata_map_gates.dot'. +Dumping selected parts of module fifo to page 1. -16.40. Executing DFFLEGALIZE pass (convert FFs to types supported by the target). +30. Executing SYNTH_ICE40 pass. -yosys> techmap -map +/ice40/ff_map.v +30.1. Executing DFFLEGALIZE pass (convert FFs to types supported by the target). -16.41. Executing TECHMAP pass (map to technology primitives). +30.2. Executing TECHMAP pass (map to technology primitives). -16.41.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v +30.2.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/ff_map.v' to AST representation. Generating RTLIL representation for module `\$_DFF_N_'. Generating RTLIL representation for module `\$_DFF_P_'. @@ -1531,218 +1462,146 @@ Generating RTLIL representation for module `\$_SDFFCE_PP0P_'. Generating RTLIL representation for module `\$_SDFFCE_PP1P_'. Successfully finished Verilog frontend. -16.41.2. Continuing TECHMAP pass. -Using template \$_DFFE_PP0P_ for cells of type $_DFFE_PP0P_. +30.2.2. Continuing TECHMAP pass. Using template \$_DFF_P_ for cells of type $_DFF_P_. +Using template \$_DFFE_PP0P_ for cells of type $_DFFE_PP0P_. No more expansions possible. <suppressed ~73 debug messages> -yosys> opt_expr -mux_undef - -16.42. Executing OPT_EXPR pass (perform const folding). +30.3. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -yosys> simplemap +30.4. Executing SIMPLEMAP pass (map simple cells to gate primitives). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$594.slice[0].carry ($lut). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$597.slice[0].carry ($lut). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$600.slice[0].carry ($lut). +Mapping fifo.$auto$alumacc.cc:485:replace_alu$591.slice[0].carry ($lut). -16.43. Executing SIMPLEMAP pass (map simple cells to gate primitives). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$577.slice[0].carry ($lut). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$580.slice[0].carry ($lut). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$583.slice[0].carry ($lut). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$574.slice[0].carry ($lut). +30.5. Executing ICE40_OPT pass (performing simple optimizations). -yosys> ice40_opt -full +30.5.1. Running ICE40 specific optimizations. -16.44. Executing ICE40_OPT pass (performing simple optimizations). - -16.44.1. Running ICE40 specific optimizations. - -yosys> opt_expr -mux_undef -undriven -full - -16.44.2. Executing OPT_EXPR pass (perform const folding). +30.5.2. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. <suppressed ~71 debug messages> -yosys> opt_merge - -16.44.3. Executing OPT_MERGE pass (detect identical cells). +30.5.3. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. <suppressed ~12 debug messages> Removed a total of 4 cells. -yosys> opt_dff +30.5.4. Executing OPT_DFF pass (perform DFF optimizations). -16.44.4. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.44.5. Executing OPT_CLEAN pass (remove unused cells and wires). +30.5.5. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 0 unused cells and 270 unused wires. <suppressed ~1 debug messages> -16.44.6. Rerunning OPT passes. (Removed registers in this run.) +30.5.6. Rerunning OPT passes. (Removed registers in this run.) -16.44.7. Running ICE40 specific optimizations. +30.5.7. Running ICE40 specific optimizations. -yosys> opt_expr -mux_undef -undriven -full - -16.44.8. Executing OPT_EXPR pass (perform const folding). +30.5.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. <suppressed ~1 debug messages> -yosys> opt_merge - -16.44.9. Executing OPT_MERGE pass (detect identical cells). +30.5.9. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +30.5.10. Executing OPT_DFF pass (perform DFF optimizations). -16.44.10. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.44.11. Executing OPT_CLEAN pass (remove unused cells and wires). +30.5.11. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -16.44.12. Rerunning OPT passes. (Removed registers in this run.) +30.5.12. Rerunning OPT passes. (Removed registers in this run.) -16.44.13. Running ICE40 specific optimizations. +30.5.13. Running ICE40 specific optimizations. -yosys> opt_expr -mux_undef -undriven -full - -16.44.14. Executing OPT_EXPR pass (perform const folding). +30.5.14. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -yosys> opt_merge - -16.44.15. Executing OPT_MERGE pass (detect identical cells). +30.5.15. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +30.5.16. Executing OPT_DFF pass (perform DFF optimizations). -16.44.16. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.44.17. Executing OPT_CLEAN pass (remove unused cells and wires). +30.5.17. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -16.44.18. Finished OPT passes. (There is nothing left to do.) +30.5.18. Finished OPT passes. (There is nothing left to do.) -yosys> techmap -map +/ice40/latches_map.v +31. Generating Graphviz representation of design. +Writing dot description to `rdata_map_ffs.dot'. +Dumping selected parts of module fifo to page 1. -16.45. Executing TECHMAP pass (map to technology primitives). +32. Executing SYNTH_ICE40 pass. -16.45.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/latches_map.v +32.1. Executing TECHMAP pass (map to technology primitives). + +32.1.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/latches_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/latches_map.v' to AST representation. Generating RTLIL representation for module `\$_DLATCH_N_'. Generating RTLIL representation for module `\$_DLATCH_P_'. Successfully finished Verilog frontend. -16.45.2. Continuing TECHMAP pass. +32.1.2. Continuing TECHMAP pass. No more expansions possible. <suppressed ~4 debug messages> -yosys> read_verilog -D ICE40_HX -icells -lib -specify +/ice40/abc9_model.v - -16.46. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/abc9_model.v +32.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/abc9_model.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/abc9_model.v' to AST representation. Generating RTLIL representation for module `$__ICE40_CARRY_WRAPPER'. Successfully finished Verilog frontend. -yosys> abc9 -W 250 +32.3. Executing ABC9 pass. -16.47. Executing ABC9 pass. +32.3.1. Executing ABC9_OPS pass (helper functions for ABC9). -yosys> abc9_ops -check +32.3.2. Executing ABC9_OPS pass (helper functions for ABC9). -16.47.1. Executing ABC9_OPS pass (helper functions for ABC9). - -yosys> abc9_ops -prep_hier - -16.47.2. Executing ABC9_OPS pass (helper functions for ABC9). - -yosys> scc -specify -set_attr abc9_scc_id {} - -16.47.3. Executing SCC pass (detecting logic loops). +32.3.3. Executing SCC pass (detecting logic loops). Found 0 SCCs in module fifo. Found 0 SCCs. -yosys> abc9_ops -prep_bypass +32.3.4. Executing ABC9_OPS pass (helper functions for ABC9). -16.47.4. Executing ABC9_OPS pass (helper functions for ABC9). +32.3.5. Executing PROC pass (convert processes to netlists). -yosys> design -stash $abc9 - -yosys> design -load $abc9_map - -yosys> proc - -16.47.5. Executing PROC pass (convert processes to netlists). - -yosys> proc_clean - -16.47.5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +32.3.5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. -yosys> proc_rmdead - -16.47.5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +32.3.5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Removed a total of 0 dead cases. -yosys> proc_prune - -16.47.5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +32.3.5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 0 assignments to connections. -yosys> proc_init +32.3.5.4. Executing PROC_INIT pass (extract init attributes). -16.47.5.4. Executing PROC_INIT pass (extract init attributes). +32.3.5.5. Executing PROC_ARST pass (detect async resets in processes). -yosys> proc_arst - -16.47.5.5. Executing PROC_ARST pass (detect async resets in processes). - -yosys> proc_rom - -16.47.5.6. Executing PROC_ROM pass (convert switches to ROMs). +32.3.5.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. -yosys> proc_mux +32.3.5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). -16.47.5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +32.3.5.8. Executing PROC_DLATCH pass (convert process syncs to latches). -yosys> proc_dlatch +32.3.5.9. Executing PROC_DFF pass (convert process syncs to FFs). -16.47.5.8. Executing PROC_DLATCH pass (convert process syncs to latches). +32.3.5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). -yosys> proc_dff - -16.47.5.9. Executing PROC_DFF pass (convert process syncs to FFs). - -yosys> proc_memwr - -16.47.5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). - -yosys> proc_clean - -16.47.5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +32.3.5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. -yosys> opt_expr -keepdc +32.3.5.12. Executing OPT_EXPR pass (perform const folding). -16.47.5.12. Executing OPT_EXPR pass (perform const folding). +32.3.6. Executing TECHMAP pass (map to technology primitives). -yosys> wbflip - -yosys> techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop - -16.47.6. Executing TECHMAP pass (map to technology primitives). - -16.47.6.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v +32.3.6.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. Generating RTLIL representation for module `\_90_simplemap_bool_ops'. Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. @@ -1770,85 +1629,55 @@ Generating RTLIL representation for module `\_90_demux'. Generating RTLIL representation for module `\_90_lut'. Successfully finished Verilog frontend. -16.47.6.2. Continuing TECHMAP pass. +32.3.6.2. Continuing TECHMAP pass. No more expansions possible. <suppressed ~128 debug messages> -yosys> opt -nodffe -nosdff +32.3.7. Executing OPT pass (performing simple optimizations). -16.47.7. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr - -16.47.7.1. Executing OPT_EXPR pass (perform const folding). +32.3.7.1. Executing OPT_EXPR pass (perform const folding). Optimizing module SB_DFFER. -yosys> opt_merge -nomux - -16.47.7.2. Executing OPT_MERGE pass (detect identical cells). +32.3.7.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\SB_DFFER'. Removed a total of 0 cells. -yosys> opt_muxtree - -16.47.7.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +32.3.7.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \SB_DFFER.. Creating internal representation of mux trees. No muxes found in this module. Removed 0 multiplexer ports. -yosys> opt_reduce - -16.47.7.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +32.3.7.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \SB_DFFER. Performed a total of 0 changes. -yosys> opt_merge - -16.47.7.5. Executing OPT_MERGE pass (detect identical cells). +32.3.7.5. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\SB_DFFER'. Removed a total of 0 cells. -yosys> opt_dff -nodffe -nosdff +32.3.7.6. Executing OPT_DFF pass (perform DFF optimizations). -16.47.7.6. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -16.47.7.7. Executing OPT_CLEAN pass (remove unused cells and wires). +32.3.7.7. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \SB_DFFER.. -yosys> opt_expr - -16.47.7.8. Executing OPT_EXPR pass (perform const folding). +32.3.7.8. Executing OPT_EXPR pass (perform const folding). Optimizing module SB_DFFER. -16.47.7.9. Finished OPT passes. (There is nothing left to do.) +32.3.7.9. Finished OPT passes. (There is nothing left to do.) -yosys> design -stash $abc9_map +32.3.8. Executing TECHMAP pass (map to technology primitives). -yosys> design -load $abc9 - -yosys> design -delete $abc9 - -yosys> techmap -wb -max_iter 1 -map %$abc9_map -map +/abc9_map.v a:abc9_scc_id %n - -16.47.8. Executing TECHMAP pass (map to technology primitives). - -16.47.8.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_map.v +32.3.8.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_map.v Parsing Verilog input from `/home/dawn/yosys/share/abc9_map.v' to AST representation. Successfully finished Verilog frontend. -16.47.8.2. Continuing TECHMAP pass. +32.3.8.2. Continuing TECHMAP pass. Using template SB_DFFER for cells of type SB_DFFER. No more expansions possible. <suppressed ~28 debug messages> -yosys> design -delete $abc9_map - -yosys> read_verilog -icells -lib -specify +/abc9_model.v - -16.47.9. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_model.v +32.3.9. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_model.v Parsing Verilog input from `/home/dawn/yosys/share/abc9_model.v' to AST representation. Generating RTLIL representation for module `$__ABC9_DELAY'. Generating RTLIL representation for module `$__ABC9_SCC_BREAKER'. @@ -1856,29 +1685,17 @@ Generating RTLIL representation for module `$__DFF_N__$abc9_flop'. Generating RTLIL representation for module `$__DFF_P__$abc9_flop'. Successfully finished Verilog frontend. -yosys> abc9_ops -break_scc -prep_delays -prep_xaiger - -16.47.10. Executing ABC9_OPS pass (helper functions for ABC9). +32.3.10. Executing ABC9_OPS pass (helper functions for ABC9). <suppressed ~86 debug messages> -yosys> abc9_ops -prep_lut 0 +32.3.11. Executing ABC9_OPS pass (helper functions for ABC9). -16.47.11. Executing ABC9_OPS pass (helper functions for ABC9). - -yosys> abc9_ops -prep_box - -16.47.12. Executing ABC9_OPS pass (helper functions for ABC9). +32.3.12. Executing ABC9_OPS pass (helper functions for ABC9). <suppressed ~2 debug messages> -yosys> design -stash $abc9 +32.3.13. Executing TECHMAP pass (map to technology primitives). -yosys> design -load $abc9_holes - -yosys> techmap -wb -map %$abc9 -map +/techmap.v - -16.47.13. Executing TECHMAP pass (map to technology primitives). - -16.47.13.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v +32.3.13.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. Generating RTLIL representation for module `\_90_simplemap_bool_ops'. Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. @@ -1906,7 +1723,7 @@ Generating RTLIL representation for module `\_90_demux'. Generating RTLIL representation for module `\_90_lut'. Successfully finished Verilog frontend. -16.47.13.2. Continuing TECHMAP pass. +32.3.13.2. Continuing TECHMAP pass. Using template $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 for cells of type $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1. Using template $paramod\SB_LUT4\LUT_INIT=16'0110100110010110 for cells of type SB_LUT4. Using template SB_CARRY for cells of type SB_CARRY. @@ -1916,100 +1733,68 @@ Using extmapper simplemap for cells of type $logic_or. No more expansions possible. <suppressed ~155 debug messages> -yosys> opt -purge +32.3.14. Executing OPT pass (performing simple optimizations). -16.47.14. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr - -16.47.14.1. Executing OPT_EXPR pass (perform const folding). +32.3.14.1. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. <suppressed ~4 debug messages> -yosys> opt_merge -nomux - -16.47.14.2. Executing OPT_MERGE pass (detect identical cells). +32.3.14.2. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. <suppressed ~29 debug messages> Removed a total of 12 cells. -yosys> opt_muxtree - -16.47.14.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +32.3.14.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. No muxes found in this module. Removed 0 multiplexer ports. -yosys> opt_reduce - -16.47.14.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +32.3.14.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. -yosys> opt_merge - -16.47.14.5. Executing OPT_MERGE pass (detect identical cells). +32.3.14.5. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +32.3.14.6. Executing OPT_DFF pass (perform DFF optimizations). -16.47.14.6. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean -purge - -16.47.14.7. Executing OPT_CLEAN pass (remove unused cells and wires). +32.3.14.7. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. Removed 0 unused cells and 24 unused wires. <suppressed ~1 debug messages> -yosys> opt_expr - -16.47.14.8. Executing OPT_EXPR pass (perform const folding). +32.3.14.8. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.47.14.9. Rerunning OPT passes. (Maybe there is more to do..) +32.3.14.9. Rerunning OPT passes. (Maybe there is more to do..) -yosys> opt_muxtree - -16.47.14.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). +32.3.14.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). Running muxtree optimizer on module \fifo.. Creating internal representation of mux trees. No muxes found in this module. Removed 0 multiplexer ports. -yosys> opt_reduce - -16.47.14.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). +32.3.14.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). Optimizing cells in module \fifo. Performed a total of 0 changes. -yosys> opt_merge - -16.47.14.12. Executing OPT_MERGE pass (detect identical cells). +32.3.14.12. Executing OPT_MERGE pass (detect identical cells). Finding identical cells in module `\fifo'. Removed a total of 0 cells. -yosys> opt_dff +32.3.14.13. Executing OPT_DFF pass (perform DFF optimizations). -16.47.14.13. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean -purge - -16.47.14.14. Executing OPT_CLEAN pass (remove unused cells and wires). +32.3.14.14. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -yosys> opt_expr - -16.47.14.15. Executing OPT_EXPR pass (perform const folding). +32.3.14.15. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. -16.47.14.16. Finished OPT passes. (There is nothing left to do.) +32.3.14.16. Finished OPT passes. (There is nothing left to do.) -yosys> aigmap - -16.47.15. Executing AIGMAP pass (map logic to AIG). +32.3.15. Executing AIGMAP pass (map logic to AIG). Module fifo: replaced 7 cells with 43 new cells, skipped 11 cells. replaced 2 cell types: 2 $_OR_ @@ -2019,15 +1804,7 @@ Module fifo: replaced 7 cells with 43 new cells, skipped 11 cells. 1 $_NOT_ 2 $_AND_ -yosys> design -stash $abc9_holes - -yosys> design -load $abc9 - -yosys> design -delete $abc9 - -yosys> aigmap - -16.47.16. Executing AIGMAP pass (map logic to AIG). +32.3.16. Executing AIGMAP pass (map logic to AIG). Module fifo: replaced 46 cells with 256 new cells, skipped 230 cells. replaced 3 cell types: 22 $_OR_ @@ -2039,36 +1816,28 @@ Module fifo: replaced 46 cells with 256 new cells, skipped 230 cells. 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011100000 26 SB_DFF 25 SB_DFFER - 30 $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 - 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011001011 25 SB_DFFER_$abc9_byp - 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000001100010 - 2 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100001011 + 1 $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K + 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011001011 + 30 $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 16 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000010100001 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000010000101 - 1 $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K + 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000001100010 16 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100010010 26 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000000010101 + 2 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100001011 -yosys*> abc9_ops -write_lut /tmp/yosys-abc-Sf9BQI/input.lut +32.3.16.1. Executing ABC9_OPS pass (helper functions for ABC9). -16.47.16.1. Executing ABC9_OPS pass (helper functions for ABC9). +32.3.16.2. Executing ABC9_OPS pass (helper functions for ABC9). -yosys*> abc9_ops -write_box /tmp/yosys-abc-Sf9BQI/input.box - -16.47.16.2. Executing ABC9_OPS pass (helper functions for ABC9). - -yosys*> write_xaiger -map /tmp/yosys-abc-Sf9BQI/input.sym /tmp/yosys-abc-Sf9BQI/input.xaig - -16.47.16.3. Executing XAIGER backend. +32.3.16.3. Executing XAIGER backend. <suppressed ~78 debug messages> Extracted 113 AND gates and 562 wires from module `fifo' to a netlist network with 71 inputs and 127 outputs. -yosys*> abc9_exe -W 250 -cwd /tmp/yosys-abc-Sf9BQI -lut /tmp/yosys-abc-Sf9BQI/input.lut -box /tmp/yosys-abc-Sf9BQI/input.box +32.3.16.4. Executing ABC9_EXE pass (technology mapping using ABC9). -16.47.16.4. Executing ABC9_EXE pass (technology mapping using ABC9). - -16.47.16.5. Executing ABC9. +32.3.16.5. Executing ABC9. Running ABC command: "<yosys-exe-dir>/yosys-abc" -s -f <abc-temp-dir>/abc.script 2>&1 ABC: ABC command line: "source <abc-temp-dir>/abc.script". ABC: @@ -2108,58 +1877,38 @@ ABC: + &write -n <abc-temp-dir>/output.aig ABC: + time ABC: elapse: 0.01 seconds, total: 0.01 seconds -yosys*> read_aiger -xaiger -wideports -module_name fifo$abc9 -map /tmp/yosys-abc-Sf9BQI/input.sym /tmp/yosys-abc-Sf9BQI/output.aig - -16.47.16.6. Executing AIGER frontend. - -yosys> clean +32.3.16.6. Executing AIGER frontend. <suppressed ~408 debug messages> Removed 175 unused cells and 883 unused wires. -yosys*> abc9_ops -reintegrate - -16.47.16.7. Executing ABC9_OPS pass (helper functions for ABC9). +32.3.16.7. Executing ABC9_OPS pass (helper functions for ABC9). ABC RESULTS: $lut cells: 29 -ABC RESULTS: $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 cells: 30 ABC RESULTS: \SB_DFFER_$abc9_byp cells: 25 +ABC RESULTS: $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 cells: 30 ABC RESULTS: input signals: 36 ABC RESULTS: output signals: 91 Removing temp directory. -yosys> techmap -wb -map %$abc9_unmap -map +/abc9_unmap.v +32.3.17. Executing TECHMAP pass (map to technology primitives). -16.47.17. Executing TECHMAP pass (map to technology primitives). - -16.47.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_unmap.v +32.3.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_unmap.v Parsing Verilog input from `/home/dawn/yosys/share/abc9_unmap.v' to AST representation. Generating RTLIL representation for module `\$__DFF_x__$abc9_flop'. Generating RTLIL representation for module `\$__ABC9_SCC_BREAKER'. Successfully finished Verilog frontend. -16.47.17.2. Continuing TECHMAP pass. +32.3.17.2. Continuing TECHMAP pass. Using template SB_DFFER_$abc9_byp for cells of type SB_DFFER_$abc9_byp. Using template $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K for cells of type $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K. Using template $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 for cells of type $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1. No more expansions possible. <suppressed ~64 debug messages> -yosys> design -delete $abc9_unmap +32.4. Executing ICE40_WRAPCARRY pass (wrap carries). -yosys> design -delete $abc9_holes +32.5. Executing TECHMAP pass (map to technology primitives). -yosys> delete =*_$abc9_byp - -yosys> setattr -mod -unset abc9_box_id - -yosys> ice40_wrapcarry -unwrap - -16.48. Executing ICE40_WRAPCARRY pass (wrap carries). - -yosys> techmap -map +/ice40/ff_map.v - -16.49. Executing TECHMAP pass (map to technology primitives). - -16.49.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v +32.5.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/ff_map.v' to AST representation. Generating RTLIL representation for module `\$_DFF_N_'. Generating RTLIL representation for module `\$_DFF_P_'. @@ -2183,16 +1932,12 @@ Generating RTLIL representation for module `\$_SDFFCE_PP0P_'. Generating RTLIL representation for module `\$_SDFFCE_PP1P_'. Successfully finished Verilog frontend. -16.49.2. Continuing TECHMAP pass. +32.5.2. Continuing TECHMAP pass. No more expansions possible. <suppressed ~22 debug messages> - -yosys> clean Removed 7 unused cells and 1055 unused wires. -yosys> opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 -dlogic SB_CARRY:CO=3 - -16.50. Executing OPT_LUT pass (optimize LUTs). +32.6. Executing OPT_LUT pass (optimize LUTs). Discovering LUTs. Number of LUTs: 58 1-LUT 3 @@ -2224,63 +1969,60 @@ Eliminated 0 LUTs. Combined 0 LUTs. <suppressed ~334 debug messages> -yosys> techmap -map +/ice40/cells_map.v +33. Generating Graphviz representation of design. +Writing dot description to `rdata_map_luts.dot'. +Dumping selected parts of module fifo to page 1. -16.51. Executing TECHMAP pass (map to technology primitives). +34. Executing SYNTH_ICE40 pass. -16.51.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_map.v +34.1. Executing TECHMAP pass (map to technology primitives). + +34.1.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_map.v Parsing Verilog input from `/home/dawn/yosys/share/ice40/cells_map.v' to AST representation. Generating RTLIL representation for module `\$lut'. Successfully finished Verilog frontend. -16.51.2. Continuing TECHMAP pass. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10111000 for cells of type $lut. +34.1.2. Continuing TECHMAP pass. Using template $paramod$fd904e9e35cfd343a9df248824bd3f1408724879\$lut for cells of type $lut. Using template $paramod$e87f431398fe61dc3cef677df705fdf1c11aa0f7\$lut for cells of type $lut. -Using template $paramod$8d7a8d6e3356de09670738ba85f2c6b874f6b06d\$lut for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10010000 for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10111000 for cells of type $lut. Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0100 for cells of type $lut. Using template $paramod$2b29ccbd5fb8b9c557f92ddec1023c75686f32ae\$lut for cells of type $lut. Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0010 for cells of type $lut. Using template $paramod$ba7c22fadfbf9ee7abcb895a21403114111dd201\$lut for cells of type $lut. Using template $paramod$5c7d886f3b88971ac55fed4bca034a87bf180f7d\$lut for cells of type $lut. +Using template $paramod$8d7a8d6e3356de09670738ba85f2c6b874f6b06d\$lut for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10010000 for cells of type $lut. Using template $paramod$571404c0889eaf57f492cb5e37f8acb5df5852f9\$lut for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'01001011 for cells of type $lut. +Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'11011000 for cells of type $lut. Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0110 for cells of type $lut. Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000001\LUT=2'01 for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'01001011 for cells of type $lut. No more expansions possible. -<suppressed ~243 debug messages> +<suppressed ~256 debug messages> +Removed 0 unused cells and 129 unused wires. -yosys> clean -Removed 0 unused cells and 130 unused wires. +34.2. Executing AUTONAME pass. +Renamed 1278 objects in module fifo (21 iterations). +<suppressed ~214 debug messages> -yosys> autoname +34.3. Executing HIERARCHY pass (managing design hierarchy). -16.52. Executing AUTONAME pass. -Renamed 1254 objects in module fifo (21 iterations). -<suppressed ~213 debug messages> - -yosys> hierarchy -check - -16.53. Executing HIERARCHY pass (managing design hierarchy). - -16.53.1. Analyzing design hierarchy.. +34.3.1. Analyzing design hierarchy.. Top module: \fifo -16.53.2. Analyzing design hierarchy.. +34.3.2. Analyzing design hierarchy.. Top module: \fifo Removed 0 unused modules. -yosys> stat - -16.54. Printing statistics. +34.4. Printing statistics. === fifo === - Number of wires: 91 - Number of wire bits: 246 - Number of public wires: 91 - Number of public wire bits: 246 + Number of wires: 92 + Number of wire bits: 250 + Number of public wires: 92 + Number of public wire bits: 250 Number of memories: 0 Number of memory bits: 0 Number of processes: 0 @@ -2291,41 +2033,10 @@ yosys> stat SB_LUT4 58 SB_RAM40_4K 1 - -yosys> check -noinit - -16.55. Executing CHECK pass (checking for obvious problems). +34.5. Executing CHECK pass (checking for obvious problems). Checking module fifo... Found and reported 0 problems. -yosys> blackbox =A:whitebox - -yosys> show -notitle -format dot -prefix fifo_synth - -17. Generating Graphviz representation of design. -Writing dot description to `fifo_synth.dot'. -Dumping module fifo to page 1. - -yosys> stat - -18. Printing statistics. - -=== fifo === - - Number of wires: 91 - Number of wire bits: 246 - Number of public wires: 91 - Number of public wire bits: 246 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 136 - SB_CARRY 26 - SB_DFF 26 - SB_DFFER 25 - SB_LUT4 58 - SB_RAM40_4K 1 - -End of script. Logfile hash: 7fbdf4b991, CPU: user 0.68s system 0.01s, MEM: 29.84 MB peak -Yosys 0.35+39 (git sha1 0cd4a10c8, clang 10.0.0-4ubuntu1 -fPIC -Os) -Time spent: 37% 27x read_verilog (0 sec), 33% 12x techmap (0 sec), ... +35. Generating Graphviz representation of design. +Writing dot description to `rdata_map_cells.dot'. +Dumping selected parts of module fifo to page 1. diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index 576704838..3bfc0468a 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -56,7 +56,51 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdat design -reset read_verilog fifo.v synth_ice40 -top fifo -run begin:map_ram -# memory_collect -# opt select -set new_cells t:$mem_v2 -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse o:rdata %ci* +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 + +# turn command echoes off to avoid randomly generated abc file names +echo off + +# ======================================================== + +synth_ice40 -top fifo -run map_ram:map_ffram +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_ffram:map_gates +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_gates:map_ffs +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_ffs:map_luts +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_luts:map_cells +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_cells: +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @rdata_path diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index a22ea1bf9..7fd48eb0c 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -299,24 +299,26 @@ optimizations and other transformations done previously. 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 - the :ref:`synth_coarse`. + this section. -In the iCE40 flow we get all the following commands: +Part 1 +^^^^^^ + +In the iCE40 flow, we start with the following commands: .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt - :linenos: :start-after: coarse: - :end-before: map_ram: + :end-before: wreduce :dedent: - :caption: ``coarse`` section - :name: synth_coarse + :caption: ``coarse`` section (part 1) + :name: synth_coarse1 -The first few commands are relatively straightforward. We've already come +The first few commands are relatively straightforward, and we've already come across :cmd:ref:`opt_clean` and :cmd:ref:`opt_expr`. 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. +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 @@ -343,12 +345,30 @@ options is able to fold one of the ``$mux`` cells into the ``$adff`` to form an ``rdata`` output after :cmd:ref:`opt_dff` +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/fsm` + - :doc:`/using_yosys/synthesis/opt` + +Part 2 +^^^^^^ + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-at: wreduce + :end-before: t:$mul + :dedent: + :caption: ``coarse`` section (part 2) + :name: synth_coarse2 + The next three (new) commands are :doc:`/cmd/wreduce`, :doc:`/cmd/peepopt`, and :doc:`/cmd/share`. None of these affect our design either, 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:`/using_yosys/synthesis/techmap_synth`. + +Our next command to run is :doc:`/cmd/memory_dff`. .. literalinclude:: /code_examples/fifo/fifo.out @@ -365,10 +385,45 @@ comparison operators by converting them to LUTs instead. The usage of 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). -Following this is a series of commands for mapping to DSPs. + +.. 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. + +.. literalinclude:: /cmd/synth_ice40.rst + :language: yoscrypt + :start-at: t:$mul + :end-before: alumacc + :dedent: + :caption: ``coarse`` section (part 3) + :name: synth_coarse3 .. TODO:: more on DSP mapping +.. 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 be mapped to hard blocks. We do this by running :cmd:ref:`alumacc`, which we can @@ -386,15 +441,7 @@ see produce the following changes in our example design: ``rdata`` output after :cmd:ref:`alumacc` -That brings us to the last commands, and a look at ``rdata`` at the end of the -:ref:`synth_coarse`. We could also have gotten here by running -:yoscrypt:`synth_ice40 -top fifo -run begin:map_ram` after loading the design. - -.. literalinclude:: /cmd/synth_ice40.rst - :language: yoscrypt - :start-at: memory -nomap - :end-before: map_ram: - :dedent: +.. TODO:: discuss :cmd:ref:`memory_collect` and ``$mem_v2`` .. figure:: /_images/code_examples/fifo/rdata_coarse.* :class: width-helper @@ -402,18 +449,26 @@ That brings us to the last commands, and a look at ``rdata`` at the end of the ``rdata`` output after :yoscrypt:`memory -nomap` -.. TODO:: discuss :cmd:ref:`memory_collect` and ``$mem_v2`` +We could also have gotten here by running :yoscrypt:`synth_ice40 -top fifo -run +begin:map_ram` after loading the design. .. seealso:: Advanced usage docs for - :doc:`/using_yosys/synthesis/fsm` - :doc:`/using_yosys/synthesis/opt` - :doc:`/using_yosys/synthesis/techmap_synth` :doc:`/using_yosys/synthesis/memory` Hardware mapping ~~~~~~~~~~~~~~~~ -.. TODO:: example_synth hardware mapping sections +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. + +Memory blocks +^^^^^^^^^^^^^ + +Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, +:cmd:ref:`memory_map`, and :cmd:ref:`techmap`. + +.. TODO:: ``$mem_v2`` -> ``SB_RAM40_4K`` .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -423,6 +478,12 @@ Hardware mapping :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` + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_ffram: @@ -431,6 +492,24 @@ Hardware mapping :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` + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/techmap_synth` + - :doc:`/using_yosys/synthesis/memory` + +Arithmetic +^^^^^^^^^^ + +Uses :cmd:ref:`techmap`. + +.. TODO:: example_synth/Arithmetic + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_gates: @@ -439,6 +518,23 @@ Hardware mapping :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. We also run :cmd:ref:`simplemap` here +to convert any remaining cells which could not be mapped to hardware into +gate-level primitives. + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_ffs: @@ -447,6 +543,23 @@ Hardware mapping :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. Note that the iCE40 +flow uses :cmd:ref:`abc` rather than :cmd:ref:`abc9`. 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: @@ -455,6 +568,22 @@ Hardware mapping :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` + +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/techmap_synth` + - :doc:`/using_yosys/synthesis/abc` + +Other cells +^^^^^^^^^^^ + +Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_cells: @@ -463,9 +592,13 @@ Hardware mapping :name: map_cells :caption: ``map_cells`` section -:cmd:ref:`dfflibmap` - This command maps the internal register cell types to the register types - described in a liberty file. +.. figure:: /_images/code_examples/fifo/rdata_map_cells.* + :class: width-helper + :name: rdata_map_cells + + ``rdata`` output after :ref:`map_cells` + +.. TODO:: example_synth other cells :cmd:ref:`hilomap` Some architectures require special driver cells for driving a constant hi or @@ -476,12 +609,8 @@ Hardware mapping Top-level input/outputs must usually be implemented using special I/O-pad cells. This command inserts such cells to the design. -:cmd:ref:`dfflegalize` - Specify a set of supported FF cells/cell groups and convert all FFs to them. - .. seealso:: Advanced usage docs for - :doc:`/yosys_internals/techmap`, and - :doc:`/using_yosys/synthesis/memory`. + :doc:`/yosys_internals/techmap` Final steps ~~~~~~~~~~~~ From 9f1c445fbf0435779a79e985fa11bb26bc0d626a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:47:33 +1300 Subject: [PATCH 063/108] docs: work on example_synth Split hardware mapping from `fifo.ys` into `fifo_map.ys`. Reduces size of `fifo.out` log and allows separate yosys calls in the makefile. Some tidy up and minor changes in `fifo.ys` for better discussion. Filled out note on `clean` (changed from `opt_clean`) and introduced `;;`. Highlighted `$memrd` and added a paragraph about it. More detail on the flatten and merging of `fifo_reader` block. Brief discussion on the changes from `$memrd` to `$memrd_v2`. --- docs/source/code_examples/fifo/Makefile | 12 +- docs/source/code_examples/fifo/fifo.out | 1743 +---------------- docs/source/code_examples/fifo/fifo.ys | 58 +- docs/source/code_examples/fifo/fifo_map.ys | 45 + docs/source/getting_started/example_synth.rst | 75 +- 5 files changed, 159 insertions(+), 1774 deletions(-) create mode 100644 docs/source/code_examples/fifo/fifo_map.ys diff --git a/docs/source/code_examples/fifo/Makefile b/docs/source/code_examples/fifo/Makefile index 795853f81..37ce0a12c 100644 --- a/docs/source/code_examples/fifo/Makefile +++ b/docs/source/code_examples/fifo/Makefile @@ -3,17 +3,21 @@ 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 -DOT_NAMES += rdata_coarse rdata_map_ram rdata_map_ffram rdata_map_gates -DOT_NAMES += rdata_map_ffs rdata_map_luts rdata_map_cells +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)) -dots: $(DOTS) fifo.out +dots: $(DOTS) $(MAPDOTS) fifo.out $(DOTS) fifo.out: fifo.v fifo.ys $(YOSYS) fifo.ys -l fifo.out -Q -T +$(MAPDOTS): fifo.v fifo_map.ys + $(YOSYS) fifo_map.ys + .PHONY: clean clean: rm -f *.dot diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index d747247c5..f0bd76f3f 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -115,16 +115,12 @@ yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc Writing dot description to `addr_gen_proc.dot'. Dumping module addr_gen to page 1. -yosys> opt_clean - -7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \addr_gen.. +yosys> clean Removed 0 unused cells and 4 unused wires. -<suppressed ~1 debug messages> yosys> show -notitle -format dot -prefix addr_gen_clean -8. Generating Graphviz representation of design. +7. Generating Graphviz representation of design. Writing dot description to `addr_gen_clean.dot'. Dumping module addr_gen to page 1. @@ -132,7 +128,7 @@ yosys> design -reset yosys> read_verilog fifo.v -9. Executing Verilog-2005 frontend: fifo.v +8. 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'. @@ -140,24 +136,24 @@ Successfully finished Verilog frontend. yosys> hierarchy -check -top fifo -10. Executing HIERARCHY pass (managing design hierarchy). +9. Executing HIERARCHY pass (managing design hierarchy). -10.1. Analyzing design hierarchy.. +9.1. Analyzing design hierarchy.. Top module: \fifo Used module: \addr_gen Parameter \MAX_DATA = 256 -10.2. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +9.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'. -10.3. Analyzing design hierarchy.. +9.3. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 -10.4. Analyzing design hierarchy.. +9.4. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 Removing unused module `\addr_gen'. @@ -165,16 +161,16 @@ Removed 1 unused modules. yosys> proc -11. Executing PROC pass (convert processes to netlists). +10. Executing PROC pass (convert processes to netlists). yosys> proc_clean -11.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +10.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. yosys> proc_rmdead -11.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +10.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Marked 2 switch rules as full_case in process $proc$fifo.v:64$24 in module fifo. Marked 1 switch rules as full_case in process $proc$fifo.v:38$16 in module fifo. Marked 2 switch rules as full_case in process $proc$fifo.v:13$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. @@ -182,13 +178,13 @@ Removed a total of 0 dead cases. yosys> proc_prune -11.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +10.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 6 assignments to connections. yosys> proc_init -11.4. Executing PROC_INIT pass (extract init attributes). +10.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'. @@ -196,19 +192,19 @@ Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000 yosys> proc_arst -11.5. Executing PROC_ARST pass (detect async resets in processes). +10.5. Executing PROC_ARST pass (detect async resets in processes). Found async reset \rst in `\fifo.$proc$fifo.v:64$24'. Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. yosys> proc_rom -11.6. Executing PROC_ROM pass (convert switches to ROMs). +10.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. <suppressed ~5 debug messages> yosys> proc_mux -11.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +10.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:64$24'. 1/1: $0\count[8:0] @@ -222,11 +218,11 @@ Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'000000000000000000 yosys> proc_dlatch -11.8. Executing PROC_DLATCH pass (convert process syncs to latches). +10.8. Executing PROC_DLATCH pass (convert process syncs to latches). yosys> proc_dff -11.9. Executing PROC_DFF pass (convert process syncs to FFs). +10.9. Executing PROC_DFF pass (convert process syncs to FFs). Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$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:38$16'. @@ -242,11 +238,11 @@ Creating register for signal `$paramod\addr_gen\MAX_DATA=s32'0000000000000000000 yosys> proc_memwr -11.10. Executing PROC_MEMWR pass (convert process memory writes to cells). +10.10. Executing PROC_MEMWR pass (convert process memory writes to cells). yosys> proc_clean -11.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +10.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:64$24'. Removing empty process `fifo.$proc$fifo.v:64$24'. @@ -259,34 +255,40 @@ Cleaned up 5 empty switches. yosys> opt_expr -keepdc -11.12. Executing OPT_EXPR pass (perform const folding). +10.12. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. -yosys> show -color maroon3 c:fifo_reader -notitle -format dot -prefix rdata_proc o:rdata %ci* +yosys> select -set new_cells t:$memrd -12. Generating Graphviz representation of design. +yosys> show -color maroon3 c:fifo_reader -color cornflowerblue @new_cells -notitle -format dot -prefix rdata_proc o:rdata %ci* + +11. Generating Graphviz representation of design. Writing dot description to `rdata_proc.dot'. Dumping selected parts of module fifo to page 1. yosys> flatten -13. Executing FLATTEN pass (flatten design). +12. Executing FLATTEN pass (flatten design). Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. <suppressed ~2 debug messages> yosys> clean Removed 3 unused cells and 25 unused wires. -yosys> show -notitle -format dot -prefix rdata_flat o:rdata %ci* +yosys> select -set rdata_path o:rdata %ci* -14. Generating Graphviz representation of design. +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 + +13. Generating Graphviz representation of design. Writing dot description to `rdata_flat.dot'. Dumping selected parts of module fifo to page 1. yosys> opt_dff -15. Executing OPT_DFF pass (perform DFF optimizations). +14. 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). @@ -295,13 +297,13 @@ yosys> select -set new_cells t:$adffe yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* -16. Generating Graphviz representation of design. +15. Generating Graphviz representation of design. Writing dot description to `rdata_adffe.dot'. Dumping selected parts of module fifo to page 1. yosys> memory_dff -17. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +16. 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. @@ -309,13 +311,13 @@ yosys> select -set new_cells t:$memrd_v2 yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdata %ci* -18. Generating Graphviz representation of design. +17. Generating Graphviz representation of design. Writing dot description to `rdata_memrdv2.dot'. Dumping selected parts of module fifo to page 1. yosys> alumacc -19. Executing ALUMACC pass (create $alu and $macc cells). +18. Executing ALUMACC pass (create $alu and $macc cells). Extracting $alu and $macc cells in module fifo: creating $macc model for $add$fifo.v:68$27 ($add). creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$34 ($add). @@ -335,864 +337,60 @@ yosys> select -set new_cells t:$alu t:$macc yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdata %ci* -20. Generating Graphviz representation of design. +19. Generating Graphviz representation of design. Writing dot description to `rdata_alumacc.dot'. Dumping selected parts of module fifo to page 1. -yosys> design -reset - -yosys> read_verilog fifo.v - -21. 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> synth_ice40 -top fifo -run begin:map_ram - -22. Executing SYNTH_ICE40 pass. - -yosys> read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v - -22.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_sim.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/cells_sim.v' to AST representation. -Generating RTLIL representation for module `\SB_IO'. -Generating RTLIL representation for module `\SB_GB_IO'. -Generating RTLIL representation for module `\SB_GB'. -Generating RTLIL representation for module `\SB_LUT4'. -Generating RTLIL representation for module `\SB_CARRY'. -Generating RTLIL representation for module `\SB_DFF'. -Generating RTLIL representation for module `\SB_DFFE'. -Generating RTLIL representation for module `\SB_DFFSR'. -Generating RTLIL representation for module `\SB_DFFR'. -Generating RTLIL representation for module `\SB_DFFSS'. -Generating RTLIL representation for module `\SB_DFFS'. -Generating RTLIL representation for module `\SB_DFFESR'. -Generating RTLIL representation for module `\SB_DFFER'. -Generating RTLIL representation for module `\SB_DFFESS'. -Generating RTLIL representation for module `\SB_DFFES'. -Generating RTLIL representation for module `\SB_DFFN'. -Generating RTLIL representation for module `\SB_DFFNE'. -Generating RTLIL representation for module `\SB_DFFNSR'. -Generating RTLIL representation for module `\SB_DFFNR'. -Generating RTLIL representation for module `\SB_DFFNSS'. -Generating RTLIL representation for module `\SB_DFFNS'. -Generating RTLIL representation for module `\SB_DFFNESR'. -Generating RTLIL representation for module `\SB_DFFNER'. -Generating RTLIL representation for module `\SB_DFFNESS'. -Generating RTLIL representation for module `\SB_DFFNES'. -Generating RTLIL representation for module `\SB_RAM40_4K'. -Generating RTLIL representation for module `\SB_RAM40_4KNR'. -Generating RTLIL representation for module `\SB_RAM40_4KNW'. -Generating RTLIL representation for module `\SB_RAM40_4KNRNW'. -Generating RTLIL representation for module `\ICESTORM_LC'. -Generating RTLIL representation for module `\SB_PLL40_CORE'. -Generating RTLIL representation for module `\SB_PLL40_PAD'. -Generating RTLIL representation for module `\SB_PLL40_2_PAD'. -Generating RTLIL representation for module `\SB_PLL40_2F_CORE'. -Generating RTLIL representation for module `\SB_PLL40_2F_PAD'. -Generating RTLIL representation for module `\SB_WARMBOOT'. -Generating RTLIL representation for module `\SB_SPRAM256KA'. -Generating RTLIL representation for module `\SB_HFOSC'. -Generating RTLIL representation for module `\SB_LFOSC'. -Generating RTLIL representation for module `\SB_RGBA_DRV'. -Generating RTLIL representation for module `\SB_LED_DRV_CUR'. -Generating RTLIL representation for module `\SB_RGB_DRV'. -Generating RTLIL representation for module `\SB_I2C'. -Generating RTLIL representation for module `\SB_SPI'. -Generating RTLIL representation for module `\SB_LEDDA_IP'. -Generating RTLIL representation for module `\SB_FILTER_50NS'. -Generating RTLIL representation for module `\SB_IO_I3C'. -Generating RTLIL representation for module `\SB_IO_OD'. -Generating RTLIL representation for module `\SB_MAC16'. -Generating RTLIL representation for module `\ICESTORM_RAM'. -Successfully finished Verilog frontend. - -yosys> hierarchy -check -top fifo - -22.2. Executing HIERARCHY pass (managing design hierarchy). - -22.2.1. Analyzing design hierarchy.. -Top module: \fifo -Used module: \addr_gen -Parameter \MAX_DATA = 256 - -22.2.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'. - -22.2.3. Analyzing design hierarchy.. -Top module: \fifo -Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 - -22.2.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 - -22.3. Executing PROC pass (convert processes to netlists). - -yosys> proc_clean - -22.3.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -yosys> proc_rmdead - -22.3.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349 in module SB_DFFNES. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342 in module SB_DFFNESS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338 in module SB_DFFNER. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331 in module SB_DFFNESR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328 in module SB_DFFNS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325 in module SB_DFFNSS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322 in module SB_DFFNR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319 in module SB_DFFNSR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311 in module SB_DFFES. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304 in module SB_DFFESS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300 in module SB_DFFER. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293 in module SB_DFFESR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290 in module SB_DFFS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287 in module SB_DFFSS. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284 in module SB_DFFR. -Marked 1 switch rules as full_case in process $proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281 in module SB_DFFSR. -Marked 2 switch rules as full_case in process $proc$fifo.v:64$101 in module fifo. -Marked 1 switch rules as full_case in process $proc$fifo.v:38$93 in module fifo. -Marked 2 switch rules as full_case in process $proc$fifo.v:13$489 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. -Removed a total of 0 dead cases. - -yosys> proc_prune - -22.3.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 8 redundant assignments. -Promoted 28 assignments to connections. - -yosys> proc_init - -22.3.4. Executing PROC_INIT pass (extract init attributes). -Found init rule in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$352'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$348'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$341'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$337'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$330'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$327'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$324'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$321'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$318'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$316'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$314'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$310'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$303'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$299'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$289'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$286'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$283'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$280'. - Set init value: \Q = 1'0 -Found init rule in `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$278'. - Set init value: \Q = 1'0 -Found init rule in `\fifo.$proc$fifo.v:0$108'. - Set init value: \count = 9'000000000 -Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$492'. - Set init value: \addr = 8'00000000 - -yosys> proc_arst - -22.3.5. Executing PROC_ARST pass (detect async resets in processes). -Found async reset \S in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. -Found async reset \R in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. -Found async reset \S in `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. -Found async reset \R in `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. -Found async reset \S in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. -Found async reset \R in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. -Found async reset \S in `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. -Found async reset \R in `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. -Found async reset \rst in `\fifo.$proc$fifo.v:64$101'. -Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. - -yosys> proc_rom - -22.3.6. Executing PROC_ROM pass (convert switches to ROMs). -Converted 0 switches. -<suppressed ~23 debug messages> - -yosys> proc_mux - -22.3.7. Executing PROC_MUX pass (convert decision trees to multiplexers). -Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$352'. -Creating decoders for process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$348'. -Creating decoders for process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$341'. -Creating decoders for process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$337'. -Creating decoders for process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$330'. -Creating decoders for process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$327'. -Creating decoders for process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$324'. -Creating decoders for process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$321'. -Creating decoders for process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$318'. -Creating decoders for process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$316'. -Creating decoders for process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$315'. -Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$314'. -Creating decoders for process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$310'. -Creating decoders for process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$303'. -Creating decoders for process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$299'. -Creating decoders for process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. -Creating decoders for process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$289'. -Creating decoders for process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$286'. -Creating decoders for process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$283'. -Creating decoders for process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$280'. -Creating decoders for process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. - 1/1: $0\Q[0:0] -Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$278'. -Creating decoders for process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$277'. -Creating decoders for process `\fifo.$proc$fifo.v:0$108'. -Creating decoders for process `\fifo.$proc$fifo.v:64$101'. - 1/1: $0\count[8:0] -Creating decoders for process `\fifo.$proc$fifo.v:38$93'. - 1/3: $1$memwr$\data$fifo.v:40$92_EN[7:0]$97 - 2/3: $1$memwr$\data$fifo.v:40$92_DATA[7:0]$98 - 3/3: $1$memwr$\data$fifo.v:40$92_ADDR[7:0]$99 -Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$492'. -Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. - 1/1: $0\addr[7:0] - -yosys> proc_dlatch - -22.3.8. Executing PROC_DLATCH pass (convert process syncs to latches). - -yosys> proc_dff - -22.3.9. Executing PROC_DFF pass (convert process syncs to FFs). -Creating register for signal `\SB_DFFNES.\Q' using process `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. - created $adff cell `$procdff$556' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNESS.\Q' using process `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. - created $dff cell `$procdff$557' with negative edge clock. -Creating register for signal `\SB_DFFNER.\Q' using process `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. - created $adff cell `$procdff$558' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNESR.\Q' using process `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. - created $dff cell `$procdff$559' with negative edge clock. -Creating register for signal `\SB_DFFNS.\Q' using process `\SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. - created $adff cell `$procdff$560' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNSS.\Q' using process `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. - created $dff cell `$procdff$561' with negative edge clock. -Creating register for signal `\SB_DFFNR.\Q' using process `\SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. - created $adff cell `$procdff$562' with negative edge clock and positive level reset. -Creating register for signal `\SB_DFFNSR.\Q' using process `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. - created $dff cell `$procdff$563' with negative edge clock. -Creating register for signal `\SB_DFFNE.\Q' using process `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. - created $dff cell `$procdff$564' with negative edge clock. -Creating register for signal `\SB_DFFN.\Q' using process `\SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$315'. - created $dff cell `$procdff$565' with negative edge clock. -Creating register for signal `\SB_DFFES.\Q' using process `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. - created $adff cell `$procdff$566' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFESS.\Q' using process `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. - created $dff cell `$procdff$567' with positive edge clock. -Creating register for signal `\SB_DFFER.\Q' using process `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. - created $adff cell `$procdff$568' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFESR.\Q' using process `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. - created $dff cell `$procdff$569' with positive edge clock. -Creating register for signal `\SB_DFFS.\Q' using process `\SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. - created $adff cell `$procdff$570' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFSS.\Q' using process `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. - created $dff cell `$procdff$571' with positive edge clock. -Creating register for signal `\SB_DFFR.\Q' using process `\SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. - created $adff cell `$procdff$572' with positive edge clock and positive level reset. -Creating register for signal `\SB_DFFSR.\Q' using process `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. - created $dff cell `$procdff$573' with positive edge clock. -Creating register for signal `\SB_DFFE.\Q' using process `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. - created $dff cell `$procdff$574' with positive edge clock. -Creating register for signal `\SB_DFF.\Q' using process `\SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$277'. - created $dff cell `$procdff$575' with positive edge clock. -Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$101'. - created $adff cell `$procdff$576' with positive edge clock and positive level reset. -Creating register for signal `\fifo.\rdata' using process `\fifo.$proc$fifo.v:38$93'. - created $dff cell `$procdff$577' with positive edge clock. -Creating register for signal `\fifo.$memwr$\data$fifo.v:40$92_EN' using process `\fifo.$proc$fifo.v:38$93'. - created $dff cell `$procdff$578' with positive edge clock. -Creating register for signal `\fifo.$memwr$\data$fifo.v:40$92_DATA' using process `\fifo.$proc$fifo.v:38$93'. - created $dff cell `$procdff$579' with positive edge clock. -Creating register for signal `\fifo.$memwr$\data$fifo.v:40$92_ADDR' using process `\fifo.$proc$fifo.v:38$93'. - created $dff cell `$procdff$580' 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:13$489'. - created $adff cell `$procdff$581' with positive edge clock and positive level reset. - -yosys> proc_memwr - -22.3.10. Executing PROC_MEMWR pass (convert process memory writes to cells). - -yosys> proc_clean - -22.3.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$352'. -Found and cleaned up 1 empty switch in `\SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. -Removing empty process `SB_DFFNES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1414$349'. -Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$348'. -Found and cleaned up 2 empty switches in `\SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. -Removing empty process `SB_DFFNESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1353$342'. -Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$341'. -Found and cleaned up 1 empty switch in `\SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. -Removing empty process `SB_DFFNER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1273$338'. -Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$337'. -Found and cleaned up 2 empty switches in `\SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. -Removing empty process `SB_DFFNESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1212$331'. -Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$330'. -Removing empty process `SB_DFFNS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1138$328'. -Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$327'. -Found and cleaned up 1 empty switch in `\SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. -Removing empty process `SB_DFFNSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1088$325'. -Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$324'. -Removing empty process `SB_DFFNR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:1017$322'. -Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$321'. -Found and cleaned up 1 empty switch in `\SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. -Removing empty process `SB_DFFNSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:967$319'. -Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$318'. -Found and cleaned up 1 empty switch in `\SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. -Removing empty process `SB_DFFNE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:922$317'. -Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$316'. -Removing empty process `SB_DFFN.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:882$315'. -Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$314'. -Found and cleaned up 1 empty switch in `\SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. -Removing empty process `SB_DFFES.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:803$311'. -Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$310'. -Found and cleaned up 2 empty switches in `\SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. -Removing empty process `SB_DFFESS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:742$304'. -Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$303'. -Found and cleaned up 1 empty switch in `\SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. -Removing empty process `SB_DFFER.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:662$300'. -Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$299'. -Found and cleaned up 2 empty switches in `\SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. -Removing empty process `SB_DFFESR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:601$293'. -Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$292'. -Removing empty process `SB_DFFS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:527$290'. -Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$289'. -Found and cleaned up 1 empty switch in `\SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. -Removing empty process `SB_DFFSS.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:477$287'. -Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$286'. -Removing empty process `SB_DFFR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:406$284'. -Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$283'. -Found and cleaned up 1 empty switch in `\SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. -Removing empty process `SB_DFFSR.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:356$281'. -Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$280'. -Found and cleaned up 1 empty switch in `\SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. -Removing empty process `SB_DFFE.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:311$279'. -Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:0$278'. -Removing empty process `SB_DFF.$proc$/home/dawn/yosys/share/ice40/cells_sim.v:271$277'. -Removing empty process `fifo.$proc$fifo.v:0$108'. -Found and cleaned up 2 empty switches in `\fifo.$proc$fifo.v:64$101'. -Removing empty process `fifo.$proc$fifo.v:64$101'. -Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:38$93'. -Removing empty process `fifo.$proc$fifo.v:38$93'. -Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:0$492'. -Found and cleaned up 2 empty switches in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. -Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$489'. -Cleaned up 23 empty switches. - -yosys> opt_expr -keepdc - -22.3.12. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. - -yosys> flatten - -22.4. Executing FLATTEN pass (flatten design). -Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. -<suppressed ~2 debug messages> - -yosys> tribuf -logic - -22.5. Executing TRIBUF pass. - -yosys> deminout - -22.6. Executing DEMINOUT pass (demote inout ports to input or output). - -yosys> opt_expr - -22.7. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -yosys> opt_clean - -22.8. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 3 unused cells and 25 unused wires. -<suppressed ~4 debug messages> - -yosys> check - -22.9. Executing CHECK pass (checking for obvious problems). -Checking module fifo... -Found and reported 0 problems. - -yosys> opt -nodffe -nosdff - -22.10. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr - -22.10.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -yosys> opt_merge -nomux - -22.10.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_muxtree - -22.10.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~6 debug messages> - -yosys> opt_reduce - -22.10.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. - Consolidated identical input bits for $mux cell $procmux$543: - Old ports: A=8'00000000, B=8'11111111, Y=$0$memwr$\data$fifo.v:40$92_EN[7:0]$94 - New ports: A=1'0, B=1'1, Y=$0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] - New connections: $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [7:1] = { $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] $0$memwr$\data$fifo.v:40$92_EN[7:0]$94 [0] } - Optimizing cells in module \fifo. -Performed a total of 1 changes. - -yosys> opt_merge - -22.10.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_dff -nodffe -nosdff - -22.10.6. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -22.10.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -yosys> opt_expr - -22.10.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -22.10.9. Rerunning OPT passes. (Maybe there is more to do..) - -yosys> opt_muxtree - -22.10.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~6 debug messages> - -yosys> opt_reduce - -22.10.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -yosys> opt_merge - -22.10.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_dff -nodffe -nosdff - -22.10.13. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -22.10.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -yosys> opt_expr - -22.10.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -22.10.16. Finished OPT passes. (There is nothing left to do.) - -yosys> fsm - -22.11. Executing FSM pass (extract and optimize FSM). - -yosys> fsm_detect - -22.11.1. Executing FSM_DETECT pass (finding FSMs in design). - -yosys> fsm_extract - -22.11.2. Executing FSM_EXTRACT pass (extracting FSM from design). - -yosys> fsm_opt - -22.11.3. Executing FSM_OPT pass (simple optimizations of FSMs). - -yosys> opt_clean - -22.11.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -yosys> fsm_opt - -22.11.5. Executing FSM_OPT pass (simple optimizations of FSMs). - -yosys> fsm_recode - -22.11.6. Executing FSM_RECODE pass (re-assigning FSM state encoding). - -yosys> fsm_info - -22.11.7. Executing FSM_INFO pass (dumping all available information on FSM cells). - -yosys> fsm_map - -22.11.8. Executing FSM_MAP pass (mapping FSMs to basic logic). - -yosys> opt - -22.12. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr - -22.12.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -yosys> opt_merge -nomux - -22.12.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_muxtree - -22.12.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~6 debug messages> - -yosys> opt_reduce - -22.12.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -yosys> opt_merge - -22.12.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_dff - -22.12.6. Executing OPT_DFF pass (perform DFF optimizations). -Adding EN signal on $procdff$576 ($adff) from module fifo (D = $0\count[8:0], Q = \count). -Adding EN signal on $flatten\fifo_writer.$procdff$581 ($adff) from module fifo (D = $flatten\fifo_writer.$procmux$552_Y, Q = \fifo_writer.addr). -Adding EN signal on $flatten\fifo_reader.$procdff$581 ($adff) from module fifo (D = $flatten\fifo_reader.$procmux$552_Y, Q = \fifo_reader.addr). - -yosys> opt_clean - -22.12.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 2 unused cells and 2 unused wires. -<suppressed ~3 debug messages> - -yosys> opt_expr - -22.12.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -<suppressed ~1 debug messages> - -22.12.9. Rerunning OPT passes. (Maybe there is more to do..) - -yosys> opt_muxtree - -22.12.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~6 debug messages> - -yosys> opt_reduce - -22.12.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -yosys> opt_merge - -22.12.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_dff - -22.12.13. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -22.12.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -yosys> opt_expr - -22.12.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -22.12.16. Finished OPT passes. (There is nothing left to do.) - -yosys> wreduce - -22.13. Executing WREDUCE pass (reducing word size of cells). -Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$107 ($sub). -Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:70$107 ($sub). -Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$104 ($add). -Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$104 ($add). -Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$491 ($add). -Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$491 ($add). -Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$491 ($add). -Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$491 ($add). -Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$104_Y. -Removed top 23 bits (of 32) from wire fifo.$sub$fifo.v:70$107_Y. - -yosys> peepopt - -22.14. Executing PEEPOPT pass (run peephole optimizers). - -yosys> opt_clean - -22.15. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 0 unused cells and 2 unused wires. -<suppressed ~1 debug messages> - -yosys> share - -22.16. Executing SHARE pass (SAT-based resource sharing). - -yosys> techmap -map +/cmp2lut.v -D LUT_WIDTH=4 - -22.17. Executing TECHMAP pass (map to technology primitives). - -22.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/cmp2lut.v -Parsing Verilog input from `/home/dawn/yosys/share/cmp2lut.v' to AST representation. -Generating RTLIL representation for module `\_90_lut_cmp_'. -Successfully finished Verilog frontend. - -22.17.2. Continuing TECHMAP pass. -No more expansions possible. -<suppressed ~6 debug messages> - -yosys> opt_expr - -22.18. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -yosys> opt_clean - -22.19. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -yosys> alumacc - -22.20. Executing ALUMACC pass (create $alu and $macc cells). -Extracting $alu and $macc cells in module fifo: - creating $macc model for $add$fifo.v:68$104 ($add). - creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$491 ($add). - creating $macc model for $flatten\fifo_writer.$add$fifo.v:20$491 ($add). - creating $macc model for $sub$fifo.v:70$107 ($sub). - creating $alu model for $macc $sub$fifo.v:70$107. - creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$491. - creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$491. - creating $alu model for $macc $add$fifo.v:68$104. - creating $alu cell for $add$fifo.v:68$104: $auto$alumacc.cc:485:replace_alu$591 - creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$491: $auto$alumacc.cc:485:replace_alu$594 - creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$491: $auto$alumacc.cc:485:replace_alu$597 - creating $alu cell for $sub$fifo.v:70$107: $auto$alumacc.cc:485:replace_alu$600 - created 4 $alu and 0 $macc cells. - -yosys> opt - -22.21. Executing OPT pass (performing simple optimizations). - -yosys> opt_expr - -22.21.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -yosys> opt_merge -nomux - -22.21.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_muxtree - -22.21.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~6 debug messages> - -yosys> opt_reduce - -22.21.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -yosys> opt_merge - -22.21.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -yosys> opt_dff - -22.21.6. Executing OPT_DFF pass (perform DFF optimizations). - -yosys> opt_clean - -22.21.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -yosys> opt_expr - -22.21.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -22.21.9. Finished OPT passes. (There is nothing left to do.) - yosys> memory -nomap -22.22. Executing MEMORY pass. +20. Executing MEMORY pass. yosys> opt_mem -22.22.1. Executing OPT_MEM pass (optimize memories). +20.1. Executing OPT_MEM pass (optimize memories). Performed a total of 0 transformations. yosys> opt_mem_priority -22.22.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). +20.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). Performed a total of 0 transformations. yosys> opt_mem_feedback -22.22.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). - Analyzing fifo.data write port 0. +20.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). yosys> memory_bmux2rom -22.22.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). +20.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). yosys> memory_dff -22.22.5. 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. +20.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). yosys> opt_clean -22.22.6. Executing OPT_CLEAN pass (remove unused cells and wires). +20.6. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -Removed 1 unused cells and 9 unused wires. -<suppressed ~2 debug messages> +Removed 3 unused cells and 11 unused wires. +<suppressed ~4 debug messages> yosys> memory_share -22.22.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). +20.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). yosys> opt_mem_widen -22.22.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). +20.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). Performed a total of 0 transformations. yosys> opt_clean -22.22.9. Executing OPT_CLEAN pass (remove unused cells and wires). +20.9. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> memory_collect -22.22.10. Executing MEMORY_COLLECT pass (generating $mem cells). - -yosys> opt_clean - -22.23. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. +20.10. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> select -set new_cells t:$mem_v2 @@ -1200,843 +398,6 @@ yosys> select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @n yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path -23. Generating Graphviz representation of design. +21. Generating Graphviz representation of design. Writing dot description to `rdata_coarse.dot'. Dumping selected parts of module fifo to page 1. - -yosys> echo off -echo off - -24. Executing SYNTH_ICE40 pass. - -24.1. Executing MEMORY_LIBMAP pass (mapping memories to cells). -mapping memory fifo.data via $__ICE40_RAM4K_ -<suppressed ~68 debug messages> - -24.2. Executing TECHMAP pass (map to technology primitives). - -24.2.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/brams_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/brams_map.v' to AST representation. -Generating RTLIL representation for module `\$__ICE40_RAM4K_'. -Successfully finished Verilog frontend. - -24.2.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/spram_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/spram_map.v' to AST representation. -Generating RTLIL representation for module `\$__ICE40_SPRAM_'. -Successfully finished Verilog frontend. - -24.2.3. Continuing TECHMAP pass. -Using template $paramod$13b3947419e62b7bbba1b93c77e4155efbe69a94\$__ICE40_RAM4K_ for cells of type $__ICE40_RAM4K_. -No more expansions possible. -<suppressed ~26 debug messages> - -24.3. Executing ICE40_BRAMINIT pass. - -25. Generating Graphviz representation of design. -Writing dot description to `rdata_map_ram.dot'. -Dumping selected parts of module fifo to page 1. - -26. Executing SYNTH_ICE40 pass. - -26.1. Executing OPT pass (performing simple optimizations). - -26.1.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -<suppressed ~13 debug messages> - -26.1.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -26.1.3. Executing OPT_DFF pass (perform DFF optimizations). -Removing always-active EN on $auto$mem.cc:1146:emulate_transparency$619 ($dffe) from module fifo. - -26.1.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 0 unused cells and 18 unused wires. -<suppressed ~1 debug messages> - -26.1.5. Rerunning OPT passes. (Removed registers in this run.) - -26.1.6. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -26.1.7. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -26.1.8. Executing OPT_DFF pass (perform DFF optimizations). - -26.1.9. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -26.1.10. Finished fast OPT passes. - -26.2. Executing MEMORY_MAP pass (converting memories to logic and flip-flops). - -26.3. Executing OPT pass (performing simple optimizations). - -26.3.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -26.3.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -26.3.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - Evaluating internal representation of mux trees. - Analyzing evaluation results. -Removed 0 multiplexer ports. -<suppressed ~4 debug messages> - -26.3.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -26.3.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -26.3.6. Executing OPT_DFF pass (perform DFF optimizations). - -26.3.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -26.3.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -26.3.9. Finished OPT passes. (There is nothing left to do.) - -27. Generating Graphviz representation of design. -Writing dot description to `rdata_map_ffram.dot'. -Dumping selected parts of module fifo to page 1. - -28. Executing SYNTH_ICE40 pass. - -28.1. Executing ICE40_WRAPCARRY pass (wrap carries). - -28.2. Executing TECHMAP pass (map to technology primitives). - -28.2.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v -Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod_trunc'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\$__div_mod_floor'. -Generating RTLIL representation for module `\_90_divfloor'. -Generating RTLIL representation for module `\_90_modfloor'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_demux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -28.2.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/arith_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/arith_map.v' to AST representation. -Generating RTLIL representation for module `\_80_ice40_alu'. -Successfully finished Verilog frontend. - -28.2.3. Continuing TECHMAP pass. -Using extmapper simplemap for cells of type $adffe. -Using template $paramod$53700bbee849b2010ad0b60a61ccd204a10e24ca\_80_ice40_alu for cells of type $alu. -Using extmapper simplemap for cells of type $dff. -Using extmapper simplemap for cells of type $logic_not. -Using extmapper simplemap for cells of type $logic_and. -Using template $paramod$c3cd1564c35d873179656addd6052d7ea8b6d991\_80_ice40_alu for cells of type $alu. -Using extmapper simplemap for cells of type $reduce_bool. -Using extmapper simplemap for cells of type $mux. -Using template $paramod$6f67705c43e5e94c02b6ebb52209ce5aa5ade4c1\_80_ice40_alu for cells of type $alu. -Using extmapper simplemap for cells of type $eq. -Using extmapper simplemap for cells of type $and. -Using extmapper simplemap for cells of type $xor. -Using extmapper simplemap for cells of type $not. -Using extmapper simplemap for cells of type $pos. -No more expansions possible. -<suppressed ~175 debug messages> - -28.3. Executing OPT pass (performing simple optimizations). - -28.3.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -<suppressed ~109 debug messages> - -28.3.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -<suppressed ~81 debug messages> -Removed a total of 27 cells. - -28.3.3. Executing OPT_DFF pass (perform DFF optimizations). - -28.3.4. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 11 unused cells and 83 unused wires. -<suppressed ~12 debug messages> - -28.3.5. Finished fast OPT passes. - -28.4. Executing ICE40_OPT pass (performing simple optimizations). - -28.4.1. Running ICE40 specific optimizations. -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$591.slice[0].carry: CO=\count [0] -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$594.slice[0].carry: CO=\fifo_reader.addr [0] -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$597.slice[0].carry: CO=\fifo_writer.addr [0] -Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) fifo.$auto$alumacc.cc:485:replace_alu$600.slice[0].carry: CO=\count [0] - -28.4.2. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -28.4.3. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -28.4.4. Executing OPT_DFF pass (perform DFF optimizations). - -28.4.5. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -28.4.6. Rerunning OPT passes. (Removed registers in this run.) - -28.4.7. Running ICE40 specific optimizations. - -28.4.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -28.4.9. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -28.4.10. Executing OPT_DFF pass (perform DFF optimizations). - -28.4.11. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -28.4.12. Finished OPT passes. (There is nothing left to do.) - -29. Generating Graphviz representation of design. -Writing dot description to `rdata_map_gates.dot'. -Dumping selected parts of module fifo to page 1. - -30. Executing SYNTH_ICE40 pass. - -30.1. Executing DFFLEGALIZE pass (convert FFs to types supported by the target). - -30.2. Executing TECHMAP pass (map to technology primitives). - -30.2.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/ff_map.v' to AST representation. -Generating RTLIL representation for module `\$_DFF_N_'. -Generating RTLIL representation for module `\$_DFF_P_'. -Generating RTLIL representation for module `\$_DFFE_NP_'. -Generating RTLIL representation for module `\$_DFFE_PP_'. -Generating RTLIL representation for module `\$_DFF_NP0_'. -Generating RTLIL representation for module `\$_DFF_NP1_'. -Generating RTLIL representation for module `\$_DFF_PP0_'. -Generating RTLIL representation for module `\$_DFF_PP1_'. -Generating RTLIL representation for module `\$_DFFE_NP0P_'. -Generating RTLIL representation for module `\$_DFFE_NP1P_'. -Generating RTLIL representation for module `\$_DFFE_PP0P_'. -Generating RTLIL representation for module `\$_DFFE_PP1P_'. -Generating RTLIL representation for module `\$_SDFF_NP0_'. -Generating RTLIL representation for module `\$_SDFF_NP1_'. -Generating RTLIL representation for module `\$_SDFF_PP0_'. -Generating RTLIL representation for module `\$_SDFF_PP1_'. -Generating RTLIL representation for module `\$_SDFFCE_NP0P_'. -Generating RTLIL representation for module `\$_SDFFCE_NP1P_'. -Generating RTLIL representation for module `\$_SDFFCE_PP0P_'. -Generating RTLIL representation for module `\$_SDFFCE_PP1P_'. -Successfully finished Verilog frontend. - -30.2.2. Continuing TECHMAP pass. -Using template \$_DFF_P_ for cells of type $_DFF_P_. -Using template \$_DFFE_PP0P_ for cells of type $_DFFE_PP0P_. -No more expansions possible. -<suppressed ~73 debug messages> - -30.3. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -30.4. Executing SIMPLEMAP pass (map simple cells to gate primitives). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$594.slice[0].carry ($lut). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$597.slice[0].carry ($lut). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$600.slice[0].carry ($lut). -Mapping fifo.$auto$alumacc.cc:485:replace_alu$591.slice[0].carry ($lut). - -30.5. Executing ICE40_OPT pass (performing simple optimizations). - -30.5.1. Running ICE40 specific optimizations. - -30.5.2. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -<suppressed ~71 debug messages> - -30.5.3. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -<suppressed ~12 debug messages> -Removed a total of 4 cells. - -30.5.4. Executing OPT_DFF pass (perform DFF optimizations). - -30.5.5. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 0 unused cells and 270 unused wires. -<suppressed ~1 debug messages> - -30.5.6. Rerunning OPT passes. (Removed registers in this run.) - -30.5.7. Running ICE40 specific optimizations. - -30.5.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -<suppressed ~1 debug messages> - -30.5.9. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -30.5.10. Executing OPT_DFF pass (perform DFF optimizations). - -30.5.11. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -30.5.12. Rerunning OPT passes. (Removed registers in this run.) - -30.5.13. Running ICE40 specific optimizations. - -30.5.14. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -30.5.15. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -30.5.16. Executing OPT_DFF pass (perform DFF optimizations). - -30.5.17. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -30.5.18. Finished OPT passes. (There is nothing left to do.) - -31. Generating Graphviz representation of design. -Writing dot description to `rdata_map_ffs.dot'. -Dumping selected parts of module fifo to page 1. - -32. Executing SYNTH_ICE40 pass. - -32.1. Executing TECHMAP pass (map to technology primitives). - -32.1.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/latches_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/latches_map.v' to AST representation. -Generating RTLIL representation for module `\$_DLATCH_N_'. -Generating RTLIL representation for module `\$_DLATCH_P_'. -Successfully finished Verilog frontend. - -32.1.2. Continuing TECHMAP pass. -No more expansions possible. -<suppressed ~4 debug messages> - -32.2. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/abc9_model.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/abc9_model.v' to AST representation. -Generating RTLIL representation for module `$__ICE40_CARRY_WRAPPER'. -Successfully finished Verilog frontend. - -32.3. Executing ABC9 pass. - -32.3.1. Executing ABC9_OPS pass (helper functions for ABC9). - -32.3.2. Executing ABC9_OPS pass (helper functions for ABC9). - -32.3.3. Executing SCC pass (detecting logic loops). -Found 0 SCCs in module fifo. -Found 0 SCCs. - -32.3.4. Executing ABC9_OPS pass (helper functions for ABC9). - -32.3.5. Executing PROC pass (convert processes to netlists). - -32.3.5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -32.3.5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). -Removed a total of 0 dead cases. - -32.3.5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). -Removed 0 redundant assignments. -Promoted 0 assignments to connections. - -32.3.5.4. Executing PROC_INIT pass (extract init attributes). - -32.3.5.5. Executing PROC_ARST pass (detect async resets in processes). - -32.3.5.6. Executing PROC_ROM pass (convert switches to ROMs). -Converted 0 switches. - -32.3.5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). - -32.3.5.8. Executing PROC_DLATCH pass (convert process syncs to latches). - -32.3.5.9. Executing PROC_DFF pass (convert process syncs to FFs). - -32.3.5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). - -32.3.5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). -Cleaned up 0 empty switches. - -32.3.5.12. Executing OPT_EXPR pass (perform const folding). - -32.3.6. Executing TECHMAP pass (map to technology primitives). - -32.3.6.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v -Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod_trunc'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\$__div_mod_floor'. -Generating RTLIL representation for module `\_90_divfloor'. -Generating RTLIL representation for module `\_90_modfloor'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_demux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -32.3.6.2. Continuing TECHMAP pass. -No more expansions possible. -<suppressed ~128 debug messages> - -32.3.7. Executing OPT pass (performing simple optimizations). - -32.3.7.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module SB_DFFER. - -32.3.7.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\SB_DFFER'. -Removed a total of 0 cells. - -32.3.7.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \SB_DFFER.. - Creating internal representation of mux trees. - No muxes found in this module. -Removed 0 multiplexer ports. - -32.3.7.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \SB_DFFER. -Performed a total of 0 changes. - -32.3.7.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\SB_DFFER'. -Removed a total of 0 cells. - -32.3.7.6. Executing OPT_DFF pass (perform DFF optimizations). - -32.3.7.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \SB_DFFER.. - -32.3.7.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module SB_DFFER. - -32.3.7.9. Finished OPT passes. (There is nothing left to do.) - -32.3.8. Executing TECHMAP pass (map to technology primitives). - -32.3.8.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_map.v -Parsing Verilog input from `/home/dawn/yosys/share/abc9_map.v' to AST representation. -Successfully finished Verilog frontend. - -32.3.8.2. Continuing TECHMAP pass. -Using template SB_DFFER for cells of type SB_DFFER. -No more expansions possible. -<suppressed ~28 debug messages> - -32.3.9. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_model.v -Parsing Verilog input from `/home/dawn/yosys/share/abc9_model.v' to AST representation. -Generating RTLIL representation for module `$__ABC9_DELAY'. -Generating RTLIL representation for module `$__ABC9_SCC_BREAKER'. -Generating RTLIL representation for module `$__DFF_N__$abc9_flop'. -Generating RTLIL representation for module `$__DFF_P__$abc9_flop'. -Successfully finished Verilog frontend. - -32.3.10. Executing ABC9_OPS pass (helper functions for ABC9). -<suppressed ~86 debug messages> - -32.3.11. Executing ABC9_OPS pass (helper functions for ABC9). - -32.3.12. Executing ABC9_OPS pass (helper functions for ABC9). -<suppressed ~2 debug messages> - -32.3.13. Executing TECHMAP pass (map to technology primitives). - -32.3.13.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/techmap.v -Parsing Verilog input from `/home/dawn/yosys/share/techmap.v' to AST representation. -Generating RTLIL representation for module `\_90_simplemap_bool_ops'. -Generating RTLIL representation for module `\_90_simplemap_reduce_ops'. -Generating RTLIL representation for module `\_90_simplemap_logic_ops'. -Generating RTLIL representation for module `\_90_simplemap_compare_ops'. -Generating RTLIL representation for module `\_90_simplemap_various'. -Generating RTLIL representation for module `\_90_simplemap_registers'. -Generating RTLIL representation for module `\_90_shift_ops_shr_shl_sshl_sshr'. -Generating RTLIL representation for module `\_90_shift_shiftx'. -Generating RTLIL representation for module `\_90_fa'. -Generating RTLIL representation for module `\_90_lcu'. -Generating RTLIL representation for module `\_90_alu'. -Generating RTLIL representation for module `\_90_macc'. -Generating RTLIL representation for module `\_90_alumacc'. -Generating RTLIL representation for module `\$__div_mod_u'. -Generating RTLIL representation for module `\$__div_mod_trunc'. -Generating RTLIL representation for module `\_90_div'. -Generating RTLIL representation for module `\_90_mod'. -Generating RTLIL representation for module `\$__div_mod_floor'. -Generating RTLIL representation for module `\_90_divfloor'. -Generating RTLIL representation for module `\_90_modfloor'. -Generating RTLIL representation for module `\_90_pow'. -Generating RTLIL representation for module `\_90_pmux'. -Generating RTLIL representation for module `\_90_demux'. -Generating RTLIL representation for module `\_90_lut'. -Successfully finished Verilog frontend. - -32.3.13.2. Continuing TECHMAP pass. -Using template $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 for cells of type $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1. -Using template $paramod\SB_LUT4\LUT_INIT=16'0110100110010110 for cells of type SB_LUT4. -Using template SB_CARRY for cells of type SB_CARRY. -Using extmapper simplemap for cells of type $mux. -Using extmapper simplemap for cells of type $logic_and. -Using extmapper simplemap for cells of type $logic_or. -No more expansions possible. -<suppressed ~155 debug messages> - -32.3.14. Executing OPT pass (performing simple optimizations). - -32.3.14.1. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. -<suppressed ~4 debug messages> - -32.3.14.2. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -<suppressed ~29 debug messages> -Removed a total of 12 cells. - -32.3.14.3. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - No muxes found in this module. -Removed 0 multiplexer ports. - -32.3.14.4. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -32.3.14.5. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -32.3.14.6. Executing OPT_DFF pass (perform DFF optimizations). - -32.3.14.7. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 0 unused cells and 24 unused wires. -<suppressed ~1 debug messages> - -32.3.14.8. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -32.3.14.9. Rerunning OPT passes. (Maybe there is more to do..) - -32.3.14.10. Executing OPT_MUXTREE pass (detect dead branches in mux trees). -Running muxtree optimizer on module \fifo.. - Creating internal representation of mux trees. - No muxes found in this module. -Removed 0 multiplexer ports. - -32.3.14.11. Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs). - Optimizing cells in module \fifo. -Performed a total of 0 changes. - -32.3.14.12. Executing OPT_MERGE pass (detect identical cells). -Finding identical cells in module `\fifo'. -Removed a total of 0 cells. - -32.3.14.13. Executing OPT_DFF pass (perform DFF optimizations). - -32.3.14.14. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - -32.3.14.15. Executing OPT_EXPR pass (perform const folding). -Optimizing module fifo. - -32.3.14.16. Finished OPT passes. (There is nothing left to do.) - -32.3.15. Executing AIGMAP pass (map logic to AIG). -Module fifo: replaced 7 cells with 43 new cells, skipped 11 cells. - replaced 2 cell types: - 2 $_OR_ - 5 $_MUX_ - not replaced 3 cell types: - 8 $specify2 - 1 $_NOT_ - 2 $_AND_ - -32.3.16. Executing AIGMAP pass (map logic to AIG). -Module fifo: replaced 46 cells with 256 new cells, skipped 230 cells. - replaced 3 cell types: - 22 $_OR_ - 8 $_XOR_ - 16 $_MUX_ - not replaced 15 cell types: - 20 $_NOT_ - 19 $_AND_ - 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011100000 - 26 SB_DFF - 25 SB_DFFER - 25 SB_DFFER_$abc9_byp - 1 $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K - 11 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000011001011 - 30 $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 - 16 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000010100001 - 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000010000101 - 1 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000001100010 - 16 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100010010 - 26 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000000010101 - 2 $paramod$__ABC9_DELAY\DELAY=32'00000000000000000000000100001011 - -32.3.16.1. Executing ABC9_OPS pass (helper functions for ABC9). - -32.3.16.2. Executing ABC9_OPS pass (helper functions for ABC9). - -32.3.16.3. Executing XAIGER backend. -<suppressed ~78 debug messages> -Extracted 113 AND gates and 562 wires from module `fifo' to a netlist network with 71 inputs and 127 outputs. - -32.3.16.4. Executing ABC9_EXE pass (technology mapping using ABC9). - -32.3.16.5. Executing ABC9. -Running ABC command: "<yosys-exe-dir>/yosys-abc" -s -f <abc-temp-dir>/abc.script 2>&1 -ABC: ABC command line: "source <abc-temp-dir>/abc.script". -ABC: -ABC: + read_lut <abc-temp-dir>/input.lut -ABC: + read_box <abc-temp-dir>/input.box -ABC: + &read <abc-temp-dir>/input.xaig -ABC: + &ps -ABC: <abc-temp-dir>/input : i/o = 71/ 127 and = 113 lev = 6 (0.27) mem = 0.01 MB box = 139 bb = 109 -ABC: Warning: AIG with boxes has internal fanout in 0 complex flops and 20 carries. -ABC: + &scorr -ABC: Warning: The network is combinational. -ABC: + &sweep -ABC: + &dc2 -ABC: + &dch -f -ABC: + &ps -ABC: <abc-temp-dir>/input : i/o = 71/ 127 and = 160 lev = 6 (0.12) mem = 0.01 MB ch = 20 box = 139 bb = 109 -ABC: Warning: AIG with boxes has internal fanout in 0 complex flops and 20 carries. -ABC: + &if -W 250 -v -ABC: K = 4. Memory (bytes): Truth = 0. Cut = 48. Obj = 128. Set = 528. CutMin = no -ABC: Node = 160. Ch = 19. Total mem = 0.11 MB. Peak cut mem = 0.01 MB. -ABC: P: Del = 2712.00. Ar = 28.0. Edge = 81. Cut = 569. T = 0.00 sec -ABC: P: Del = 2712.00. Ar = 27.0. Edge = 87. Cut = 564. T = 0.00 sec -ABC: P: Del = 2712.00. Ar = 26.0. Edge = 86. Cut = 565. T = 0.00 sec -ABC: F: Del = 2712.00. Ar = 26.0. Edge = 88. Cut = 554. T = 0.00 sec -ABC: A: Del = 2712.00. Ar = 26.0. Edge = 86. Cut = 537. T = 0.00 sec -ABC: A: Del = 2712.00. Ar = 26.0. Edge = 86. Cut = 545. T = 0.00 sec -ABC: Total time = 0.00 sec -ABC: + &write -n <abc-temp-dir>/output.aig -ABC: + &mfs -ABC: The network is not changed by "&mfs". -ABC: + &ps -l -ABC: <abc-temp-dir>/input : i/o = 71/ 127 and = 91 lev = 6 (0.12) mem = 0.01 MB box = 139 bb = 109 -ABC: Mapping (K=4) : lut = 26 edge = 86 lev = 3 (0.05) levB = 10 mem = 0.00 MB -ABC: LUT = 26 : 2=4 15.4 % 3=10 38.5 % 4=12 46.2 % Ave = 3.31 -ABC: Warning: AIG with boxes has internal fanout in 0 complex flops and 20 carries. -ABC: + &write -n <abc-temp-dir>/output.aig -ABC: + time -ABC: elapse: 0.01 seconds, total: 0.01 seconds - -32.3.16.6. Executing AIGER frontend. -<suppressed ~408 debug messages> -Removed 175 unused cells and 883 unused wires. - -32.3.16.7. Executing ABC9_OPS pass (helper functions for ABC9). -ABC RESULTS: $lut cells: 29 -ABC RESULTS: \SB_DFFER_$abc9_byp cells: 25 -ABC RESULTS: $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 cells: 30 -ABC RESULTS: input signals: 36 -ABC RESULTS: output signals: 91 -Removing temp directory. - -32.3.17. Executing TECHMAP pass (map to technology primitives). - -32.3.17.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/abc9_unmap.v -Parsing Verilog input from `/home/dawn/yosys/share/abc9_unmap.v' to AST representation. -Generating RTLIL representation for module `\$__DFF_x__$abc9_flop'. -Generating RTLIL representation for module `\$__ABC9_SCC_BREAKER'. -Successfully finished Verilog frontend. - -32.3.17.2. Continuing TECHMAP pass. -Using template SB_DFFER_$abc9_byp for cells of type SB_DFFER_$abc9_byp. -Using template $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K for cells of type $paramod$ba68a0420314c29d51ab7ddbd2ec9361aa29f018\SB_RAM40_4K. -Using template $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1 for cells of type $paramod$__ICE40_CARRY_WRAPPER\LUT=16'0110100110010110\I3_IS_CI=1'1. -No more expansions possible. -<suppressed ~64 debug messages> - -32.4. Executing ICE40_WRAPCARRY pass (wrap carries). - -32.5. Executing TECHMAP pass (map to technology primitives). - -32.5.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/ff_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/ff_map.v' to AST representation. -Generating RTLIL representation for module `\$_DFF_N_'. -Generating RTLIL representation for module `\$_DFF_P_'. -Generating RTLIL representation for module `\$_DFFE_NP_'. -Generating RTLIL representation for module `\$_DFFE_PP_'. -Generating RTLIL representation for module `\$_DFF_NP0_'. -Generating RTLIL representation for module `\$_DFF_NP1_'. -Generating RTLIL representation for module `\$_DFF_PP0_'. -Generating RTLIL representation for module `\$_DFF_PP1_'. -Generating RTLIL representation for module `\$_DFFE_NP0P_'. -Generating RTLIL representation for module `\$_DFFE_NP1P_'. -Generating RTLIL representation for module `\$_DFFE_PP0P_'. -Generating RTLIL representation for module `\$_DFFE_PP1P_'. -Generating RTLIL representation for module `\$_SDFF_NP0_'. -Generating RTLIL representation for module `\$_SDFF_NP1_'. -Generating RTLIL representation for module `\$_SDFF_PP0_'. -Generating RTLIL representation for module `\$_SDFF_PP1_'. -Generating RTLIL representation for module `\$_SDFFCE_NP0P_'. -Generating RTLIL representation for module `\$_SDFFCE_NP1P_'. -Generating RTLIL representation for module `\$_SDFFCE_PP0P_'. -Generating RTLIL representation for module `\$_SDFFCE_PP1P_'. -Successfully finished Verilog frontend. - -32.5.2. Continuing TECHMAP pass. -No more expansions possible. -<suppressed ~22 debug messages> -Removed 7 unused cells and 1055 unused wires. - -32.6. Executing OPT_LUT pass (optimize LUTs). -Discovering LUTs. -Number of LUTs: 58 - 1-LUT 3 - 2-LUT 8 - 3-LUT 35 - 4-LUT 12 - with \SB_CARRY (#0) 25 - with \SB_CARRY (#1) 26 - -Eliminating LUTs. -Number of LUTs: 58 - 1-LUT 3 - 2-LUT 8 - 3-LUT 35 - 4-LUT 12 - with \SB_CARRY (#0) 25 - with \SB_CARRY (#1) 26 - -Combining LUTs. -Number of LUTs: 58 - 1-LUT 3 - 2-LUT 8 - 3-LUT 35 - 4-LUT 12 - with \SB_CARRY (#0) 25 - with \SB_CARRY (#1) 26 - -Eliminated 0 LUTs. -Combined 0 LUTs. -<suppressed ~334 debug messages> - -33. Generating Graphviz representation of design. -Writing dot description to `rdata_map_luts.dot'. -Dumping selected parts of module fifo to page 1. - -34. Executing SYNTH_ICE40 pass. - -34.1. Executing TECHMAP pass (map to technology primitives). - -34.1.1. Executing Verilog-2005 frontend: /home/dawn/yosys/share/ice40/cells_map.v -Parsing Verilog input from `/home/dawn/yosys/share/ice40/cells_map.v' to AST representation. -Generating RTLIL representation for module `\$lut'. -Successfully finished Verilog frontend. - -34.1.2. Continuing TECHMAP pass. -Using template $paramod$fd904e9e35cfd343a9df248824bd3f1408724879\$lut for cells of type $lut. -Using template $paramod$e87f431398fe61dc3cef677df705fdf1c11aa0f7\$lut for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10111000 for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0100 for cells of type $lut. -Using template $paramod$2b29ccbd5fb8b9c557f92ddec1023c75686f32ae\$lut for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0010 for cells of type $lut. -Using template $paramod$ba7c22fadfbf9ee7abcb895a21403114111dd201\$lut for cells of type $lut. -Using template $paramod$5c7d886f3b88971ac55fed4bca034a87bf180f7d\$lut for cells of type $lut. -Using template $paramod$8d7a8d6e3356de09670738ba85f2c6b874f6b06d\$lut for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'10010000 for cells of type $lut. -Using template $paramod$571404c0889eaf57f492cb5e37f8acb5df5852f9\$lut for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'01001011 for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000011\LUT=8'11011000 for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000010\LUT=4'0110 for cells of type $lut. -Using template $paramod\$lut\WIDTH=32'00000000000000000000000000000001\LUT=2'01 for cells of type $lut. -No more expansions possible. -<suppressed ~256 debug messages> -Removed 0 unused cells and 129 unused wires. - -34.2. Executing AUTONAME pass. -Renamed 1278 objects in module fifo (21 iterations). -<suppressed ~214 debug messages> - -34.3. Executing HIERARCHY pass (managing design hierarchy). - -34.3.1. Analyzing design hierarchy.. -Top module: \fifo - -34.3.2. Analyzing design hierarchy.. -Top module: \fifo -Removed 0 unused modules. - -34.4. Printing statistics. - -=== fifo === - - Number of wires: 92 - Number of wire bits: 250 - Number of public wires: 92 - Number of public wire bits: 250 - Number of memories: 0 - Number of memory bits: 0 - Number of processes: 0 - Number of cells: 136 - SB_CARRY 26 - SB_DFF 26 - SB_DFFER 25 - SB_LUT4 58 - SB_RAM40_4K 1 - -34.5. Executing CHECK pass (checking for obvious problems). -Checking module fifo... -Found and reported 0 problems. - -35. Generating Graphviz representation of design. -Writing dot description to `rdata_map_cells.dot'. -Dumping selected parts of module fifo to page 1. diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index 3bfc0468a..66fdc4b19 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -18,7 +18,7 @@ select -set new_cells t:$mux t:*dff show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc # ======================================================== -opt_clean +clean show -notitle -format dot -prefix addr_gen_clean # ======================================================== @@ -26,12 +26,15 @@ design -reset read_verilog fifo.v hierarchy -check -top fifo proc -show -color maroon3 c:fifo_reader -notitle -format dot -prefix rdata_proc o:rdata %ci* +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;; -show -notitle -format dot -prefix rdata_flat o:rdata %ci* +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 # ======================================================== @@ -53,54 +56,7 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdat # ======================================================== -design -reset -read_verilog fifo.v -synth_ice40 -top fifo -run begin:map_ram +memory -nomap 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 - -# turn command echoes off to avoid randomly generated abc file names -echo off - -# ======================================================== - -synth_ice40 -top fifo -run map_ram:map_ffram -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path - -# ======================================================== - -synth_ice40 -top fifo -run map_ffram:map_gates -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path - -# ======================================================== - -synth_ice40 -top fifo -run map_gates:map_ffs -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path - -# ======================================================== - -synth_ice40 -top fifo -run map_ffs:map_luts -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path - -# ======================================================== - -synth_ice40 -top fifo -run map_luts:map_cells -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path - -# ======================================================== - -synth_ice40 -top fifo -run map_cells: -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @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 000000000..42403d1c0 --- /dev/null +++ b/docs/source/code_examples/fifo/fifo_map.ys @@ -0,0 +1,45 @@ +read_verilog fifo.v +synth_ice40 -top fifo -run begin:map_ram +# this point should be the same as rdata_coarse + +# ======================================================== + +synth_ice40 -top fifo -run map_ram:map_ffram +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_ffram:map_gates +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_gates:map_ffs +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_ffs:map_luts +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_luts:map_cells +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path + +# ======================================================== + +synth_ice40 -top fifo -run map_cells: +select -set new_cells t:SB_RAM40_4K +select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% +show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @rdata_path diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 7fd48eb0c..2a7ff597f 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -149,25 +149,29 @@ each of these in more detail in :doc:`/using_yosys/synthesis/proc`. :doc:`/cmd/opt_expr` - by default called at the end of :cmd:ref:`proc` + - can be disabled with ``-noopt`` + - done here for... reasons? 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:`opt_clean`: +:cmd:ref:`clean`: .. figure:: /_images/code_examples/fifo/addr_gen_clean.* :class: width-helper :name: addr_gen_clean - ``addr_gen`` module after :cmd:ref:`opt_clean` + ``addr_gen`` module after :cmd:ref:`clean` -.. TODO:: more on opt_clean - :doc:`/cmd/opt_clean` +.. note:: - - :cmd:ref:`clean` for short, ``;;`` for even shorter - - final command of :cmd:ref:`opt` - - can run at any time + :doc:`/cmd/clean` can also be called with two semicolons after any command, + for example we could have called :yoscrypt:`proc;;` instead of + :yoscrypt:`proc` and then :yoscrypt:`clean`. It is generally beneficial to + run :cmd:ref:`clean` after each command as a quick way of removing + disconnected parts of the circuit which have been left over. You may notice + some scripts will end each line with ``;;``. .. todo:: consider a brief glossary for terms like adff @@ -231,11 +235,15 @@ command only works with a single module, so you may need to call it with 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`` set to the given -value. +``$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. -.. TODO:: comment on ``$memrd`` +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` @@ -261,7 +269,7 @@ optimizations between modules which would otherwise be missed. Let's run .. literalinclude:: /code_examples/fifo/fifo.out :language: doscon :start-at: yosys> flatten - :end-before: yosys> show + :end-before: yosys> select :name: flat_clean :caption: output of :yoscrypt:`flatten;;` @@ -271,16 +279,24 @@ optimizations between modules which would otherwise be missed. Let's run ``rdata`` output after :yoscrypt:`flatten;;` -We can now see both :ref:`rdata_proc` and :ref:`addr_gen_proc` together. Note -that in the :ref:`flat_clean` we see above has two separate calls: one to -:cmd:ref:`flatten` and one to :cmd:ref:`clean`. In an interactive terminal the -output of both commands will be combined into the single `yosys> flatten;;` -output. +.. role:: yoterm(code) + :language: doscon -Depending on the target architecture, we 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. +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 ``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 that in an interactive terminal the outputs of +:cmd:ref:`flatten` and :cmd:ref:`clean` will be combined into a single +:yoterm:`yosys> flatten;;` 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -314,18 +330,18 @@ In the iCE40 flow, we start with the following commands: :caption: ``coarse`` section (part 1) :name: synth_coarse1 -The first few commands are relatively straightforward, and we've already come -across :cmd:ref:`opt_clean` and :cmd:ref:`opt_expr`. 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 +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/fsm` and -:doc:`/using_yosys/synthesis/opt` respectively. +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. @@ -384,7 +400,10 @@ Our next command to run is ``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). +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 From 3e653fe4a64955fe8e498533373175e0c3b88edd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 4 Jan 2024 12:49:48 +1300 Subject: [PATCH 064/108] docs: more on wreduce in synth starter --- docs/source/code_examples/fifo/fifo.out | 77 +++++++++++++------ docs/source/code_examples/fifo/fifo.ys | 13 ++++ docs/source/getting_started/example_synth.rst | 35 +++++++-- 3 files changed, 97 insertions(+), 28 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index f0bd76f3f..47b867da1 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -301,9 +301,42 @@ yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o Writing dot description to `rdata_adffe.dot'. Dumping selected parts of module fifo to page 1. +yosys> wreduce + +16. Executing WREDUCE pass (reducing word size of cells). +Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$27 ($add). +Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$27 ($add). +Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$30 ($sub). +Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:70$30 ($sub). +Removed top 1 bits (of 2) from port B of cell fifo.$auto$opt_dff.cc:195:make_patterns_logic$64 ($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:20$34 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$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:20$34 ($add). +Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$34 ($add). +Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$27_Y. +Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_reader.$add$fifo.v:20$34_Y. +Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_writer.$add$fifo.v:20$34_Y. + +yosys> select -set new_cells t:$add %co t:$add %d + +yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_wreduce o:rdata %ci* + +17. Generating Graphviz representation of design. +Writing dot description to `rdata_wreduce.dot'. +Dumping selected parts of module fifo to page 1. + +yosys> opt_clean + +18. Executing OPT_CLEAN pass (remove unused cells and wires). +Finding unused cells or wires in module \fifo.. +Removed 0 unused cells and 5 unused wires. +<suppressed ~1 debug messages> + yosys> memory_dff -16. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +19. 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. @@ -311,13 +344,13 @@ yosys> select -set new_cells t:$memrd_v2 yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdata %ci* -17. Generating Graphviz representation of design. +20. Generating Graphviz representation of design. Writing dot description to `rdata_memrdv2.dot'. Dumping selected parts of module fifo to page 1. yosys> alumacc -18. Executing ALUMACC pass (create $alu and $macc cells). +21. Executing ALUMACC pass (create $alu and $macc cells). Extracting $alu and $macc cells in module fifo: creating $macc model for $add$fifo.v:68$27 ($add). creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$34 ($add). @@ -327,70 +360,70 @@ Extracting $alu and $macc cells in module fifo: creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$34. creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$34. creating $alu model for $macc $add$fifo.v:68$27. - creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$76 - creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$79 - creating $alu cell for $add$fifo.v:68$27: $auto$alumacc.cc:485:replace_alu$82 - creating $alu cell for $sub$fifo.v:70$30: $auto$alumacc.cc:485:replace_alu$85 + creating $alu cell for $add$fifo.v:68$27: $auto$alumacc.cc:485:replace_alu$79 + creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$82 + creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$85 + creating $alu cell for $sub$fifo.v:70$30: $auto$alumacc.cc:485:replace_alu$88 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* -19. Generating Graphviz representation of design. +22. Generating Graphviz representation of design. Writing dot description to `rdata_alumacc.dot'. Dumping selected parts of module fifo to page 1. yosys> memory -nomap -20. Executing MEMORY pass. +23. Executing MEMORY pass. yosys> opt_mem -20.1. Executing OPT_MEM pass (optimize memories). +23.1. Executing OPT_MEM pass (optimize memories). Performed a total of 0 transformations. yosys> opt_mem_priority -20.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). +23.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). Performed a total of 0 transformations. yosys> opt_mem_feedback -20.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). +23.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). yosys> memory_bmux2rom -20.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). +23.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). yosys> memory_dff -20.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +23.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). yosys> opt_clean -20.6. Executing OPT_CLEAN pass (remove unused cells and wires). +23.6. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -Removed 3 unused cells and 11 unused wires. -<suppressed ~4 debug messages> +Removed 1 unused cells and 9 unused wires. +<suppressed ~2 debug messages> yosys> memory_share -20.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). +23.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). yosys> opt_mem_widen -20.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). +23.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). Performed a total of 0 transformations. yosys> opt_clean -20.9. Executing OPT_CLEAN pass (remove unused cells and wires). +23.9. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. yosys> memory_collect -20.10. Executing MEMORY_COLLECT pass (generating $mem cells). +23.10. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> select -set new_cells t:$mem_v2 @@ -398,6 +431,6 @@ yosys> select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @n yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path -21. Generating Graphviz representation of design. +24. 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.ys b/docs/source/code_examples/fifo/fifo.ys index 66fdc4b19..d181ca1fe 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -44,6 +44,15 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata # ======================================================== +wreduce +select -set new_cells t:$add %co t:$add %d +show -color maroon3 @new_cells -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* @@ -57,6 +66,10 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdat # ======================================================== memory -nomap +# 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/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 2a7ff597f..0aecc4493 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -369,6 +369,8 @@ options is able to fold one of the ``$mux`` cells into the ``$adff`` to form an Part 2 ^^^^^^ +The next group of commands performs a series of optimizations: + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-at: wreduce @@ -377,12 +379,33 @@ Part 2 :caption: ``coarse`` section (part 2) :name: synth_coarse2 -The next three (new) commands are :doc:`/cmd/wreduce`, :doc:`/cmd/peepopt`, and -:doc:`/cmd/share`. None of these affect our design either, 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`. +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`. From e6f8804e6a6eb852c13efd11fb3e5aab9cd40ae7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:24:52 +1300 Subject: [PATCH 065/108] example_synth: more on DSP mapping --- docs/source/getting_started/example_synth.rst | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 0aecc4493..eb4f099d6 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -438,7 +438,11 @@ Part 3 ^^^^^^ The third part of the :cmd:ref:`synth_ice40` flow is a series of commands for -mapping to DSPs. +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 @@ -448,7 +452,28 @@ mapping to DSPs. :caption: ``coarse`` section (part 3) :name: synth_coarse3 -.. TODO:: more on DSP mapping +: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. + +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` From eb5da87d526575daed900905023aa755004697d9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:59:03 +1300 Subject: [PATCH 066/108] example_synth: hardware mapping Filling out the hardware mapping sections, and actually highlighting the changes in schematics instead of just the memory block. Also includes Part 4 of the coarse-grain rep, looking at `memory_collect` and putting the `synth_ice40 -top fifo -run :map_ram` command in its own (sub)section. Includes a `no_rw_check` section label in `memory.rst` for reference (because I can't remember how to reference by heading). Not sure about the opt output after map_ram section which has an open TODO, and the final steps section is also still open. --- docs/source/code_examples/fifo/fifo.out | 49 +--------- docs/source/code_examples/fifo/fifo.ys | 2 +- docs/source/code_examples/fifo/fifo_map.ys | 38 ++++---- docs/source/getting_started/example_synth.rst | 91 +++++++++++++------ docs/source/using_yosys/synthesis/memory.rst | 2 + 5 files changed, 88 insertions(+), 94 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index 47b867da1..a1a7c08f2 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -374,56 +374,9 @@ yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc Writing dot description to `rdata_alumacc.dot'. Dumping selected parts of module fifo to page 1. -yosys> memory -nomap - -23. Executing MEMORY pass. - -yosys> opt_mem - -23.1. Executing OPT_MEM pass (optimize memories). -Performed a total of 0 transformations. - -yosys> opt_mem_priority - -23.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). -Performed a total of 0 transformations. - -yosys> opt_mem_feedback - -23.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). - -yosys> memory_bmux2rom - -23.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). - -yosys> memory_dff - -23.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). - -yosys> opt_clean - -23.6. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 1 unused cells and 9 unused wires. -<suppressed ~2 debug messages> - -yosys> memory_share - -23.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). - -yosys> opt_mem_widen - -23.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). -Performed a total of 0 transformations. - -yosys> opt_clean - -23.9. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - yosys> memory_collect -23.10. Executing MEMORY_COLLECT pass (generating $mem cells). +23. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> select -set new_cells t:$mem_v2 diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index d181ca1fe..497481166 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -65,7 +65,7 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdat # ======================================================== -memory -nomap +memory_collect # or use the following commands: # design -reset # read_verilog fifo.v diff --git a/docs/source/code_examples/fifo/fifo_map.ys b/docs/source/code_examples/fifo/fifo_map.ys index 42403d1c0..00c1f08ad 100644 --- a/docs/source/code_examples/fifo/fifo_map.ys +++ b/docs/source/code_examples/fifo/fifo_map.ys @@ -5,41 +5,43 @@ synth_ice40 -top fifo -run begin:map_ram # ======================================================== synth_ice40 -top fifo -run map_ram:map_ffram -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path +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 maroon3 @mem -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ram @rdata_path # ======================================================== synth_ice40 -top fifo -run map_ffram:map_gates -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path +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 new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path +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 new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path +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 new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path +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 new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @rdata_path +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 diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index eb4f099d6..82c6bdf0e 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -508,20 +508,39 @@ see produce the following changes in our example design: ``rdata`` output after :cmd:ref:`alumacc` -.. TODO:: discuss :cmd:ref:`memory_collect` and ``$mem_v2`` +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 :yoscrypt:`memory -nomap` + ``rdata`` output after :cmd:ref:`memory_collect` -We could also have gotten here by running :yoscrypt:`synth_ice40 -top fifo -run -begin:map_ram` after loading the design. +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/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 <from_label>:<to_label>` option +with an empty ``<from_label>`` starts from the :ref:`synth_begin`, while the +``<to_label>`` runs up to but including the :ref:`map_ram`. + Hardware mapping ~~~~~~~~~~~~~~~~ @@ -535,8 +554,6 @@ Memory blocks Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, :cmd:ref:`memory_map`, and :cmd:ref:`techmap`. -.. TODO:: ``$mem_v2`` -> ``SB_RAM40_4K`` - .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_ram: @@ -551,6 +568,16 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, ``rdata`` output after :ref:`map_ram` +: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. + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_ffram: @@ -565,6 +592,8 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, ``rdata`` output after :ref:`map_ffram` +.. TODO:: what even is this opt output + .. seealso:: Advanced usage docs for - :doc:`/using_yosys/synthesis/techmap_synth` @@ -573,9 +602,11 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, Arithmetic ^^^^^^^^^^ -Uses :cmd:ref:`techmap`. - -.. TODO:: example_synth/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 @@ -598,9 +629,13 @@ Flip-flops ^^^^^^^^^^ Convert FFs to the types supported in hardware with :cmd:ref:`dfflegalize`, and -then use :cmd:ref:`techmap` to map them. We also run :cmd:ref:`simplemap` here -to convert any remaining cells which could not be mapped to hardware into -gate-level primitives. +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 @@ -622,9 +657,10 @@ gate-level primitives. LUTs ^^^^ -:cmd:ref:`abc` and :cmd:ref:`techmap` are used to map LUTs. Note that the iCE40 -flow uses :cmd:ref:`abc` rather than :cmd:ref:`abc9`. For more on what these -do, and what the difference between these two commands are, refer to +: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 @@ -641,15 +677,8 @@ do, and what the difference between these two commands are, refer to ``rdata`` output after :ref:`map_luts` -.. seealso:: Advanced usage docs for - - - :doc:`/using_yosys/synthesis/techmap_synth` - - :doc:`/using_yosys/synthesis/abc` - -Other cells -^^^^^^^^^^^ - -Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. +Finally we use :cmd:ref:`techmap` to map the generic ``$lut`` cells to iCE40 +``SB_LUT4`` cells. .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -665,7 +694,15 @@ Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. ``rdata`` output after :ref:`map_cells` -.. TODO:: example_synth other 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 @@ -676,8 +713,8 @@ Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. Top-level input/outputs must usually be implemented using special I/O-pad cells. This command inserts such cells to the design. -.. seealso:: Advanced usage docs for - :doc:`/yosys_internals/techmap` +These commands tend to either be in the :ref:`map_cells` or after the +:ref:`check` depending on the flow. Final steps ~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 499f73d5a..71da211d5 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -253,6 +253,8 @@ Synchronous SDP read first read_data <= mem[read_addr]; end +.. _no_rw_check: + Synchronous SDP with undefined collision behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 064723a1cc056e8a1039ddfb00881004254180ff Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:46:00 +1300 Subject: [PATCH 067/108] example_synth: tidying Adds note on `+/`. Clarifies that we can't entirely skip loading `cells_sim.v`, and then mentions it again later once we need it. More on final steps (and synthesis outputs). --- docs/source/getting_started/example_synth.rst | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 82c6bdf0e..256bf7bba 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -75,15 +75,23 @@ Let's start with the section labeled ``begin``: 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 safely -skip this command. +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. 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. +-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 @@ -548,6 +556,9 @@ 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 ^^^^^^^^^^^^^ @@ -719,7 +730,8 @@ These commands tend to either be in the :ref:`map_cells` or after the Final steps ~~~~~~~~~~~~ -.. TODO:: example_synth final steps (check section and outputting) +The next section of the iCE40 synth flow performs some sanity checking and final +tidy up: .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -729,6 +741,28 @@ Final steps :name: check :caption: ``check`` section -- :doc:`/cmd/check` -- :doc:`/cmd/autoname` -- :doc:`/cmd/stat` +The new commands here are: + +- :doc:`/cmd/autoname`, +- :doc:`/cmd/stat`, and +- :doc:`/cmd/blackbox`. + +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 ``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` From a3255fd8d31f44b4000a35d5a9b9d895c1620950 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Jan 2024 16:57:10 +1300 Subject: [PATCH 068/108] Docs: opt_rmunused -> opt_clean --- docs/source/yosys_internals/formats/rtlil_rep.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index ce373ce6c..5de3430f2 100644 --- a/docs/source/yosys_internals/formats/rtlil_rep.rst +++ b/docs/source/yosys_internals/formats/rtlil_rep.rst @@ -74,13 +74,13 @@ This has three advantages: - First, it is impossible that an auto-generated identifier collides with an identifier that was provided by the user. -.. TODO:: ``opt_clean`` (or clean), also ``-purge`` - - 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 + 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. + 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 From 12fa443fe36514329a87ae3cb394a4ab1ec1d578 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:46:04 +1300 Subject: [PATCH 069/108] example_synth: more on hierarchy and stat --- docs/source/code_examples/fifo/fifo.stat | 56 +++++++++++++++++++ docs/source/code_examples/fifo/fifo_map.ys | 7 +++ docs/source/getting_started/example_synth.rst | 43 ++++++++++++-- 3 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 docs/source/code_examples/fifo/fifo.stat diff --git a/docs/source/code_examples/fifo/fifo.stat b/docs/source/code_examples/fifo/fifo.stat new file mode 100644 index 000000000..b3a3d926f --- /dev/null +++ b/docs/source/code_examples/fifo/fifo.stat @@ -0,0 +1,56 @@ + +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 + +16. Printing statistics. + +=== fifo === + + Number of wires: 97 + Number of wire bits: 268 + Number of public wires: 97 + Number of public wire bits: 268 + Number of memories: 0 + Number of memory bits: 0 + Number of processes: 0 + Number of cells: 138 + SB_CARRY 26 + SB_DFF 26 + SB_DFFER 25 + SB_LUT4 60 + SB_RAM40_4K 1 + diff --git a/docs/source/code_examples/fifo/fifo_map.ys b/docs/source/code_examples/fifo/fifo_map.ys index 00c1f08ad..701de3c35 100644 --- a/docs/source/code_examples/fifo/fifo_map.ys +++ b/docs/source/code_examples/fifo/fifo_map.ys @@ -1,4 +1,7 @@ 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 @@ -45,3 +48,7 @@ show -color maroon3 t:SB_CARRY -color cornflowerblue t:$lut -notitle -format dot 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/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 256bf7bba..9664b04f3 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -104,7 +104,9 @@ Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy .. note:: :cmd:ref:`hierarchy` should always be the first command after the design has - been read. + 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. @@ -215,7 +217,7 @@ 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:: more on why :cmd:ref:`hierarchy` is important +.. todo:: :cmd:ref:`hierarchy` failure modes .. note:: @@ -747,6 +749,39 @@ The new commands here are: - :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 ^^^^^^^^^^^^^^^^ @@ -757,8 +792,8 @@ The iCE40 synthesis flow has the following output modes available: - :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 ``fifo.json``. We can then read -the design back into Yosys with :cmd:ref:`read_json`, but make sure you use +our synthesized ``fifo`` design will be output as ``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. From 3360c612d55e026b748d7af316b797752b860a31 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:46:19 +1300 Subject: [PATCH 070/108] Docs: remove hanging reference --- docs/source/using_yosys/yosys_flows.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 22f964a02..040ef5a4c 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -280,9 +280,7 @@ Checking techmap .. todo:: add/expand supporting text -.. TODO:: reference no longer exists - -Remember the following example from :doc:`/getting_started/typical_phases`? +Let's look at the following example: .. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog @@ -296,7 +294,9 @@ Remember the following example from :doc:`/getting_started/typical_phases`? :language: yoscrypt :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` -Lets see if it is correct.. +To see if it is correct we can use the following code: + +.. todo:: replace inline yosys script code .. code:: yoscrypt From 9eab5d8b242bdfc5a764c9e6e9f232446b6e0e90 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:27:38 +1300 Subject: [PATCH 071/108] Updated Yosys family --- docs/source/introduction.rst | 41 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 292c6ceec..fcb54542d 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -75,28 +75,41 @@ The Yosys family ---------------- As mentioned above, `YosysHQ`_ maintains not just Yosys but an entire family of -tools built around it. +tools built around it. In no particular order: .. _YosysHQ: https://github.com/YosysHQ -.. TODO:: Yosys family descriptions +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`_ -In no particular order: +.. _SBY source: https://github.com/YosysHQ/sby +.. _SBY docs: https://yosyshq.readthedocs.io/projects/sby -- SBY for formal verification - - https://github.com/YosysHQ/sby - - 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 for equivalence checking - - https://github.com/YosysHQ/eqy - - https://yosyshq.readthedocs.io/projects/eqy +.. _EQY source: https://github.com/YosysHQ/eqy +.. _EQY docs: https://yosyshq.readthedocs.io/projects/eqy -- MCY for mutation coverage - - https://github.com/YosysHQ/mcy - - https://yosyshq.readthedocs.io/projects/mcy +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`_ -- SCY for deep formal traces - - https://github.com/YosysHQ/scy +.. _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 ---------------------------- From 9fe3dcda780ad60ea46106eb2fd9706f87a3fc35 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:15:11 +1300 Subject: [PATCH 072/108] Docs: optimization passes Working on `opt.rst`. Replace the hardcoded `opt` psuedo code listing with a `literalinclude` from `/cmd/opt.rst`. Reorder and update `opt_*` list to match current `opt`. Expand sub-section titles with the function of the pass (keeping the `:cmd:ref:` part at the end to prevent the Esbonio error in vscode when a heading starts with a directive). Move comments about `clean` and `;;` being aliases into final `opt` subsection. Also renames `Test suites` -> `Testing Yosys`. --- docs/source/test_suites.rst | 4 +- docs/source/using_yosys/synthesis/opt.rst | 112 +++++++++++----------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index b37263144..3e016400e 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -1,5 +1,5 @@ -Test suites -=========== +Testing Yosys +============= .. todo:: more about the included test suite diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index 407308a29..d60e17a48 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -1,43 +1,28 @@ Optimization passes =================== -.. todo:: check text context, also check the optimization passes still do what they say - Yosys employs a number of optimizations to generate better and cleaner results. This chapter outlines these optimizations. -The :cmd:ref:`opt` pass --------------------------- +.. 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. At the time of -this writing the :cmd:ref:`opt` pass executes the following passes that each -perform a simple optimization: +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: -.. code-block:: yoscrypt +.. literalinclude:: /cmd/opt.rst + :language: yoscrypt + :start-after: following order: + :end-at: while <changed design> + :dedent: + :caption: Passes called by :cmd:ref:`opt` - 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] - -The command :cmd:ref:`clean` can be used as alias for :cmd:ref:`opt_clean`. And -``;;`` can be used as shortcut for :cmd:ref:`clean`. For example: - -.. code-block:: yoscrypt - - hierarchy; proc; opt; memory; opt_expr;; fsm;; - -The :cmd:ref:`opt_expr` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Const folding and simple expression rewriting - :cmd:ref:`opt_expr` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This pass performs const folding on the internal combinational cell types described in :doc:`/yosys_internals/formats/cell_library`. This means a cell @@ -90,8 +75,20 @@ 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. -The :cmd:ref:`opt_muxtree` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Merging identical cells - :cmd:ref:`opt_merge` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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 :cmd:ref:`opt_muxtree` to identify +possible optimizations. + +Removing never-active branches from multiplexer tree - :cmd:ref:`opt_muxtree` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This pass optimizes trees of multiplexer cells by analyzing the select inputs. Consider the following simple example: @@ -108,8 +105,8 @@ multiplexer and 0 for the inner multiplexer. The :cmd:ref:`opt_muxtree` pass detects this contradiction and replaces the inner multiplexer with a constant 1, yielding the logic for ``y = a ? 1 : 3``. -The :cmd:ref:`opt_reduce` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Simplifying large MUXes and AND/OR gates - :cmd:ref:`opt_reduce` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 @@ -126,38 +123,36 @@ Lastly this pass consolidates trees of ``$reduce_and`` cells and trees of These three simple optimizations are performed in a loop until a stable result is produced. -The ``opt_rmdff`` pass -~~~~~~~~~~~~~~~~~~~~~~ +Merging mutually exclusive cells with shared inputs - :cmd:ref:`opt_share` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. TODO:: Update to ``opt_dff`` +.. TODO:: ``opt_share`` + +Performing DFF optimizations - :cmd:ref:`opt_dff` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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. +driver. It can also merge clock enables and synchronous reset multiplexers, +removing unused control inputs. -The :cmd:ref:`opt_clean` pass -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Called with ``-nodffe`` and ``-nosdff``, this pass is used to prepare a design +for :doc:`/using_yosys/synthesis/fsm`. + +Removing unused cells and wires - :cmd:ref:`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 :cmd:ref:`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 :cmd:ref:`opt_muxtree` to identify -possible optimizations. - Example ~~~~~~~ .. todo:: describe ``opt`` images + + and/or replace with an example image showing before/after of each ``opt_*`` + command .. figure:: /_images/code_examples/synth_flow/opt_01.* :class: width-helper @@ -214,11 +209,16 @@ It is generally a good idea to call :cmd:ref:`opt` before inherently expensive commands such as :cmd:ref:`sat` or :cmd:ref:`freduce`, as the possible gain is much higher in these cases as the possible loss. -The :cmd:ref:`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 -``;;`` is a good idea in every synthesis script. +The :cmd:ref:`clean` command, which is an alias for :cmd:ref:`opt_clean` with +fewer outputs, 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 ``;;``, which itself is +an alias for :cmd:ref:`clean`, is a good idea in every synthesis script, e.g: + +.. code-block:: yoscrypt + + hierarchy; proc; opt; memory; opt_expr;; fsm;; Other optimizations ------------------- From 646ff6d32dd15f01e45f5a778b8cc2fc45b588b3 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:32:14 +1300 Subject: [PATCH 073/108] Docs: interactive investigation More `literalinclude` and references to source. Adding `example_show.ys` and `example_lscd.ys`. Rename `example_00` et al to `example_first` et al. Also some other minor tidying. --- docs/source/code_examples/show/Makefile | 7 +- docs/source/code_examples/show/example.out | 54 +++++++++ docs/source/code_examples/show/example.ys | 6 +- .../source/code_examples/show/example_lscd.ys | 8 ++ .../source/code_examples/show/example_show.ys | 6 + .../interactive_investigation.rst | 105 +++++++----------- .../using_yosys/more_scripting/selections.rst | 8 +- 7 files changed, 122 insertions(+), 72 deletions(-) create mode 100644 docs/source/code_examples/show/example.out create mode 100644 docs/source/code_examples/show/example_lscd.ys create mode 100644 docs/source/code_examples/show/example_show.ys diff --git a/docs/source/code_examples/show/Makefile b/docs/source/code_examples/show/Makefile index c57012f92..c254ed255 100644 --- a/docs/source/code_examples/show/Makefile +++ b/docs/source/code_examples/show/Makefile @@ -2,13 +2,13 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -EXAMPLE = example_00 example_01 example_02 +EXAMPLE = example_first example_second example_third EXAMPLE_DOTS := $(addsuffix .dot,$(EXAMPLE)) CMOS = cmos_00 cmos_01 CMOS_DOTS := $(addsuffix .dot,$(CMOS)) -dots: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) +dots: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) example.out splice.dot: splice.v $(YOSYS) -p 'prep -top splice_demo; show -format dot -prefix splice' splice.v @@ -16,6 +16,9 @@ splice.dot: splice.v $(EXAMPLE_DOTS): example.v example.ys $(YOSYS) example.ys +example.out: example_lscd.ys example.v + $(YOSYS) $< -l $@ -Q -T + $(CMOS_DOTS): cmos.v cmos.ys $(YOSYS) cmos.ys diff --git a/docs/source/code_examples/show/example.out b/docs/source/code_examples/show/example.out new file mode 100644 index 000000000..b8569e640 --- /dev/null +++ b/docs/source/code_examples/show/example.out @@ -0,0 +1,54 @@ + +-- Executing script file `example_lscd.ys' -- + +1. Executing Verilog-2005 frontend: example.v +Parsing Verilog input from `example.v' to AST representation. +Generating RTLIL representation for module `\example'. +Successfully finished Verilog frontend. +echo on + +yosys> 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/code_examples/show/example.ys b/docs/source/code_examples/show/example.ys index 6c9ff7983..a5332f134 100644 --- a/docs/source/code_examples/show/example.ys +++ b/docs/source/code_examples/show/example.ys @@ -1,6 +1,6 @@ read_verilog example.v -show -format dot -prefix example_00 +show -format dot -prefix example_first proc -show -format dot -prefix example_01 +show -format dot -prefix example_second opt -show -format dot -prefix example_02 +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 000000000..de2484228 --- /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 000000000..711af84d9 --- /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/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index baa4b7e03..a5e91a5a1 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -15,12 +15,16 @@ in the circuit diagrams generated by it. A simple circuit ^^^^^^^^^^^^^^^^ -:numref:`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. +: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. The +code used is included in the Yosys code base under +`docs/source/code_examples/show`_. + +.. _docs/source/code_examples/show: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/show .. literalinclude:: /code_examples/show/example.v :language: Verilog - :caption: ``docs/source/code_examples/show/example.v`` + :caption: ``example.v`` :name: example_v The Yosys synthesis script we will be running is included as @@ -30,22 +34,24 @@ Enter key. Using :yoscrypt:`show -pause` also allows the user to enter an interactive shell to further investigate the circuit before continuing synthesis. -.. code-block:: yoscrypt - :caption: ``docs/source/code_examples/show/example.ys`` +.. literalinclude:: /code_examples/show/example_show.ys + :language: yoscrypt + :caption: ``example_show.ys`` :name: example_ys - - read_verilog example.v - show -pause # first - proc - show -pause # second - opt - show -pause # third 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. -.. figure:: /_images/code_examples/show/example_00.* +.. note:: + + The images uses in this document are generated from the ``example.ys`` file, + rather than ``example_show.ys``. ``example.ys`` outputs the schematics as + ``.dot`` files rather than displaying them directly. You can view these + images yourself by running ``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` @@ -59,7 +65,7 @@ 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 -``<bit_width>'<bits>`` is used for for constants that are not 32-bit wide and/or +``<bit_width>'<bits>`` 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. @@ -77,7 +83,7 @@ original ``always``-block in the second line. Note how the multiplexer from the 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_01.* +.. figure:: /_images/code_examples/show/example_second.* :class: width-helper Output of the second :cmd:ref:`show` command in :numref:`example_ys` @@ -99,11 +105,11 @@ 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_02.* +.. figure:: /_images/code_examples/show/example_third.* :class: width-helper :name: example_out - Output of the third :cmd:ref:`show` command in :numref:`example_ys` + 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 @@ -256,39 +262,16 @@ 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 `ls` command lists the objects within that module. -:numref:`lscd` below demonstrates this using the ``example.v`` from -`A simple circuit`_ +switch back). Now the :cmd:ref:`ls` command lists the objects within that +module. This is demonstrated below using ``example.v`` from `A simple circuit`_: -.. TODO:: update yosys output with $ternary$example.v$3 - -.. code-block:: none - :caption: Demonstration of :cmd:ref:`ls` and :cmd:ref:`cd` having run ``yosys example.v`` +.. 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 ``yosys example.v`` :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 - 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 @@ -308,25 +291,21 @@ Usually all interactive work is done with one module selected using the 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 ``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. +object. For example, calling :yoscrypt:`dump $2` after the :yoscrypt:`cd +example` above: -.. code-block:: RTLIL - :caption: Output of ``dump $2`` using ``example.v`` from `A simple circuit`_ +.. 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 - 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 +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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 0db716ccc..2bc6540b8 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -141,10 +141,10 @@ See :doc:`/cmd/select` for the full list. Expanding selections ^^^^^^^^^^^^^^^^^^^^ -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.) +: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 From 5a4c2e5c79715375dab622bb221bd63467951818 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:23:04 +1300 Subject: [PATCH 074/108] example_synth: proc and opt_expr Highlight `proc` blocks and intro `opt_expr`. --- docs/source/code_examples/fifo/fifo.out | 97 ++++++++++--------- docs/source/code_examples/fifo/fifo.ys | 9 +- docs/source/getting_started/example_synth.rst | 39 +++++--- 3 files changed, 82 insertions(+), 63 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index a1a7c08f2..30236a7ab 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -29,13 +29,13 @@ Removed 2 unused modules. yosys> select -set new_cells t:* -yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_hier +yosys> show -color maroon3 @new_cells -color cornflowerblue p:* -notitle -format dot -prefix addr_gen_hier 4. Generating Graphviz representation of design. Writing dot description to `addr_gen_hier.dot'. Dumping module addr_gen to page 1. -yosys> proc +yosys> proc -noopt 5. Executing PROC pass (convert processes to netlists). @@ -102,11 +102,6 @@ Found and cleaned up 2 empty switches in `\addr_gen.$proc$fifo.v:13$1'. Removing empty process `addr_gen.$proc$fifo.v:13$1'. Cleaned up 2 empty switches. -yosys> opt_expr -keepdc - -5.12. Executing OPT_EXPR pass (perform const folding). -Optimizing module addr_gen. - yosys> select -set new_cells t:$mux t:*dff yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc @@ -115,12 +110,19 @@ yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc Writing dot description to `addr_gen_proc.dot'. Dumping module addr_gen to page 1. +yosys> opt_expr + +7. Executing OPT_EXPR pass (perform const folding). +Optimizing module addr_gen. + yosys> clean Removed 0 unused cells and 4 unused wires. -yosys> show -notitle -format dot -prefix addr_gen_clean +yosys> select -set new_cells t:$eq -7. Generating Graphviz representation of design. +yosys> show -color cornflowerblue @new_cells -notitle -format dot -prefix addr_gen_clean + +8. Generating Graphviz representation of design. Writing dot description to `addr_gen_clean.dot'. Dumping module addr_gen to page 1. @@ -128,7 +130,7 @@ yosys> design -reset yosys> read_verilog fifo.v -8. Executing Verilog-2005 frontend: fifo.v +9. 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'. @@ -136,24 +138,24 @@ Successfully finished Verilog frontend. yosys> hierarchy -check -top fifo -9. Executing HIERARCHY pass (managing design hierarchy). +10. Executing HIERARCHY pass (managing design hierarchy). -9.1. Analyzing design hierarchy.. +10.1. Analyzing design hierarchy.. Top module: \fifo Used module: \addr_gen Parameter \MAX_DATA = 256 -9.2. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +10.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'. -9.3. Analyzing design hierarchy.. +10.3. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 -9.4. Analyzing design hierarchy.. +10.4. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 Removing unused module `\addr_gen'. @@ -161,16 +163,16 @@ Removed 1 unused modules. yosys> proc -10. Executing PROC pass (convert processes to netlists). +11. Executing PROC pass (convert processes to netlists). yosys> proc_clean -10.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +11.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. yosys> proc_rmdead -10.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +11.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Marked 2 switch rules as full_case in process $proc$fifo.v:64$24 in module fifo. Marked 1 switch rules as full_case in process $proc$fifo.v:38$16 in module fifo. Marked 2 switch rules as full_case in process $proc$fifo.v:13$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. @@ -178,13 +180,13 @@ Removed a total of 0 dead cases. yosys> proc_prune -10.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +11.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 6 assignments to connections. yosys> proc_init -10.4. Executing PROC_INIT pass (extract init attributes). +11.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'. @@ -192,19 +194,19 @@ Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000 yosys> proc_arst -10.5. Executing PROC_ARST pass (detect async resets in processes). +11.5. Executing PROC_ARST pass (detect async resets in processes). Found async reset \rst in `\fifo.$proc$fifo.v:64$24'. Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. yosys> proc_rom -10.6. Executing PROC_ROM pass (convert switches to ROMs). +11.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. <suppressed ~5 debug messages> yosys> proc_mux -10.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +11.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:64$24'. 1/1: $0\count[8:0] @@ -218,11 +220,11 @@ Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'000000000000000000 yosys> proc_dlatch -10.8. Executing PROC_DLATCH pass (convert process syncs to latches). +11.8. Executing PROC_DLATCH pass (convert process syncs to latches). yosys> proc_dff -10.9. Executing PROC_DFF pass (convert process syncs to FFs). +11.9. Executing PROC_DFF pass (convert process syncs to FFs). Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$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:38$16'. @@ -238,11 +240,11 @@ Creating register for signal `$paramod\addr_gen\MAX_DATA=s32'0000000000000000000 yosys> proc_memwr -10.10. Executing PROC_MEMWR pass (convert process memory writes to cells). +11.10. Executing PROC_MEMWR pass (convert process memory writes to cells). yosys> proc_clean -10.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +11.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:64$24'. Removing empty process `fifo.$proc$fifo.v:64$24'. @@ -255,7 +257,7 @@ Cleaned up 5 empty switches. yosys> opt_expr -keepdc -10.12. Executing OPT_EXPR pass (perform const folding). +11.12. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. @@ -263,13 +265,13 @@ 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* -11. Generating Graphviz representation of design. +12. Generating Graphviz representation of design. Writing dot description to `rdata_proc.dot'. Dumping selected parts of module fifo to page 1. yosys> flatten -12. Executing FLATTEN pass (flatten design). +13. Executing FLATTEN pass (flatten design). Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. <suppressed ~2 debug messages> @@ -282,13 +284,13 @@ 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 -13. Generating Graphviz representation of design. +14. Generating Graphviz representation of design. Writing dot description to `rdata_flat.dot'. Dumping selected parts of module fifo to page 1. yosys> opt_dff -14. Executing OPT_DFF pass (perform DFF optimizations). +15. 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). @@ -297,13 +299,13 @@ yosys> select -set new_cells t:$adffe yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* -15. Generating Graphviz representation of design. +16. Generating Graphviz representation of design. Writing dot description to `rdata_adffe.dot'. Dumping selected parts of module fifo to page 1. yosys> wreduce -16. Executing WREDUCE pass (reducing word size of cells). +17. Executing WREDUCE pass (reducing word size of cells). Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$27 ($add). Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$27 ($add). Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$30 ($sub). @@ -317,26 +319,25 @@ Removed top 31 bits (of 32) from port B of cell fifo.$flatten\fifo_reader.$add$f Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$34 ($add). Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$27_Y. Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_reader.$add$fifo.v:20$34_Y. -Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_writer.$add$fifo.v:20$34_Y. yosys> select -set new_cells t:$add %co t:$add %d yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_wreduce o:rdata %ci* -17. Generating Graphviz representation of design. +18. Generating Graphviz representation of design. Writing dot description to `rdata_wreduce.dot'. Dumping selected parts of module fifo to page 1. yosys> opt_clean -18. Executing OPT_CLEAN pass (remove unused cells and wires). +19. Executing OPT_CLEAN pass (remove unused cells and wires). Finding unused cells or wires in module \fifo.. -Removed 0 unused cells and 5 unused wires. +Removed 0 unused cells and 4 unused wires. <suppressed ~1 debug messages> yosys> memory_dff -19. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +20. 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. @@ -344,13 +345,13 @@ yosys> select -set new_cells t:$memrd_v2 yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdata %ci* -20. Generating Graphviz representation of design. +21. Generating Graphviz representation of design. Writing dot description to `rdata_memrdv2.dot'. Dumping selected parts of module fifo to page 1. yosys> alumacc -21. Executing ALUMACC pass (create $alu and $macc cells). +22. Executing ALUMACC pass (create $alu and $macc cells). Extracting $alu and $macc cells in module fifo: creating $macc model for $add$fifo.v:68$27 ($add). creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$34 ($add). @@ -360,23 +361,23 @@ Extracting $alu and $macc cells in module fifo: creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$34. creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$34. creating $alu model for $macc $add$fifo.v:68$27. - creating $alu cell for $add$fifo.v:68$27: $auto$alumacc.cc:485:replace_alu$79 - creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$82 - creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$85 - creating $alu cell for $sub$fifo.v:70$30: $auto$alumacc.cc:485:replace_alu$88 + creating $alu cell for $add$fifo.v:68$27: $auto$alumacc.cc:485:replace_alu$78 + creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$81 + creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$84 + creating $alu cell for $sub$fifo.v:70$30: $auto$alumacc.cc:485:replace_alu$87 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* -22. Generating Graphviz representation of design. +23. Generating Graphviz representation of design. Writing dot description to `rdata_alumacc.dot'. Dumping selected parts of module fifo to page 1. yosys> memory_collect -23. Executing MEMORY_COLLECT pass (generating $mem cells). +24. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> select -set new_cells t:$mem_v2 @@ -384,6 +385,6 @@ yosys> select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @n yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path -24. Generating Graphviz representation of design. +25. 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.ys b/docs/source/code_examples/fifo/fifo.ys index 497481166..b89361e75 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -10,16 +10,17 @@ read_verilog -defer fifo.v echo on hierarchy -top addr_gen select -set new_cells t:* -show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_hier +show -color maroon3 @new_cells -color cornflowerblue p:* -notitle -format dot -prefix addr_gen_hier # ======================================================== -proc +proc -noopt select -set new_cells t:$mux t:*dff show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc # ======================================================== -clean -show -notitle -format dot -prefix addr_gen_clean +opt_expr; clean +select -set new_cells t:$eq +show -color cornflowerblue @new_cells -notitle -format dot -prefix addr_gen_clean # ======================================================== design -reset diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 9664b04f3..3317656a1 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -124,8 +124,7 @@ Our ``addr_gen`` circuit now looks like this: ``addr_gen`` module after :cmd:ref:`hierarchy` -.. todo:: how to highlight PROC blocks? - They seem to be replaced in ``show``, so the selection never matches +.. TODO:: pending https://github.com/YosysHQ/yosys/pull/4133 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 @@ -141,13 +140,14 @@ To handle these, let us now introduce the next command: :doc:`/cmd/proc`. 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. +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 :cmd:ref:`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 @@ -166,25 +166,42 @@ 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`: +: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: :yoscrypt:`opt_expr; clean`. .. figure:: /_images/code_examples/fifo/addr_gen_clean.* :class: width-helper :name: addr_gen_clean - ``addr_gen`` module after :cmd:ref:`clean` + ``addr_gen`` module after :yoscrypt:`opt_expr; clean` + +You may also notice that the highlighted ``$eq`` cell input of ``255`` has been +converted to ``8'11111111``. Constant values are presented in the format +``<bit_width>'<bits>``, 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. :cmd:ref:`opt_expr` performs simple expression rewriting and +constant folding, which we discuss in more detail in +:doc:`/using_yosys/synthesis/opt`. + +.. TODO:: why doesn't the 32-bit value 1 get converted to 1'1? .. note:: :doc:`/cmd/clean` can also be called with two semicolons after any command, - for example we could have called :yoscrypt:`proc;;` instead of - :yoscrypt:`proc` and then :yoscrypt:`clean`. It is generally beneficial to - run :cmd:ref:`clean` after each command as a quick way of removing - disconnected parts of the circuit which have been left over. You may notice - some scripts will end each line with ``;;``. + for example we could have called :yoscrypt:`opt_expr;;` instead of + :yoscrypt:`opt_expr; clean`. It is generally beneficial to run + :cmd:ref:`clean` after each command as a quick way of removing disconnected + parts of the circuit which have been left over. You may notice some scripts + will end each line with ``;;``. .. 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 ^^^^^^^^^^^^^^^^ From aa652f9634baf4171c81f165987a6ffaae0fb814 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:23:30 +1300 Subject: [PATCH 075/108] Docs: fix scripting_intro.rst images --- docs/source/getting_started/scripting_intro.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index d065a6485..4ce038e91 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -138,20 +138,20 @@ different stages of the yosys tool flow. .. role:: yoscrypt(code) :language: yoscrypt -.. figure:: /_images/code_examples/show/example_00.* +.. figure:: /_images/code_examples/show/example_first.* :class: width-helper - ``example_00`` - shown after :yoscrypt:`read_verilog example.v` + ``example_first`` - shown after :yoscrypt:`read_verilog example.v` -.. figure:: /_images/code_examples/show/example_01.* +.. figure:: /_images/code_examples/show/example_second.* :class: width-helper - ``example_01`` - shown after :yoscrypt:`proc` + ``example_second`` - shown after :yoscrypt:`proc` -.. figure:: /_images/code_examples/show/example_02.* +.. figure:: /_images/code_examples/show/example_third.* :class: width-helper - ``example_02`` - shown after :yoscrypt:`opt` + ``example_third`` - shown after :yoscrypt:`opt` A circuit diagram is generated for the design in its current state. Various options can be used to change the appearance of the circuit diagram, set the From 14f2208e47573c56e6478333f8df320ce44081cb Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:32:14 +1300 Subject: [PATCH 076/108] Docs: opt_expr --- docs/source/getting_started/example_synth.rst | 20 ++++++------------- docs/source/using_yosys/synthesis/opt.rst | 14 +++++++++---- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 3317656a1..e1cc257db 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -155,13 +155,6 @@ 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`. -.. TODO:: intro ``opt_expr`` - :doc:`/cmd/opt_expr` - - - by default called at the end of :cmd:ref:`proc` - - can be disabled with ``-noopt`` - - done here for... reasons? - 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 @@ -176,15 +169,14 @@ at the same time by separating them with a colon: :yoscrypt:`opt_expr; clean`. ``addr_gen`` module after :yoscrypt:`opt_expr; clean` -You may also notice that the highlighted ``$eq`` cell input of ``255`` has been -converted to ``8'11111111``. Constant values are presented in the format +You may also notice that the highlighted ``$eq`` cell input of ``255`` has +changed to ``8'11111111``. Constant values are presented in the format ``<bit_width>'<bits>``, 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. :cmd:ref:`opt_expr` performs simple expression rewriting and -constant folding, which we discuss in more detail in -:doc:`/using_yosys/synthesis/opt`. - -.. TODO:: why doesn't the 32-bit value 1 get converted to 1'1? +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 <adv_opt_expr>`. .. note:: diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index d60e17a48..219a139c1 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -21,10 +21,12 @@ to run this pass after each major step in the synthesis script. As listed in :dedent: :caption: Passes called by :cmd:ref:`opt` -Const folding and simple expression rewriting - :cmd:ref:`opt_expr` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _adv_opt_expr: -This pass performs const folding on the internal combinational cell types +Constant folding and simple expression rewriting - :cmd:ref:`opt_expr` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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. @@ -69,7 +71,11 @@ 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. +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 From 63a0f80996eb70217da3d0f7dd18c808d235b2e7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:47:50 +1300 Subject: [PATCH 077/108] Docs: opt_share --- docs/source/using_yosys/synthesis/opt.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index 219a139c1..2d543c0b5 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -132,7 +132,15 @@ is produced. Merging mutually exclusive cells with shared inputs - :cmd:ref:`opt_share` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. TODO:: ``opt_share`` +This pass identifies mutually exclusive cells of the same type that: + a. share an input signal, and + b. drive the same ``$mux``, ``$_MUX_``, or ``$pmux`` multiplexing cell, + +allowing the cell to be merged and the multiplexer to be moved from +multiplexing its output to multiplexing the non-shared input signals. + +.. todo:: more detailed description of :cmd:ref:`opt_share` (esp. why) + so that it's not just a copy-paste of the help output Performing DFF optimizations - :cmd:ref:`opt_dff` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 27ae093dba499d2972f4f0cd5bef956a55976d7c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:00:42 +1300 Subject: [PATCH 078/108] Docs: working on opt page Replace leftover `opt` example source/images with examples specific to the `opt_*` pass. Currently has images for `opt_expr`, `opt_merge`, `opt_muxtree`, and `opt_share`. Also includes some other TODO updates. --- docs/source/code_examples/opt/Makefile | 19 +++ docs/source/code_examples/opt/opt_expr.ys | 17 +++ docs/source/code_examples/opt/opt_merge.ys | 18 +++ docs/source/code_examples/opt/opt_muxtree.ys | 17 +++ docs/source/code_examples/opt/opt_share.ys | 17 +++ docs/source/code_examples/synth_flow/Makefile | 1 - docs/source/code_examples/synth_flow/opt_01.v | 3 - .../source/code_examples/synth_flow/opt_01.ys | 3 - docs/source/code_examples/synth_flow/opt_02.v | 3 - .../source/code_examples/synth_flow/opt_02.ys | 3 - docs/source/code_examples/synth_flow/opt_03.v | 4 - .../source/code_examples/synth_flow/opt_03.ys | 3 - docs/source/code_examples/synth_flow/opt_04.v | 19 --- .../source/code_examples/synth_flow/opt_04.ys | 3 - .../interactive_investigation.rst | 2 +- .../more_scripting/troubleshooting.rst | 2 + docs/source/using_yosys/synthesis/opt.rst | 109 ++++++++---------- docs/source/yosys_internals/flow/overview.rst | 2 + 18 files changed, 140 insertions(+), 105 deletions(-) create mode 100644 docs/source/code_examples/opt/Makefile create mode 100644 docs/source/code_examples/opt/opt_expr.ys create mode 100644 docs/source/code_examples/opt/opt_merge.ys create mode 100644 docs/source/code_examples/opt/opt_muxtree.ys create mode 100644 docs/source/code_examples/opt/opt_share.ys delete mode 100644 docs/source/code_examples/synth_flow/opt_01.v delete mode 100644 docs/source/code_examples/synth_flow/opt_01.ys delete mode 100644 docs/source/code_examples/synth_flow/opt_02.v delete mode 100644 docs/source/code_examples/synth_flow/opt_02.ys delete mode 100644 docs/source/code_examples/synth_flow/opt_03.v delete mode 100644 docs/source/code_examples/synth_flow/opt_03.ys delete mode 100644 docs/source/code_examples/synth_flow/opt_04.v delete mode 100644 docs/source/code_examples/synth_flow/opt_04.ys diff --git a/docs/source/code_examples/opt/Makefile b/docs/source/code_examples/opt/Makefile new file mode 100644 index 000000000..e59130ecd --- /dev/null +++ b/docs/source/code_examples/opt/Makefile @@ -0,0 +1,19 @@ +PROGRAM_PREFIX := + +YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys + +DOT_NAMES = opt_share opt_muxtree opt_merge opt_expr + +DOTS := $(addsuffix .dot,$(DOT_NAMES)) + +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 000000000..e87da339e --- /dev/null +++ b/docs/source/code_examples/opt/opt_expr.ys @@ -0,0 +1,17 @@ +read_verilog <<EOT + +module uut( + input a, + output y, z +); + assign y = a == a; + assign z = a != a; +endmodule + +EOT + +copy uut after +opt_expr after +clean + +show -format dot -prefix opt_expr_full -notitle -color cornflowerblue uut diff --git a/docs/source/code_examples/opt/opt_merge.ys b/docs/source/code_examples/opt/opt_merge.ys new file mode 100644 index 000000000..38434ca3a --- /dev/null +++ b/docs/source/code_examples/opt/opt_merge.ys @@ -0,0 +1,18 @@ +read_verilog <<EOT + +module uut( + input [3:0] a, b, + output [3:0] y, z +); + assign y = a + b; + assign z = b + a; +endmodule + +EOT + +copy uut after +opt_merge after +clean + +show -format dot -prefix opt_merge_full -notitle -color cornflowerblue uut + diff --git a/docs/source/code_examples/opt/opt_muxtree.ys b/docs/source/code_examples/opt/opt_muxtree.ys new file mode 100644 index 000000000..b9d394c08 --- /dev/null +++ b/docs/source/code_examples/opt/opt_muxtree.ys @@ -0,0 +1,17 @@ +read_verilog <<EOT + +module uut( + input a, b, c, d, + output y +); + assign y = a ? (a ? b : c) : d; +endmodule + +EOT + +copy uut after +opt_muxtree after +clean + +show -format dot -prefix opt_muxtree_full -notitle -color cornflowerblue uut + diff --git a/docs/source/code_examples/opt/opt_share.ys b/docs/source/code_examples/opt/opt_share.ys new file mode 100644 index 000000000..bcf638748 --- /dev/null +++ b/docs/source/code_examples/opt/opt_share.ys @@ -0,0 +1,17 @@ +read_verilog <<EOT + +module uut( + input [15:0] a, b, + input sel, + output [15:0] res, +); + assign res = {sel ? a + b : a - b}; +endmodule + +EOT + +copy uut after +opt_share after +clean + +show -format dot -prefix opt_share_full -notitle -color cornflowerblue uut diff --git a/docs/source/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index b6c83f05d..af5d41493 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -1,6 +1,5 @@ TARGETS += proc_01 proc_02 proc_03 -TARGETS += opt_01 opt_02 opt_03 opt_04 TARGETS += memory_01 memory_02 TARGETS += techmap_01 diff --git a/docs/source/code_examples/synth_flow/opt_01.v b/docs/source/code_examples/synth_flow/opt_01.v deleted file mode 100644 index 5d3c1ea49..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/opt_01.ys b/docs/source/code_examples/synth_flow/opt_01.ys deleted file mode 100644 index 34ed123be..000000000 --- a/docs/source/code_examples/synth_flow/opt_01.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_01.v -hierarchy -check -top test -opt diff --git a/docs/source/code_examples/synth_flow/opt_02.v b/docs/source/code_examples/synth_flow/opt_02.v deleted file mode 100644 index 762fc1a89..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/opt_02.ys b/docs/source/code_examples/synth_flow/opt_02.ys deleted file mode 100644 index fc92a636e..000000000 --- a/docs/source/code_examples/synth_flow/opt_02.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_02.v -hierarchy -check -top test -opt diff --git a/docs/source/code_examples/synth_flow/opt_03.v b/docs/source/code_examples/synth_flow/opt_03.v deleted file mode 100644 index 134161bb8..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/opt_03.ys b/docs/source/code_examples/synth_flow/opt_03.ys deleted file mode 100644 index 282f06dde..000000000 --- a/docs/source/code_examples/synth_flow/opt_03.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_03.v -hierarchy -check -top test -opt diff --git a/docs/source/code_examples/synth_flow/opt_04.v b/docs/source/code_examples/synth_flow/opt_04.v deleted file mode 100644 index 2ed447639..000000000 --- a/docs/source/code_examples/synth_flow/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/docs/source/code_examples/synth_flow/opt_04.ys b/docs/source/code_examples/synth_flow/opt_04.ys deleted file mode 100644 index f5ddae29f..000000000 --- a/docs/source/code_examples/synth_flow/opt_04.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_04.v -hierarchy -check -top test -proc; opt diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index a5e91a5a1..7e01ff06d 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -437,7 +437,7 @@ sections: ``outstage``, ``selstage``, and ``scramble``. :language: yoscrypt :caption: Using :cmd:ref:`submod` to break up the circuit from ``memdemo.v`` :start-after: cd memdemo - :end-at: @selstage + :end-before: cd .. :name: submod The ``-name`` option is used to specify the name of the new module and also the diff --git a/docs/source/using_yosys/more_scripting/troubleshooting.rst b/docs/source/using_yosys/more_scripting/troubleshooting.rst index ff87d63cd..8b7876607 100644 --- a/docs/source/using_yosys/more_scripting/troubleshooting.rst +++ b/docs/source/using_yosys/more_scripting/troubleshooting.rst @@ -1,4 +1,6 @@ Troubleshooting ~~~~~~~~~~~~~~~ +.. TODO:: more on troubleshooting + See :doc:`/cmd/bugpoint` diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index 2d543c0b5..fb75c9fa1 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -81,6 +81,17 @@ 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 <<EOT + :end-before: EOT + :caption: example verilog for demonstrating :cmd:ref:`opt_expr` + +.. figure:: /_images/code_examples/opt/opt_expr.* + :class: width-helper + + Before and after :cmd:ref:`opt_expr` + Merging identical cells - :cmd:ref:`opt_merge` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -93,23 +104,38 @@ cells (``$mux`` and ``$pmux``.) This can be useful as it prevents multiplexer trees to be merged, which might prevent :cmd:ref:`opt_muxtree` to identify possible optimizations. +.. literalinclude:: /code_examples/opt/opt_merge.ys + :language: Verilog + :start-after: read_verilog <<EOT + :end-before: EOT + :caption: example verilog for demonstrating :cmd:ref:`opt_merge` + +.. figure:: /_images/code_examples/opt/opt_merge.* + :class: width-helper + + Before and after :cmd:ref:`opt_merge` + Removing never-active branches from multiplexer tree - :cmd:ref:`opt_muxtree` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This pass optimizes trees of multiplexer cells by analyzing the select inputs. Consider the following simple example: -.. code:: verilog +.. literalinclude:: /code_examples/opt/opt_muxtree.ys + :language: Verilog + :start-after: read_verilog <<EOT + :end-before: EOT + :caption: example verilog for demonstrating :cmd:ref:`opt_muxtree` - 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 +The output can never be ``c``, as this would require ``a`` to be 1 for the outer multiplexer and 0 for the inner multiplexer. The :cmd:ref:`opt_muxtree` pass detects this contradiction and replaces the inner multiplexer with a constant 1, -yielding the logic for ``y = a ? 1 : 3``. +yielding the logic for ``y = a ? b : d``. + +.. figure:: /_images/code_examples/opt/opt_muxtree.* + :class: width-helper + + Before and after :cmd:ref:`opt_muxtree` Simplifying large MUXes and AND/OR gates - :cmd:ref:`opt_reduce` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,8 +165,19 @@ This pass identifies mutually exclusive cells of the same type that: allowing the cell to be merged and the multiplexer to be moved from multiplexing its output to multiplexing the non-shared input signals. -.. todo:: more detailed description of :cmd:ref:`opt_share` (esp. why) - so that it's not just a copy-paste of the help output +.. literalinclude:: /code_examples/opt/opt_share.ys + :language: Verilog + :start-after: read_verilog <<EOT + :end-before: EOT + :caption: example verilog for demonstrating :cmd:ref:`opt_share` + +.. figure:: /_images/code_examples/opt/opt_share.* + :class: width-helper + + Before and after :cmd:ref:`opt_share` + +When running :cmd:ref:`opt` in full, the original ``$mux`` (labeled ``$3``) is +optimized away by :cmd:ref:`opt_expr`. Performing DFF optimizations - :cmd:ref:`opt_dff` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -160,58 +197,6 @@ 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. -Example -~~~~~~~ - -.. todo:: describe ``opt`` images - - and/or replace with an example image showing before/after of each ``opt_*`` - command - -.. figure:: /_images/code_examples/synth_flow/opt_01.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_01.ys`` - -.. literalinclude:: /code_examples/synth_flow/opt_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_01.v`` - -.. figure:: /_images/code_examples/synth_flow/opt_02.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_02.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_02.ys`` - -.. literalinclude:: /code_examples/synth_flow/opt_02.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_02.v`` - -.. figure:: /_images/code_examples/synth_flow/opt_03.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_03.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_03.ys`` - -.. literalinclude:: /code_examples/synth_flow/opt_03.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_03.v`` - -.. figure:: /_images/code_examples/synth_flow/opt_04.* - :class: width-helper - -.. literalinclude:: /code_examples/synth_flow/opt_04.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/opt_04.v`` - -.. literalinclude:: /code_examples/synth_flow/opt_04.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/opt_04.ys`` - When to use :cmd:ref:`opt` or :cmd:ref:`clean` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst index 08ead2570..ae07e6f1f 100644 --- a/docs/source/yosys_internals/flow/overview.rst +++ b/docs/source/yosys_internals/flow/overview.rst @@ -18,6 +18,8 @@ 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. +.. TODO:: what next section + There is also a text representation of the RTLIL data structure that can be parsed using the RTLIL Frontend. From 93ceda5c631819e7afe0bb0ad5b3184e3766a919 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:14:00 +1300 Subject: [PATCH 079/108] Docs: auxlibs --- docs/source/appendix/auxlibs.rst | 34 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/source/appendix/auxlibs.rst b/docs/source/appendix/auxlibs.rst index 4c845f197..321cb52c4 100644 --- a/docs/source/appendix/auxlibs.rst +++ b/docs/source/appendix/auxlibs.rst @@ -4,8 +4,6 @@ Auxiliary libraries The Yosys source distribution contains some auxiliary libraries that are compiled into Yosys and can be used in plugins. -.. TODO:: fill out the newer auxiliary libs - BigInt ------ @@ -20,30 +18,50 @@ See also: http://mattmccutchen.net/bigint/ dlfcn-win32 ----------- -The files in ``libs/dlfcn-win32`` provide... +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 sat pass (see -:doc:`../cmd/sat`). +library is written by C. Wolf. It is used by the :cmd:ref:`sat` pass (see +:doc:`/cmd/sat`). fst --- -The files in ``libs/fst`` provide... +``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 ------ -The files in ``libs/json11`` provide... +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... +The files in ``libs/minisat`` provide a high-performance SAT solver, used by the +:cmd:ref:`sat` command. SHA1 ---- From 74d2c918cdfe2a90fa05906727e880e4eedcb94b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:52:32 +1300 Subject: [PATCH 080/108] Docs: installation/source tree --- docs/source/getting_started/installation.rst | 73 ++++++++++++-------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 66c5a3335..e8dbbe77a 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -143,43 +143,56 @@ executable name). Source tree and build system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. TODO:: check if source tree/build system details need updating - The Yosys source tree is organized into the following top-level directories: -- | backends/ - | This directory contains a subdirectory for each of the backend modules. +``backends/`` + This directory contains a subdirectory for each of the backend modules. -- | frontends/ - | This directory contains a subdirectory for each of the frontend modules. +``docs/`` + Contains the source for this documentation, including images and sample code. -- | 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. +``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. -- | 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. +``frontends/`` + This directory contains a subdirectory for each of the frontend modules. -- | techlibs/ - | This directory contains simulation models and standard implementations for - the cells from the internal cell library. +``guidelines/`` + Contains developer guidelines, including the code of conduct and coding style + guide. -- | 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. +``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|cc}``), the ``main()`` function (``driver.cc``), the internal + framework for generating log messages (``log.{h|cc}``), the internal + framework for registering and calling passes (``register.{h|cc}``), some core + commands that are not really passes (``select.cc``, ``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 ``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 ``frontends/*/Makefile.inc``, ``passes/*/Makefile.inc`` and ``backends/*/Makefile.inc``. So when extending @@ -189,7 +202,7 @@ 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``. +passes are ``passes/opt/opt_dff.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. From 14b7c581fa97e914441c059095705fac8e4a9dbc Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 18 Jan 2024 15:33:59 +1300 Subject: [PATCH 081/108] Docs: reworking scripting_intro Now comes *after* example_synth, with references back to it. Includes some minor adjustment to the `fifo.ys` script to better demonstrate the `select` command. Still needs an updated section on `show`. Also includes some other minor updates. --- docs/source/code_examples/fifo/fifo.out | 31 +++- docs/source/code_examples/fifo/fifo.ys | 7 +- docs/source/getting_started/example_synth.rst | 3 + docs/source/getting_started/index.rst | 2 +- .../getting_started/scripting_intro.rst | 169 ++++++++---------- docs/source/using_yosys/synthesis/opt.rst | 2 + docs/source/using_yosys/yosys_flows.rst | 38 ++-- docs/source/yosys_internals/flow/overview.rst | 7 +- 8 files changed, 139 insertions(+), 120 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index 30236a7ab..d18fce14b 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -27,7 +27,36 @@ Removing unused module `$abstract\fifo'. Removing unused module `$abstract\addr_gen'. Removed 2 unused modules. -yosys> select -set new_cells t:* +yosys> select -module addr_gen + +yosys [addr_gen]> select -list +addr_gen +addr_gen/$1\addr[7:0] +addr_gen/$add$fifo.v:20$3_Y +addr_gen/$eq$fifo.v:17$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:20$3 +addr_gen/$eq$fifo.v:17$2 +addr_gen/$proc$fifo.v:0$4 +addr_gen/$proc$fifo.v:13$1 + +yosys [addr_gen]> select t:* + +yosys [addr_gen]*> select -list +addr_gen/$add$fifo.v:20$3 +addr_gen/$eq$fifo.v:17$2 + +yosys [addr_gen]*> select -set new_cells % + +yosys [addr_gen]*> select -clear + +yosys> select -list addr_gen/t:* +addr_gen/$add$fifo.v:20$3 +addr_gen/$eq$fifo.v:17$2 yosys> show -color maroon3 @new_cells -color cornflowerblue p:* -notitle -format dot -prefix addr_gen_hier diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index b89361e75..0584285ea 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -9,7 +9,12 @@ 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 -set new_cells t:* +select -module addr_gen +select -list +select t:* +select -list +select -set new_cells % +select -clear show -color maroon3 @new_cells -color cornflowerblue p:* -notitle -format dot -prefix addr_gen_hier # ======================================================== diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index e1cc257db..811c39a28 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -86,6 +86,8 @@ start mapping to hardware we will still need to load them later. Yosys from the source directory, this will be the ``share`` folder in the same directory. +.. _addr_gen_example: + The addr_gen module ^^^^^^^^^^^^^^^^^^^ @@ -115,6 +117,7 @@ Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy :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: diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index a3c4a265b..51628c67f 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -7,5 +7,5 @@ Getting started with Yosys :maxdepth: 3 installation - scripting_intro example_synth + scripting_intro diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 4ce038e91..d4d809fbd 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -1,116 +1,91 @@ Scripting in Yosys ------------------ -.. TODO:: logical consistency, esp with example_synth +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 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. Also see :doc:`example_synth`. +Yosys script files typically use the ``.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 command :cmd:ref:`help` can be used to access the command reference manual, -with ``help <command>`` providing details for a specific command. ``yosys -H`` -or ``yosys -h <command>`` will do the same outside of an interactive prompt. -The entire reference manual is also available here at :doc:`/cmd_ref`. +The synthesis starter script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Example commands -~~~~~~~~~~~~~~~~ +.. role:: yoscrypt(code) + :language: yoscrypt -Commands for design navigation and investigation: +All of the images and console output used in +:doc:`/getting_started/example_synth` were generated by Yosys, using Yosys +script files found in ``docs/source/code_examples/fifo``. If you haven't +already, let's take a look at some of those script files now. -.. code-block:: yoscrypt +.. literalinclude:: /code_examples/fifo/fifo.ys + :language: yoscrypt + :lineno-match: + :start-at: echo on + :end-before: design -reset + :caption: A section of ``fifo.ys``, generating the images used for :ref:`addr_gen_example` + :name: fifo-ys - cd # a shortcut for 'select -module <name>' - 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 +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. -Commands for executing scripts or entering interactive mode: - -.. code-block:: yoscrypt - - shell # enter interactive command mode - history # show last interactive commands - script # execute commands from script file - tcl # execute a TCL script file - -Commands for reading and elaborating the design: - -.. code-block:: yoscrypt - - read_rtlil # read modules from RTLIL file - read_verilog # read modules from Verilog file - hierarchy # check, expand and clean up design hierarchy - - -Commands for high-level synthesis: - -.. code-block:: yoscrypt - - proc # translate processes to netlists - fsm # extract and optimize finite state machines - memory # translate memories to basic cells - opt # perform simple optimizations - - -Commands for technology mapping: - -.. code-block:: yoscrypt - - 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 - -Commands for writing the results: - -.. code-block:: yoscrypt - - 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 - - -Script-Commands for standard synthesis tasks: - -.. code-block:: yoscrypt - - synth # generic synthesis script - synth_xilinx # synthesis for Xilinx FPGAs - - -Commands for model checking: - -.. code-block:: yoscrypt - - sat # solve a SAT problem in the circuit - miter # automatically create a miter circuit - scc # detect strongly connected components (logic loops) +We briefly touched on :cmd:ref:`select` when it came up in +:cmd:ref:`synth_ice40`, but let's look at it more now. Selections intro -~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^ -.. todo:: reorder text for logical consistency +The :cmd:ref:`select` command is used to modify and view the list of selected +objects: -Most commands can operate not only on the entire design but also specifically on -selected parts of the design. For example the command :cmd:ref:`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. +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: yosys> select + :end-before: yosys> show -.. code:: yoscrypt +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. - dump */t:$add %x:+[A] */w:* %i +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. + +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. 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 <fifo-ys>` 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. -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 under :doc:`/using_yosys/more_scripting/selections` or in the command reference at :doc:`/cmd/select`. @@ -118,6 +93,8 @@ Detailed documentation of the select framework can be found under The show command ~~~~~~~~~~~~~~~~ +.. TODO:: scripting_intro/show section + The :cmd:ref:`show` command requires a working installation of `GraphViz`_ and `xdot`_ for generating the actual circuit diagrams. Below is an example of how this command can be used, showing the changes in the generated circuit at diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index fb75c9fa1..0ba108131 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -26,6 +26,8 @@ to run this pass after each major step in the synthesis script. As listed in 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. diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/yosys_flows.rst index 040ef5a4c..5bca90ade 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/yosys_flows.rst @@ -4,7 +4,7 @@ Flows, command types, and order Command order ------------- -.. TODO:: check text is coherent +.. todo:: More surrounding text (esp as it relates to command order) Intro to coarse-grain synthesis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -42,6 +42,8 @@ The extract pass .. todo:: add/expand supporting text, also mention custom pattern matching and pmgen +Example code can be found in ``docs/source/code_examples/macc/``. + .. literalinclude:: /code_examples/macc/macc_simple_test.ys :language: yoscrypt :lines: 1-2 @@ -62,15 +64,15 @@ The extract pass .. literalinclude:: /code_examples/macc/macc_simple_test.v :language: verilog - :caption: ``docs/source/code_examples/macc/macc_simple_test.v`` + :caption: ``macc_simple_test.v`` .. literalinclude:: /code_examples/macc/macc_simple_xmap.v :language: verilog - :caption: ``docs/source/code_examples/macc/macc_simple_xmap.v`` + :caption: ``macc_simple_xmap.v`` .. literalinclude:: /code_examples/macc/macc_simple_test_01.v :language: verilog - :caption: ``docs/source/code_examples/macc/macc_simple_test_01.v`` + :caption: ``macc_simple_test_01.v`` .. figure:: /_images/code_examples/macc/macc_simple_test_01a.* :class: width-helper @@ -80,7 +82,7 @@ The extract pass .. literalinclude:: /code_examples/macc/macc_simple_test_02.v :language: verilog - :caption: ``docs/source/code_examples/macc/macc_simple_test_02.v`` + :caption: ``macc_simple_test_02.v`` .. figure:: /_images/code_examples/macc/macc_simple_test_02a.* :class: width-helper @@ -95,14 +97,15 @@ 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: +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 ``connwrappers`` command to connect up - the bit-extended in- and outputs of the wrapper cells. + 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 @@ -117,7 +120,8 @@ 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). +(such as the Xilinx DSP48 cells). Source code can be found in +``docs/source/code_examples/macc/``. Preconditioning: ``macc_xilinx_swap_map.v`` @@ -127,27 +131,27 @@ Make sure ``A`` is the smaller port on all multipliers .. literalinclude:: /code_examples/macc/macc_xilinx_swap_map.v :language: verilog - :caption: ``docs/source/code_examples/macc/macc_xilinx_swap_map.v`` + :caption: ``macc_xilinx_swap_map.v`` Wrapping multipliers: ``macc_xilinx_wrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v :language: verilog :lines: 1-46 - :caption: ``docs/source/code_examples/macc/macc_xilinx_wrap_map.v`` + :caption: ``macc_xilinx_wrap_map.v`` Wrapping adders: ``macc_xilinx_wrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_wrap_map.v :language: verilog :lines: 48-89 - :caption: ``docs/source/code_examples/macc/macc_xilinx_wrap_map.v`` + :caption: ``macc_xilinx_wrap_map.v`` Extract: ``macc_xilinx_xmap.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_xmap.v :language: verilog - :caption: ``docs/source/code_examples/macc/macc_xilinx_xmap.v`` + :caption: ``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. @@ -157,19 +161,19 @@ Unwrapping multipliers: ``macc_xilinx_unwrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v :language: verilog :lines: 1-30 - :caption: ``docs/source/code_examples/macc/macc_xilinx_unwrap_map.v`` + :caption: ``$__mul_wrapper`` module in ``macc_xilinx_unwrap_map.v`` Unwrapping adders: ``macc_xilinx_unwrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_unwrap_map.v :language: verilog :lines: 32-61 - :caption: ``docs/source/code_examples/macc/macc_xilinx_unwrap_map.v`` + :caption: ``$__add_wrapper`` module in ``macc_xilinx_unwrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_test.v :language: verilog :lines: 1-6 - :caption: ``test1`` of ``docs/source/code_examples/macc/macc_xilinx_test.v`` + :caption: ``test1`` of ``macc_xilinx_test.v`` .. figure:: /_images/code_examples/macc/macc_xilinx_test1a.* :class: width-helper @@ -180,7 +184,7 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_test.v :language: verilog :lines: 8-13 - :caption: ``test2`` of ``docs/source/code_examples/macc/macc_xilinx_test.v`` + :caption: ``test2`` of ``macc_xilinx_test.v`` .. figure:: /_images/code_examples/macc/macc_xilinx_test2a.* :class: width-helper diff --git a/docs/source/yosys_internals/flow/overview.rst b/docs/source/yosys_internals/flow/overview.rst index ae07e6f1f..f7589df03 100644 --- a/docs/source/yosys_internals/flow/overview.rst +++ b/docs/source/yosys_internals/flow/overview.rst @@ -16,12 +16,11 @@ 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. - -.. TODO:: what next section +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. +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. From 794ad381c6dcaad52554fe93f502760e517ca91d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 22 Jan 2024 11:10:02 +1300 Subject: [PATCH 082/108] Docs: scripting_intro/show_intro Adds two new `show` commands to `fifo.ys` for demo purposes. Mention referencing named selections with `@<name>`. Also adds a note to `example_synth` to point to the show intro. --- docs/source/code_examples/fifo/fifo.out | 112 ++++++++------- docs/source/code_examples/fifo/fifo.ys | 2 + docs/source/getting_started/example_synth.rst | 3 +- .../getting_started/scripting_intro.rst | 134 ++++++++++++------ 4 files changed, 157 insertions(+), 94 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index d18fce14b..85cf14f9c 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -54,78 +54,86 @@ yosys [addr_gen]*> select -set new_cells % yosys [addr_gen]*> select -clear -yosys> select -list addr_gen/t:* -addr_gen/$add$fifo.v:20$3 -addr_gen/$eq$fifo.v:17$2 +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 -4. Generating Graphviz representation of design. +6. Generating Graphviz representation of design. Writing dot description to `addr_gen_hier.dot'. Dumping module addr_gen to page 1. yosys> proc -noopt -5. Executing PROC pass (convert processes to netlists). +7. Executing PROC pass (convert processes to netlists). yosys> proc_clean -5.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +7.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. yosys> proc_rmdead -5.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +7.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Marked 2 switch rules as full_case in process $proc$fifo.v:13$1 in module addr_gen. Removed a total of 0 dead cases. yosys> proc_prune -5.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +7.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 1 assignment to connection. yosys> proc_init -5.4. Executing PROC_INIT pass (extract init attributes). +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 -5.5. Executing PROC_ARST pass (detect async resets in processes). +7.5. Executing PROC_ARST pass (detect async resets in processes). Found async reset \rst in `\addr_gen.$proc$fifo.v:13$1'. yosys> proc_rom -5.6. Executing PROC_ROM pass (convert switches to ROMs). +7.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. <suppressed ~2 debug messages> yosys> proc_mux -5.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +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:13$1'. 1/1: $0\addr[7:0] yosys> proc_dlatch -5.8. Executing PROC_DLATCH pass (convert process syncs to latches). +7.8. Executing PROC_DLATCH pass (convert process syncs to latches). yosys> proc_dff -5.9. Executing PROC_DFF pass (convert process syncs to FFs). +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:13$1'. created $adff cell `$procdff$10' with positive edge clock and positive level reset. yosys> proc_memwr -5.10. Executing PROC_MEMWR pass (convert process memory writes to cells). +7.10. Executing PROC_MEMWR pass (convert process memory writes to cells). yosys> proc_clean -5.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +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:13$1'. Removing empty process `addr_gen.$proc$fifo.v:13$1'. @@ -135,13 +143,13 @@ yosys> select -set new_cells t:$mux t:*dff yosys> show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc -6. Generating Graphviz representation of design. +8. Generating Graphviz representation of design. Writing dot description to `addr_gen_proc.dot'. Dumping module addr_gen to page 1. yosys> opt_expr -7. Executing OPT_EXPR pass (perform const folding). +9. Executing OPT_EXPR pass (perform const folding). Optimizing module addr_gen. yosys> clean @@ -151,7 +159,7 @@ yosys> select -set new_cells t:$eq yosys> show -color cornflowerblue @new_cells -notitle -format dot -prefix addr_gen_clean -8. Generating Graphviz representation of design. +10. Generating Graphviz representation of design. Writing dot description to `addr_gen_clean.dot'. Dumping module addr_gen to page 1. @@ -159,7 +167,7 @@ yosys> design -reset yosys> read_verilog fifo.v -9. Executing Verilog-2005 frontend: 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'. @@ -167,24 +175,24 @@ Successfully finished Verilog frontend. yosys> hierarchy -check -top fifo -10. Executing HIERARCHY pass (managing design hierarchy). +12. Executing HIERARCHY pass (managing design hierarchy). -10.1. Analyzing design hierarchy.. +12.1. Analyzing design hierarchy.. Top module: \fifo Used module: \addr_gen Parameter \MAX_DATA = 256 -10.2. Executing AST frontend in derive mode using pre-parsed AST for module `\addr_gen'. +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'. -10.3. Analyzing design hierarchy.. +12.3. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 -10.4. Analyzing design hierarchy.. +12.4. Analyzing design hierarchy.. Top module: \fifo Used module: $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000 Removing unused module `\addr_gen'. @@ -192,16 +200,16 @@ Removed 1 unused modules. yosys> proc -11. Executing PROC pass (convert processes to netlists). +13. Executing PROC pass (convert processes to netlists). yosys> proc_clean -11.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). +13.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. yosys> proc_rmdead -11.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). +13.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Marked 2 switch rules as full_case in process $proc$fifo.v:64$24 in module fifo. Marked 1 switch rules as full_case in process $proc$fifo.v:38$16 in module fifo. Marked 2 switch rules as full_case in process $proc$fifo.v:13$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. @@ -209,13 +217,13 @@ Removed a total of 0 dead cases. yosys> proc_prune -11.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). +13.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 6 assignments to connections. yosys> proc_init -11.4. Executing PROC_INIT pass (extract init attributes). +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'. @@ -223,19 +231,19 @@ Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000 yosys> proc_arst -11.5. Executing PROC_ARST pass (detect async resets in processes). +13.5. Executing PROC_ARST pass (detect async resets in processes). Found async reset \rst in `\fifo.$proc$fifo.v:64$24'. Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. yosys> proc_rom -11.6. Executing PROC_ROM pass (convert switches to ROMs). +13.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. <suppressed ~5 debug messages> yosys> proc_mux -11.7. Executing PROC_MUX pass (convert decision trees to multiplexers). +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:64$24'. 1/1: $0\count[8:0] @@ -249,11 +257,11 @@ Creating decoders for process `$paramod\addr_gen\MAX_DATA=s32'000000000000000000 yosys> proc_dlatch -11.8. Executing PROC_DLATCH pass (convert process syncs to latches). +13.8. Executing PROC_DLATCH pass (convert process syncs to latches). yosys> proc_dff -11.9. Executing PROC_DFF pass (convert process syncs to FFs). +13.9. Executing PROC_DFF pass (convert process syncs to FFs). Creating register for signal `\fifo.\count' using process `\fifo.$proc$fifo.v:64$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:38$16'. @@ -269,11 +277,11 @@ Creating register for signal `$paramod\addr_gen\MAX_DATA=s32'0000000000000000000 yosys> proc_memwr -11.10. Executing PROC_MEMWR pass (convert process memory writes to cells). +13.10. Executing PROC_MEMWR pass (convert process memory writes to cells). yosys> proc_clean -11.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). +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:64$24'. Removing empty process `fifo.$proc$fifo.v:64$24'. @@ -286,7 +294,7 @@ Cleaned up 5 empty switches. yosys> opt_expr -keepdc -11.12. Executing OPT_EXPR pass (perform const folding). +13.12. Executing OPT_EXPR pass (perform const folding). Optimizing module fifo. Optimizing module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. @@ -294,13 +302,13 @@ 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* -12. Generating Graphviz representation of design. +14. Generating Graphviz representation of design. Writing dot description to `rdata_proc.dot'. Dumping selected parts of module fifo to page 1. yosys> flatten -13. Executing FLATTEN pass (flatten design). +15. Executing FLATTEN pass (flatten design). Deleting now unused module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. <suppressed ~2 debug messages> @@ -313,13 +321,13 @@ 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 -14. Generating Graphviz representation of design. +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 -15. Executing OPT_DFF pass (perform DFF optimizations). +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). @@ -328,13 +336,13 @@ yosys> select -set new_cells t:$adffe yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata %ci* -16. Generating Graphviz representation of design. +18. Generating Graphviz representation of design. Writing dot description to `rdata_adffe.dot'. Dumping selected parts of module fifo to page 1. yosys> wreduce -17. Executing WREDUCE pass (reducing word size of cells). +19. Executing WREDUCE pass (reducing word size of cells). Removed top 31 bits (of 32) from port B of cell fifo.$add$fifo.v:68$27 ($add). Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$27 ($add). Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$30 ($sub). @@ -353,20 +361,20 @@ yosys> select -set new_cells t:$add %co t:$add %d yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_wreduce o:rdata %ci* -18. Generating Graphviz representation of design. +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 -19. Executing OPT_CLEAN pass (remove unused cells and wires). +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. <suppressed ~1 debug messages> yosys> memory_dff -20. Executing MEMORY_DFF pass (merging $dff cells to $memrd). +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. @@ -374,13 +382,13 @@ yosys> select -set new_cells t:$memrd_v2 yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_memrdv2 o:rdata %ci* -21. Generating Graphviz representation of design. +23. Generating Graphviz representation of design. Writing dot description to `rdata_memrdv2.dot'. Dumping selected parts of module fifo to page 1. yosys> alumacc -22. Executing ALUMACC pass (create $alu and $macc cells). +24. Executing ALUMACC pass (create $alu and $macc cells). Extracting $alu and $macc cells in module fifo: creating $macc model for $add$fifo.v:68$27 ($add). creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$34 ($add). @@ -400,13 +408,13 @@ yosys> select -set new_cells t:$alu t:$macc yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdata %ci* -23. Generating Graphviz representation of design. +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 -24. Executing MEMORY_COLLECT pass (generating $mem cells). +26. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> select -set new_cells t:$mem_v2 @@ -414,6 +422,6 @@ yosys> select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @n yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path -25. Generating Graphviz representation of design. +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.ys b/docs/source/code_examples/fifo/fifo.ys index 0584285ea..b6e0e34ed 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -15,6 +15,8 @@ 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 # ======================================================== diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 811c39a28..db7511c76 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -247,7 +247,8 @@ 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`. +: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 diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index d4d809fbd..6e75a3bcc 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -43,6 +43,8 @@ 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 ^^^^^^^^^^^^^^^^ @@ -70,16 +72,19 @@ cells, regardless of their type. The active selection is now shown as 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. 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 <fifo-ys>` 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. +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 <fifo-ys>` 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 @@ -90,53 +95,100 @@ 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: + The show command ~~~~~~~~~~~~~~~~ -.. TODO:: scripting_intro/show section +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. -The :cmd:ref:`show` command requires a working installation of `GraphViz`_ and -`xdot`_ for generating the actual circuit diagrams. Below is an example of how -this command can be used, showing the changes in the generated circuit at -different stages of the yosys tool flow. +.. 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 -.. literalinclude:: /code_examples/show/example.ys - :language: yoscrypt - :caption: docs/source/code_examples/show/example.ys +This is the first :yoscrypt:`show` command we called in ``fifo.ys``, :ref:`as we +saw above <fifo-ys>`. If we look at the log output for this image we see the +following: -.. literalinclude:: /code_examples/show/example.v - :language: Verilog - :caption: docs/source/code_examples/show/example.v +.. literalinclude:: /code_examples/fifo/fifo.out + :language: doscon + :start-at: -prefix addr_gen_show + :end-before: yosys> show -.. role:: yoscrypt(code) - :language: yoscrypt +Calling :cmd:ref:`show` with :yoscrypt:`-format dot` tells it we want to output +a ``.dot`` file rather than opening it for display. The :yoscrypt:`-prefix +addr_gen_show` option indicates we want the file to be called `addr_gen_show.*`. +Remember, we do this in ``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 ``.dot``. Check `GraphViz output docs`_ for more on +available formats. -.. figure:: /_images/code_examples/show/example_first.* +.. _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<select_new_cells>` 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 - - ``example_first`` - shown after :yoscrypt:`read_verilog example.v` + :name: new_cells_show -.. figure:: /_images/code_examples/show/example_second.* + 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 - - ``example_second`` - shown after :yoscrypt:`proc` -.. figure:: /_images/code_examples/show/example_third.* - :class: width-helper - - ``example_third`` - shown after :yoscrypt:`opt` + Calling :yoscrypt:`show -color maroon3 @new_cells -color cornflowerblue p:* -notitle` -A circuit diagram is generated 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). +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> <object>`. Color names for the ``<color>`` portion can be found on the +`GraphViz color docs`_. Unlike the final :cmd:ref:`show` parameter which can +have be any selection string, the ``<object>`` 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. -For more information on the :cmd:ref:`show` command, including a guide on what -the different symbols represent, see :ref:`interactive_show` and the -:doc:`/using_yosys/more_scripting/interactive_investigation` page. +.. _GraphViz color docs: https://graphviz.org/doc/info/colors + +.. seealso:: :ref:`interactive_show` on the + :doc:`/using_yosys/more_scripting/interactive_investigation` page. From 9ec1536f1fe925b4426ad0367a0733a96c6ee951 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 22 Jan 2024 11:35:00 +1300 Subject: [PATCH 083/108] Docs: getting_started tidy Rename `show` intro and point to `/cmd/show`. Add getting_started section overview. --- docs/source/getting_started/index.rst | 4 +++- docs/source/getting_started/scripting_intro.rst | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index 51628c67f..7a92c212a 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -1,7 +1,9 @@ Getting started with Yosys ========================== -.. todo:: brief overview for the getting started index +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 diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index 6e75a3bcc..e971432c0 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -97,8 +97,8 @@ Detailed documentation of the select framework can be found under .. _show_intro: -The show command -~~~~~~~~~~~~~~~~ +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 @@ -190,5 +190,8 @@ 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. From 95849edbba68dd453f6d9f9167ad18ceafdb4b40 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:35:06 +1300 Subject: [PATCH 084/108] Docs: changes from JF `yosys-witness` prereq `click`. Yosys environment vars & `yosys --help` output. Removing Ubuntu/macOS version numbers/names. Hide `troubleshooting` page. --- Makefile | 2 +- docs/source/appendix/auxprogs.rst | 4 +++ docs/source/appendix/env_vars.rst | 31 +++++++++++++++++++ docs/source/cmd_ref.rst | 5 +++ docs/source/test_suites.rst | 15 ++++++--- .../using_yosys/more_scripting/index.rst | 3 +- .../more_scripting/troubleshooting.rst | 2 +- 7 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 docs/source/appendix/env_vars.rst diff --git a/Makefile b/Makefile index cf73728ea..753ff9b92 100644 --- a/Makefile +++ b/Makefile @@ -982,7 +982,7 @@ docs/guidelines: # many of these will return an error which can be safely ignored, so we prefix # the command with a '-' -DOCS_USAGE_PROGS := yosys-config yosys-filterlib yosys-abc yosys-smtbmc yosys-witness +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 diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index 752d4a0c8..b6defbe80 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -57,3 +57,7 @@ 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 000000000..bb8ef34df --- /dev/null +++ b/docs/source/appendix/env_vars.rst @@ -0,0 +1,31 @@ +Yosys environment variables +=========================== + +``HOME`` + Yosys command history is stored in ``$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 ``~``. + +``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 ``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/cmd_ref.rst b/docs/source/cmd_ref.rst index 24b24015a..f0c4eaaf9 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: + /appendix/env_vars /cmd/* diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index 3e016400e..2edb0e67d 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -6,15 +6,20 @@ Testing Yosys Automatic testing ----------------- -The `Yosys Git repo`_ has automatic testing of builds and running of the -included test suite on the following platforms: - .. only:: html - - Ubuntu 20.04 (Focal Fossa) |test-linux| - - macOS 11 (Big Sur) |test-macos| + 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/more_scripting/index.rst b/docs/source/using_yosys/more_scripting/index.rst index 7c3f2ae56..2d67b6a09 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -9,4 +9,5 @@ More scripting load_design selections interactive_investigation - troubleshooting + +.. troubleshooting diff --git a/docs/source/using_yosys/more_scripting/troubleshooting.rst b/docs/source/using_yosys/more_scripting/troubleshooting.rst index 8b7876607..a17a552d2 100644 --- a/docs/source/using_yosys/more_scripting/troubleshooting.rst +++ b/docs/source/using_yosys/more_scripting/troubleshooting.rst @@ -1,6 +1,6 @@ Troubleshooting ~~~~~~~~~~~~~~~ -.. TODO:: more on troubleshooting +.. todo:: troubleshooting document(?) See :doc:`/cmd/bugpoint` From 6c8949cacc4cb4970e45265646b992571e788a8d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:56:00 +1300 Subject: [PATCH 085/108] Docs: static opt macro list Also adds `docs/tests/macro_commands.py` which checks all commands in `code_examples/macro_commands` against the current yosys build. Format similar to `run-test.sh` files: logging the file under test and reporting errors. --- .../code_examples/macro_commands/opt.ys | 14 +++ docs/source/using_yosys/synthesis/opt.rst | 6 +- docs/tests/macro_commands.py | 91 +++++++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 docs/source/code_examples/macro_commands/opt.ys create mode 100755 docs/tests/macro_commands.py 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 000000000..cb883bc58 --- /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 <changed design> diff --git a/docs/source/using_yosys/synthesis/opt.rst b/docs/source/using_yosys/synthesis/opt.rst index 0ba108131..7861f66d4 100644 --- a/docs/source/using_yosys/synthesis/opt.rst +++ b/docs/source/using_yosys/synthesis/opt.rst @@ -14,11 +14,9 @@ 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:: /cmd/opt.rst +.. literalinclude:: /code_examples/macro_commands/opt.ys :language: yoscrypt - :start-after: following order: - :end-at: while <changed design> - :dedent: + :start-after: #end: :caption: Passes called by :cmd:ref:`opt` .. _adv_opt_expr: diff --git a/docs/tests/macro_commands.py b/docs/tests/macro_commands.py new file mode 100755 index 000000000..7942e4d31 --- /dev/null +++ b/docs/tests/macro_commands.py @@ -0,0 +1,91 @@ +#!/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() + expected_content = f.readlines() + # 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 + actual_content = match.group(1).strip().splitlines() + # 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<cmd>\S+)(?P<pass> \[.*\])?(?P<opt>.*?)(?P<cond> \(.*\))?(?P<comment>\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) From 449135a9d4c1817611bbf3edf8e887bc9ae6b485 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:29:40 +1300 Subject: [PATCH 086/108] Docs: adding other macro command lists Also updates `macro_commands.py` to skip empty lines, and moves comment stripping earlier in parsing. --- .../code_examples/macro_commands/fsm.ys | 27 ++++++ .../code_examples/macro_commands/memory.ys | 15 +++ .../code_examples/macro_commands/proc.ys | 14 +++ docs/source/using_yosys/synthesis/fsm.rst | 95 ++++--------------- docs/source/using_yosys/synthesis/memory.rst | 23 +++-- docs/source/using_yosys/synthesis/proc.rst | 21 ++-- docs/source/using_yosys/synthesis/synth.rst | 3 +- docs/tests/macro_commands.py | 15 ++- 8 files changed, 111 insertions(+), 102 deletions(-) create mode 100644 docs/source/code_examples/macro_commands/fsm.ys create mode 100644 docs/source/code_examples/macro_commands/memory.ys create mode 100644 docs/source/code_examples/macro_commands/proc.ys 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 000000000..627df1209 --- /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 000000000..ea4800a1c --- /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 <bram_rules> (when called with -bram) +memory_map (skipped if called with -nomap) 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 000000000..7a78ce0c6 --- /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/using_yosys/synthesis/fsm.rst b/docs/source/using_yosys/synthesis/fsm.rst index 11da17eba..e1ed55133 100644 --- a/docs/source/using_yosys/synthesis/fsm.rst +++ b/docs/source/using_yosys/synthesis/fsm.rst @@ -5,79 +5,22 @@ 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: -#. :cmd:ref:`fsm_detect` identifies FSM state registers and marks them - with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the - ``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" - *)`` to disable FSM optimization for a register. -#. :cmd:ref:`fsm_extract` replaces the entire FSM (logic and state registers) - with a ``$fsm`` cell. -#. :cmd:ref:`fsm_opt` optimizes the FSM. Called multiple times. -#. :cmd:ref:`fsm_expand` optionally merges additional auxilliary gates into the - ``$fsm`` cell. -#. :cmd:ref:`fsm_recode` also optimizes the FSM. -#. :cmd:ref:`fsm_info` logs internal FSM information. -#. :cmd:ref:`fsm_export` optionally exports each FSM to KISS2 files. -#. :cmd:ref:`fsm_map` converts the (optimized) ``$fsm`` cell back to logic and - registers. +.. 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 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 :cmd:ref:`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: +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. @@ -101,7 +44,7 @@ results. FSM extraction ~~~~~~~~~~~~~~ -The fsm_extract pass operates on all state signals marked with the +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: @@ -142,8 +85,8 @@ 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: +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 @@ -163,8 +106,9 @@ 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): +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 @@ -188,10 +132,11 @@ state recoding). The following optimizations are performed (in this order): 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 :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 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. +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/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 71da211d5..f2bfe9650 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -7,19 +7,22 @@ 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 the other common -``memory_*`` commands in a sensible order: +address decoders and registers. It also is a macro command that calls the other +common ``memory_*`` passes in a sensible order: -.. todo:: fill out missing :cmd:ref:`memory` subcommands descriptions +.. literalinclude:: /code_examples/macro_commands/memory.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`memory` -#. :cmd:ref:`memory_bmux2rom` -#. :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. -#. :cmd:ref:`memory_share` -#. :cmd:ref:`memory_memx` -#. :cmd:ref:`memory_collect` collects all read and write cells for a memory and +.. 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_bram` -#. :cmd:ref:`memory_map` takes the multi-port memory cell and transforms it to +- :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 diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst index 498e1264a..265930c8c 100644 --- a/docs/source/using_yosys/synthesis/proc.rst +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -1,26 +1,21 @@ Converting process blocks ~~~~~~~~~~~~~~~~~~~~~~~~~ +.. role:: yoscrypt(code) + :language: yoscrypt + The Verilog frontend converts ``always``-blocks to RTL netlists for the expressions and "processess" for the control- and memory elements. The :cmd:ref:`proc` command then transforms these "processess" to netlists of RTL multiplexer and register cells. It also is a macro command that calls the other ``proc_*`` commands in a sensible order: -#. :cmd:ref:`proc_clean` removes empty branches and processes. -#. :cmd:ref:`proc_rmdead` removes unreachable branches. -#. :cmd:ref:`proc_prune` -#. :cmd:ref:`proc_init` special handling of "initial" blocks. -#. :cmd:ref:`proc_arst` identifies modeling of async resets. -#. :cmd:ref:`proc_rom` -#. :cmd:ref:`proc_mux` converts decision trees to multiplexer networks. -#. :cmd:ref:`proc_dlatch` -#. :cmd:ref:`proc_dff` extracts registers from processes. -#. :cmd:ref:`proc_memwr` -#. :cmd:ref:`proc_clean` this should remove all the processes, provided all went - fine. +.. literalinclude:: /code_examples/macro_commands/proc.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`proc` -After all the ``proc_*`` commands, :yoscrypt:`opt_expr` is called. This can be +After all the ``proc_*`` commands, :cmd:ref:`opt_expr` is called. This can be disabled by calling :yoscrypt:`proc -noopt`. For more information about :cmd:ref:`proc`, such as disabling certain sub commands, see :doc:`/cmd/proc`. diff --git a/docs/source/using_yosys/synthesis/synth.rst b/docs/source/using_yosys/synthesis/synth.rst index c9ec45b8a..15d701fb4 100644 --- a/docs/source/using_yosys/synthesis/synth.rst +++ b/docs/source/using_yosys/synthesis/synth.rst @@ -43,4 +43,5 @@ The following commands are executed by the :cmd:ref:`prep` command: :end-before: .. raw:: latex :dedent: -The following sections will get more into what each of these commands do. +:doc:`/getting_started/example_synth` covers most of these commands and what +they do. diff --git a/docs/tests/macro_commands.py b/docs/tests/macro_commands.py index 7942e4d31..faf2baa53 100755 --- a/docs/tests/macro_commands.py +++ b/docs/tests/macro_commands.py @@ -35,7 +35,12 @@ for macro in MACRO_SOURCE.glob("*.ys"): # immediately after. start = f.readline() end = f.readline() - expected_content = f.readlines() + 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}") @@ -49,7 +54,11 @@ for macro in MACRO_SOURCE.glob("*.ys"): logging.error(f"Couldn't find {start!r} and/or {end!r} in `yosys -h {command}` output") raise_error = True continue - actual_content = match.group(1).strip().splitlines() + 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() @@ -59,7 +68,7 @@ for macro in MACRO_SOURCE.glob("*.ys"): continue # rip apart formatting to match line parts - pattern = r"(?P<cmd>\S+)(?P<pass> \[.*\])?(?P<opt>.*?)(?P<cond> \(.*\))?(?P<comment>\s+#.*)?" + pattern = r"(?P<cmd>\S+)(?P<pass> \[.*\])?(?P<opt>.*?)(?P<cond>\s+\(.*\))?" try: expected_dict = re.fullmatch(pattern, expected).groupdict() except AttributeError: From 9b820108d624562248b905679ae8419e646e4482 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:50:06 +1300 Subject: [PATCH 087/108] Docs: add test-docs.yml --- .github/workflows/test-docs.yml | 42 +++++++++++++++++++++++++++++++++ docs/Makefile | 6 +++++ 2 files changed, 48 insertions(+) create mode 100644 .github/workflows/test-docs.yml diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml new file mode 100644 index 000000000..2c69e0170 --- /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 python 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/docs/Makefile b/docs/Makefile index 2319e1665..41b24f937 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -224,3 +224,9 @@ dummy: $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy @echo @echo "Build finished. Dummy builder generates no files." + +PYTHON ?= python3 + +.PHONY: test +test: + $(PYTHON) tests/macro_commands.py From e10d9b1fe0f4c2a9fade217e85ab8275937e24a4 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:38:50 +1300 Subject: [PATCH 088/108] Remove python dep from test-docs --- .github/workflows/test-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml index 2c69e0170..e8064e485 100644 --- a/.github/workflows/test-docs.yml +++ b/.github/workflows/test-docs.yml @@ -13,7 +13,7 @@ jobs: 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 python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev + 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 From 57a7532227c021c13a19b97b10887800b7da094a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:15:00 +1300 Subject: [PATCH 089/108] Docs: add test-examples target `test` becomes `test-macros`, with a new `test` calling both `test-*` targets. --- docs/Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 41b24f937..56d59cb3a 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -227,6 +227,11 @@ dummy: PYTHON ?= python3 -.PHONY: test -test: +.PHONY: test test-examples test-macros +test: test-examples test-macros + +test-examples: + $(MAKE) -C source/_images examples + +test-macros: $(PYTHON) tests/macro_commands.py From bb4d69005f766a7c5c3e497da8399cb762efb1c9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:15:43 +1300 Subject: [PATCH 090/108] Docs: can we re-use build artifacts? --- .github/workflows/test-linux.yml | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 103c060a2..a3f34d692 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -113,8 +113,44 @@ jobs: make config-${CC%%-*} make -j${{ env.procs }} CCXXSTD=${{ 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 run: | make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC + + test-docs: + name: test documentation code samples + needs: test-linux + 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: Runtime environment + shell: bash + env: + WORKSPACE: ${{ github.workspace }} + run: | + echo "procs=$(nproc)" >> $GITHUB_ENV + + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: compiled-yosys + + - name: Run tests + shell: bash + run: | + make -C docs test -j${{ env.procs }} + From 4ac983e56c99454b4675eff211ca64e6e68ae3a5 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:32:39 +1300 Subject: [PATCH 091/108] test-docs: Checkout Yosys --- .github/workflows/test-linux.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index a3f34d692..15f922d78 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -144,6 +144,9 @@ jobs: run: | echo "procs=$(nproc)" >> $GITHUB_ENV + - name: Checkout Yosys + uses: actions/checkout@v4 + - name: Download build artifact uses: actions/download-artifact@v4 with: From 2a14c721100270bf4ecbf186861f7dc7ddeae1de Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:36:59 +1300 Subject: [PATCH 092/108] test-docs: target examples directly --- docs/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 56d59cb3a..71a6b3152 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -230,8 +230,12 @@ PYTHON ?= python3 .PHONY: test test-examples test-macros test: test-examples test-macros -test-examples: - $(MAKE) -C source/_images examples +FORCE: +../%/Makefile: FORCE + +$(MAKE) -C $(@D) + +CODE_EXAMPLES := source/code_examples/*/Makefile +test-examples: $(CODE_EXAMPLES) test-macros: $(PYTHON) tests/macro_commands.py From 62d2f89c74ee4065fcd7b1e39c2aece4f0a99442 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:18:06 +1300 Subject: [PATCH 093/108] Revert artifact reuse --- .github/workflows/test-linux.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 15f922d78..40b81e217 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -125,35 +125,3 @@ jobs: shell: bash run: | make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC - - test-docs: - name: test documentation code samples - needs: test-linux - 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: Runtime environment - shell: bash - env: - WORKSPACE: ${{ github.workspace }} - run: | - echo "procs=$(nproc)" >> $GITHUB_ENV - - - name: Checkout Yosys - uses: actions/checkout@v4 - - - name: Download build artifact - uses: actions/download-artifact@v4 - with: - name: compiled-yosys - - - name: Run tests - shell: bash - run: | - make -C docs test -j${{ env.procs }} - From 6e38848b92e078f9d0f263b54adb7b84cb9f5eb3 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:35:03 +1300 Subject: [PATCH 094/108] Docs: updating makefiles --- Makefile | 11 +++++---- docs/Makefile | 23 ++++++++++++++----- docs/source/code_examples/extensions/Makefile | 11 +++++---- docs/source/code_examples/fifo/Makefile | 5 ++-- docs/source/code_examples/intro/Makefile | 1 + docs/source/code_examples/macc/Makefile | 1 + docs/source/code_examples/opt/Makefile | 1 + docs/source/code_examples/scrambler/Makefile | 2 ++ docs/source/code_examples/selections/Makefile | 2 ++ docs/source/code_examples/show/Makefile | 4 +++- docs/source/code_examples/stubnets/Makefile | 4 ++++ docs/source/code_examples/synth_flow/Makefile | 2 ++ docs/source/code_examples/techmap/Makefile | 2 ++ .../extending_yosys/extensions.rst | 2 ++ 14 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 753ff9b92..cdcf96b0c 100644 --- a/Makefile +++ b/Makefile @@ -971,9 +971,12 @@ 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 docs/usage +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/source/_images all + $(Q) $(MAKE) -C docs images DOCS_GUIDELINE_FILES := GettingStarted CodingStyle docs/guidelines: @@ -988,7 +991,7 @@ 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/usage +docs: docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage $(Q) $(MAKE) -C docs $(DOC_TARGET) clean: @@ -1007,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/source/_images clean - rm -rf docs/source/cmd docs/util/__pycache__ clean-abc: $(MAKE) -C abc DEP= clean diff --git a/docs/Makefile b/docs/Makefile index 71a6b3152..c2e730fa8 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: @@ -227,15 +229,24 @@ dummy: PYTHON ?= python3 -.PHONY: test test-examples test-macros +.PHONY: test test-examples test-macros examples test: test-examples test-macros FORCE: -../%/Makefile: FORCE - +$(MAKE) -C $(@D) +Makefile-%: FORCE + $(MAKE) -C $(@D) $(*F) -CODE_EXAMPLES := source/code_examples/*/Makefile -test-examples: $(CODE_EXAMPLES) +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/source/code_examples/extensions/Makefile b/docs/source/code_examples/extensions/Makefile index bec29369c..288983ed3 100644 --- a/docs/source/code_examples/extensions/Makefile +++ b/docs/source/code_examples/extensions/Makefile @@ -2,15 +2,15 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys -all: test0.log test1.log test2.log - +.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 + $(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 @@ -20,10 +20,13 @@ 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: +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/docs/source/code_examples/fifo/Makefile b/docs/source/code_examples/fifo/Makefile index 37ce0a12c..0a1186a62 100644 --- a/docs/source/code_examples/fifo/Makefile +++ b/docs/source/code_examples/fifo/Makefile @@ -10,12 +10,13 @@ MAPDOT_NAMES += rdata_map_ffs rdata_map_luts rdata_map_cells DOTS := $(addsuffix .dot,$(DOT_NAMES)) MAPDOTS := $(addsuffix .dot,$(MAPDOT_NAMES)) -dots: $(DOTS) $(MAPDOTS) fifo.out +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.v fifo_map.ys +$(MAPDOTS) fifo.stat: fifo.v fifo_map.ys $(YOSYS) fifo_map.ys .PHONY: clean diff --git a/docs/source/code_examples/intro/Makefile b/docs/source/code_examples/intro/Makefile index e6509681f..009c82c62 100644 --- a/docs/source/code_examples/intro/Makefile +++ b/docs/source/code_examples/intro/Makefile @@ -4,6 +4,7 @@ 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 diff --git a/docs/source/code_examples/macc/Makefile b/docs/source/code_examples/macc/Makefile index 57ba455bb..e93fe0657 100644 --- a/docs/source/code_examples/macc/Makefile +++ b/docs/source/code_examples/macc/Makefile @@ -4,6 +4,7 @@ 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 diff --git a/docs/source/code_examples/opt/Makefile b/docs/source/code_examples/opt/Makefile index e59130ecd..4cb51e90b 100644 --- a/docs/source/code_examples/opt/Makefile +++ b/docs/source/code_examples/opt/Makefile @@ -6,6 +6,7 @@ DOT_NAMES = opt_share opt_muxtree opt_merge opt_expr DOTS := $(addsuffix .dot,$(DOT_NAMES)) +all: dots dots: $(DOTS) %_full.dot: %.ys diff --git a/docs/source/code_examples/scrambler/Makefile b/docs/source/code_examples/scrambler/Makefile index 4fdb0610a..de475b8b1 100644 --- a/docs/source/code_examples/scrambler/Makefile +++ b/docs/source/code_examples/scrambler/Makefile @@ -2,6 +2,8 @@ PROGRAM_PREFIX := YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys +.PHONY: all dots +all: dots dots: scrambler_p01.dot scrambler_p02.dot scrambler_p01.dot scrambler_p02.dot: scrambler.ys scrambler.v diff --git a/docs/source/code_examples/selections/Makefile b/docs/source/code_examples/selections/Makefile index 06abd2a3e..bb506ff38 100644 --- a/docs/source/code_examples/selections/Makefile +++ b/docs/source/code_examples/selections/Makefile @@ -11,6 +11,8 @@ MEMDEMO_DOTS := $(addsuffix .dot,$(MEMDEMO)) SUBMOD = submod_00 submod_01 submod_02 submod_03 SUBMOD_DOTS := $(addsuffix .dot,$(SUBMOD)) +.PHONY: all dots +all: dots dots: select.dot $(SUMPROD_DOTS) $(MEMDEMO_DOTS) $(SUBMOD_DOTS) select.dot: select.v select.ys diff --git a/docs/source/code_examples/show/Makefile b/docs/source/code_examples/show/Makefile index c254ed255..4b269a4ab 100644 --- a/docs/source/code_examples/show/Makefile +++ b/docs/source/code_examples/show/Makefile @@ -8,7 +8,9 @@ EXAMPLE_DOTS := $(addsuffix .dot,$(EXAMPLE)) CMOS = cmos_00 cmos_01 CMOS_DOTS := $(addsuffix .dot,$(CMOS)) -dots: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) example.out +.PHONY: all dots +all: dots example.out +dots: splice.dot $(EXAMPLE_DOTS) $(CMOS_DOTS) splice.dot: splice.v $(YOSYS) -p 'prep -top splice_demo; show -format dot -prefix splice' splice.v diff --git a/docs/source/code_examples/stubnets/Makefile b/docs/source/code_examples/stubnets/Makefile index cbcd71113..ec501f006 100644 --- a/docs/source/code_examples/stubnets/Makefile +++ b/docs/source/code_examples/stubnets/Makefile @@ -1,5 +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" @@ -9,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/code_examples/synth_flow/Makefile b/docs/source/code_examples/synth_flow/Makefile index af5d41493..cc5a34b26 100644 --- a/docs/source/code_examples/synth_flow/Makefile +++ b/docs/source/code_examples/synth_flow/Makefile @@ -9,6 +9,8 @@ YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys DOTS = $(addsuffix .dot,$(TARGETS)) +.PHONY: all dots +all: dots dots: $(DOTS) %.dot: %.v %.ys diff --git a/docs/source/code_examples/techmap/Makefile b/docs/source/code_examples/techmap/Makefile index e4e0ac745..e900fea4c 100644 --- a/docs/source/code_examples/techmap/Makefile +++ b/docs/source/code_examples/techmap/Makefile @@ -2,6 +2,8 @@ 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_* diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index ab8cf0cb6..2d6847f25 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -6,6 +6,8 @@ Writing extensions .. todo:: check text is coherent +.. todo:: update to use ``/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. From 4582ab59daa6a095f8bfcd96b9bc2687b8958c85 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:15:01 +1300 Subject: [PATCH 095/108] Docs: intro to memory_libmap --- docs/source/using_yosys/synthesis/memory.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index f2bfe9650..2378af542 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -60,8 +60,6 @@ Example Memory mapping ^^^^^^^^^^^^^^ -.. TODO:: :cmd:ref:`memory_libmap` description - Usually it is preferred to use architecture-specific RAM resources for memory. For example: @@ -72,6 +70,18 @@ For example: 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 (``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. + +For more on the lib format for :cmd:ref:`memory_libmap`, see +`passes/memory/memlib.md +<https://github.com/YosysHQ/yosys/blob/master/passes/memory/memlib.md>`_ + Supported memory patterns ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,8 +92,6 @@ 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. -See also: `passes/memory/memlib.md <https://github.com/YosysHQ/yosys/blob/master/passes/memory/memlib.md>`_ - Notes ----- From e2e7065590ff8dbd1baa7bbfd9c91fb890428f55 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:06:02 +1300 Subject: [PATCH 096/108] Docs: some restructure of advanced section - Filling out index descriptions for `using_yosys` and `using_yosys/synthesis`. - To discourage skipping over these index pages, the toctree in `using_yosys/index` is hidden and instead has inline links to the two subsections. - Tidying todos. - Moves technology mapping to `techmap_synth`, leaving the techmap by example in the internals section. `yosys_flows` gets split up, with the coarse-grain intro replaced by `synthesis/index`, the extract pass moving to `synthesis/extract` and model checking to `more_scripting/model_checking`. --- docs/source/index.rst | 17 ++- docs/source/using_yosys/index.rst | 18 ++- .../using_yosys/more_scripting/index.rst | 1 + .../more_scripting/model_checking.rst | 108 +++++++++++++ .../using_yosys/synthesis/cell_libs.rst | 4 - .../extract.rst} | 143 +----------------- docs/source/using_yosys/synthesis/index.rst | 20 ++- docs/source/using_yosys/synthesis/synth.rst | 2 + .../using_yosys/synthesis/techmap_synth.rst | 109 ++++++++++++- docs/source/yosys_internals/techmap.rst | 110 -------------- 10 files changed, 259 insertions(+), 273 deletions(-) create mode 100644 docs/source/using_yosys/more_scripting/model_checking.rst rename docs/source/using_yosys/{yosys_flows.rst => synthesis/extract.rst} (63%) diff --git a/docs/source/index.rst b/docs/source/index.rst index bbefa521f..582551f74 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -33,12 +33,13 @@ available, go to :ref:`commandindex`. ----------------- .. toctree:: - :maxdepth: 3 - - introduction - getting_started/index - using_yosys/index - yosys_internals/index - test_suites + :maxdepth: 3 + :includehidden: - appendix + introduction + getting_started/index + using_yosys/index + yosys_internals/index + test_suites + + appendix diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst index 91d34bfe4..55bd5c291 100644 --- a/docs/source/using_yosys/index.rst +++ b/docs/source/using_yosys/index.rst @@ -1,11 +1,17 @@ Using Yosys (advanced) ====================== -.. todo:: brief overview for the using Yosys index +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 +.. toctree:: + :maxdepth: 2 + :hidden: - synthesis/index - more_scripting/index - yosys_flows + 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 index 2d67b6a09..490a5a7ad 100644 --- a/docs/source/using_yosys/more_scripting/index.rst +++ b/docs/source/using_yosys/more_scripting/index.rst @@ -9,5 +9,6 @@ More scripting load_design selections interactive_investigation + model_checking .. troubleshooting diff --git a/docs/source/using_yosys/more_scripting/model_checking.rst b/docs/source/using_yosys/more_scripting/model_checking.rst new file mode 100644 index 000000000..f0171b14c --- /dev/null +++ b/docs/source/using_yosys/more_scripting/model_checking.rst @@ -0,0 +1,108 @@ +Symbolic model checking +----------------------- + +.. todo:: check text context + +.. 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. + +Symbolic Model Checking (SMC) is used to formally prove that a circuit has (or +has not) a given property. + +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. + +Other applications include checking if a module conforms to interface standards. + +The :cmd:ref:`sat` command in Yosys can be used to perform Symbolic Model +Checking. + +Checking techmap +~~~~~~~~~~~~~~~~ + +.. todo:: add/expand supporting text + +Let's look at the following example: + +.. literalinclude:: /code_examples/synth_flow/techmap_01_map.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` + +.. literalinclude:: /code_examples/synth_flow/techmap_01.v + :language: verilog + :caption: ``docs/source/code_examples/synth_flow/techmap_01.v`` + +.. literalinclude:: /code_examples/synth_flow/techmap_01.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` + +To see if it is correct we can use the following code: + +.. todo:: replace inline yosys script code + +.. code:: yoscrypt + + # 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 + +Result: + +.. code:: + + Solving problem with 945 variables and 2505 clauses.. + SAT proof finished - no model found: SUCCESS! + +AXI4 Stream Master +~~~~~~~~~~~~~~~~~~ + +The following AXI4 Stream Master has a bug. But the bug is not exposed if the +slave keeps ``tready`` asserted all the time. (Something a test bench might do.) + +Symbolic Model Checking can be used to expose the bug and find a sequence of +values for ``tready`` that yield the incorrect behavior. + +.. todo:: add/expand supporting text + +.. literalinclude:: /code_examples/axis/axis_master.v + :language: verilog + :caption: ``docs/source/code_examples/axis/axis_master.v`` + +.. literalinclude:: /code_examples/axis/axis_test.v + :language: verilog + :caption: ``docs/source/code_examples/axis/axis_test.v`` + +.. literalinclude:: /code_examples/axis/axis_test.ys + :language: yoscrypt + :caption: ``docs/source/code_examples/axis/test.ys`` + +Result with unmodified ``axis_master.v``: + +.. code:: + + Solving problem with 159344 variables and 442126 clauses.. + SAT proof finished - model found: FAIL! + +Result with fixed ``axis_master.v``: + +.. code:: + + Solving problem with 159144 variables and 441626 clauses.. + SAT proof finished - no model found: SUCCESS! diff --git a/docs/source/using_yosys/synthesis/cell_libs.rst b/docs/source/using_yosys/synthesis/cell_libs.rst index 5f54b894f..4353b3cdc 100644 --- a/docs/source/using_yosys/synthesis/cell_libs.rst +++ b/docs/source/using_yosys/synthesis/cell_libs.rst @@ -73,8 +73,6 @@ Coarse-grain representation Logic gate mapping ~~~~~~~~~~~~~~~~~~ -.. TODO:: comment on similarities and/or differences with example_synth - .. literalinclude:: /code_examples/intro/counter.ys :language: yoscrypt :lines: 14-15 @@ -89,8 +87,6 @@ Logic gate mapping Mapping to hardware ~~~~~~~~~~~~~~~~~~~ -.. todo:: are we recalling or is this new information - For this example, we are using a Liberty file to describe a cell library which our internal cell library will be mapped to: diff --git a/docs/source/using_yosys/yosys_flows.rst b/docs/source/using_yosys/synthesis/extract.rst similarity index 63% rename from docs/source/using_yosys/yosys_flows.rst rename to docs/source/using_yosys/synthesis/extract.rst index 5bca90ade..c5a64273a 100644 --- a/docs/source/using_yosys/yosys_flows.rst +++ b/docs/source/using_yosys/synthesis/extract.rst @@ -1,35 +1,5 @@ -Flows, command types, and order -=============================== - -Command order -------------- - -.. todo:: More surrounding text (esp as it relates to command order) - -Intro to coarse-grain synthesis -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In coarse-grain synthesis the target architecture has cells of the same -complexity or larger complexity than the internal RTL representation. - -For example: - -.. code:: verilog - - wire [15:0] a, b; - wire [31:0] c, y; - assign y = a * b + c; - -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. - -Fine-grain synthesis would be matching the circuit elements to smaller -components, such as LUTs, gates, or half- and full-adders. - 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 @@ -255,113 +225,4 @@ Unwrap in ``test2``: :end-before: end part e .. figure:: /_images/code_examples/macc/macc_xilinx_test2e.* - :class: width-helper - -Symbolic model checking ------------------------ - -.. todo:: check text context - -.. 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. - -Symbolic Model Checking (SMC) is used to formally prove that a circuit has (or -has not) a given property. - -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. - -Other applications include checking if a module conforms to interface standards. - -The :cmd:ref:`sat` command in Yosys can be used to perform Symbolic Model -Checking. - -Checking techmap -~~~~~~~~~~~~~~~~ - -.. todo:: add/expand supporting text - -Let's look at the following example: - -.. literalinclude:: /code_examples/synth_flow/techmap_01_map.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` - -.. literalinclude:: /code_examples/synth_flow/techmap_01.v - :language: verilog - :caption: ``docs/source/code_examples/synth_flow/techmap_01.v`` - -.. literalinclude:: /code_examples/synth_flow/techmap_01.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` - -To see if it is correct we can use the following code: - -.. todo:: replace inline yosys script code - -.. code:: yoscrypt - - # 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 - -Result: - -.. code:: - - Solving problem with 945 variables and 2505 clauses.. - SAT proof finished - no model found: SUCCESS! - -AXI4 Stream Master -~~~~~~~~~~~~~~~~~~ - -The following AXI4 Stream Master has a bug. But the bug is not exposed if the -slave keeps ``tready`` asserted all the time. (Something a test bench might do.) - -Symbolic Model Checking can be used to expose the bug and find a sequence of -values for ``tready`` that yield the incorrect behavior. - -.. todo:: add/expand supporting text - -.. literalinclude:: /code_examples/axis/axis_master.v - :language: verilog - :caption: ``docs/source/code_examples/axis/axis_master.v`` - -.. literalinclude:: /code_examples/axis/axis_test.v - :language: verilog - :caption: ``docs/source/code_examples/axis/axis_test.v`` - -.. literalinclude:: /code_examples/axis/axis_test.ys - :language: yoscrypt - :caption: ``docs/source/code_examples/axis/test.ys`` - -Result with unmodified ``axis_master.v``: - -.. code:: - - Solving problem with 159344 variables and 442126 clauses.. - SAT proof finished - model found: FAIL! - -Result with fixed ``axis_master.v``: - -.. code:: - - Solving problem with 159144 variables and 441626 clauses.. - SAT proof finished - no model found: SUCCESS! + :class: width-helper \ No newline at end of file diff --git a/docs/source/using_yosys/synthesis/index.rst b/docs/source/using_yosys/synthesis/index.rst index 095dd4b61..c00a940da 100644 --- a/docs/source/using_yosys/synthesis/index.rst +++ b/docs/source/using_yosys/synthesis/index.rst @@ -1,7 +1,24 @@ Synthesis in detail ------------------- -.. todo:: brief overview for the synthesis index +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 @@ -12,6 +29,7 @@ Synthesis in detail memory opt techmap_synth + extract abc cell_libs diff --git a/docs/source/using_yosys/synthesis/synth.rst b/docs/source/using_yosys/synthesis/synth.rst index 15d701fb4..cba7db1a7 100644 --- a/docs/source/using_yosys/synthesis/synth.rst +++ b/docs/source/using_yosys/synthesis/synth.rst @@ -1,6 +1,8 @@ Synth commands -------------- +.. todo:: comment on common ``synth_*`` options, like ``-run`` + Packaged ``synth_*`` commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/synthesis/techmap_synth.rst b/docs/source/using_yosys/synthesis/techmap_synth.rst index db1d0c96a..dc9d8b195 100644 --- a/docs/source/using_yosys/synthesis/techmap_synth.rst +++ b/docs/source/using_yosys/synthesis/techmap_synth.rst @@ -1,4 +1,107 @@ -techmap_synth -------------- +Technology mapping +================== -.. TODO:: techmap_synth +.. todo:: less academic, check text is coherent + +Previous chapters outlined how HDL code is transformed into an RTL netlist. The +RTL netlist is still based on abstract coarse-grain cell types like arbitrary +width adders and even multipliers. This chapter covers how an RTL netlist is +transformed into a functionally equivalent netlist utilizing the cell types +available in the target architecture. + +Technology mapping is often performed in two phases. In the first phase RTL +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 +ALUs), these must be mapped to directly form the RTL netlist, as information on +the coarse-grain structure of the design is lost when it is mapped to bit-width +gate types. + +Cell substitution +----------------- + +The simplest form of technology mapping is cell substitution, as performed by +the techmap pass. This pass, when provided with a Verilog file that implements +the RTL cell types using simpler cells, simply replaces the RTL cells with the +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 +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 +architecture supports hardware multipliers for certain bit-widths but not for +others. + +A usual synthesis flow would first use the techmap pass to directly map some RTL +cells to coarse-grain cells provided by the target architecture (if any) and +then use techmap with the built-in default file to map the remaining RTL cells +to gate logic. + +Subcircuit substitution +----------------------- + +Sometimes the target architecture provides cells that are more powerful than the +RTL cells used by Yosys. For example a cell in the target architecture that can +calculate the absolute-difference of two numbers does not match any single RTL +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 +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 +design. This has a few applications, including the design of new coarse-grain +architectures :cite:p:`intersynthFdlBookChapter`. + +The hard algorithmic work done by the extract pass (solving the isomorphic +subcircuit problem and frequent subcircuit mining) is performed using the +SubCircuit library that can also be used stand-alone without Yosys (see +:ref:`sec:SubCircuit`). + +.. _sec:techmap_extern: + +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 it to this representation using the techmap pass) is performed in two +phases. + +First the register cells must be mapped to the registers that are available on +the target architectures. The target architecture might not provide all +variations of d-type flip-flops with positive and negative clock edge, +high-active and low-active asynchronous set and/or reset, etc. Therefore the +process of mapping the registers might add additional inverters to the design +and thus it is important to map the register cells first. + +Mapping of the register cells may be performed by using the dfflibmap pass. This +pass expects a Liberty file as argument (using the -liberty option) and only +uses the register cells from the Liberty file. + +Secondly the combinational logic must be mapped to the target architecture. This +is done using the external program ABC via the abc pass by using the -liberty +option to the pass. Note that in this case only the combinatorial cells are used +from the cell library. + +Occasionally Liberty files contain trade secrets (such as sensitive timing +information) that cannot be shared freely. This complicates processes such as +reporting bugs in the tools involved. When the information in the Liberty file +used by Yosys and ABC are not part of the sensitive information, the additional +tool yosys-filterlib (see :ref:`sec:filterlib`) can be used to strip the +sensitive information from the Liberty file. diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index d7186ab6c..ce40ea19c 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -1,113 +1,3 @@ -.. _chapter:techmap: - -.. todo:: less academic, check text is coherent - -.. TODO:: can we split some of this into synthesis/techmap ? - -Technology mapping -================== - -Previous chapters outlined how HDL code is transformed into an RTL netlist. The -RTL netlist is still based on abstract coarse-grain cell types like arbitrary -width adders and even multipliers. This chapter covers how an RTL netlist is -transformed into a functionally equivalent netlist utilizing the cell types -available in the target architecture. - -Technology mapping is often performed in two phases. In the first phase RTL -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 -ALUs), these must be mapped to directly form the RTL netlist, as information on -the coarse-grain structure of the design is lost when it is mapped to bit-width -gate types. - -Cell substitution ------------------ - -The simplest form of technology mapping is cell substitution, as performed by -the techmap pass. This pass, when provided with a Verilog file that implements -the RTL cell types using simpler cells, simply replaces the RTL cells with the -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 -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 -architecture supports hardware multipliers for certain bit-widths but not for -others. - -A usual synthesis flow would first use the techmap pass to directly map some RTL -cells to coarse-grain cells provided by the target architecture (if any) and -then use techmap with the built-in default file to map the remaining RTL cells -to gate logic. - -Subcircuit substitution ------------------------ - -Sometimes the target architecture provides cells that are more powerful than the -RTL cells used by Yosys. For example a cell in the target architecture that can -calculate the absolute-difference of two numbers does not match any single RTL -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 -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 -design. This has a few applications, including the design of new coarse-grain -architectures :cite:p:`intersynthFdlBookChapter`. - -The hard algorithmic work done by the extract pass (solving the isomorphic -subcircuit problem and frequent subcircuit mining) is performed using the -SubCircuit library that can also be used stand-alone without Yosys (see -:ref:`sec:SubCircuit`). - -.. _sec:techmap_extern: - -Gate-level technology mapping ------------------------------ - -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 it to this representation using the techmap pass) is performed in two -phases. - -First the register cells must be mapped to the registers that are available on -the target architectures. The target architecture might not provide all -variations of d-type flip-flops with positive and negative clock edge, -high-active and low-active asynchronous set and/or reset, etc. Therefore the -process of mapping the registers might add additional inverters to the design -and thus it is important to map the register cells first. - -Mapping of the register cells may be performed by using the dfflibmap pass. This -pass expects a Liberty file as argument (using the -liberty option) and only -uses the register cells from the Liberty file. - -Secondly the combinational logic must be mapped to the target architecture. This -is done using the external program ABC via the abc pass by using the -liberty -option to the pass. Note that in this case only the combinatorial cells are used -from the cell library. - -Occasionally Liberty files contain trade secrets (such as sensitive timing -information) that cannot be shared freely. This complicates processes such as -reporting bugs in the tools involved. When the information in the Liberty file -used by Yosys and ABC are not part of the sensitive information, the additional -tool yosys-filterlib (see :ref:`sec:filterlib`) can be used to strip the -sensitive information from the Liberty file. - Techmap by example ------------------ From 22808e0e3f3ab9e4e9cb55384a96df730a32fe39 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:29:59 +1300 Subject: [PATCH 097/108] Docs: work on selections.rst Highlighting the difference between `select prod %ci` and `select prod %ci2` by introducing `sumproud.out` using the `dump` command. Playing around with advanced cone example code. --- .../code_examples/selections/memdemo.ys | 7 +- .../code_examples/selections/sumprod.out | 38 +++++++++ .../code_examples/selections/sumprod.ys | 3 + .../using_yosys/more_scripting/selections.rst | 81 +++++++++++-------- 4 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 docs/source/code_examples/selections/sumprod.out diff --git a/docs/source/code_examples/selections/memdemo.ys b/docs/source/code_examples/selections/memdemo.ys index e240f1621..cb7700a7e 100644 --- a/docs/source/code_examples/selections/memdemo.ys +++ b/docs/source/code_examples/selections/memdemo.ys @@ -4,6 +4,7 @@ prep -top memdemo; memory; opt cd memdemo show -format dot -prefix memdemo_00 show -format dot -prefix memdemo_01 y %ci2 -show -format dot -prefix memdemo_02 y %ci2:+$dff[Q,D] -show -format dot -prefix memdemo_03 y %ci2:-[CLK] %ci2 -show -format dot -prefix memdemo_04 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff +show -format dot -prefix memdemo_02 y %ci5 +show -format dot -prefix memdemo_03 y %ci5:-$mux[S] +show -format dot -prefix memdemo_04 y %ci*:-[CLK,S]:+$dff,$mux +show -format dot -prefix memdemo_05 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff diff --git a/docs/source/code_examples/selections/sumprod.out b/docs/source/code_examples/selections/sumprod.out new file mode 100644 index 000000000..f7c259499 --- /dev/null +++ b/docs/source/code_examples/selections/sumprod.out @@ -0,0 +1,38 @@ + + + attribute \src "sumprod.v:4.21-4.25" + wire width 8 output 5 \prod + + attribute \src "sumprod.v:10.17-10.26" + cell $mul $mul$sumprod.v:10$4 + parameter \A_SIGNED 0 + parameter \A_WIDTH 8 + parameter \B_SIGNED 0 + parameter \B_WIDTH 8 + parameter \Y_WIDTH 8 + connect \A $mul$sumprod.v:10$3_Y + connect \B \c + connect \Y \prod + end + + + attribute \src "sumprod.v:10.17-10.22" + wire width 8 $mul$sumprod.v:10$3_Y + + attribute \src "sumprod.v:3.21-3.22" + wire width 8 input 3 \c + + attribute \src "sumprod.v:4.21-4.25" + wire width 8 output 5 \prod + + attribute \src "sumprod.v:10.17-10.26" + cell $mul $mul$sumprod.v:10$4 + parameter \A_SIGNED 0 + parameter \A_WIDTH 8 + parameter \B_SIGNED 0 + parameter \B_WIDTH 8 + parameter \Y_WIDTH 8 + connect \A $mul$sumprod.v:10$3_Y + connect \B \c + connect \Y \prod + end diff --git a/docs/source/code_examples/selections/sumprod.ys b/docs/source/code_examples/selections/sumprod.ys index 1e687fa4e..67e2a28d5 100644 --- a/docs/source/code_examples/selections/sumprod.ys +++ b/docs/source/code_examples/selections/sumprod.ys @@ -8,3 +8,6 @@ show -format dot -prefix sumprod_02 prod show -format dot -prefix sumprod_03 prod %ci show -format dot -prefix sumprod_04 prod %ci2 show -format dot -prefix sumprod_05 prod %ci3 + +dump -o sumprod.out prod %ci +dump -a sumprod.out prod %ci2 diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 2bc6540b8..517304fad 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -197,22 +197,39 @@ The following sequence of diagrams demonstrates this step-wise expansion: .. figure:: /_images/code_examples/selections/sumprod_02.* :class: width-helper - Output of ``show prod`` on :numref:`sumprod` + Output of :yoscrypt:`show prod` on :numref:`sumprod` .. figure:: /_images/code_examples/selections/sumprod_03.* :class: width-helper - Output of ``show prod %ci`` on :numref:`sumprod` + Output of :yoscrypt:`show prod %ci` on :numref:`sumprod` .. figure:: /_images/code_examples/selections/sumprod_04.* :class: width-helper - Output of ``show prod %ci %ci`` on :numref:`sumprod` + Output of :yoscrypt:`show prod %ci %ci` on :numref:`sumprod` .. figure:: /_images/code_examples/selections/sumprod_05.* :class: width-helper - Output of ``show prod %ci %ci %ci`` on :numref:`sumprod` + 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 @@ -263,9 +280,6 @@ diagram in :numref:`memdemo_00`. Complete circuit diagram for the design shown in :numref:`memdemo_src` -.. TODO:: :ref:`memdemo_01` and :ref:`memdemo_02` are the same, probably change - the example so they aren't. - 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 @@ -279,51 +293,52 @@ cones`_ from above, we can use :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 :yoscrypt:`show y %ci2:+$dff[Q,D]`, that tells it to only follow -ports ``Q`` and ``D`` of ``$dff`` cells: +``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 %ci2:+$dff[Q,D]` + Output of :yoscrypt:`show y %ci5` -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. - -Since we know that the only cell considered in this case is a ``$dff`` cell, we -could as well only specify the port names, :yoscrypt:`show y %ci2:+[Q,D]`. Or we -could decide to tell the ``%ci`` action to not follow the ``CLK`` input, -:yoscrypt:`show y %ci2:-[CLK]`. - -Next we would investigate the next logic level by adding another ``%ci2`` to the -command, :yoscrypt:`show y %ci2:-[CLK] %ci2`: +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 %ci2:-[CLK] %ci2` + Output of :yoscrypt:`show y %ci5:-$mux[S]` -From this we would learn that the next cell is a ``$mux`` cell and we would add -an additional pattern to narrow the selection on the path we are interested. In -the end we would end up with a command such as :yoscrypt:`show y %ci2:+$dff[Q,D] +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. The diagram produced by this -command is shown in :numref:`memdemo_04`. +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 ``show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff`` + 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 From a7e1c6e530fd6cb6447efef401612eaaaff2e6c8 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 27 Jan 2024 11:32:08 +1300 Subject: [PATCH 098/108] codeowners: adopting docs folder --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index a33a9a68c..7d680e9f2 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 From 9878e69d6c6450a90f16f4c5649328221ebaa968 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:31:00 +1300 Subject: [PATCH 099/108] Docs: tidying - Use `:file:` role for file names, as well as `:makevar:` and `:program:`. - Remove deprecated `linux-arm` and `linux-riscv64` oss-cad-suite targets. - Add link to ABC. - More (and better) links to code examples. Formatted `:file:` text with link to source on github. - Includes a few extra todos (mostly picking up inline code blocks and a couple intro reminders). - Fixing a few missing `:yoscrypt:` and `:cmd:ref:` tags. - Reflowing some paragraphs for spacing/width. --- docs/source/appendix/env_vars.rst | 10 +- docs/source/getting_started/example_synth.rst | 22 ++-- docs/source/getting_started/installation.rst | 38 +++--- .../getting_started/scripting_intro.rst | 32 ++--- .../interactive_investigation.rst | 109 +++++++++++------- .../more_scripting/model_checking.rst | 32 +++-- .../using_yosys/more_scripting/selections.rst | 28 +++-- .../using_yosys/synthesis/cell_libs.rst | 28 ++--- docs/source/using_yosys/synthesis/extract.rst | 45 ++++---- docs/source/using_yosys/synthesis/memory.rst | 15 ++- docs/source/using_yosys/synthesis/proc.rst | 17 ++- .../extending_yosys/abc_flow.rst | 10 +- .../extending_yosys/extensions.rst | 41 ++++--- docs/source/yosys_internals/flow/index.rst | 1 - .../yosys_internals/flow/verilog_frontend.rst | 73 ++++++------ .../yosys_internals/formats/cell_library.rst | 45 ++++---- docs/source/yosys_internals/formats/index.rst | 2 + docs/source/yosys_internals/techmap.rst | 55 +++++---- 18 files changed, 348 insertions(+), 255 deletions(-) diff --git a/docs/source/appendix/env_vars.rst b/docs/source/appendix/env_vars.rst index bb8ef34df..26cc37c81 100644 --- a/docs/source/appendix/env_vars.rst +++ b/docs/source/appendix/env_vars.rst @@ -2,10 +2,10 @@ Yosys environment variables =========================== ``HOME`` - Yosys command history is stored in ``$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 ``~``. + 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. @@ -14,7 +14,7 @@ Yosys environment variables Used for storing temporary files. ``ABC`` - When compiling Yosys with out-of-tree ABC using ``ABCEXTERNAL``, this + When compiling Yosys with out-of-tree ABC using :makevar:`ABCEXTERNAL`, this variable can be used to override the external ABC executable. ``YOSYS_NOVERIFIC`` diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index edeb2c118..371115117 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -26,7 +26,7 @@ First, let's quickly look at the design we'll be synthesizing: .. literalinclude:: /code_examples/fifo/fifo.v :language: Verilog :linenos: - :caption: ``fifo.v`` + :caption: :file:`fifo.v` :name: fifo-v .. todo:: fifo.v description @@ -36,7 +36,7 @@ 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 ``fifo.v`` and convert it into an Abstract Syntax Tree +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 @@ -214,7 +214,7 @@ could restart our shell session, but instead let's use two new commands: :language: doscon :start-at: design -reset :end-before: yosys> proc - :caption: reloading ``fifo.v`` and running :yoscrypt:`hierarchy -check -top fifo` + :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 @@ -234,7 +234,7 @@ design. If we know that our design won't run into this issue, we can skip the 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 ``fifo.ys``. There are extra commands being run + 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 ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys @@ -305,8 +305,8 @@ optimizations between modules which would otherwise be missed. Let's run 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 ``fifo_reader.addr`` and -merged with the ``raddr`` wire feeding into the ``$memrd`` cell. This wire +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 that in an interactive terminal the outputs of :cmd:ref:`flatten` and :cmd:ref:`clean` will be combined into a single @@ -803,11 +803,11 @@ The iCE40 synthesis flow has the following output modes available: - :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 ``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. +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 diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index e8dbbe77a..302d6d291 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -49,9 +49,7 @@ The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures: - Targeted for Windows 10 and 11, but older 64-bit version of Windows 7, 8, or 8.1 should work - - linux-arm |linux-arm| - linux-arm64 |linux-arm64| - - linux-riscv64 (untested) |linux-riscv64| .. _OSS CAD Suite: https://github.com/YosysHQ/oss-cad-suite-build .. _nightly builds: https://github.com/YosysHQ/oss-cad-suite-build/releases/latest @@ -60,9 +58,7 @@ The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures: .. |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-arm| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-arm.yml/badge.svg .. |linux-arm64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-arm64.yml/badge.svg -.. |linux-riscv64| image:: https://github.com/YosysHQ/oss-cad-suite-build/actions/workflows/linux-riscv64.yml/badge.svg Building from source ~~~~~~~~~~~~~~~~~~~~ @@ -133,8 +129,10 @@ Then, simply run ``make`` in this directory. make sudo make install -Note that this also downloads, builds, and installs ABC (using yosys-abc as the -executable name). +Note that this also downloads, builds, and installs `ABC`_ (using +:program:`yosys-abc` as the executable name). + +.. _ABC: https://github.com/berkeley-abc/abc .. seealso:: @@ -167,11 +165,12 @@ directories: ``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|cc}``), the ``main()`` function (``driver.cc``), the internal - framework for generating log messages (``log.{h|cc}``), the internal - framework for registering and calling passes (``register.{h|cc}``), some core - commands that are not really passes (``select.cc``, ``show.cc``, …) and a - couple of other small utility libraries. + (: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 @@ -182,7 +181,7 @@ directories: ``passes/`` This directory contains a subdirectory for each pass or group of passes. For - example as of this writing the directory ``passes/hierarchy/`` contains the + 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`. @@ -194,15 +193,16 @@ directories: This directory contains the suite of unit tests and regression tests used by Yosys. See :doc:`/test_suites`. -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. +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 ``passes/opt/opt_dff.cc`` and ``passes/opt/opt_merge.cc``. +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. diff --git a/docs/source/getting_started/scripting_intro.rst b/docs/source/getting_started/scripting_intro.rst index e971432c0..63eca9901 100644 --- a/docs/source/getting_started/scripting_intro.rst +++ b/docs/source/getting_started/scripting_intro.rst @@ -5,13 +5,13 @@ 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 ``.ys`` extension and contain a set of +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. +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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -21,7 +21,7 @@ The synthesis starter script All of the images and console output used in :doc:`/getting_started/example_synth` were generated by Yosys, using Yosys -script files found in ``docs/source/code_examples/fifo``. If you haven't +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 @@ -29,7 +29,7 @@ already, let's take a look at some of those script files now. :lineno-match: :start-at: echo on :end-before: design -reset - :caption: A section of ``fifo.ys``, generating the images used for :ref:`addr_gen_example` + :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 @@ -121,9 +121,9 @@ what the different symbols represent, see :ref:`interactive_show` and the .. _GraphViz: http://www.graphviz.org/ .. _xdot: https://github.com/jrfonseca/xdot.py -This is the first :yoscrypt:`show` command we called in ``fifo.ys``, :ref:`as we -saw above <fifo-ys>`. If we look at the log output for this image we see the -following: +This is the first :yoscrypt:`show` command we called in :file:`fifo.ys`, +:ref:`as we saw above <fifo-ys>`. If we look at the log output for this image +we see the following: .. literalinclude:: /code_examples/fifo/fifo.out :language: doscon @@ -131,14 +131,14 @@ following: :end-before: yosys> show Calling :cmd:ref:`show` with :yoscrypt:`-format dot` tells it we want to output -a ``.dot`` file rather than opening it for display. The :yoscrypt:`-prefix -addr_gen_show` option indicates we want the file to be called `addr_gen_show.*`. -Remember, we do this in ``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 ``.dot``. Check `GraphViz output docs`_ for more on -available formats. +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/ diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index 7e01ff06d..d0d78a783 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -1,6 +1,8 @@ Interactive design investigation -------------------------------- +.. todo:: interactive design opening text + .. role:: yoscrypt(code) :language: yoscrypt @@ -9,22 +11,24 @@ Interactive design investigation 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. +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. The -code used is included in the Yosys code base under -`docs/source/code_examples/show`_. - -.. _docs/source/code_examples/show: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/show +will use to demonstrate the usage of :cmd:ref:`show` in a simple setting. .. literalinclude:: /code_examples/show/example.v :language: Verilog - :caption: ``example.v`` + :caption: :file:`example.v` :name: example_v The Yosys synthesis script we will be running is included as @@ -36,7 +40,7 @@ synthesis. .. literalinclude:: /code_examples/show/example_show.ys :language: yoscrypt - :caption: ``example_show.ys`` + :caption: :file:`example_show.ys` :name: example_ys This script, when executed, will show the design after each of the three @@ -45,11 +49,11 @@ is shown. .. note:: - The images uses in this document are generated from the ``example.ys`` file, - rather than ``example_show.ys``. ``example.ys`` outputs the schematics as - ``.dot`` files rather than displaying them directly. You can view these - images yourself by running ``yosys example.ys`` and then ``xdot - example_first.dot`` etc. + 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 @@ -122,7 +126,7 @@ The code listing below shows a simple circuit which uses a lot of spliced signal accesses. .. literalinclude:: /code_examples/show/splice.v - :caption: ``docs/source/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 @@ -199,15 +203,15 @@ 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 <filename>`` option. Secondly it is possible to load cell libraries into the design with the -``read_verilog -lib <filename>`` 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. +:yoscrypt:`read_verilog -lib <filename>` 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 ``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. +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 ^^^^^^^^^^^^^^^^^^^ @@ -225,16 +229,16 @@ 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 :cmd:ref:`show` command. +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. +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 @@ -244,10 +248,12 @@ reproduced. So if, for example, the internal state before calling the 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 ``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``). +.. 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 ^^^^^^^^^^^^^^^^^^^^^^ @@ -263,13 +269,14 @@ 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 ``example.v`` from `A simple circuit`_: +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 ``yosys example.v`` + :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 @@ -324,6 +331,12 @@ tools). - :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 ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,11 +349,11 @@ reorganizing a module in Yosys and checking the resulting circuit. .. literalinclude:: /code_examples/scrambler/scrambler.v :language: verilog - :caption: ``docs/source/code_examples/scrambler/scrambler.v`` + :caption: :file:`scrambler.v` .. literalinclude:: /code_examples/scrambler/scrambler.ys :language: yoscrypt - :caption: ``docs/source/code_examples/scrambler/scrambler.ys`` + :caption: :file:`scrambler.ys` :end-before: cd .. .. figure:: /_images/code_examples/scrambler/scrambler_p01.* @@ -351,6 +364,8 @@ reorganizing a module in Yosys and checking the resulting circuit. Analyzing the resulting circuit with :doc:`/cmd/eval`: +.. todo:: replace inline code + .. code:: text > cd xorshift32 @@ -381,6 +396,8 @@ 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" *) @@ -435,7 +452,7 @@ sections: ``outstage``, ``selstage``, and ``scramble``. .. literalinclude:: /code_examples/selections/submod.ys :language: yoscrypt - :caption: Using :cmd:ref:`submod` to break up the circuit from ``memdemo.v`` + :caption: Using :cmd:ref:`submod` to break up the circuit from :file:`memdemo.v` :start-after: cd memdemo :end-before: cd .. :name: submod @@ -467,6 +484,8 @@ 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 @@ -535,6 +554,8 @@ 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 @@ -569,7 +590,7 @@ circuit.) .. literalinclude:: /code_examples/primetest.v :language: verilog - :caption: ``primetest.v``, a simple miter circuit for testing if a number is + :caption: :file:`primetest.v`, a simple miter circuit for testing if a number is prime. But it has a problem. :name: primetest @@ -577,8 +598,10 @@ circuit.) 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 ``primetest.v``. + :caption: Experiments with the miter circuit from :file:`primetest.v`. :name: prime_shell yosys [primetest]> sat -prove ok 1 -set p 31 @@ -621,8 +644,10 @@ 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 ``primetest.v``, with the upper 8 bits of ``a`` + :caption: Miter circuit from :file:`primetest.v`, with the upper 8 bits of ``a`` and ``b`` constrained to prevent overflow. :name: prime_fixed @@ -672,6 +697,8 @@ 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 \ @@ -695,6 +722,8 @@ 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 diff --git a/docs/source/using_yosys/more_scripting/model_checking.rst b/docs/source/using_yosys/more_scripting/model_checking.rst index f0171b14c..0f722e05c 100644 --- a/docs/source/using_yosys/more_scripting/model_checking.rst +++ b/docs/source/using_yosys/more_scripting/model_checking.rst @@ -25,23 +25,27 @@ Checking techmap .. todo:: add/expand supporting text -Let's look at the following example: +Let's take a look at an example included in the Yosys code base under +|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 .. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog - :caption: ``docs/source/code_examples/synth_flow/techmap_01_map.v`` + :caption: :file:`techmap_01_map.v` .. literalinclude:: /code_examples/synth_flow/techmap_01.v :language: verilog - :caption: ``docs/source/code_examples/synth_flow/techmap_01.v`` + :caption: :file:`techmap_01.v` .. literalinclude:: /code_examples/synth_flow/techmap_01.ys :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/techmap_01.ys`` + :caption: :file:`techmap_01.ys` To see if it is correct we can use the following code: -.. todo:: replace inline yosys script code +.. todo:: replace inline code .. code:: yoscrypt @@ -73,6 +77,12 @@ Result: AXI4 Stream Master ~~~~~~~~~~~~~~~~~~ +The code used in this section is included in the Yosys code base under +|code_examples/axis|_. + +.. |code_examples/axis| replace:: :file:`docs/source/code_examples/axis` +.. _code_examples/axis: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/axis + The following AXI4 Stream Master has a bug. But the bug is not exposed if the slave keeps ``tready`` asserted all the time. (Something a test bench might do.) @@ -83,24 +93,26 @@ values for ``tready`` that yield the incorrect behavior. .. literalinclude:: /code_examples/axis/axis_master.v :language: verilog - :caption: ``docs/source/code_examples/axis/axis_master.v`` + :caption: :file:`axis_master.v` .. literalinclude:: /code_examples/axis/axis_test.v :language: verilog - :caption: ``docs/source/code_examples/axis/axis_test.v`` + :caption: :file:`axis_test.v` .. literalinclude:: /code_examples/axis/axis_test.ys :language: yoscrypt - :caption: ``docs/source/code_examples/axis/test.ys`` + :caption: :file:`test.ys` -Result with unmodified ``axis_master.v``: +Result with unmodified :file:`axis_master.v`: + +.. todo:: replace inline code .. code:: Solving problem with 159344 variables and 442126 clauses.. SAT proof finished - model found: FAIL! -Result with fixed ``axis_master.v``: +Result with fixed :file:`axis_master.v`: .. code:: diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index 517304fad..72316d75a 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -7,6 +7,8 @@ Selections The selection framework ~~~~~~~~~~~~~~~~~~~~~~~ +.. todo:: reduce overlap with :doc:`/getting_started/scripting_intro` select section + The :cmd:ref:`select` command can be used to create a selection for subsequent commands. For example: @@ -56,7 +58,7 @@ in synthesis scripts that are hand-tailored for a specific design. Module and design context ^^^^^^^^^^^^^^^^^^^^^^^^^ -Commands can be executed in *module/* or *design/* context. Until now all +Commands can be executed in *module/* or *design/* context. Until now, all commands have been executed in design context. The :cmd:ref:`cd` command can be used to switch to module context. @@ -83,9 +85,12 @@ 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 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`. @@ -255,11 +260,11 @@ code is available in ``docs/source/code_examples/selections`` of the Yosys source repository. .. literalinclude:: /code_examples/selections/memdemo.v - :caption: ``memdemo.v`` + :caption: :file:`memdemo.v` :name: memdemo_src :language: verilog -The script ``memdemo.ys`` is used to generate the images included here. Let's +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 @@ -270,7 +275,7 @@ look at the first section: 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 ``memdemo.v`` is in the same directory. We can now change to the +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`. @@ -397,15 +402,18 @@ 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: +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: ``docs/source/code_examples/selections/select.v`` + :caption: :file:`select.v` .. literalinclude:: /code_examples/selections/select.ys :language: yoscrypt - :caption: ``docs/source/code_examples/selections/select.ys`` + :caption: :file:`select.ys` :name: select_ys .. figure:: /_images/code_examples/selections/select.* diff --git a/docs/source/using_yosys/synthesis/cell_libs.rst b/docs/source/using_yosys/synthesis/cell_libs.rst index 4353b3cdc..a2fac8dbf 100644 --- a/docs/source/using_yosys/synthesis/cell_libs.rst +++ b/docs/source/using_yosys/synthesis/cell_libs.rst @@ -7,16 +7,16 @@ Mapping to cell libraries 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 as ``docs/source/code_examples/intro/*``. The project contains a -simple ASIC synthesis script (``counter.ys``), a digital design written in -Verilog (``counter.v``), and a simple CMOS cell library (``mycells.lib``). Many -of the early steps here are already covered in more detail in the -:doc:`/getting_started/example_synth` document. +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 ``counter.ys`` script includes the commands used to generate the images - in this document. Code snippets in this document skip these commands; + 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`. @@ -32,7 +32,7 @@ First, let's quickly look at the design: :language: Verilog :linenos: :name: counter-v - :caption: ``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, @@ -46,7 +46,7 @@ Loading the design :language: yoscrypt :lines: 1-3 :lineno-match: - :caption: ``counter.ys`` - read design + :caption: :file:`counter.ys` - read design Our circuit now looks like this: @@ -63,7 +63,7 @@ Coarse-grain representation :language: yoscrypt :lines: 7-10 :lineno-match: - :caption: ``counter.ys`` - the high-level stuff + :caption: :file:`counter.ys` - the high-level stuff .. figure:: /_images/code_examples/intro/counter_01.* :class: width-helper @@ -77,7 +77,7 @@ Logic gate mapping :language: yoscrypt :lines: 14-15 :lineno-match: - :caption: ``counter.ys`` - mapping to internal cell library + :caption: :file:`counter.ys` - mapping to internal cell library .. figure:: /_images/code_examples/intro/counter_02.* :class: width-helper @@ -94,7 +94,7 @@ our internal cell library will be mapped to: :language: Liberty :linenos: :name: mycells-lib - :caption: ``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. @@ -106,7 +106,7 @@ Recall that the Yosys built-in logic gate types are ``$_NOT_``, ``$_AND_``, :language: yoscrypt :lines: 20-27 :lineno-match: - :caption: ``counter.ys`` - mapping to hardware + :caption: :file:`counter.ys` - mapping to hardware The final version of our ``counter`` module looks like this: @@ -122,4 +122,4 @@ which can then be loaded into another tool: :language: yoscrypt :lines: 30-31 :lineno-match: - :caption: ``counter.ys`` - write synthesized design + :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 index c5a64273a..650354469 100644 --- a/docs/source/using_yosys/synthesis/extract.rst +++ b/docs/source/using_yosys/synthesis/extract.rst @@ -12,7 +12,11 @@ The extract pass .. todo:: add/expand supporting text, also mention custom pattern matching and pmgen -Example code can be found in ``docs/source/code_examples/macc/``. +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 @@ -34,15 +38,15 @@ Example code can be found in ``docs/source/code_examples/macc/``. .. literalinclude:: /code_examples/macc/macc_simple_test.v :language: verilog - :caption: ``macc_simple_test.v`` + :caption: :file:`macc_simple_test.v` .. literalinclude:: /code_examples/macc/macc_simple_xmap.v :language: verilog - :caption: ``macc_simple_xmap.v`` + :caption: :file:`macc_simple_xmap.v` .. literalinclude:: /code_examples/macc/macc_simple_test_01.v :language: verilog - :caption: ``macc_simple_test_01.v`` + :caption: :file:`macc_simple_test_01.v` .. figure:: /_images/code_examples/macc/macc_simple_test_01a.* :class: width-helper @@ -52,7 +56,7 @@ Example code can be found in ``docs/source/code_examples/macc/``. .. literalinclude:: /code_examples/macc/macc_simple_test_02.v :language: verilog - :caption: ``macc_simple_test_02.v`` + :caption: :file:`macc_simple_test_02.v` .. figure:: /_images/code_examples/macc/macc_simple_test_02a.* :class: width-helper @@ -90,10 +94,9 @@ 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). Source code can be found in -``docs/source/code_examples/macc/``. +(such as the Xilinx DSP48 cells). -Preconditioning: ``macc_xilinx_swap_map.v`` +Preconditioning: :file:`macc_xilinx_swap_map.v` Make sure ``A`` is the smaller port on all multipliers @@ -101,49 +104,49 @@ Make sure ``A`` is the smaller port on all multipliers .. literalinclude:: /code_examples/macc/macc_xilinx_swap_map.v :language: verilog - :caption: ``macc_xilinx_swap_map.v`` + :caption: :file:`macc_xilinx_swap_map.v` -Wrapping multipliers: ``macc_xilinx_wrap_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: ``macc_xilinx_wrap_map.v`` + :caption: :file:`macc_xilinx_wrap_map.v` -Wrapping adders: ``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: ``macc_xilinx_wrap_map.v`` + :caption: :file:`macc_xilinx_wrap_map.v` -Extract: ``macc_xilinx_xmap.v`` +Extract: :file:`macc_xilinx_xmap.v` .. literalinclude:: /code_examples/macc/macc_xilinx_xmap.v :language: verilog - :caption: ``macc_xilinx_xmap.v`` + :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: ``macc_xilinx_unwrap_map.v`` +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 ``macc_xilinx_unwrap_map.v`` + :caption: ``$__mul_wrapper`` module in :file:`macc_xilinx_unwrap_map.v` -Unwrapping adders: ``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 ``macc_xilinx_unwrap_map.v`` + :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 ``macc_xilinx_test.v`` + :caption: ``test1`` of :file:`macc_xilinx_test.v` .. figure:: /_images/code_examples/macc/macc_xilinx_test1a.* :class: width-helper @@ -154,7 +157,7 @@ Unwrapping adders: ``macc_xilinx_unwrap_map.v`` .. literalinclude:: /code_examples/macc/macc_xilinx_test.v :language: verilog :lines: 8-13 - :caption: ``test2`` of ``macc_xilinx_test.v`` + :caption: ``test2`` of :file:`macc_xilinx_test.v` .. figure:: /_images/code_examples/macc/macc_xilinx_test2a.* :class: width-helper diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 2378af542..9301b8d54 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -33,27 +33,32 @@ 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: ``docs/source/code_examples/synth_flow/memory_01.ys`` + :caption: :file:`memory_01.ys` .. literalinclude:: /code_examples/synth_flow/memory_01.v :language: verilog - :caption: ``docs/source/code_examples/synth_flow/memory_01.v`` + :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: ``docs/source/code_examples/synth_flow/memory_02.v`` + :caption: :file:`memory_02.v` .. literalinclude:: /code_examples/synth_flow/memory_02.ys :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/memory_02.ys`` + :caption: :file:`memory_02.ys` .. _memory_map: @@ -71,7 +76,7 @@ For example: memory_map :cmd:ref:`memory_libmap` attempts to convert memory cells (``$mem_v2`` etc) into -hardware supported memory using a provided library (``my_memory_map.txt`` in the +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 diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst index 265930c8c..8c047e6b8 100644 --- a/docs/source/using_yosys/synthesis/proc.rst +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -28,13 +28,18 @@ Example .. todo:: describe ``proc`` 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 + .. literalinclude:: /code_examples/synth_flow/proc_01.v :language: verilog - :caption: ``docs/source/code_examples/synth_flow/proc_01.v`` + :caption: :file:`proc_01.v` .. literalinclude:: /code_examples/synth_flow/proc_01.ys :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/proc_01.ys`` + :caption: :file:`proc_01.ys` .. figure:: /_images/code_examples/synth_flow/proc_01.* :class: width-helper @@ -44,19 +49,19 @@ Example .. literalinclude:: /code_examples/synth_flow/proc_02.v :language: verilog - :caption: ``docs/source/code_examples/synth_flow/proc_02.v`` + :caption: :file:`proc_02.v` .. literalinclude:: /code_examples/synth_flow/proc_02.ys :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/proc_02.ys`` + :caption: :file:`proc_02.ys` .. figure:: /_images/code_examples/synth_flow/proc_03.* :class: width-helper .. literalinclude:: /code_examples/synth_flow/proc_03.ys :language: yoscrypt - :caption: ``docs/source/code_examples/synth_flow/proc_03.ys`` + :caption: :file:`proc_03.ys` .. literalinclude:: /code_examples/synth_flow/proc_03.v :language: verilog - :caption: ``docs/source/code_examples/synth_flow/proc_03.v`` + :caption: :file:`proc_03.v` diff --git a/docs/source/yosys_internals/extending_yosys/abc_flow.rst b/docs/source/yosys_internals/extending_yosys/abc_flow.rst index e55c87870..86afd3336 100644 --- a/docs/source/yosys_internals/extending_yosys/abc_flow.rst +++ b/docs/source/yosys_internals/extending_yosys/abc_flow.rst @@ -22,7 +22,7 @@ guide to the syntax: By convention, all delays in ``specify`` blocks are in integer picoseconds. Files containing ``specify`` blocks should be read with the ``-specify`` option -to ``read_verilog`` so that they aren't skipped. +to :cmd:ref:`read_verilog` so that they aren't skipped. LUTs ^^^^ @@ -41,9 +41,9 @@ 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 ``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). +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 @@ -59,7 +59,7 @@ 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. +input signals, and an arrival time for the ``Q`` output. Boxes ^^^^^ diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 2d6847f25..902c1c66c 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -6,7 +6,7 @@ Writing extensions .. todo:: check text is coherent -.. todo:: update to use ``/code_examples/extensions/test*.log`` +.. 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. @@ -21,7 +21,11 @@ Quick guide ----------- Code examples from this section are included in the -``docs/code_examples/extensions/`` directory of the Yosys source code. +|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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -31,7 +35,7 @@ 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 ``memory -nomap``): +commands :cmd:ref:`proc` and :cmd:ref:`memory` (or :yoscrypt:`memory -nomap`): .. figure:: /_images/internals/simplified_rtlil.* :class: width-helper @@ -41,6 +45,8 @@ commands :cmd:ref:`proc` and :cmd:ref:`memory` (or ``memory -nomap``): It is possible to only work on this simpler version: +.. todo:: consider replacing inline code + .. code:: c++ for (RTLIL::Module *module : design->selected_modules() { @@ -66,10 +72,10 @@ 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 ``my_cmd.cc`` + :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 ``kernel/yosys.h``. +``Yosys::Pass``, which we get by including :file:`kernel/yosys.h`. Compiling to a plugin ~~~~~~~~~~~~~~~~~~~~~ @@ -80,6 +86,8 @@ 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 \ @@ -120,7 +128,7 @@ 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 ``my_cmd.cc`` + :caption: :yoscrypt:`test1` - creating the absval module, from :file:`my_cmd.cc` .. code:: shell-session @@ -160,7 +168,7 @@ Consider the following module: .. literalinclude:: /code_examples/extensions/sigmap_test.v :language: Verilog - :caption: sigmap_test.v + :caption: :file:`sigmap_test.v` In this case ``a``, ``x``, and ``y`` are all different names for the same signal. However: @@ -204,7 +212,10 @@ Use ``log_id()`` to create a C-string for an ``RTLIL::IdString``: log("Name of this module: %s\n", log_id(module->name)); -Use ``log_header()`` and ``log_push()``/``log_pop()`` to structure log messages: +Use ``log_header()`` and ``log_push()``/\ ``log_pop()`` to structure log +messages: + +.. todo:: replace inline code .. code:: C++ @@ -219,6 +230,8 @@ Error handling Use ``log_error()`` to report a non-recoverable error: +.. todo:: replace inline code + .. code:: C++ if (design->modules.count(module->name) != 0) @@ -238,20 +251,22 @@ The "stubnets" example module ------------------------------ The following is the complete code of the "stubnets" example module. It is -included in the Yosys source distribution as -``docs/source/code_examples/stubnets/stubnets.cc``. +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: docs/source/code_examples/stubnets/stubnets.cc + :caption: :file:`stubnets.cc` .. literalinclude:: /code_examples/stubnets/Makefile :language: makefile :linenos: - :caption: docs/source/code_examples/stubnets/Makefile + :caption: :file:`Makefile` .. literalinclude:: /code_examples/stubnets/test.v :language: verilog :linenos: - :caption: docs/source/code_examples/stubnets/test.v + :caption: :file:`test.v` diff --git a/docs/source/yosys_internals/flow/index.rst b/docs/source/yosys_internals/flow/index.rst index 7733ec855..c7ab0ebcc 100644 --- a/docs/source/yosys_internals/flow/index.rst +++ b/docs/source/yosys_internals/flow/index.rst @@ -1,7 +1,6 @@ Internal flow ============= - A (usually short) synthesis script controls Yosys. These scripts contain three types of commands: diff --git a/docs/source/yosys_internals/flow/verilog_frontend.rst b/docs/source/yosys_internals/flow/verilog_frontend.rst index b36eb3bbf..127fa7be3 100644 --- a/docs/source/yosys_internals/flow/verilog_frontend.rst +++ b/docs/source/yosys_internals/flow/verilog_frontend.rst @@ -23,8 +23,8 @@ 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 source code to the Verilog frontend can be found in +:file:`frontends/verilog/` in the Yosys source tree. The Verilog preprocessor ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -37,20 +37,19 @@ 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. +: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 ``frontends/verilog/verilog_lexer.l`` in the Yosys source tree. +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. +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 @@ -62,10 +61,11 @@ 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. +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 -``frontends/ast/ast.h``. An ``AST::AstNode`` object has the following +:file:`frontends/ast/ast.h`. An ``AST::AstNode`` object has the following properties: .. list-table:: AST node types with their corresponding Verilog constructs. @@ -77,7 +77,8 @@ properties: * - 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. + - 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 @@ -99,9 +100,11 @@ properties: * - 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) + - An Identifier (signal name in expression or cell/task/etc. name in other + contexts) * - AST_PREFIX - - Construct an identifier in the form <prefix>[<index>].<suffix> (used only in advanced generate constructs) + - Construct an identifier in the form <prefix>[<index>].<suffix> (used + only in advanced generate constructs) * - AST_FCALL, AST_TCALL - Call to function or task * - AST_TO_SIGNED, AST_TO_UNSIGNED @@ -113,7 +116,8 @@ properties: * - 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) + - 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 @@ -127,7 +131,8 @@ properties: * - 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. + - 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 @@ -139,13 +144,16 @@ properties: * - AST_BLOCK - A ``begin``-``end``-block * - AST_ASSIGN_EQ. AST_ASSIGN_LE - - Blocking (``=``) and nonblocking (``<=``) assignments within an ``always``- or ``initial``-block + - 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 + - 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. + - The ``genvar`` and ``generate`` keywords and ``for`` and ``if`` within a + generate block. * - AST_POSEDGE, AST_NEGEDGE, AST_EDGE - Event conditions for ``always`` blocks. @@ -295,7 +303,7 @@ 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 +``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: @@ -371,7 +379,7 @@ 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 +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 @@ -388,7 +396,7 @@ following way: 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 +- 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. @@ -403,11 +411,11 @@ 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 +``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 +``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. @@ -583,7 +591,7 @@ 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 +``subst_rvalue_from``/\ ``subst_rvalue_to``-tuple that contained the right-hand-side of the old assignment. The proc pass @@ -609,17 +617,17 @@ from a behavioural model to an RTL representation is performed by the and the top-level ``RTLIL::SwitchRule`` has been removed. - | :cmd:ref:`proc_mux` - | This pass converts the ``RTLIL::CaseRule``/ ``RTLIL::SwitchRule``-tree to a + | 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 + | 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. + | 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 @@ -636,18 +644,13 @@ 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 ---------------------------- - -.. todo:: +.. todo:: 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 -------------------------------- -.. todo:: +.. 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/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index bbbec836c..7d4670797 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -9,8 +9,11 @@ Internal cell library .. 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. +``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. @@ -33,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 ~~~~~~~~~~~~~~~ @@ -42,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``. @@ -110,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 @@ -124,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`` @@ -141,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. @@ -334,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 @@ -353,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`` @@ -413,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`` @@ -452,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`` @@ -468,9 +471,9 @@ 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 :cmd:ref:`memory` pass (i.e.~its -various sub-passes) migrates ``$dff`` cells into the ``$memrd_v2`` and +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 @@ -480,7 +483,7 @@ 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`` @@ -1145,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 index aa77d1ea6..c187a8238 100644 --- a/docs/source/yosys_internals/formats/index.rst +++ b/docs/source/yosys_internals/formats/index.rst @@ -1,6 +1,8 @@ Internal formats ================ +.. todo:: brief overview for the internal formats index + .. toctree:: :maxdepth: 3 diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index ce40ea19c..8508e6280 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -12,6 +12,13 @@ Yosys' internal cell types (such as ``$or``) as well as user-defined cell types. 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 ~~~~~~~~~~~~~ @@ -24,31 +31,32 @@ Mapping OR3X1 .. literalinclude:: /code_examples/techmap/red_or3x1_map.v :language: verilog - :caption: ``docs/source/code_examples/techmap/red_or3x1_map.v`` + :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: ``docs/source/code_examples/techmap/red_or3x1_test.ys`` + :caption: :file:`red_or3x1_test.ys` .. literalinclude:: /code_examples/techmap/red_or3x1_test.v :language: verilog - :caption: ``docs/source/code_examples/techmap/red_or3x1_test.v`` + :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. +- 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.) + - memory resources for different memory geometries (width, depth, ports, + etc.) Example: @@ -57,22 +65,22 @@ Example: .. literalinclude:: /code_examples/techmap/sym_mul_map.v :language: verilog - :caption: ``docs/source/code_examples/techmap/sym_mul_map.v`` + :caption: :file:`sym_mul_map.v` .. literalinclude:: /code_examples/techmap/sym_mul_test.v :language: verilog - :caption: ``docs/source/code_examples/techmap/sym_mul_test.v`` + :caption: :file:`sym_mul_test.v` .. literalinclude:: /code_examples/techmap/sym_mul_test.ys :language: yoscrypt - :caption: ``docs/source/code_examples/techmap/sym_mul_test.ys`` + :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 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. @@ -96,15 +104,15 @@ Example: .. literalinclude:: /code_examples/techmap/mymul_map.v :language: verilog - :caption: ``docs/source/code_examples/techmap/mymul_map.v`` + :caption: :file:`mymul_map.v` .. literalinclude:: /code_examples/techmap/mymul_test.v :language: verilog - :caption: ``docs/source/code_examples/techmap/mymul_test.v`` + :caption: :file:`mymul_test.v` .. literalinclude:: /code_examples/techmap/mymul_test.ys :language: yoscrypt - :caption: ``docs/source/code_examples/techmap/mymul_test.ys`` + :caption: :file:`mymul_test.ys` Handling constant inputs ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -126,15 +134,15 @@ Example: .. literalinclude:: /code_examples/techmap/mulshift_map.v :language: verilog - :caption: ``docs/source/code_examples/techmap/mulshift_map.v`` + :caption: :file:`mulshift_map.v` .. literalinclude:: /code_examples/techmap/mulshift_test.v :language: verilog - :caption: ``docs/source/code_examples/techmap/mulshift_test.v`` + :caption: :file:`mulshift_test.v` .. literalinclude:: /code_examples/techmap/mulshift_test.ys :language: yoscrypt - :caption: ``docs/source/code_examples/techmap/mulshift_test.ys`` + :caption: :file:`mulshift_test.ys` Handling shorted inputs ~~~~~~~~~~~~~~~~~~~~~~~ @@ -143,7 +151,8 @@ Handling shorted inputs ``_TECHMAP_CONNMAP_<port-name>_`` can be used to handle shorted inputs. - Each bit of the port correlates to an ``_TECHMAP_BITS_CONNMAP_`` bits wide number in ``_TECHMAP_CONNMAP_<port-name>_``. -- Each unique signal bit is assigned its own number. Identical fields in the ``_TECHMAP_CONNMAP_<port-name>_`` parameters mean shorted signal bits. +- Each unique signal bit is assigned its own number. Identical fields in the + ``_TECHMAP_CONNMAP_<port-name>_`` parameters mean shorted signal bits. - The numbers 0-3 are reserved for ``0``, ``1``, ``x``, and ``z`` respectively. - Example use-cases: @@ -157,15 +166,15 @@ Example: .. literalinclude:: /code_examples/techmap/addshift_map.v :language: verilog - :caption: ``docs/source/code_examples/techmap/addshift_map.v`` + :caption: :file:`addshift_map.v` .. literalinclude:: /code_examples/techmap/addshift_test.v :language: verilog - :caption: ``docs/source/code_examples/techmap/addshift_test.v`` + :caption: :file:`addshift_test.v` .. literalinclude:: /code_examples/techmap/addshift_test.ys :language: yoscrypt - :caption: ``docs/source/code_examples/techmap/addshift_test.ys`` + :caption: :file:`addshift_test.ys` Notes on using techmap ~~~~~~~~~~~~~~~~~~~~~~ From fd0c574942b654e3d8a98c526c140fb3fb442c0e Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:33:07 +1300 Subject: [PATCH 100/108] Docs: changes/todos from JF --- docs/source/getting_started/example_synth.rst | 53 ++++++++++++------- docs/source/getting_started/installation.rst | 12 ++--- docs/source/introduction.rst | 7 +-- .../interactive_investigation.rst | 3 +- 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 371115117..a8babb647 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -161,8 +161,9 @@ 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: :yoscrypt:`opt_expr; clean`. +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 @@ -183,10 +184,11 @@ on opt_expr <adv_opt_expr>`. :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`. It is generally beneficial to run - :cmd:ref:`clean` after each command as a quick way of removing disconnected - parts of the circuit which have been left over. You may notice some scripts - will end each line with ``;;``. + :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 @@ -199,9 +201,9 @@ 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. +-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 @@ -237,8 +239,9 @@ design. If we know that our design won't run into this issue, we can skip the 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 ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys - interactive terminal. + ``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 @@ -308,9 +311,14 @@ 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 that in an interactive terminal the outputs of -:cmd:ref:`flatten` and :cmd:ref:`clean` will be combined into a single -:yoterm:`yosys> flatten;;` output. +: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 @@ -490,6 +498,8 @@ 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, @@ -513,9 +523,10 @@ That brings us to the fourth and final part for the iCE40 synthesis flow: :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 be -mapped to hard blocks. We do this by running :cmd:ref:`alumacc`, which we can -see produce the following changes in our example design: +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 @@ -529,6 +540,10 @@ see produce the following changes in our example design: ``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 @@ -551,7 +566,9 @@ one for writing (``WR_*``), as well as both ``WR_DATA`` input and ``RD_DATA`` output. .. seealso:: Advanced usage docs for - :doc:`/using_yosys/synthesis/memory` + + - :doc:`/using_yosys/synthesis/opt` + - :doc:`/using_yosys/synthesis/memory` Final note ^^^^^^^^^^ diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 302d6d291..d664d17ef 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -86,14 +86,10 @@ Build prerequisites ^^^^^^^^^^^^^^^^^^^ A C++ compiler with C++11 support is required as well as some standard tools -such as GNU Flex, GNU Bison, Make, libffi, and Python3.6 or later. Some -additional tools: readline, Tcl and zlib; are optional but enabled by default -(see ``ENABLE_*`` settings in Makefile). Xdot (graphviz) is optional unless -using the :cmd:ref:`show` command to display schematics. - -.. - unclear if libffi is required now or still optional - readme says optional, but I can't find a corresponding ENABLE_* +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: diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index fcb54542d..936784d74 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -69,6 +69,8 @@ Things you can't do - Check out `nextpnr`_ for that +.. todo:: nextpnr for FPGAs, consider mentioning openlane, vpr, coriolis + .. _nextpnr: https://github.com/YosysHQ/nextpnr The Yosys family @@ -191,11 +193,6 @@ Benefits of open source HDL synthesis workings. They often are ``black boxes``. Yosys is very open about its internals and it is easy to observe the different steps of synthesis. -.. note:: 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. - History of Yosys ~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index d0d78a783..223e09a12 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -220,7 +220,8 @@ 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. +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 From fae35fe98b7cec73d688bfef9b033b907b5e12c8 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:34:29 +1300 Subject: [PATCH 101/108] Docs: example_synth fifo update More detail on `memory_libmap`, the `$__ICE40_RAM4K_` intermediate step, and the bizarre opt output. --- docs/source/code_examples/fifo/fifo.libmap | 65 +++++++++++++++++++ docs/source/code_examples/fifo/fifo.stat | 2 +- docs/source/code_examples/fifo/fifo_map.ys | 5 +- docs/source/getting_started/example_synth.rst | 48 ++++++++++---- 4 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 docs/source/code_examples/fifo/fifo.libmap diff --git a/docs/source/code_examples/fifo/fifo.libmap b/docs/source/code_examples/fifo/fifo.libmap new file mode 100644 index 000000000..5889b7cfd --- /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.stat b/docs/source/code_examples/fifo/fifo.stat index b3a3d926f..0a278b6e2 100644 --- a/docs/source/code_examples/fifo/fifo.stat +++ b/docs/source/code_examples/fifo/fifo.stat @@ -36,7 +36,7 @@ yosys> stat yosys> stat -top fifo -16. Printing statistics. +17. Printing statistics. === fifo === diff --git a/docs/source/code_examples/fifo/fifo_map.ys b/docs/source/code_examples/fifo/fifo_map.ys index 701de3c35..f5a3edeb4 100644 --- a/docs/source/code_examples/fifo/fifo_map.ys +++ b/docs/source/code_examples/fifo/fifo_map.ys @@ -7,11 +7,14 @@ synth_ice40 -top fifo -run begin:map_ram # ======================================================== +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 maroon3 @mem -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ram @rdata_path +show -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ram @rdata_path # ======================================================== diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index a8babb647..bcbe6efc9 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -592,8 +592,8 @@ If you skipped calling :yoscrypt:`read_verilog -D ICE40_HX -lib -specify Memory blocks ^^^^^^^^^^^^^ -Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, -:cmd:ref:`memory_map`, and :cmd:ref:`techmap`. +Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap` and +:cmd:ref:`techmap`. .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -609,15 +609,33 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, ``rdata`` output after :ref:`map_ram` -: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. +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 @@ -633,7 +651,13 @@ our hardware instead. ``rdata`` output after :ref:`map_ffram` -.. TODO:: what even is this opt output +.. 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 From 9eed04dd4b8265ec7691c89fc3a6e8197de5b4c4 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 5 Feb 2024 15:38:01 +1300 Subject: [PATCH 102/108] Docs: Note on debug for memory_libmap --- docs/source/using_yosys/synthesis/memory.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 9301b8d54..c04a21e53 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -83,6 +83,13 @@ 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. +.. note:: + + 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. + For more on the lib format for :cmd:ref:`memory_libmap`, see `passes/memory/memlib.md <https://github.com/YosysHQ/yosys/blob/master/passes/memory/memlib.md>`_ From 35960252837fa0d9f4f914819f8fd8daa7ef182b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 5 Mar 2024 05:44:40 +1300 Subject: [PATCH 103/108] docs: Remove TODOs from output Remove highlighting of wreduce/opt_clean bug. --- docs/source/code_examples/fifo/fifo.out | 4 +--- docs/source/code_examples/fifo/fifo.ys | 3 +-- docs/source/conf.py | 2 +- docs/source/getting_started/example_synth.rst | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index 85cf14f9c..7aeee10f4 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -357,9 +357,7 @@ Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$f Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$27_Y. Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_reader.$add$fifo.v:20$34_Y. -yosys> select -set new_cells t:$add %co t:$add %d - -yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_wreduce o:rdata %ci* +yosys> show -notitle -format dot -prefix rdata_wreduce o:rdata %ci* 20. Generating Graphviz representation of design. Writing dot description to `rdata_wreduce.dot'. diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index b6e0e34ed..57a28e63e 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -53,8 +53,7 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_adffe o:rdata # ======================================================== wreduce -select -set new_cells t:$add %co t:$add %d -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_wreduce o:rdata %ci* +show -notitle -format dot -prefix rdata_wreduce o:rdata %ci* # unclear if this is necessary or only because of bug(s) opt_clean diff --git a/docs/source/conf.py b/docs/source/conf.py index 003887498..29d36d9c4 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -61,7 +61,7 @@ latex_elements = { # include todos during rewrite extensions.append('sphinx.ext.todo') -todo_include_todos = True +todo_include_todos = False # custom cmd-ref parsing/linking sys.path += [os.path.dirname(__file__) + "/../"] diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index bcbe6efc9..799b4ec48 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -421,7 +421,7 @@ 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` +.. todo:: pending bugfix in :cmd:ref:`wreduce` and/or :cmd:ref:`opt_clean` .. figure:: /_images/code_examples/fifo/rdata_wreduce.* :class: width-helper From 3635f911dc53bff4a605e37ec69efd1e74401619 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 5 Mar 2024 05:57:27 +1300 Subject: [PATCH 104/108] Docs: Updates from @povik comments --- docs/source/yosys_internals/index.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst index d349f6f1b..b04f13699 100644 --- a/docs/source/yosys_internals/index.rst +++ b/docs/source/yosys_internals/index.rst @@ -15,6 +15,8 @@ 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 @@ -23,13 +25,11 @@ wide range of real-world designs, including the `OpenRISC 1200 CPU`_, the .. _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. +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 From bc9cccacf2d521216764ce887dc23c1d836e286d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 18 Mar 2024 10:02:40 +1300 Subject: [PATCH 105/108] docs: Move fifo localparams into module def Fix for failing CI. --- docs/source/code_examples/fifo/fifo.out | 118 +++++++++++------------ docs/source/code_examples/fifo/fifo.stat | 11 ++- docs/source/code_examples/fifo/fifo.v | 10 +- 3 files changed, 69 insertions(+), 70 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index 7aeee10f4..ac132ee6c 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -32,23 +32,23 @@ yosys> select -module addr_gen yosys [addr_gen]> select -list addr_gen addr_gen/$1\addr[7:0] -addr_gen/$add$fifo.v:20$3_Y -addr_gen/$eq$fifo.v:17$2_Y +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:20$3 -addr_gen/$eq$fifo.v:17$2 +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:13$1 +addr_gen/$proc$fifo.v:12$1 yosys [addr_gen]> select t:* yosys [addr_gen]*> select -list -addr_gen/$add$fifo.v:20$3 -addr_gen/$eq$fifo.v:17$2 +addr_gen/$add$fifo.v:19$3 +addr_gen/$eq$fifo.v:16$2 yosys [addr_gen]*> select -set new_cells % @@ -84,7 +84,7 @@ 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:13$1 in module addr_gen. +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 @@ -102,7 +102,7 @@ Found init rule in `\addr_gen.$proc$fifo.v:0$4'. yosys> proc_arst 7.5. Executing PROC_ARST pass (detect async resets in processes). -Found async reset \rst in `\addr_gen.$proc$fifo.v:13$1'. +Found async reset \rst in `\addr_gen.$proc$fifo.v:12$1'. yosys> proc_rom @@ -114,7 +114,7 @@ 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:13$1'. +Creating decoders for process `\addr_gen.$proc$fifo.v:12$1'. 1/1: $0\addr[7:0] yosys> proc_dlatch @@ -124,7 +124,7 @@ yosys> proc_dlatch 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:13$1'. +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 @@ -135,8 +135,8 @@ 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:13$1'. -Removing empty process `addr_gen.$proc$fifo.v:13$1'. +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 @@ -210,9 +210,9 @@ 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:64$24 in module fifo. -Marked 1 switch rules as full_case in process $proc$fifo.v:38$16 in module fifo. -Marked 2 switch rules as full_case in process $proc$fifo.v:13$32 in module $paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000. +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 @@ -232,8 +232,8 @@ Found init rule in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000 yosys> proc_arst 13.5. Executing PROC_ARST pass (detect async resets in processes). -Found async reset \rst in `\fifo.$proc$fifo.v:64$24'. -Found async reset \rst in `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. +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 @@ -245,14 +245,14 @@ 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:64$24'. +Creating decoders for process `\fifo.$proc$fifo.v:62$24'. 1/1: $0\count[8:0] -Creating decoders for process `\fifo.$proc$fifo.v:38$16'. - 1/3: $1$memwr$\data$fifo.v:40$15_EN[7:0]$22 - 2/3: $1$memwr$\data$fifo.v:40$15_DATA[7:0]$21 - 3/3: $1$memwr$\data$fifo.v:40$15_ADDR[7:0]$20 +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:13$32'. +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 @@ -262,17 +262,17 @@ yosys> proc_dlatch 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:64$24'. +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:38$16'. +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:40$15_ADDR' using process `\fifo.$proc$fifo.v:38$16'. +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:40$15_DATA' using process `\fifo.$proc$fifo.v:38$16'. +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:40$15_EN' using process `\fifo.$proc$fifo.v:38$16'. +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:13$32'. +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 @@ -283,13 +283,13 @@ 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:64$24'. -Removing empty process `fifo.$proc$fifo.v:64$24'. -Found and cleaned up 1 empty switch in `\fifo.$proc$fifo.v:38$16'. -Removing empty process `fifo.$proc$fifo.v:38$16'. +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:13$32'. -Removing empty process `$paramod\addr_gen\MAX_DATA=s32'00000000000000000000000100000000.$proc$fifo.v:13$32'. +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 @@ -343,19 +343,19 @@ 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:68$27 ($add). -Removed top 23 bits (of 32) from port Y of cell fifo.$add$fifo.v:68$27 ($add). -Removed top 31 bits (of 32) from port B of cell fifo.$sub$fifo.v:70$30 ($sub). -Removed top 23 bits (of 32) from port Y of cell fifo.$sub$fifo.v:70$30 ($sub). -Removed top 1 bits (of 2) from port B of cell fifo.$auto$opt_dff.cc:195:make_patterns_logic$64 ($ne). +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:20$34 ($add). -Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_writer.$add$fifo.v:20$34 ($add). +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:20$34 ($add). -Removed top 24 bits (of 32) from port Y of cell fifo.$flatten\fifo_reader.$add$fifo.v:20$34 ($add). -Removed top 23 bits (of 32) from wire fifo.$add$fifo.v:68$27_Y. -Removed top 24 bits (of 32) from wire fifo.$flatten\fifo_reader.$add$fifo.v:20$34_Y. +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* @@ -388,18 +388,18 @@ 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:68$27 ($add). - creating $macc model for $flatten\fifo_reader.$add$fifo.v:20$34 ($add). - creating $macc model for $flatten\fifo_writer.$add$fifo.v:20$34 ($add). - creating $macc model for $sub$fifo.v:70$30 ($sub). - creating $alu model for $macc $sub$fifo.v:70$30. - creating $alu model for $macc $flatten\fifo_writer.$add$fifo.v:20$34. - creating $alu model for $macc $flatten\fifo_reader.$add$fifo.v:20$34. - creating $alu model for $macc $add$fifo.v:68$27. - creating $alu cell for $add$fifo.v:68$27: $auto$alumacc.cc:485:replace_alu$78 - creating $alu cell for $flatten\fifo_reader.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$81 - creating $alu cell for $flatten\fifo_writer.$add$fifo.v:20$34: $auto$alumacc.cc:485:replace_alu$84 - creating $alu cell for $sub$fifo.v:70$30: $auto$alumacc.cc:485:replace_alu$87 + 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 diff --git a/docs/source/code_examples/fifo/fifo.stat b/docs/source/code_examples/fifo/fifo.stat index 0a278b6e2..263c618e3 100644 --- a/docs/source/code_examples/fifo/fifo.stat +++ b/docs/source/code_examples/fifo/fifo.stat @@ -40,17 +40,18 @@ yosys> stat -top fifo === fifo === - Number of wires: 97 - Number of wire bits: 268 - Number of public wires: 97 - Number of public wire bits: 268 + 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 60 + 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 index e70005765..769dfafd4 100644 --- a/docs/source/code_examples/fifo/fifo.v +++ b/docs/source/code_examples/fifo/fifo.v @@ -1,11 +1,10 @@ // address generator/counter module addr_gen -#( parameter MAX_DATA=256 +#( parameter MAX_DATA=256, + localparam AWIDTH = $clog2(MAX_DATA) ) ( input en, clk, rst, output reg [AWIDTH-1:0] addr ); - localparam AWIDTH = $clog2(MAX_DATA); - initial addr <= 0; // async reset @@ -23,14 +22,13 @@ endmodule //addr_gen // Define our top level fifo entity module fifo -#( parameter MAX_DATA=256 +#( 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 ); - localparam AWIDTH = $clog2(MAX_DATA); - // fifo storage // sync read before write wire [AWIDTH-1:0] waddr, raddr; From 2832034877036616533b954fec26935761648613 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 18 Mar 2024 10:35:01 +1300 Subject: [PATCH 106/108] docs: Clarify install instructions `config-clang` is the default, and doesn't need to be run first. Previous instructions were ambiguous about that point. Add note on using a different `CXX`. --- docs/source/getting_started/installation.rst | 27 ++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index d664d17ef..14eefe2ac 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -110,26 +110,33 @@ Installing all prerequisites for macOS 11 (with Homebrew): Running the build system ^^^^^^^^^^^^^^^^^^^^^^^^ -To configure the build system to use a specific compiler, use one of the -following: - -.. code:: console - - make config-clang - make config-gcc - -Then, simply run ``make`` in this directory. +From the root `yosys` directory, call the following commands: .. code:: console make sudo make install -Note that this also downloads, builds, and installs `ABC`_ (using +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. From b6ffdec2ceee56459266209b46f80095faa0ae9c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 18 Mar 2024 10:45:31 +1300 Subject: [PATCH 107/108] docs: Update OSS CAD suite info --- docs/source/getting_started/installation.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 14eefe2ac..4dd5244b9 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -40,14 +40,13 @@ The `OSS CAD Suite`_ releases `nightly builds`_ for the following architectures: - Most personal Linux based computers - darwin-x64 |darwin-x64| - - macOS 10.14 or later with Intel CPU + - macOS 12 or later with Intel CPU - darwin-arm64 |darwin-arm64| - - macOS 11.00 or later with M1 CPU + - macOS 12 or later with M1/M2 CPU - windows-x64 |windows-x64| - - Targeted for Windows 10 and 11, but older 64-bit version of Windows 7, - 8, or 8.1 should work + - Targeted for Windows 10 and 11 - linux-arm64 |linux-arm64| From 49f1bea1d20498d7caf6dbc51e90529f72c79f5b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 18 Mar 2024 10:58:08 +1300 Subject: [PATCH 108/108] docs: Add synth_ice40 to macro checks --- .../macro_commands/synth_ice40.ys | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 docs/source/code_examples/macro_commands/synth_ice40.ys 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 000000000..443b8e0b0 --- /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 <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