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 5e5a8ec3e12..87d9730a431 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 ab9618c8b47..52a21afb22e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -43,6 +43,7 @@ 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 00000000000..75a58c089c4 --- /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 111aea873a4..681c18f7a9d 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 00000000000..c87326b9d3f --- /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 00000000000..fbf1e98b4c8 --- /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 00000000000..89b45669767 --- /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 00000000000..6e22bdcbd19 --- /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 32980e788bf..00000000000 --- a/docs/source/CHAPTER_Approach.rst +++ /dev/null @@ -1,141 +0,0 @@ -.. _chapter:approach: - -Approach -======== - -Yosys is a tool for synthesising (behavioural) Verilog HDL code to target -architecture netlists. Yosys aims at a wide range of application domains and -thus must be flexible and easy to adapt to new tasks. This chapter covers the -general approach followed in the effort to implement this tool. - -Data- and control-flow ----------------------- - -The data- and control-flow of a typical synthesis tool is very similar to the -data- and control-flow of a typical compiler: different subsystems are called in -a predetermined order, each consuming the data generated by the last subsystem -and generating the data for the next subsystem (see :numref:`Fig. %s -`). - -.. figure:: ../images/approach_flow.* - :class: width-helper - :name: fig:approach_flow - - General data- and control-flow of a synthesis tool - -The first subsystem to be called is usually called a frontend. It does not -process the data generated by another subsystem but instead reads the user -input—in the case of a HDL synthesis tool, the behavioural HDL code. - -The subsystems that consume data from previous subsystems and produce data for -the next subsystems (usually in the same or a similar format) are called passes. - -The last subsystem that is executed transforms the data generated by the last -pass into a suitable output format and writes it to a disk file. This subsystem -is usually called the backend. - -In Yosys all frontends, passes and backends are directly available as commands -in the synthesis script. Thus the user can easily create a custom synthesis flow -just by calling passes in the right order in a synthesis script. - -Internal formats in Yosys -------------------------- - -Yosys uses two different internal formats. The first is used to store an -abstract syntax tree (AST) of a Verilog input file. This format is simply called -AST and is generated by the Verilog Frontend. This data structure is consumed by -a subsystem called AST Frontend [1]_. This AST Frontend then generates a design -in Yosys' main internal format, the -Register-Transfer-Level-Intermediate-Language (RTLIL) representation. It does -that by first performing a number of simplifications within the AST -representation and then generating RTLIL from the simplified AST data structure. - -The RTLIL representation is used by all passes as input and outputs. This has -the following advantages over using different representational formats between -different passes: - -- The passes can be rearranged in a different order and passes can be removed - or inserted. - -- Passes can simply pass-thru the parts of the design they don't change without - the need to convert between formats. In fact Yosys passes output the same - data structure they received as input and performs all changes in place. - -- All passes use the same interface, thus reducing the effort required to - understand a pass when reading the Yosys source code, e.g. when adding - additional features. - -The RTLIL representation is basically a netlist representation with the -following additional features: - -- An internal cell library with fixed-function cells to represent RTL datapath - and register cells as well as logical gate-level cells (single-bit gates and - registers). - -- Support for multi-bit values that can use individual bits from wires as well - as constant bits to represent coarse-grain netlists. - -- Support for basic behavioural constructs (if-then-else structures and - multi-case switches with a sensitivity list for updating the outputs). - -- Support for multi-port memories. - -The use of RTLIL also has the disadvantage of having a very powerful format -between all passes, even when doing gate-level synthesis where the more advanced -features are not needed. In order to reduce complexity for passes that operate -on a low-level representation, these passes check the features used in the input -RTLIL and fail to run when unsupported high-level constructs are used. In such -cases a pass that transforms the higher-level constructs to lower-level -constructs must be called from the synthesis script first. - -.. _sec:typusecase: - -Typical use case ----------------- - -The following example script may be used in a synthesis flow to convert the -behavioural Verilog code from the input file design.v to a gate-level netlist -synth.v using the cell library described by the Liberty file : - -.. code:: yoscrypt - :number-lines: - - # read input file to internal representation - read_verilog design.v - - # convert high-level behavioral parts ("processes") to d-type flip-flops and muxes - proc - - # perform some simple optimizations - opt - - # convert high-level memory constructs to d-type flip-flops and multiplexers - memory - - # perform some simple optimizations - opt - - # convert design to (logical) gate-level netlists - techmap - - # perform some simple optimizations - opt - - # map internal register types to the ones from the cell library - dfflibmap -liberty cells.lib - - # use ABC to map remaining logic to cells from the cell library - abc -liberty cells.lib - - # cleanup - opt - - # write results to output file - write_verilog synth.v - -A detailed description of the commands available in Yosys can be found in -:ref:`cmd_ref`. - -.. [1] - In Yosys the term pass is only used to refer to commands that operate on the - RTLIL data structure. diff --git a/docs/source/CHAPTER_Eval.rst b/docs/source/CHAPTER_Eval.rst deleted file mode 100644 index 3d463d3f90b..00000000000 --- a/docs/source/CHAPTER_Eval.rst +++ /dev/null @@ -1,233 +0,0 @@ -.. _chapter:eval: - -Evaluation, conclusion, future Work -=================================== - -The Yosys source tree contains over 200 test cases [1]_ which are used -in the make test make-target. Besides these there is an external Yosys -benchmark and test case package that contains a few larger designs . -This package contains the designs listed in -Tab. \ `[tab:yosys-test-designs] <#tab:yosys-test-designs>`__. - -.. table:: Tests included in the yosys-tests package. - - =========== ========= ================ - ====================================================== - Test-Design Source Gates Description / Comments - =========== ========= ================ - ====================================================== - aes_core IWLS2005 :math:`41{,}837` AES Cipher written by Rudolf Usselmann - i2c IWLS2005 :math:`1{,}072` WISHBONE compliant I2C Master by Richard Herveille - openmsp430 OpenCores :math:`7{,}173` MSP430 compatible CPU by Olivier Girard - or1200 OpenCores :math:`42{,}675` The OpenRISC 1200 CPU by Damjan Lampret - sasc IWLS2005 :math:`456` Simple Async. Serial Comm. Device by Rudolf Usselmann - simple_spi IWLS2005 :math:`690` MC68HC11E based SPI interface by Richard Herveille - spi IWLS2005 :math:`2{,}478` SPI IP core by Simon Srot - ss_pcm IWLS2005 :math:`279` PCM IO Slave by Rudolf Usselmann - systemcaes IWLS2005 :math:`6{,}893` AES core (using SystemC to Verilog) by Javier Castillo - usb_phy IWLS2005 :math:`515` USB 1.1 PHY by Rudolf Usselmann - =========== ========= ================ - ====================================================== - -Correctness of synthesis results --------------------------------- - -The following measures were taken to increase the confidence in the -correctness of the Yosys synthesis results: - -- Yosys comes with a large selection [2]_ of small test cases that are - evaluated when the command make test is executed. During development - of Yosys it was shown that this collection of test cases is - sufficient to catch most bugs. The following more sophisticated test - procedures only caught a few additional bugs. Whenever this happened, - an appropriate test case was added to the collection of small test - cases for make test to ensure better testability of the feature in - question in the future. - -- The designs listed in - Tab. \ `[tab:yosys-test-designs] <#tab:yosys-test-designs>`__ where - validated using the formal verification tool Synopsys Formality. The - Yosys synthesis scripts used to synthesize the individual designs for - this test are slightly different per design in order to broaden the - coverage of Yosys features. The large majority of all errors - encountered using these tests are false-negatives, mostly related to - FSM encoding or signal naming in large array logic (such as in memory - blocks). Therefore the fsm_recode pass was extended so it can be used - to generate TCL commands for Synopsys Formality that describe the - relationship between old and new state encodings. Also the method - used to generate signal and cell names in the Verilog backend was - slightly modified in order to improve the automatic matching of net - names in Synopsys Formality. With these changes in place all designs - in Tab. \ `[tab:yosys-test-designs] <#tab:yosys-test-designs>`__ - validate successfully using Formality. - -- VlogHammer is a set of scripts that auto-generate a large collection - of test cases [3]_ and synthesize them using Yosys and the following - freely available proprietary synthesis tools. - - - Xilinx Vivado WebPack (2013.2) - - - Xilinx ISE (XST) WebPack (14.5) - - - Altera Quartus II Web Edition (13.0) - - The built-in SAT solver of Yosys is used to formally verify the Yosys - RTL- and Gate-Level netlists against the netlists generated by this - other tools. [4]_ When differences are found, the input pattern that - result in different outputs are used for simulating the original - Verilog code as well as the synthesis results using the following - Verilog simulators. - - - Xilinx ISIM (from Xilinx ISE 14.5 ) - - - Modelsim 10.1d (from Quartus II 13.0 ) - - - Icarus Verilog (no specific version) - - The set of tests performed by VlogHammer systematically verify the - correct behaviour of - - - Yosys Verilog Frontend and RTL generation - - - Yosys Gate-Level Technology Mapping - - - Yosys SAT Models for RTL- and Gate-Level cells - - - Yosys Constant Evaluator Models for RTL- and Gate-Level cells - - against the reference provided by the other tools. A few bugs related - to sign extensions and bit-width extensions where found (and have - been fixed meanwhile) using this approach. This test also revealed a - small number of bugs in the other tools (i.e. Vivado, XST, Quartus, - ISIM and Icarus Verilog; no bugs where found in Modelsim using - vlogHammer so far). - -Although complex software can never be expected to be fully bug-free -:cite:p:`MURPHY`, it has been shown that Yosys is mature and -feature-complete enough to handle most real-world cases correctly. - -Quality of synthesis results ----------------------------- - -In this section an attempt to evaluate the quality of Yosys synthesis -results is made. To this end the synthesis results of a commercial FPGA -synthesis tool when presented with the original HDL code vs. when -presented with the Yosys synthesis result are compared. - -The OpenMSP430 and the OpenRISC 1200 test cases were synthesized using -the following Yosys synthesis script: - -:: - - hierarchy -check - proc; opt; fsm; opt; memory; opt - techmap; opt; abc; opt - -The original RTL and the Yosys output where both passed to the Xilinx -XST 14.5 FPGA synthesis tool. The following setting where used for XST: - -:: - - -p artix7 - -use_dsp48 NO - -iobuf NO - -ram_extract NO - -rom_extract NO - -fsm_extract YES - -fsm_encoding Auto - -The results of this comparison is summarized in -Tab. \ `[tab:synth-test] <#tab:synth-test>`__. The used FPGA resources -(registers and LUTs) and performance (maximum frequency as reported by -XST) are given per module (indentation indicates module hierarchy, the -numbers are including all contained modules). - -For most modules the results are very similar between XST and Yosys. XST -is used in both cases for the final mapping of logic to LUTs. So this -comparison only compares the high-level synthesis functions (such as FSM -extraction and encoding) of Yosys and XST. - -.. table:: Synthesis results (as reported by XST) for OpenMSP430 and -OpenRISC 1200 - - ============================ ==== ==== ========== ==== ===== - ========== - \ - Module Regs LUTs Max. Freq. Regs LUTs Max. Freq. - openMSP430 689 2210 71 MHz 719 2779 53 MHz - 1em omsp_clock_module 21 30 645 MHz 21 30 644 MHz - 1em 1em omsp_sync_cell 2 — 1542 MHz 2 — 1542 MHz - 1em 1em omsp_sync_reset 2 — 1542 MHz 2 — 1542 MHz - 1em omsp_dbg 143 344 292 MHz 149 430 353 MHz - 1em 1em omsp_dbg_uart 76 135 377 MHz 79 139 389 MHz - 1em omsp_execution_unit 266 911 80 MHz 266 1034 137 MHz - 1em 1em omsp_alu — 202 — — 263 — - 1em 1em omsp_register_file 231 478 285 MHz 231 506 293 MHz - 1em omsp_frontend 115 340 178 MHz 118 527 206 MHz - 1em omsp_mem_backbone 38 141 1087 MHz 38 144 1087 MHz - 1em omsp_multiplier 73 397 129 MHz 102 1053 55 MHz - 1em omsp_sfr 6 18 1023 MHz 6 20 1023 MHz - 1em omsp_watchdog 24 53 362 MHz 24 70 360 MHz - or1200_top 7148 9969 135 MHz 7173 10238 108 MHz - 1em or1200_alu — 681 — — 641 — - 1em or1200_cfgr — 11 — — 11 — - 1em or1200_ctrl 175 186 464 MHz 174 279 377 MHz - 1em or1200_except 241 451 313 MHz 241 353 301 MHz - 1em or1200_freeze 6 18 507 MHz 6 16 515 MHz - 1em or1200_if 68 143 806 MHz 68 139 790 MHz - 1em or1200_lsu 8 138 — 12 205 1306 MHz - 1em 1em or1200_mem2reg — 60 — — 66 — - 1em 1em or1200_reg2mem — 29 — — 29 — - 1em or1200_mult_mac 394 2209 240 MHz 394 2230 241 MHz - 1em 1em or1200_amultp2_32x32 256 1783 240 MHz 256 1770 241 MHz - 1em or1200_operandmuxes 65 129 1145 MHz 65 129 1145 MHz - 1em or1200_rf 1041 1722 822 MHz 1042 1722 581 MHz - 1em or1200_sprs 18 432 724 MHz 18 469 722 MHz - 1em or1200_wbmux 33 93 — 33 78 — - 1em or1200_dc_top — 5 — — 5 — - 1em or1200_dmmu_top 2445 1004 — 2445 1043 — - 1em 1em or1200_dmmu_tlb 2444 975 — 2444 1013 — - 1em or1200_du 67 56 859 MHz 67 56 859 MHz - 1em or1200_ic_top 39 100 527 MHz 41 136 514 MHz - 1em 1em or1200_ic_fsm 40 42 408 MHz 40 75 484 MHz - 1em or1200_pic 38 50 1169 MHz 38 50 1177 MHz - 1em or1200_tt 64 112 370 MHz 64 186 437 MHz - ============================ ==== ==== ========== ==== ===== - ========== - -Conclusion and future Work --------------------------- - -Yosys is capable of correctly synthesizing real-world Verilog designs. -The generated netlists are of a decent quality. However, in cases where -dedicated hardware resources should be used for certain functions it is -of course necessary to implement proper technology mapping for these -functions in Yosys. This can be as easy as calling the techmap pass with -an architecture-specific mapping file in the synthesis script. As no -such thing has been done in the above tests, it is only natural that the -resulting designs cannot benefit from these dedicated hardware -resources. - -Therefore future work includes the implementation of -architecture-specific technology mappings besides additional frontends -(VHDL), backends (EDIF), and above all else, application specific -passes. After all, this was the main motivation for the development of -Yosys in the first place. - -.. [1] - Most of this test cases are copied from HANA or the ASIC-WORLD - website . - -.. [2] - At the time of this writing 269 test cases. - -.. [3] - At the time of this writing over 6600 test cases. - -.. [4] - A SAT solver is a program that can solve the boolean satisfiability - problem. The built-in SAT solver in Yosys can be used for formal - equivalence checking, amongst other things. See - Sec. \ \ `[cmd:sat] <#cmd:sat>`__ for details. - -.. footbibliography:: diff --git a/docs/source/CHAPTER_Intro.rst b/docs/source/CHAPTER_Intro.rst deleted file mode 100644 index 90b001c2312..00000000000 --- a/docs/source/CHAPTER_Intro.rst +++ /dev/null @@ -1,96 +0,0 @@ -.. _chapter:intro: - -Introduction -============ - -This document presents the Free and Open Source (FOSS) Verilog HDL synthesis -tool "Yosys". Its design and implementation as well as its performance on -real-world designs is discussed in this document. - -History of Yosys ----------------- - -A Hardware Description Language (HDL) is a computer language used to describe -circuits. A HDL synthesis tool is a computer program that takes a formal -description of a circuit written in an HDL as input and generates a netlist that -implements the given circuit as output. - -Currently the most widely used and supported HDLs for digital circuits are -Verilog :cite:p:`Verilog2005,VerilogSynth` and :abbr:`VHDL (VHSIC HDL, where -VHSIC is an acronym for Very-High-Speed Integrated Circuits)` -:cite:p:`VHDL,VHDLSynth`. Both HDLs are used for test and verification purposes -as well as logic synthesis, resulting in a set of synthesizable and a set of -non-synthesizable language features. In this document we only look at the -synthesizable subset of the language features. - -In recent work on heterogeneous coarse-grain reconfigurable logic -:cite:p:`intersynth` the need for a custom application-specific HDL synthesis -tool emerged. It was soon realised that a synthesis tool that understood Verilog -or VHDL would be preferred over a synthesis tool for a custom HDL. Given an -existing Verilog or VHDL front end, the work for writing the necessary -additional features and integrating them in an existing tool can be estimated to -be about the same as writing a new tool with support for a minimalistic custom -HDL. - -The proposed custom HDL synthesis tool should be licensed under a Free and Open -Source Software (FOSS) licence. So an existing FOSS Verilog or VHDL synthesis -tool would have been needed as basis to build upon. The main advantages of -choosing Verilog or VHDL is the ability to synthesize existing HDL code and to -mitigate the requirement for circuit-designers to learn a new language. In order -to take full advantage of any existing FOSS Verilog or VHDL tool, such a tool -would have to provide a feature-complete implementation of the synthesizable HDL -subset. - -Basic RTL synthesis is a well understood field :cite:p:`LogicSynthesis`. Lexing, -parsing and processing of computer languages :cite:p:`Dragonbook` is a -thoroughly researched field. All the information required to write such tools -has been openly available for a long time, and it is therefore likely that a -FOSS HDL synthesis tool with a feature-complete Verilog or VHDL front end must -exist which can be used as a basis for a custom RTL synthesis tool. - -Due to the author's preference for Verilog over VHDL it was decided early on to -go for Verilog instead of VHDL [#]_. So the existing FOSS Verilog synthesis -tools were evaluated. The results of this evaluation are utterly devastating. -Therefore a completely new Verilog synthesis tool was implemented and is -recommended as basis for custom synthesis tools. This is the tool that is -discussed in this document. - -Structure of this document --------------------------- - -The structure of this document is as follows: - -:numref:`Chapter %s ` is this introduction. - -:numref:`Chapter %s ` covers a short introduction to the world -of HDL synthesis. Basic principles and the terminology are outlined in this -chapter. - -:numref:`Chapter %s ` gives the quickest possible outline to -how the problem of implementing a HDL synthesis tool is approached in the case -of Yosys. - -:numref:`Chapter %s ` contains a more detailed overview of the -implementation of Yosys. This chapter covers the data structures used in Yosys -to represent a design in detail and is therefore recommended reading for -everyone who is interested in understanding the Yosys internals. - -:numref:`Chapter %s ` covers the internal cell library used by -Yosys. This is especially important knowledge for anyone who wants to understand -the intermediate netlists used internally by Yosys. - -:numref:`Chapter %s ` gives a tour to the internal APIs of Yosys. -This is recommended reading for everyone who actually wants to read or write -Yosys source code. The chapter concludes with an example loadable module for -Yosys. - -Chapters :numref:`%s `, :numref:`%s ` and -:numref:`%s ` cover three important pieces of the synthesis -pipeline: The Verilog frontend, the optimization passes and the technology -mapping to the target architecture, respectively. - -Various appendices, including a :ref:`cmd_ref`, complete this document. - -.. [#] - A quick investigation into FOSS VHDL tools yielded similar grim results for - FOSS VHDL synthesis tools. diff --git a/docs/source/_templates/page.html b/docs/source/_templates/page.html new file mode 100644 index 00000000000..d830124c176 --- /dev/null +++ b/docs/source/_templates/page.html @@ -0,0 +1,44 @@ +{# + +See https://github.com/pradyunsg/furo/blob/main/src/furo/theme/furo/page.html for the original +block this is overwriting. + +The part that is customized is between the "begin of custom part" and "end of custom part" +comments below. It uses the same styles as the existing right sidebar code. + +#} +{% extends "furo/page.html" %} +{% block right_sidebar %} +
+ {# begin of custom part #} +
+ + YosysHQ + +
+ + {# end of custom part #} + {% if not furo_hide_toc %} +
+ + {{ _("On this page") }} + +
+
+
+ {{ toc }} +
+
+ {% endif %} +
+{% endblock %} + \ No newline at end of file diff --git a/docs/source/appendix.rst b/docs/source/appendix.rst new file mode 100644 index 00000000000..87581793b35 --- /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 894d0fbbe2b..00000000000 --- a/docs/source/appendix/CHAPTER_StateOfTheArt.rst +++ /dev/null @@ -1,410 +0,0 @@ -.. _chapter:sota: - -Evaluation of other OSS Verilog Synthesis Tools -=============================================== - -In this appendix [1]_ the existing FOSS Verilog synthesis tools [2]_ are -evaluated. Extremely limited or application specific tools (e.g. pure -Verilog Netlist parsers) as well as Verilog simulators are not included. -These existing solutions are tested using a set of representative -Verilog code snippets. It is shown that no existing FOSS tool implements -even close to a sufficient subset of Verilog to be usable as synthesis -tool for a wide range existing Verilog code. - -The packages evaluated are: - -- Icarus Verilog [3]_ - -- Verilog-to-Routing (VTR) / Odin-II - :cite:p:`vtr2012}`:raw-latex:`\cite{Odin` - -- HDL Analyzer and Netlist Architect (HANA) - -- Verilog front-end to VIS (vl2mv) :cite:p:`Cheng93vl2mv:a` - -In each of the following sections Verilog modules that test a certain -Verilog language feature are presented and the support for these -features is tested in all the tools mentioned above. It is evaluated -whether the tools under test successfully generate netlists for the -Verilog input and whether these netlists match the simulation behavior -of the designs using testbenches. - -All test cases are verified to be synthesizeable using Xilinx XST from -the Xilinx WebPACK suite. - -Trivial features such as support for simple structural Verilog are not -explicitly tested. - -Vl2mv and Odin-II generate output in the BLIF (Berkeley Logic -Interchange Format) and BLIF-MV (an extended version of BLIF) formats -respectively. ABC is used to convert this output to Verilog for -verification using testbenches. - -Icarus Verilog generates EDIF (Electronic Design Interchange Format) -output utilizing LPM (Library of Parameterized Modules) cells. The EDIF -files are converted to Verilog using edif2ngd and netgen from Xilinx -WebPACK. A hand-written implementation of the LPM cells utilized by the -generated netlists is used for verification. - -Following these functional tests, a quick analysis of the extensibility -of the tools under test is provided in a separate section. - -The last section of this chapter finally concludes these series of -evaluations with a summary of the results. - -.. code:: verilog - :number-lines: - - module uut_always01(clock, - reset, count); - - input clock, reset; - output [3:0] count; - reg [3:0] count; - - always @(posedge clock) - count <= reset ? - 0 : count + 1; - - - - endmodule - -.. code:: verilog - - module uut_always02(clock, - reset, count); - - input clock, reset; - output [3:0] count; - reg [3:0] count; - - always @(posedge clock) begin - count <= count + 1; - if (reset) - count <= 0; - end - - endmodule - -[fig:StateOfTheArt_always12] - -.. code:: verilog - :number-lines: - - module uut_always03(clock, in1, in2, in3, in4, in5, in6, in7, - out1, out2, out3); - - input clock, in1, in2, in3, in4, in5, in6, in7; - output out1, out2, out3; - reg out1, out2, out3; - - always @(posedge clock) begin - out1 = in1; - if (in2) - out1 = !out1; - out2 <= out1; - if (in3) - out2 <= out2; - if (in4) - if (in5) - out3 <= in6; - else - out3 <= in7; - out1 = out1 ^ out2; - end - - endmodule - -[fig:StateOfTheArt_always3] - -.. _sec:blocking_nonblocking: - -Always blocks and blocking vs. nonblocking assignments ------------------------------------------------------- - -The "always"-block is one of the most fundamental non-trivial Verilog -language features. It can be used to model a combinatorial path (with -optional registers on the outputs) in a way that mimics a regular -programming language. - -Within an always block, if- and case-statements can be used to model -multiplexers. Blocking assignments (:math:`=`) and nonblocking -assignments (:math:`<=`) are used to populate the leaf-nodes of these -multiplexer trees. Unassigned leaf-nodes default to feedback paths that -cause the output register to hold the previous value. More advanced -synthesis tools often convert these feedback paths to register enable -signals or even generate circuits with clock gating. - -Registers assigned with nonblocking assignments (:math:`<=`) behave -differently from variables in regular programming languages: In a -simulation they are not updated immediately after being assigned. -Instead the right-hand sides are evaluated and the results stored in -temporary memory locations. After all pending updates have been prepared -in this way they are executed, thus yielding semi-parallel execution of -all nonblocking assignments. - -For synthesis this means that every occurrence of that register in an -expression addresses the output port of the corresponding register -regardless of the question whether the register has been assigned a new -value in an earlier command in the same always block. Therefore with -nonblocking assignments the order of the assignments has no effect on -the resulting circuit as long as the left-hand sides of the assignments -are unique. - -The three example codes in -:numref:`Fig. %s ` -and :numref:`Fig. %s ` -use all these features and can thus be used to test the synthesis tools -capabilities to synthesize always blocks correctly. - -The first example is only using the most fundamental Verilog features. -All tools under test were able to successfully synthesize this design. - -.. code:: verilog - :number-lines: - - module uut_arrays01(clock, we, addr, wr_data, rd_data); - - input clock, we; - input [3:0] addr, wr_data; - output [3:0] rd_data; - reg [3:0] rd_data; - - reg [3:0] memory [15:0]; - - always @(posedge clock) begin - if (we) - memory[addr] <= wr_data; - rd_data <= memory[addr]; - end - - endmodule - -[fig:StateOfTheArt_arrays] - -The 2nd example is functionally identical to the 1st one but is using an -if-statement inside the always block. Odin-II fails to synthesize it and -instead produces the following error message: - -:: - - ERROR: (File: always02.v) (Line number: 13) - You've defined the driver "count~0" twice - -Vl2mv does not produce an error message but outputs an invalid synthesis -result that is not using the reset input at all. - -Icarus Verilog also doesn't produce an error message but generates an -invalid output for this 2nd example. The code generated by Icarus -Verilog only implements the reset path for the count register, -effectively setting the output to constant 0. - -So of all tools under test only HANA was able to create correct -synthesis results for the 2nd example. - -The 3rd example is using blocking and nonblocking assignments and many -if statements. Odin also fails to synthesize this example: - -:: - - ERROR: (File: always03.v) (Line number: 8) - ODIN doesn't handle blocking statements in Sequential blocks - -HANA, Icarus Verilog and vl2mv create invalid synthesis results for the -3rd example. - -So unfortunately none of the tools under test provide a complete and -correct implementation of blocking and nonblocking assignments. - -Arrays for memory modelling ---------------------------- - -Verilog arrays are part of the synthesizeable subset of Verilog and are -commonly used to model addressable memory. The Verilog code in -:numref:`Fig. %s ` -demonstrates this by implementing a single port memory. - -For this design HANA, vl2m and ODIN-II generate error messages -indicating that arrays are not supported. - -.. code:: verilog - :number-lines: - - module uut_forgen01(a, y); - - input [4:0] a; - output y; - - integer i, j; - reg [31:0] lut; - - initial begin - for (i = 0; i < 32; i = i+1) begin - lut[i] = i > 1; - for (j = 2; j*j <= i; j = j+1) - if (i % j == 0) - lut[i] = 0; - end - end - - assign y = lut[a]; - - endmodule - -[fig:StateOfTheArt_for] - -Icarus Verilog produces an invalid output that is using the address only -for reads. Instead of using the address input for writes, the generated -design simply loads the data to all memory locations whenever the -write-enable input is active, effectively turning the design into a -single 4-bit D-Flip-Flop with enable input. - -As all tools under test already fail this simple test, there is nothing -to gain by continuing tests on this aspect of Verilog synthesis such as -synthesis of dual port memories, correct handling of write collisions, -and so forth. - -.. code:: verilog - :number-lines: - - module uut_forgen02(a, b, cin, y, cout); - - parameter WIDTH = 8; - - input [WIDTH-1:0] a, b; - input cin; - - output [WIDTH-1:0] y; - output cout; - - genvar i; - wire [WIDTH-1:0] carry; - - generate - for (i = 0; i < WIDTH; i=i+1) begin:adder - wire [2:0] D; - assign D[1:0] = { a[i], b[i] }; - if (i == 0) begin:chain - assign D[2] = cin; - end else begin:chain - assign D[2] = carry[i-1]; - end - assign y[i] = ^D; - assign carry[i] = &D[1:0] | (^D[1:0] & D[2]); - end - endgenerate - - assign cout = carry[WIDTH-1]; - - endmodule - -[fig:StateOfTheArt_gen] - -For-loops and generate blocks ------------------------------ - -For-loops and generate blocks are more advanced Verilog features. These -features allow the circuit designer to add program code to her design -that is evaluated during synthesis to generate (parts of) the circuits -description; something that could only be done using a code generator -otherwise. - -For-loops are only allowed in synthesizeable Verilog if they can be -completely unrolled. Then they can be a powerful tool to generate array -logic or static lookup tables. The code in -:numref:`Fig. %s ` generates a -circuit that tests a 5 bit value for being a prime number using a static -lookup table. - -Generate blocks can be used to model array logic in complex parametric -designs. The code in -:numref:`Fig. %s ` implements a -ripple-carry adder with parametric width from simple assign-statements -and logic operations using a Verilog generate block. - -All tools under test failed to synthesize both test cases. HANA creates -invalid output in both cases. Icarus Verilog creates invalid output for -the first test and fails with an error for the second case. The other -two tools fail with error messages for both tests. - -Extensibility -------------- - -This section briefly discusses the extensibility of the tools under test -and their internal data- and control-flow. As all tools under test -already failed to synthesize simple Verilog always-blocks correctly, not -much resources have been spent on evaluating the extensibility of these -tools and therefore only a very brief discussion of the topic is -provided here. - -HANA synthesizes for a built-in library of standard cells using two -passes over an AST representation of the Verilog input. This approach -executes fast but limits the extensibility as everything happens in only -two comparable complex AST walks and there is no universal intermediate -representation that is flexible enough to be used in arbitrary -optimizations. - -Odin-II and vl2m are both front ends to existing synthesis flows. As -such they only try to quickly convert the Verilog input into the -internal representation of their respective flows (BLIF). So -extensibility is less of an issue here as potential extensions would -likely be implemented in other components of the flow. - -Icarus Verilog is clearly designed to be a simulation tool rather than a -synthesis tool. The synthesis part of Icarus Verilog is an ad-hoc add-on -to Icarus Verilog that aims at converting an internal representation -that is meant for generation of a virtual machine based simulation code -to netlists. - -Summary and Outlook -------------------- - -Table \ :numref:`tab:StateOfTheArt_sum` summarizes -the tests performed. Clearly none of the tools under test make a serious -attempt at providing a feature-complete implementation of Verilog. It -can be argued that Odin-II performed best in the test as it never -generated incorrect code but instead produced error messages indicating -that unsupported Verilog features where used in the Verilog input. - -In conclusion, to the best knowledge of the author, there is no FOSS -Verilog synthesis tool other than Yosys that is anywhere near feature -completeness and therefore there is no other candidate for a generic -Verilog front end and/or synthesis framework to be used as a basis for -custom synthesis tools. - -Yosys could also replace vl2m and/or Odin-II in their respective flows -or function as a pre-compiler that can translate full-featured Verilog -code to the simple subset of Verilog that is understood by vl2m and -Odin-II. - -Yosys is designed for extensibility. It can be used as-is to synthesize -Verilog code to netlists, but its main purpose is to be used as basis -for custom tools. Yosys is structured in a language dependent Verilog -front end and language independent synthesis code (which is in itself -structured in independent passes). This architecture will simplify -implementing additional HDL front ends and/or additional synthesis -passes. - -Chapter \ :numref:`` contains a more detailed -evaluation of Yosys using real-world designs that are far out of reach -for any of the other tools discussed in this appendix. - -…passed 2em …produced error 2em :math:`\skull` …incorrect output - -[tab:StateOfTheArt_sum] - -.. [1] - This appendix is an updated version of an unpublished student - research paper. :cite:p:`VerilogFossEval` - -.. [2] - To the author's best knowledge, all relevant tools that existed at - the time of this writing are included. But as there is no formal - channel through which such tools are published it is hard to give any - guarantees in that matter. - -.. [3] - Icarus Verilog is mainly a simulation tool but also supported - synthesis up to version 0.8. Therefore version 0.8.7 is used for this - evaluation.) diff --git a/docs/source/appendix/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 361f00e025b..2f443c041da 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 e4f6f62cfb6..9071abfd1b3 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 ` 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 618bec545a9..ed1a3188c53 100644 --- a/docs/source/CHAPTER_Basics.rst +++ b/docs/source/appendix/primer.rst @@ -3,8 +3,8 @@ .. _chapter:basics: -Basic principles -================ +A primer on digital circuit synthesis +===================================== This chapter contains a short introduction to the basic principles of digital circuit synthesis. @@ -23,7 +23,7 @@ circuit to a functionally equivalent low-level representation of a circuit. :numref:`Figure %s ` lists the different levels of abstraction and how they relate to different kinds of synthesis. -.. figure:: ../images/basics_abstractions.* +.. figure:: ../../images/basics_abstractions.* :class: width-helper :name: fig:Basics_abstractions @@ -161,7 +161,7 @@ At the logical gate level the design is represented by a netlist that uses only cells from a small number of single-bit cells, such as basic logic gates (AND, OR, NOT, XOR, etc.) and registers (usually D-Type Flip-flops). -A number of netlist formats exists that can be used on this level, e.g. the +A number of netlist formats exists that can be used on this level, e.g. the Electronic Design Interchange Format (EDIF), but for ease of simulation often a HDL netlist is used. The latter is a HDL file (Verilog or VHDL) that only uses the most basic language constructs for instantiation and connecting of cells. @@ -172,7 +172,7 @@ good) mapping of the logic gate netlist to an equivalent netlist of physically available gate types. The simplest approach to logic synthesis is two-level logic synthesis, where a -logic function is converted into a sum-of-products representation, e.g. using a +logic function is converted into a sum-of-products representation, e.g. using a Karnaugh map. This is a simple approach, but has exponential worst-case effort and cannot make efficient use of physical gates other than AND/NAND-, OR/NOR- and NOT-Gates. @@ -196,7 +196,7 @@ Physical gate level On the physical gate level only gates are used that are physically available on the target architecture. In some cases this may only be NAND, NOR and NOT gates as well as D-Type registers. In other cases this might include cells that are -more complex than the cells used at the logical gate level (e.g. complete +more complex than the cells used at the logical gate level (e.g. complete half-adders). In the case of an FPGA-based design the physical gate level representation is a netlist of LUTs with optional output registers, as these are the basic building blocks of FPGA logic cells. @@ -345,7 +345,7 @@ covered by the Verilog synthesis standard and when writing new designs one should limit herself or himself to these cases. In behavioural modelling, blocking assignments (=) and non-blocking assignments -(<=) can be used. The concept of blocking vs. non-blocking assignment is one of +(<=) can be used. The concept of blocking vs. non-blocking assignment is one of the most misunderstood constructs in Verilog :cite:p:`Cummings00`. The blocking assignment behaves exactly like an assignment in any imperative @@ -498,7 +498,7 @@ Then the synthesizable description is transformed to lower-level representations using a series of tools and the results are again verified using simulation. This process is illustrated in :numref:`Fig. %s `. -.. figure:: ../images/basics_flow.* +.. figure:: ../../images/basics_flow.* :class: width-helper :name: fig:Basics_flow @@ -515,8 +515,8 @@ Gate-Level Model are verified and the design process is finished. However, in any real-world design effort there will be multiple iterations for this design process. The reason for this can be the late change of a design requirement or the fact that the analysis of a low-abstraction model -(e.g. gate-level timing analysis) revealed that a design change is required in -order to meet the design requirements (e.g. maximum possible clock speed). +(e.g. gate-level timing analysis) revealed that a design change is required in +order to meet the design requirements (e.g. maximum possible clock speed). Whenever the behavioural model or the system level model is changed their equivalence must be re-verified by re-running the simulations and comparing the @@ -572,7 +572,7 @@ of lexical tokens given in :numref:`Tab. %s `. TOK_SEMICOLON \- ============== =============== -The lexer is usually generated by a lexer generator (e.g. flex ) from a +The lexer is usually generated by a lexer generator (e.g. flex ) from a description file that is using regular expressions to specify the text pattern that should match the individual tokens. @@ -586,7 +586,7 @@ use the Token-Type to make a decision on the grammatical role of a token. The parser then transforms the list of tokens into a parse tree that closely resembles the productions from the computer languages grammar. As the lexer, the -parser is also typically generated by a code generator (e.g. bison ) from a +parser is also typically generated by a code generator (e.g. bison ) from a grammar description in Backus-Naur Form (BNF). Let's consider the following BNF (in Bison syntax): @@ -597,7 +597,7 @@ Let's consider the following BNF (in Bison syntax): assign_stmt: TOK_ASSIGN TOK_IDENTIFIER TOK_EQ expr TOK_SEMICOLON; expr: TOK_IDENTIFIER | TOK_NUMBER | expr TOK_PLUS expr; -.. figure:: ../images/basics_parsetree.* +.. figure:: ../../images/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 4b9dc91f3e1..138e934e337 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 52a21afb22e..512521a835a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -7,11 +7,31 @@ 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 @@ 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 @@ # 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 75a58c089c4..00000000000 --- 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 00000000000..88458c50e29 --- /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 00000000000..310a7029ee1 --- /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 00000000000..b832968167f --- /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 00000000000..5c6f7398cdf --- /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 681c18f7a9d..0cae4aa0dbd 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 c87326b9d3f..c4d6c128597 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 d357a83b7cc..74c8dd090cb 100644 --- a/docs/source/requirements.txt +++ b/docs/source/requirements.txt @@ -1,2 +1,2 @@ -sphinx-press-theme +furo sphinxcontrib-bibtex diff --git a/docs/source/using_yosys.rst b/docs/source/using_yosys.rst deleted file mode 100644 index 89b45669767..00000000000 --- 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 00000000000..ea451d395ce --- /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 00000000000..e9e005c5eef --- /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 53e0a67aa09..8905a3455f3 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 `. 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 -` 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 00000000000..bdbb762f44e --- /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 00000000000..ff87d63cdb6 --- /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 00000000000..61317f7cd36 --- /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 6e22bdcbd19..00000000000 --- 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 23aeed5a50c..a9653a7d304 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 00000000000..65eaaa5d59b --- /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 +`). + +.. 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 00000000000..a235996e9f8 --- /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 00000000000..025d6f8b7b5 --- /dev/null +++ b/docs/source/yosys_internals/flow/overview.rst @@ -0,0 +1,48 @@ +Flow overview +============= + +.. TODO: copypaste + +:numref:`Figure %s ` shows the simplified data flow within +Yosys. Rectangles in the figure represent program modules and ellipses internal +data structures that are used to exchange design data between the program +modules. + +Design data is read in using one of the frontend modules. The high-level HDL +frontends for Verilog and VHDL code generate an abstract syntax tree (AST) that +is then passed to the AST frontend. Note that both HDL frontends use the same +AST representation that is powerful enough to cover the Verilog HDL and VHDL +language. + +The AST Frontend then compiles the AST to Yosys's main internal data format, the +RTL Intermediate Language (RTLIL). A more detailed description of this format is +given in the next section. + +There is also a text representation of the RTLIL data structure that can be +parsed using the RTLIL Frontend. + +The design data may then be transformed using a series of passes that all +operate on the RTLIL representation of the design. + +Finally the design in RTLIL representation is converted back to text by one of +the backends, namely the Verilog Backend for generating Verilog netlists and the +RTLIL Backend for writing the RTLIL data in the same format that is understood +by the RTLIL Frontend. + +With the exception of the AST Frontend, which is called by the high-level HDL +frontends and can't be called directly by the user, all program modules are +called by the user (usually using a synthesis script that contains text commands +for Yosys). + +By combining passes in different ways and/or adding additional passes to Yosys +it is possible to adapt Yosys to a wide range of applications. For this to be +possible it is key that (1) all passes operate on the same data structure +(RTLIL) and (2) that this data structure is powerful enough to represent the +design in different stages of the synthesis. + +.. figure:: ../../../images/overview_flow.* + :class: width-helper + :name: fig:Overview_flow + + Yosys simplified data flow (ellipses: data structures, rectangles: + program modules) 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 484844fba04..cded945e5b0 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 `. -.. 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 c8904086879..67e1fc0ef92 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 `, :numref:`%s +Tables \ :numref:`%s `, :numref:`%s `, :numref:`%s `, :numref:`%s `, :numref:`%s `, :numref:`%s `, :numref:`%s `, diff --git a/docs/source/yosys_internals/formats/index.rst b/docs/source/yosys_internals/formats/index.rst new file mode 100644 index 00000000000..4acf9202f16 --- /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 00000000000..cbf5369bc06 --- /dev/null +++ b/docs/source/yosys_internals/formats/overview.rst @@ -0,0 +1,53 @@ +Format overview +=============== + +Yosys uses two different internal formats. The first is used to store an +abstract syntax tree (AST) of a Verilog input file. This format is simply called +AST and is generated by the Verilog Frontend. This data structure is consumed by +a subsystem called AST Frontend [1]_. This AST Frontend then generates a design +in Yosys' main internal format, the +Register-Transfer-Level-Intermediate-Language (RTLIL) representation. It does +that by first performing a number of simplifications within the AST +representation and then generating RTLIL from the simplified AST data structure. + +The RTLIL representation is used by all passes as input and outputs. This has +the following advantages over using different representational formats between +different passes: + +- The passes can be rearranged in a different order and passes can be removed + or inserted. + +- Passes can simply pass-thru the parts of the design they don't change without + the need to convert between formats. In fact Yosys passes output the same + data structure they received as input and performs all changes in place. + +- All passes use the same interface, thus reducing the effort required to + understand a pass when reading the Yosys source code, e.g. when adding + additional features. + +The RTLIL representation is basically a netlist representation with the +following additional features: + +- An internal cell library with fixed-function cells to represent RTL datapath + and register cells as well as logical gate-level cells (single-bit gates and + registers). + +- Support for multi-bit values that can use individual bits from wires as well + as constant bits to represent coarse-grain netlists. + +- Support for basic behavioural constructs (if-then-else structures and + multi-case switches with a sensitivity list for updating the outputs). + +- Support for multi-port memories. + +The use of RTLIL also has the disadvantage of having a very powerful format +between all passes, even when doing gate-level synthesis where the more advanced +features are not needed. In order to reduce complexity for passes that operate +on a low-level representation, these passes check the features used in the input +RTLIL and fail to run when unsupported high-level constructs are used. In such +cases a pass that transforms the higher-level constructs to lower-level +constructs must be called from the synthesis script first. + +.. [1] + In Yosys the term pass is only used to refer to commands that operate on the + RTLIL data structure. \ No newline at end of file diff --git a/docs/source/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 10d2ce47840..d247a5da42e 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 ` 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 ` 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 ` for details about the memory cell types. - -Command interface and synthesis scripts ---------------------------------------- - -Yosys reads and processes commands from synthesis scripts, command line -arguments and an interactive command prompt. Yosys commands consist of a command -name and an optional whitespace separated list of arguments. Commands are -terminated using the newline character or a semicolon (;). Empty lines and lines -starting with the hash sign (#) are ignored. See :numref:`Sec. %s -` for an example synthesis script. - -The command help can be used to access the command reference manual. - -Most commands can operate not only on the entire design but also specifically on -selected parts of the design. For example the command dump will print all -selected objects in the current design while dump foobar will only print the -module foobar and dump \* will print the entire design regardless of the current -selection. - -.. code:: yoscrypt - - dump */t:$add %x:+[A] \*/w:\* %i - -The selection mechanism is very powerful. For example the command above will -print all wires that are connected to the ``\A`` port of a ``$add`` cell. -Detailed documentation of the select framework can be found in the command -reference for the ``select`` command. - -Source tree and build system ----------------------------- - -The Yosys source tree is organized into the following top-level -directories: - -- | backends/ - | This directory contains a subdirectory for each of the backend modules. - -- | frontends/ - | This directory contains a subdirectory for each of the frontend modules. - -- | kernel/ - | This directory contains all the core functionality of Yosys. This includes - the functions and definitions for working with the RTLIL data structures - (rtlil.h and rtlil.cc), the main() function (driver.cc), the internal - framework for generating log messages (log.h and log.cc), the internal - framework for registering and calling passes (register.h and register.cc), - some core commands that are not really passes (select.cc, show.cc, …) and a - couple of other small utility libraries. - -- | passes/ - | This directory contains a subdirectory for each pass or group of passes. - For example as of this writing the directory passes/opt/ contains the code - for seven passes: opt, opt_expr, opt_muxtree, opt_reduce, opt_rmdff, - opt_rmunused and opt_merge. - -- | techlibs/ - | This directory contains simulation models and standard implementations for - the cells from the internal cell library. - -- | tests/ - | This directory contains a couple of test cases. Most of the smaller tests - are executed automatically when make test is called. The larger tests must - be executed manually. Most of the larger tests require downloading external - HDL source code and/or external tools. The tests range from comparing - simulation results of the synthesized design to the original sources to - logic equivalence checking of entire CPU cores. - -The top-level Makefile includes frontends/\*/Makefile.inc, -passes/\*/Makefile.inc and backends/\*/Makefile.inc. So when extending Yosys it -is enough to create a new directory in frontends/, passes/ or backends/ with -your sources and a Makefile.inc. The Yosys kernel automatically detects all -commands linked with Yosys. So it is not needed to add additional commands to a -central list of commands. - -Good starting points for reading example source code to learn how to write -passes are passes/opt/opt_rmdff.cc and passes/opt/opt_merge.cc. - -See the top-level README file for a quick Getting Started guide and build -instructions. The Yosys build is based solely on Makefiles. - -Users of the Qt Creator IDE can generate a QT Creator project file using make -qtcreator. Users of the Eclipse IDE can use the "Makefile Project with Existing -Code" project type in the Eclipse "New Project" dialog (only available after the -CDT plugin has been installed) to create an Eclipse project in order to -programming extensions to Yosys or just browse the Yosys code base. +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 dc3d72230b9..a7f1d843b62 100644 --- a/docs/source/appendix/CHAPTER_TextRtlil.rst +++ b/docs/source/yosys_internals/formats/rtlil_text.rst @@ -1,7 +1,7 @@ .. _chapter:textrtlil: RTLIL text representation -========================= +------------------------- This appendix documents the text representation of RTLIL in extended Backus-Naur form (EBNF). @@ -17,10 +17,10 @@ Finally, note that all statements (rules ending in ``-stmt``) terminate in an end-of-line. Because of this, a statement cannot be broken into multiple lines. Lexical elements ----------------- +~~~~~~~~~~~~~~~~ Characters -~~~~~~~~~~ +^^^^^^^^^^ An RTLIL file is a stream of bytes. Strictly speaking, a "character" in an RTLIL file is a single byte. The lexer treats multi-byte encoded characters as @@ -37,7 +37,7 @@ An ``eol`` is one or more consecutive ASCII newlines (10) and carriage returns (13). Identifiers -~~~~~~~~~~~ +^^^^^^^^^^^ There are two types of identifiers in RTLIL: @@ -51,7 +51,7 @@ There are two types of identifiers in RTLIL: ::= $ + Values -~~~~~~ +^^^^^^ A *value* consists of a width in bits and a bit representation, most significant bit first. Bits may be any of: @@ -76,7 +76,7 @@ error. ::= -? + Strings -~~~~~~~ +^^^^^^^ A string is a series of characters delimited by double-quote characters. Within a string, any character except ASCII NUL (0) may be used. In addition, certain @@ -94,13 +94,13 @@ character. Thus: - ``\r``: An 'r' character Comments -~~~~~~~~ +^^^^^^^^ A comment starts with a ``#`` character and proceeds to the end of the line. All comments are ignored. File ----- +~~~~ A file consists of an optional autoindex statement followed by zero or more modules. @@ -110,7 +110,7 @@ modules. ::= ? * Autoindex statements -~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^ The autoindex statement sets the global autoindex value used by Yosys when it needs to generate a unique name, e.g. ``flattenN``. The N part is filled with @@ -123,7 +123,7 @@ would have different properties than just running a pass on a warm design. ::= autoidx Modules -~~~~~~~ +^^^^^^^ Declares a module, with zero or more attributes, consisting of zero or more wires, memories, cells, processes, and connections. @@ -142,7 +142,7 @@ wires, memories, cells, processes, and connections. ::= end Attribute statements -~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^ Declares an attribute with the given identifier and value. @@ -151,7 +151,7 @@ Declares an attribute with the given identifier and value. ::= attribute Signal specifications -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^ A signal is anything that can be applied to a cell port, i.e. a constant value, all bits or a selection of bits from a wire, or concatenations of those. @@ -161,8 +161,7 @@ all bits or a selection of bits from a wire, or concatenations of those. ``32'11111111111111111111111111111111``, while a constant of :math:`1` is the same as ``32'1``. -See :numref:`Sec. %s ` for an overview of signal -specifications. +See :ref:`sec:rtlil_sigspec` for an overview of signal specifications. .. code:: BNF @@ -172,7 +171,7 @@ specifications. | { * } Connections -~~~~~~~~~~~ +^^^^^^^^^^^ Declares a connection between the given signals. @@ -181,12 +180,12 @@ Declares a connection between the given signals. ::= connect Wires -~~~~~ +^^^^^ Declares a wire, with zero or more attributes, with the given identifier and options in the enclosing module. -See :numref:`Sec. %s ` for an overview of wires. +See :ref:`sec:rtlil_cell_wire` for an overview of wires. .. code:: BNF @@ -202,13 +201,13 @@ See :numref:`Sec. %s ` for an overview of wires. | signed Memories -~~~~~~~~ +^^^^^^^^ Declares a memory, with zero or more attributes, with the given identifier and options in the enclosing module. -See :numref:`Sec. %s ` for an overview of memory cells, and -:numref:`Sec. %s ` for details about memory cell types. +See :ref:`sec:rtlil_memory` for an overview of memory cells, and +:ref:`sec:memcells` for details about memory cell types. .. code:: BNF @@ -219,13 +218,13 @@ See :numref:`Sec. %s ` for an overview of memory cells, and | offset Cells -~~~~~ +^^^^^ Declares a cell, with zero or more attributes, with the given identifier and type in the enclosing module. -Cells perform functions on input signals. See :numref:`Chap. %s -` for a detailed list of cell types. +Cells perform functions on input signals. See :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 ` for an overview of processes. +See :ref:`sec:rtlil_process` for an overview of processes. .. code:: BNF @@ -258,7 +257,7 @@ See :numref:`Sec. %s ` for an overview of processes. ::= end Switches -~~~~~~~~ +^^^^^^^^ Switches test a signal for equality against a list of cases. Each case specifies a comma-separated list of signals to check against. If there are no signals in @@ -277,7 +276,7 @@ attributes. ::= end Syncs -~~~~~ +^^^^^ Syncs update signals with other signals when an event happens. Such an event may be: diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst new file mode 100644 index 00000000000..e8d6fd1a05f --- /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 6cd1eb44f39..18eec664b6a 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 `). 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 00000000000..9dc0a7d4c7a --- /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 bdbb762f44e..3b81785dc15 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 a9653a7d304..99eba5a7678 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 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 4acf9202f16..2e6fba0178a 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 b0390cb9977..00000000000 --- a/manual/PRESENTATION_Prog.tex +++ /dev/null @@ -1,596 +0,0 @@ - -\section{Writing Yosys extensions in C++} - -\begin{frame} -\sectionpage -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Program Components and Data Formats} - -\begin{frame}{\subsecname} -\begin{center} -\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{process} = [draw, fill=green!10, rectangle, minimum height=3em, minimum width=10em, node distance=15em] - \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em] - \node[process] (vlog) {Verilog Frontend}; - \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend}; - \node[process] (ilang) [right of=vhdl] {Other Frontends}; - \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST}; - \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend}; - \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; - \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; - \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; - \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; - \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; - - \draw[-latex] (vlog) -- (ast); - \draw[-latex] (vhdl) -- (ast); - \draw[-latex] (ast) -- (astfe); - \draw[-latex] (astfe) -- (rtlil); - \draw[-latex] (ilang) -- (rtlil); - \draw[latex-latex] (rtlil) -- (pass); - \draw[-latex] (rtlil) -- (vlbe); - \draw[-latex] (rtlil) -- (ilangbe); - \draw[-latex] (rtlil) -- (otherbe); -\end{tikzpicture} -\end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Simplified RTLIL Entity-Relationship Diagram} - -\begin{frame}{\subsecname} -Between passses and frontends/backends the design is stored in Yosys' internal -RTLIL (RTL Intermediate Language) format. For writing Yosys extensions it is -key to understand this format. - -\bigskip -\begin{center} -\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}] - \node[entity] (design) {RTLIL::Design}; - \node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design); - - \node[entity] (process) [fill=green!10, right of=module, node distance=10em] {RTLIL::Process} (process.west) edge [-latex] (module); - \node[entity] (memory) [fill=red!10, below of=process] {RTLIL::Memory} edge [-latex] (module); - \node[entity] (wire) [fill=blue!10, above of=process] {RTLIL::Wire} (wire.west) edge [-latex] (module); - \node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module); - - \node[entity] (case) [fill=green!10, right of=process, node distance=10em] {RTLIL::CaseRule} edge [latex-latex] (process); - \node[entity] (sync) [fill=green!10, above of=case] {RTLIL::SyncRule} edge [-latex] (process); - \node[entity] (switch) [fill=green!10, below of=case] {RTLIL::SwitchRule} edge [-latex] (case); - \draw[latex-] (switch.east) -- ++(1em,0) |- (case.east); -\end{tikzpicture} -\end{center} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{RTLIL without memories and processes} - -\begin{frame}[fragile]{\subsecname} -After the commands {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are -left with a much simpler version of RTLIL: - -\begin{center} -\begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] - \tikzstyle{entity} = [draw, fill=gray!10, rectangle, minimum height=3em, minimum width=7em, node distance=5em, font={\ttfamily}] - \node[entity] (design) {RTLIL::Design}; - \node[entity] (module) [right of=design, node distance=11em] {RTLIL::Module} edge [-latex] node[above] {\tiny 1 \hskip3em N} (design); - - \node[entity] (wire) [fill=blue!10, right of=module, node distance=10em] {RTLIL::Wire} (wire.west) edge [-latex] (module); - \node[entity] (cell) [fill=blue!10, above of=wire] {RTLIL::Cell} (cell.west) edge [-latex] (module); -\end{tikzpicture} -\end{center} - -\bigskip -Many commands simply choose to only work on this simpler version: -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -for (RTLIL::Module *module : design->selected_modules() { - if (module->has_memories_warn() || module->has_processes_warn()) - continue; - .... -} -\end{lstlisting} - -For simplicity we only discuss this version of RTLIL in this presentation. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Using dump and show commands} - -\begin{frame}{\subsecname} -\begin{itemize} -\item The {\tt dump} command prints the design (or parts of it) in the text representation of RTLIL. - -\bigskip -\item The {\tt show} command visualizes how the components in the design are connected. -\end{itemize} - -\bigskip -When trying to understand what a command does, create a small test case and -look at the output of {\tt dump} and {\tt show} before and after the command -has been executed. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The RTLIL Data Structures} - -\begin{frame}{\subsecname} -The RTLIL data structures are simple structs utilizing {\tt pool<>} and -{\tt dict<>} containers (drop-in replacements for {\tt -std::unordered\_set<>} and {\tt std::unordered\_map<>}). - -\bigskip -\begin{itemize} -\item Most operations are performed directly on the RTLIL structs without -setter or getter functions. - -\bigskip -\item In debug builds a consistency checker is run over the in-memory design -between commands to make sure that the RTLIL representation is intact. - -\bigskip -\item Most RTLIL structs have helper methods that perform the most common operations. -\end{itemize} - -\bigskip -See {\tt yosys/kernel/rtlil.h} for details. -\end{frame} - -\subsubsection{RTLIL::IdString} - -\begin{frame}{\subsubsecname}{} -{\tt RTLIL::IdString} in many ways behave like a {\tt std::string}. It is used -for names of RTLIL objects. Internally a RTLIL::IdString object is only a -single integer. - -\medskip -The first character of a {\tt RTLIL::IdString} specifies if the name is {\it public\/} or {\it private\/}: - -\medskip -\begin{itemize} -\item {\tt RTLIL::IdString[0] == '\textbackslash\textbackslash'}: \\ -This is a public name. Usually this means it is a name that was declared in a Verilog file. - -\bigskip -\item {\tt RTLIL::IdString[0] == '\$'}: \\ -This is a private name. It was assigned by Yosys. -\end{itemize} - -\bigskip -Use the {\tt NEW\_ID} macro to create a new unique private name. -\end{frame} - -\subsubsection{RTLIL::Design and RTLIL::Module} - -\begin{frame}[t, fragile]{\subsubsecname} -The {\tt RTLIL::Design} and {\tt RTLIL::Module} structs are the top-level RTLIL -data structures. Yosys always operates on one active design, but can hold many designs in memory. - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Design { - dict modules_; - ... -}; - -struct RTLIL::Module { - RTLIL::IdString name; - dict wires_; - dict cells_; - std::vector connections_; - ... -}; -\end{lstlisting} - -(Use the various accessor functions instead of directly working with the {\tt *\_} members.) -\end{frame} - -\subsubsection{The RTLIL::Wire Structure} - -\begin{frame}[t, fragile]{\subsubsecname} -Each wire in the design is represented by a {\tt RTLIL::Wire} struct: - -\medskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Wire { - RTLIL::IdString name; - int width, start_offset, port_id; - bool port_input, port_output; - ... -}; -\end{lstlisting} - -\medskip -\hfil\begin{tabular}{p{3cm}l} -{\tt width} \dotfill & The total number of bits. E.g. 10 for {\tt [9:0]}. \\ -{\tt start\_offset} \dotfill & The lowest bit index. E.g. 3 for {\tt [5:3]}. \\ -{\tt port\_id} \dotfill & Zero for non-ports. Positive index for ports. \\ -{\tt port\_input} \dotfill & True for {\tt input} and {\tt inout} ports. \\ -{\tt port\_output} \dotfill & True for {\tt output} and {\tt inout} ports. \\ -\end{tabular} -\end{frame} - -\subsubsection{RTLIL::State and RTLIL::Const} - -\begin{frame}[t, fragile]{\subsubsecname} -The {\tt RTLIL::State} enum represents a simple 1-bit logic level: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -enum RTLIL::State { - S0 = 0, - S1 = 1, - Sx = 2, // undefined value or conflict - Sz = 3, // high-impedance / not-connected - Sa = 4, // don't care (used only in cases) - Sm = 5 // marker (used internally by some passes) -}; -\end{lstlisting} - -\bigskip -The {\tt RTLIL::Const} struct represents a constant multi-bit value: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Const { - std::vector bits; - ... -}; -\end{lstlisting} - -\bigskip -Notice that Yosys is not using special {\tt VCC} or {\tt GND} driver cells to represent constants. Instead -constants are part of the RTLIL representation itself. -\end{frame} - -\subsubsection{The RTLIL::SigSpec Structure} - -\begin{frame}[t, fragile]{\subsubsecname} -The {\tt RTLIL::SigSpec} struct represents a signal vector. Each bit can either be a bit from a wire -or a constant value. - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::SigBit -{ - RTLIL::Wire *wire; - union { - RTLIL::State data; // used if wire == NULL - int offset; // used if wire != NULL - }; - ... -}; - -struct RTLIL::SigSpec { - std::vector bits_; // LSB at index 0 - ... -}; -\end{lstlisting} - -\bigskip -The {\tt RTLIL::SigSpec} struct has a ton of additional helper methods to compare, analyze, and -manipulate instances of {\tt RTLIL::SigSpec}. -\end{frame} - -\subsubsection{The RTLIL::Cell Structure} - -\begin{frame}[t, fragile]{\subsubsecname (1/2)} -The {\tt RTLIL::Cell} struct represents an instance of a module or library cell. - -\smallskip -The ports of the cell -are associated with {\tt RTLIL::SigSpec} instances and the parameters are associated with {\tt RTLIL::Const} -instances: - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -struct RTLIL::Cell { - RTLIL::IdString name, type; - dict connections_; - dict parameters; - ... -}; -\end{lstlisting} - -\bigskip -The {\tt type} may refer to another module in the same design, a cell name from a cell library, or a -cell name from the internal cell library: - -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] -$not $pos $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor -$reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod -$divfloor $modfloor $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff -$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ -$_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ -$_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ -$_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_ -$_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ $_DLATCHSR_PPP_ -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname (2/2)} -Simulation models (i.e. {\it documentation\/} :-) for the internal cell library: - -\smallskip -\hskip2em {\tt yosys/techlibs/common/simlib.v} and \\ -\hskip2em {\tt yosys/techlibs/common/simcells.v} - -\bigskip -The lower-case cell types (such as {\tt \$and}) are parameterized cells of variable -width. This so-called {\it RTL Cells\/} are the cells described in {\tt simlib.v}. - -\bigskip -The upper-case cell types (such as {\tt \$\_AND\_}) are single-bit cells that are not -parameterized. This so-called {\it Internal Logic Gates} are the cells described -in {\tt simcells.v}. - -\bigskip -The consistency checker also checks the interfaces to the internal cell library. -If you want to use private cell types for your own purposes, use the {\tt \$\_\_}-prefix -to avoid name collisions. -\end{frame} - -\subsubsection{Connecting wires or constant drivers} - -\begin{frame}[t, fragile]{\subsubsecname} -Additional connections between wires or between wires and constants are modelled using -{\tt RTLIL::Module::connections}: - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -typedef std::pair RTLIL::SigSig; - -struct RTLIL::Module { - ... - std::vector connections_; - ... -}; -\end{lstlisting} - -\bigskip -{\tt RTLIL::SigSig::first} is the driven signal and {\tt RTLIL::SigSig::second} is the driving signal. -Example usage (setting wire {\tt foo} to value {\tt 42}): -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -module->connect(module->wire("\\foo"), - RTLIL::SigSpec(42, module->wire("\\foo")->width)); -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Creating modules from scratch} - -\begin{frame}[t, fragile]{\subsecname} -Let's create the following module using the RTLIL API: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module absval(input signed [3:0] a, output [3:0] y); - assign y = a[3] ? -a : a; -endmodule -\end{lstlisting} - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -RTLIL::Module *module = new RTLIL::Module; -module->name = "\\absval"; - -RTLIL::Wire *a = module->addWire("\\a", 4); -a->port_input = true; -a->port_id = 1; - -RTLIL::Wire *y = module->addWire("\\y", 4); -y->port_output = true; -y->port_id = 2; - -RTLIL::Wire *a_inv = module->addWire(NEW_ID, 4); -module->addNeg(NEW_ID, a, a_inv, true); -module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); - -module->fixup_ports(); -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Modifying modules} - -\begin{frame}{\subsecname} -Most commands modify existing modules, not create new ones. - -When modifying existing modules, stick to the following DOs and DON'Ts: - -\begin{itemize} -\item Do not remove wires. Simply disconnect them and let a successive {\tt clean} command worry about removing it. - -\item Use {\tt module->fixup\_ports()} after changing the {\tt port\_*} properties of wires. - -\item You can safely remove cells or change the {\tt connections} property of a cell, but be careful when -changing the size of the {\tt SigSpec} connected to a cell port. - -\item Use the {\tt SigMap} helper class (see next slide) when you need a unique handle for each signal bit. -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Using the SigMap helper class} - -\begin{frame}[t, fragile]{\subsecname} -Consider the following module: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module test(input a, output x, y); - assign x = a, y = a; -endmodule -\end{lstlisting} - -In this case {\tt a}, {\tt x}, and {\tt y} are all different names for the same signal. However: - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), - y(module->wire("\\y")); -log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" -\end{lstlisting} - -The {\tt SigMap} helper class can be used to map all such aliasing signals to a -unique signal from the group (usually the wire that is directly driven by a cell or port). - -\smallskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -SigMap sigmap(module); -log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y), - sigmap(y) == sigmap(a)); // will print "1 1 1" -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Printing log messages} - -\begin{frame}[t, fragile]{\subsecname} -The {\tt log()} function is a {\tt printf()}-like function that can be used to create log messages. - -\medskip -Use {\tt log\_signal()} to create a C-string for a SigSpec object\footnote[frame]{The pointer returned -by {\tt log\_signal()} is automatically freed by the log framework at a later time.}: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -log("Mapped signal x: %s\n", log_signal(sigmap(x))); -\end{lstlisting} - -\medskip -Use {\tt log\_id()} to create a C-string for an {\tt RTLIL::IdString}: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -log("Name of this module: %s\n", log_id(module->name)); -\end{lstlisting} - -\medskip -Use {\tt log\_header()} and {\tt log\_push()}/{\tt log\_pop()} to structure log messages: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -log_header(design, "Doing important stuff!\n"); -log_push(); -for (int i = 0; i < 10; i++) - log("Log message #%d.\n", i); -log_pop(); -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Error handling} - -\begin{frame}[t, fragile]{\subsecname} -Use {\tt log\_error()} to report a non-recoverable error: - -\medskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -if (design->modules.count(module->name) != 0) - log_error("A module with the name %s already exists!\n", - RTLIL::id2cstr(module->name)); -\end{lstlisting} - -\bigskip -Use {\tt log\_cmd\_error()} to report a recoverable error: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -if (design->selection_stack.back().empty()) - log_cmd_error("This command can't operator on an empty selection!\n"); -\end{lstlisting} - -\bigskip -Use {\tt log\_assert()} and {\tt log\_abort()} instead of {\tt assert()} and {\tt abort()}. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Creating a command} - -\begin{frame}[t, fragile]{\subsecname} -Simply create a global instance of a class derived from {\tt Pass} to create -a new yosys command: - -\bigskip -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] -#include "kernel/yosys.h" -USING_YOSYS_NAMESPACE - -struct MyPass : public Pass { - MyPass() : Pass("my_cmd", "just a simple test") { } - virtual void execute(std::vector args, RTLIL::Design *design) - { - log("Arguments to my_cmd:\n"); - for (auto &arg : args) - log(" %s\n", arg.c_str()); - - log("Modules in current design:\n"); - for (auto mod : design->modules()) - log(" %s (%d wires, %d cells)\n", log_id(mod), - GetSize(mod->wires()), GetSize(mod->cells())); - } -} MyPass; -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Creating a plugin} - -\begin{frame}[fragile]{\subsecname} -Yosys can be extended by adding additional C++ code to the Yosys code base, or -by loading plugins into Yosys. - -\bigskip -Use the following command to compile a Yosys plugin: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -yosys-config --exec --cxx --cxxflags --ldflags \ - -o my_cmd.so -shared my_cmd.cc --ldlibs -\end{lstlisting} - -\bigskip -Or shorter: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -yosys-config --build my_cmd.so my_cmd.cc -\end{lstlisting} - -\bigskip -Load the plugin using the yosys {\tt -m} option: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -yosys -m ./my_cmd.so -p 'my_cmd foo bar' -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Writing Yosys extensions is very straight-forward. -\item \dots and even simpler if you don't need RTLIL::Memory or RTLIL::Process objects. - -\bigskip -\item Writing synthesis software? Consider learning the Yosys API and make your work -part of the Yosys framework. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - 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 e36f2309a01..40b78190444 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 a7216ec9010..ed0255b09ed 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 $(] (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 d0c4618ac70..c3cbb8c5185 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 00000000000..48946f1e1e2 --- /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 00000000000..5582f1b780d --- /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 cc4e7cd3199..a35c83d6fe0 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 88458c50e29..30a522ba3dd 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 c4d6c128597..f9be83ec5c2 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 a235996e9f8..195e50f6421 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 1c3b79fa034..acd909c1230 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -8,247 +8,6 @@ \section{Introduction to Yosys} \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 @@ \subsection{Example Project} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\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 abc354e4691..00000000000 --- a/manual/PRESENTATION_Intro/Makefile +++ /dev/null @@ -1,10 +0,0 @@ - -all: counter_00.pdf counter_01.pdf counter_02.pdf counter_03.pdf - -counter_00.pdf: counter.v counter.ys mycells.lib - ../../yosys counter.ys - -counter_01.pdf: counter_00.pdf -counter_02.pdf: counter_00.pdf -counter_03.pdf: counter_00.pdf - 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 5c6f7398cdf..a6e891e2e1e 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 `` providing details for a specific command. ``yosys -H`` or +``yosys -h `` 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 ' + 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 f9be83ec5c2..db43f2f7842 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 fbf1e98b4c8..18cccca7c27 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 ea451d395ce..fd8b2171f4a 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 e9e005c5eef..32aa8fc04b9 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 8905a3455f3..fc1ba60630b 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 ` 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 00000000000..c5616336072 --- /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 99eba5a7678..1b601acbd4e 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 acd909c1230..00000000000 --- 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 ] - -coarse: - proc - opt - wreduce - alumacc - share - opt - fsm - opt -fast - memory -nomap - opt_clean -\end{lstlisting} -\column[t]{5cm} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -fine: - opt -fast -full - memory_map - opt -full - techmap - opt -fast - -abc: - abc -fast - opt -fast -\end{lstlisting} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Yosys Commands} - -\begin{frame}[fragile]{\subsecname{} 1/3 \hspace{0pt plus 1 filll} (excerpt)} -Command reference: -\begin{itemize} -\item Use ``{\tt help}'' for a command list and ``{\tt help \it command}'' for details. -\item Or run ``{\tt yosys -H}'' or ``{\tt yosys -h \it command}''. -\item Or go to \url{https://yosyshq.net/yosys/documentation.html}. -\end{itemize} - -\bigskip -Commands for design navigation and investigation: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - cd # a shortcut for 'select -module ' - ls # list modules or objects in modules - dump # print parts of the design in RTLIL format - show # generate schematics using graphviz - select # modify and view the list of selected objects -\end{lstlisting} - -\bigskip -Commands for executing scripts or entering interactive mode: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - shell # enter interactive command mode - history # show last interactive commands - script # execute commands from script file - tcl # execute a TCL script file -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 2/3 \hspace{0pt plus 1 filll} (excerpt)} -Commands for reading and elaborating the design: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - read_rtlil # read modules from RTLIL file - read_verilog # read modules from Verilog file - hierarchy # check, expand and clean up design hierarchy -\end{lstlisting} - -\bigskip -Commands for high-level synthesis: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - proc # translate processes to netlists - fsm # extract and optimize finite state machines - memory # translate memories to basic cells - opt # perform simple optimizations -\end{lstlisting} - -\bigskip -Commands for technology mapping: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - techmap # generic technology mapper - abc # use ABC for technology mapping - dfflibmap # technology mapping of flip-flops - hilomap # technology mapping of constant hi- and/or lo-drivers - iopadmap # technology mapping of i/o pads (or buffers) - flatten # flatten design -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 3/3 \hspace{0pt plus 1 filll} (excerpt)} -Commands for writing the results: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - write_blif # write design to BLIF file - write_btor # write design to BTOR file - write_edif # write design to EDIF netlist file - write_rtlil # write design to RTLIL file - write_spice # write design to SPICE netlist file - write_verilog # write design to Verilog file -\end{lstlisting} - -\bigskip -Script-Commands for standard synthesis tasks: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - synth # generic synthesis script - synth_xilinx # synthesis for Xilinx FPGAs -\end{lstlisting} - -\bigskip -Commands for model checking: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - sat # solve a SAT problem in the circuit - miter # automatically create a miter circuit - scc # detect strongly connected components (logic loops) -\end{lstlisting} - -\bigskip -... and many many more. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{More Verilog Examples} - -\begin{frame}[fragile]{\subsecname{} 1/3} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module detectprime(a, y); - input [4:0] a; - output y; - - integer i, j; - reg [31:0] lut; - - initial begin - for (i = 0; i < 32; i = i+1) begin - lut[i] = i > 1; - for (j = 2; j*j <= i; j = j+1) - if (i % j == 0) - lut[i] = 0; - end - end - - assign y = lut[a]; -endmodule -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 2/3} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -module carryadd(a, b, y); - parameter WIDTH = 8; - input [WIDTH-1:0] a, b; - output [WIDTH-1:0] y; - - genvar i; - generate - for (i = 0; i < WIDTH; i = i+1) begin:STAGE - wire IN1 = a[i], IN2 = b[i]; - wire C, Y; - if (i == 0) - assign C = IN1 & IN2, Y = IN1 ^ IN2; - else - assign C = (IN1 & IN2) | ((IN1 | IN2) & STAGE[i-1].C), - Y = IN1 ^ IN2 ^ STAGE[i-1].C; - assign y[i] = Y; - end - endgenerate -endmodule -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} 3/3} -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{7pt}{8.5pt}\selectfont, language=Verilog] -module cam(clk, wr_enable, wr_addr, wr_data, rd_data, rd_addr, rd_match); - parameter WIDTH = 8; - parameter DEPTH = 16; - localparam ADDR_BITS = $clog2(DEPTH-1); - - input clk, wr_enable; - input [ADDR_BITS-1:0] wr_addr; - input [WIDTH-1:0] wr_data, rd_data; - output reg [ADDR_BITS-1:0] rd_addr; - output reg rd_match; - - integer i; - reg [WIDTH-1:0] mem [0:DEPTH-1]; - - always @(posedge clk) begin - rd_addr <= 'bx; - rd_match <= 0; - for (i = 0; i < DEPTH; i = i+1) - if (mem[i] == rd_data) begin - rd_addr <= i; - rd_match <= 1; - end - if (wr_enable) - mem[wr_addr] <= wr_data; - end -endmodule -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Currently unsupported Verilog-2005 language features} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Tri-state logic -\item The wor/wand wire types (maybe for 0.5) -\item Latched logic (is synthesized as logic with feedback loops) -\item Some non-synthesizable features that should be ignored in synthesis are not supported by the parser and cause a parser error (file a bug report if you encounter this problem) -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Verification of Yosys} - -\begin{frame}{\subsecname} -Continuously checking the correctness of Yosys and making sure that new features -do not break old ones is a high priority in Yosys. - -\bigskip -Two external test suites have been built for Yosys: VlogHammer and yosys-bigsim -(see next slides) - -\bigskip -In addition to that, yosys comes with $\approx\!200$ test cases used in ``{\tt make test}''. - -\bigskip -A debug build of Yosys also contains a lot of asserts and checks the integrity of -the internal state after each command. -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- VlogHammer} -VlogHammer is a Verilog regression test suite developed to test the different -subsystems in Yosys by comparing them to each other and to the output created -by some other tools (Xilinx Vivado, Xilinx XST, Altera Quartus II, ...). - -\bigskip -Yosys Subsystems tested: Verilog frontend, const folding, const eval, technology mapping, -simulation models, SAT models. - -\bigskip -Thousands of auto-generated test cases containing code such as: -\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] -assign y9 = $signed(((+$signed((^(6'd2 ** a2))))<$unsigned($unsigned(((+a3)))))); -assign y10 = (-((+((+{2{(~^p13)}})))^~(!{{b5,b1,a0},(a1&p12),(a4+a3)}))); -assign y11 = (~&(-{(-3'sd3),($unsigned($signed($unsigned({p0,b4,b1}))))})); -\end{lstlisting} - -\bigskip -Some bugs in Yosys where found and fixed thanks to VlogHammer. Over 50 bugs in -the other tools used as external reference where found and reported so far. -\end{frame} - -\begin{frame}{\subsecname{} -- yosys-bigsim} -yosys-bigsim is a collection of real-world open-source Verilog designs and test -benches. yosys-bigsim compares the testbench outputs of simulations of the original -Verilog code and synthesis results. - -\bigskip -The following designs are included in yosys-bigsim (excerpt): -\begin{itemize} -\item {\tt openmsp430} -- an MSP430 compatible 16 bit CPU -\item {\tt aes\_5cycle\_2stage} -- an AES encryption core -\item {\tt softusb\_navre} -- an AVR compatible 8 bit CPU -\item {\tt amber23} -- an ARMv2 compatible 32 bit CPU -\item {\tt lm32} -- another 32 bit CPU from Lattice Semiconductor -\item {\tt verilog-pong} -- a hardware pong game with VGA output -\item {\tt elliptic\_curve\_group} -- ECG point-add and point-scalar-mul core -\item {\tt reed\_solomon\_decoder} -- a Reed-Solomon Error Correction Decoder -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Benefits of Open Source HDL Synthesis} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Cost (also applies to ``free as in free beer'' solutions) -\item Availability and Reproducibility -\item Framework- and all-in-one-aspects -\item Educational Tool -\end{itemize} - -\bigskip - -Yosys is open source under the ISC license. -\end{frame} - -\begin{frame}{\subsecname{} -- 1/3} -\begin{itemize} -\item Cost (also applies to ``free as in free beer'' solutions): \smallskip\par -Today the cost for a mask set in $\unit[180]{nm}$ technology is far less than -the cost for the design tools needed to design the mask layouts. Open Source -ASIC flows are an important enabler for ASIC-level Open Source Hardware. - -\bigskip -\item Availability and Reproducibility: \smallskip\par -If you are a researcher who is publishing, you want to use tools that everyone -else can also use. Even if most universities have access to all major -commercial tools, you usually do not have easy access to the version that was -used in a research project a couple of years ago. With Open Source tools you -can even release the source code of the tool you have used alongside your data. -\end{itemize} -\end{frame} - -\begin{frame}{\subsecname{} -- 2/3} -\begin{itemize} -\item Framework: \smallskip\par -Yosys is not only a tool. It is a framework that can be used as basis for other -developments, so researchers and hackers alike do not need to re-invent the -basic functionality. Extensibility was one of Yosys' design goals. - -\bigskip -\item All-in-one: \smallskip\par -Because of the framework characteristics of Yosys, an increasing number of features -become available in one tool. Yosys not only can be used for circuit synthesis but -also for formal equivalence checking, SAT solving, and for circuit analysis, to -name just a few other application domains. With proprietary software one needs to -learn a new tool for each of these applications. -\end{itemize} -\end{frame} - -\begin{frame}{\subsecname{} -- 3/3} -\begin{itemize} -\item Educational Tool: \smallskip\par -Proprietary synthesis tools are at times very secretive about their inner -workings. They often are ``black boxes''. Yosys is very open about its -internals and it is easy to observe the different steps of synthesis. -\end{itemize} - -\bigskip -\begin{block}{Yosys is licensed under the ISC license:} -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Typical Applications for Yosys} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Synthesis of final production designs -\item Pre-production synthesis (trial runs before investing in other tools) -\item Conversion of full-featured Verilog to simple Verilog -\item Conversion of Verilog to other formats (BLIF, BTOR, etc) -\item Demonstrating synthesis algorithms (e.g. for educational purposes) -\item Framework for experimenting with new algorithms -\item Framework for building custom flows\footnote[frame]{Not limited to synthesis -but also formal verification, reverse engineering, ...} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Projects (that I know of) using Yosys} - -\begin{frame}{\subsecname{} -- (1/2)} -\begin{itemize} -\item Ongoing PhD project on coarse grain synthesis \\ -{\setlength{\parindent}{0.5cm}\footnotesize -Johann Glaser and C. Wolf. Methodology and Example-Driven Interconnect -Synthesis for Designing Heterogeneous Coarse-Grain Reconfigurable -Architectures. In Jan Haase, editor, \it Models, Methods, and Tools for Complex -Chip Design. Lecture Notes in Electrical Engineering. Volume 265, 2014, pp -201-221. Springer, 2013.} - -\bigskip -\item I know several people that use Yosys simply as Verilog frontend for other -flows (using either the BLIF and BTOR backends). - -\bigskip -\item I know some analog chip designers that use Yosys for small digital -control logic because it is simpler than setting up a commercial flow. -\end{itemize} -\end{frame} - -\begin{frame}{\subsecname{} -- (2/2)} -\begin{itemize} -\item Efabless -\begin{itemize} -\smallskip \item Not much information on the website (\url{http://efabless.com}) yet. -\smallskip \item Very cheap 180nm prototyping process (partnering with various fabs) -\smallskip \item A semiconductor company, NOT an EDA company -\smallskip \item Web-based design environment -\smallskip \item HDL Synthesis using Yosys -\smallskip \item Custom place\&route tool - -\bigskip -\item efabless is building an Open Source IC as reference design. \\ -\hskip1cm (to be announced soon: \url{http://www.openic.io}) -\end{itemize} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Supported Platforms} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Main development OS: Kubuntu 14.04 -\item There is a PPA for ubuntu (not maintained by me) -\item Any current Debian-based system should work out of the box -\item When building on other Linux distributions: -\begin{itemize} -\item Needs compiler with some C++11 support -\item See README file for build instructions -\item Post to the subreddit if you get stuck -\end{itemize} -\item Ported to OS X (Darwin) and OpenBSD -\item Native win32 build with VisualStudio -\item Cross win32 build with MXE -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Other Open Source Tools} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Icarus Verilog \\ -\smallskip\hskip1cm{}Verilog Simulation (and also a good syntax checker) \\ -\smallskip\hskip1cm{}\url{http://iverilog.icarus.com/} - -\bigskip -\item Qflow (incl. TimberWolf, qrouter and Magic) \\ -\smallskip\hskip1cm{}A complete ASIC synthesis flow, using Yosys and ABC \\ -\smallskip\hskip1cm{}\url{http://opencircuitdesign.com/qflow/} - -\bigskip -\item ABC \\ -\smallskip\hskip1cm{}Logic optimization, technology mapping, and more \\ -\smallskip\hskip1cm{}\url{http://www.eecs.berkeley.edu/~alanmi/abc/} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Yosys needs you} - -\begin{frame}{\subsecname} -\dots as an active user: -\begin{itemize} -\item Use Yosys for on your own projects -\item .. even if you are not using it as final synthesis tool -\item Join the discussion on the Subreddit -\item Report bugs and send in feature requests -\end{itemize} - -\bigskip -\dots as a developer: -\begin{itemize} -\item Use Yosys as environment for your (research) work -\item .. you might also want to look into ABC for logic-level stuff -\item Fork the project on github or create loadable plugins -\item We need a VHDL frontend or a good VHDL-to-Verilog converter -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Documentation, Downloads, Contacts} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Website: \\ -\smallskip\hskip1cm\url{https://yosyshq.net/yosys/} - -\bigskip -\item Manual, Command Reference, Application Notes: \\ -\smallskip\hskip1cm\url{https://yosyshq.net/yosys/documentation.html} - -\bigskip -\item Instead of a mailing list we have a SubReddit: \\ -\smallskip\hskip1cm\url{http://www.reddit.com/r/yosys/} - -\bigskip -\item Direct link to the source code: \\ -\smallskip\hskip1cm\url{https://github.com/YosysHQ/yosys} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Yosys is a powerful tool and framework for Verilog synthesis. -\item It uses a command-based interface and can be controlled by scripts. -\item By combining existing commands and implementing new commands Yosys can -be used in a wide range of application far beyond simple synthesis. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - 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 512521a835a..bca4971e9bd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -51,11 +51,6 @@ 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 18cccca7c27..bc56bbf7762 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 | 541 +++++++++--------- .../yosys_internals/formats/cell_library.rst | 22 +- .../yosys_internals/formats/rtlil_rep.rst | 222 +++---- 10 files changed, 449 insertions(+), 459 deletions(-) diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index a48401dcc18..d4448895ba0 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 44819e28332..d2b33bd1cb6 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 ``/``. 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 ed1a3188c53..6c9aa167381 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 b832968167f..0b7f52b1d0b 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 a6e891e2e1e..9f7ae2ba736 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 db43f2f7842..81d89d7a677 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 fc1ba60630b..387a3fb1fb0 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 cded945e5b0..cb5b65d8afc 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 ` - contains a list of all node types. + :numref:`Table %s ` contains a list of all node + types. - | The child nodes - | This is a list of pointers to all children in the abstract syntax - tree. + | 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. - -First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all -signals assigned within the block. It then creates a set of temporary -signals using the naming scheme $\ \\\ for each -of the assigned signals. - -Then an ``RTLIL::Process`` is created that assigns all intermediate -values for each left-hand-side signal to the temporary signal in its +``initial``-block, it creates an instance of ``AST_INTERNAL::ProcessGenerator``. +This object then generates the ``RTLIL::Process`` object for the block. It also +calls ``AST::AstNode::genRTLIL()`` for all right-hand-side expressions contained +within the block. + +First the ``AST_INTERNAL::ProcessGenerator`` creates a list of all signals +assigned within the block. It then creates a set of temporary signals using the +naming scheme ``$ \ `` for each of the assigned signals. + +Then an ``RTLIL::Process`` is created that assigns all intermediate values for +each left-hand-side signal to the temporary signal in its ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree. -Finally a ``RTLIL::SyncRule`` is created for the ``RTLIL::Process`` that -assigns the temporary signals for the final values to the actual -signals. +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". - -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. + asynchronous circuit. I.e. the decision tree formed by the switches can be + seen independently for each assigned signal. Whenever one assigned signal + changes, all signals that depend on the changed signals are to be updated. + For example the assignments in lines 16 and 18 in the RTLIL code in fact + influence the assignment in line 12, even though they are in the "wrong + order". + +The only synchronous part of the process is in the ``RTLIL::SyncRule`` object +generated at line 35 in the RTLIL code. The sync rule is the only part of the +process where the original signals are assigned. The synchronization event from +the original Verilog code has been translated into the synchronization type +(posedge) and signal (``\clock``) for the ``RTLIL::SyncRule`` object. In the +case of this simple example the ``RTLIL::SyncRule`` object is later simply +transformed into a set of d-type flip-flops and the +``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree to a decision tree using +multiplexers. In more complex examples (e.g. asynchronous resets) the part of the ``RTLIL::CaseRule``/``RTLIL::SwitchRule`` tree that describes the @@ -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. - -- | ``subst_lvalue_from`` and ``subst_lvalue_to`` - | These two variables contain the mapping from left-hand-side signals - (\\\ ) to the current temporary signal for the same thing - (initially $0\\\ ). - -- | ``current_case`` - | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the - root case of the generated ``RTLIL::Process``. - -As the algorithm runs these variables are continuously modified as well -as pushed to the stack and later restored to their earlier values by -popping from the stack. - -On startup the ProcessGenerator generates a new ``RTLIL::Process`` -object with an empty root case and initializes its state variables as -described above. Then the ``RTLIL::SyncRule`` objects are created using -the synchronization events from the AST_ALWAYS node and the initial -values of ``subst_lvalue_from`` and ``subst_lvalue_to``. Then the AST -for this process is evaluated recursively. - -During this recursive evaluation, three different relevant types of AST -nodes can be discovered: AST_ASSIGN_LE (nonblocking assignments), -AST_ASSIGN_EQ (blocking assignments) and AST_CASE (``if`` or ``case`` + | These two variables hold the replacement pattern that should be used by + ``AST::AstNode::genRTLIL()`` for signals with blocking assignments. After + initialization of ``AST_INTERNAL::ProcessGenerator`` these two variables are + empty. + +- | ``subst_lvalue_from`` and ``subst_lvalue_to`` + | These two variables contain the mapping from left-hand-side signals (``\ + ``) to the current temporary signal for the same thing (initially + ``$0\ ``). + +- | ``current_case`` + | A pointer to a ``RTLIL::CaseRule`` object. Initially this is the root case + of the generated ``RTLIL::Process``. + +As the algorithm runs these variables are continuously modified as well as +pushed to the stack and later restored to their earlier values by popping from +the stack. + +On startup the ProcessGenerator generates a new ``RTLIL::Process`` object with +an empty root case and initializes its state variables as described above. Then +the ``RTLIL::SyncRule`` objects are created using the synchronization events +from the AST_ALWAYS node and the initial values of ``subst_lvalue_from`` and +``subst_lvalue_to``. Then the AST for this process is evaluated recursively. + +During this recursive evaluation, three different relevant types of AST nodes +can be discovered: ``AST_ASSIGN_LE`` (nonblocking assignments), +``AST_ASSIGN_EQ`` (blocking assignments) and ``AST_CASE`` (``if`` or ``case`` statement). Handling of nonblocking assignments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When an AST_ASSIGN_LE node is discovered, the following actions are +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. - -Note how all the ``_eq_``-variables become empty when no blocking -assignments are used and many of the steps in the algorithm can then be -ignored as a result of this. - -For a variable with blocking assignments the algorithm shows the -following behaviour: First a new temporary variable is created. This new -temporary variable is then registered as the assignment target for all -assignments for this variable within the cases for this AST_CASE node. -Then for each case the new temporary variable is first assigned the old -temporary variable. This assignment is overwritten if the variable is -actually assigned in this case and is kept as a default value otherwise. - -This yields an ``RTLIL::CaseRule`` that assigns the new temporary -variable in all branches. So when all cases have been processed a final -assignment is added to the containing block that assigns the new -temporary variable to the old one. Note how this step always overrides a -previous assignment to the old temporary variable. Other than -nonblocking assignments, the old assignment could still have an effect -somewhere in the design, as there have been calls to +With respect to nonblocking assignments the algorithm is easy: later assignments +invalidate earlier assignments. For each signal assigned using nonblocking +assignments exactly one temporary variable is generated (with the ``$0``-prefix) +and this variable is used for all assignments of the variable. + +Note how all the ``_eq_``-variables become empty when no blocking assignments +are used and many of the steps in the algorithm can then be ignored as a result +of this. + +For a variable with blocking assignments the algorithm shows the following +behaviour: First a new temporary variable is created. This new temporary +variable is then registered as the assignment target for all assignments for +this variable within the cases for this ``AST_CASE`` node. Then for each case +the new temporary variable is first assigned the old temporary variable. This +assignment is overwritten if the variable is actually assigned in this case and +is kept as a default value otherwise. + +This yields an ``RTLIL::CaseRule`` that assigns the new temporary variable in +all branches. So when all cases have been processed a final assignment is added +to the containing block that assigns the new temporary variable to the old one. +Note how this step always overrides a previous assignment to the old temporary +variable. Other than nonblocking assignments, the old assignment could still +have an effect somewhere in the design, as there have been calls to ``AST::AstNode::genRTLIL()`` with a -``subst_rvalue_from``/``subst_rvalue_to``-tuple that contained the +``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. - -- | 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. + 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 ``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 67e1fc0ef92..7768c3cc941 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 `, :numref:`%s -`, :numref:`%s `, :numref:`%s -`, :numref:`%s `, :numref:`%s -`, :numref:`%s `, -:numref:`%s ` and :numref:`%s -` list all cell types used for gate level logic. The cell -types ``$_BUF_``, ``$_NOT_``, ``$_AND_``, ``$_NAND_``, ``$_ANDNOT_``, ``$_OR_``, -``$_NOR_``, ``$_ORNOT_``, ``$_XOR_``, ``$_XNOR_``, ``$_AOI3_``, ``$_OAI3_``, -``$_AOI4_``, ``$_OAI4_``, ``$_MUX_``, ``$_MUX4_``, ``$_MUX8_``, ``$_MUX16_`` and -``$_NMUX_`` are used to model combinatorial logic. The cell type ``$_TBUF_`` is -used to model tristate logic. +Tables :numref:`%s `, :numref:`%s `, +:numref:`%s `, :numref:`%s `, +:numref:`%s `, :numref:`%s `, +:numref:`%s `, :numref:`%s +` and :numref:`%s ` list all +cell types used for gate level logic. The cell types ``$_BUF_``, ``$_NOT_``, +``$_AND_``, ``$_NAND_``, ``$_ANDNOT_``, ``$_OR_``, ``$_NOR_``, ``$_ORNOT_``, +``$_XOR_``, ``$_XNOR_``, ``$_AOI3_``, ``$_OAI3_``, ``$_AOI4_``, ``$_OAI4_``, +``$_MUX_``, ``$_MUX4_``, ``$_MUX8_``, ``$_MUX16_`` and ``$_NMUX_`` are used to +model combinatorial logic. The cell type ``$_TBUF_`` is used to model tristate +logic. The ``$_MUX4_``, ``$_MUX8_`` and ``$_MUX16_`` cells are used to model wide muxes, and correspond to the following Verilog code: diff --git a/docs/source/yosys_internals/formats/rtlil_rep.rst b/docs/source/yosys_internals/formats/rtlil_rep.rst index d247a5da42e..4ed7d910726 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 ` 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 -` an RTLIL::Module object contains the following additional -properties: +Besides the objects shown in the :ref:`ER diagram ` above, +an ``RTLIL::Module`` object contains the following additional properties: - The module name - A list of attributes @@ -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. - -An RTLIL::Process is a container for zero or more RTLIL::SyncRule objects and -exactly one RTLIL::CaseRule object, which is called the root case. - -An RTLIL::SyncRule object contains an (optional) synchronization condition -(signal and edge-type), zero or more assignments (RTLIL::SigSig), and zero or -more memory writes (RTLIL::MemWriteAction). The always synchronization condition -is used to break combinatorial loops when a latch should be inferred instead. - -An RTLIL::CaseRule is a container for zero or more assignments (RTLIL::SigSig) -and zero or more RTLIL::SwitchRule objects. An RTLIL::SwitchRule objects is a -container for zero or more RTLIL::CaseRule objects. - -In the above example the lines :math:`2 \dots 12` are the root case. Here -$0\q[0:0] is first assigned the old value \\q as default value (line 2). The -root case also contains an RTLIL::SwitchRule object (lines :math:`3 \dots 12`). -Such an object is very similar to the C switch statement as it uses a control -signal (\\reset in this case) to determine which of its cases should be active. -The RTLIL::SwitchRule object then contains one RTLIL::CaseRule object per case. -In this example there is a case [1]_ for \\reset == 1 that causes $0\q[0:0] to -be set (lines 4 and 5) and a default case that in turn contains a switch that -sets $0\q[0:0] to the value of \\d if \\enable is active (lines :math:`6 \dots -11`). +This ``RTLIL::Process`` contains two ``RTLIL::SyncRule`` objects, two +``RTLIL::SwitchRule`` objects and five ``RTLIL::CaseRule`` objects. The wire +``$0\q[0:0]`` is an automatically created wire that holds the next value of +``\q``. The lines 2..12 describe how ``$0\q[0:0]`` should be calculated. The +lines 13..16 describe how the value of ``$0\q[0:0]`` is used to update ``\q``. + +An ``RTLIL::Process`` is a container for zero or more ``RTLIL::SyncRule`` +objects and exactly one ``RTLIL::CaseRule`` object, which is called the root +case. + +An ``RTLIL::SyncRule`` object contains an (optional) synchronization condition +(signal and edge-type), zero or more assignments (``RTLIL::SigSig``), and zero +or more memory writes (``RTLIL::MemWriteAction``). The always synchronization +condition is used to break combinatorial loops when a latch should be inferred +instead. + +An ``RTLIL::CaseRule`` is a container for zero or more assignments +(``RTLIL::SigSig``) and zero or more ``RTLIL::SwitchRule`` objects. An +``RTLIL::SwitchRule`` objects is a container for zero or more +``RTLIL::CaseRule`` objects. + +In the above example the lines 2..12 are the root case. Here ``$0\q[0:0]`` is +first assigned the old value ``\q`` as default value (line 2). The root case +also contains an ``RTLIL::SwitchRule`` object (lines 3..12). Such an object is +very similar to the C switch statement as it uses a control signal (``\reset`` +in this case) to determine which of its cases should be active. The +``RTLIL::SwitchRule`` object then contains one ``RTLIL::CaseRule`` object per +case. In this example there is a case [1]_ for ``\reset == 1`` that causes +``$0\q[0:0]`` to be set (lines 4 and 5) and a default case that in turn contains +a switch that sets ``$0\q[0:0]`` to the value of ``\d`` if ``\enable`` is active +(lines 6..11). A case can specify zero or more compare values that will determine whether it matches. Each of the compare values must be the exact same width as the control @@ -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 ed0255b09ed..4c84a01db65 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 cf658897d52..b4a858a0134 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 c34eae3ffcf..e9986ff05f2 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 310a7029ee1..e53e344d831 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 00000000000..b647324796f --- /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`. diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex deleted file mode 100644 index d7cfdc6f2fc..00000000000 --- a/manual/PRESENTATION_ExSyn.tex +++ /dev/null @@ -1,515 +0,0 @@ - -\section{Yosys by example -- Synthesis} - -\begin{frame} -\sectionpage -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Typical Phases of a Synthesis Flow} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Reading and elaborating the design -\item Higher-level synthesis and optimization -\begin{itemize} -\item Converting {\tt always}-blocks to logic and registers -\item Perform coarse-grain optimizations (resource sharing, const folding, ...) -\item Handling of memories and other coarse-grain blocks -\item Extracting and optimizing finite state machines -\end{itemize} -\item Convert remaining logic to bit-level logic functions -\item Perform optimizations on bit-level logic functions -\item Map bit-level logic gates and registers to cell library -\item Write results to output file -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Reading the design} - -\begin{frame}[fragile]{\subsecname} -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -read_verilog file1.v -read_verilog -I include_dir -D enable_foo -D WIDTH=12 file2.v -read_verilog -lib cell_library.v - -verilog_defaults -add -I include_dir -read_verilog file3.v -read_verilog file4.v -verilog_defaults -clear - -verilog_defaults -push -verilog_defaults -add -I include_dir -read_verilog file5.v -read_verilog file6.v -verilog_defaults -pop -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Design elaboration} - -\begin{frame}[fragile]{\subsecname} -During design elaboration Yosys figures out how the modules are hierarchically -connected. It also re-runs the AST parts of the Verilog frontend to create -all needed variations of parametric modules. - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# simplest form. at least this version should be used after reading all input files -# -hierarchy - -# recommended form. fails if parts of the design hierarchy are missing, removes -# everything that is unreachable from the top module, and marks the top module. -# -hierarchy -check -top top_module -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt proc} command} - -\begin{frame}[fragile]{\subsecname} -The Verilog frontend converts {\tt always}-blocks to RTL netlists for the -expressions and ``processes'' for the control- and memory elements. - -\medskip -The {\tt proc} command transforms this ``processes'' to netlists of RTL -multiplexer and register cells. - -\medskip -The {\tt proc} command is actually a macro-command that calls the following -other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -proc_clean # remove empty branches and processes -proc_rmdead # remove unreachable branches -proc_init # special handling of "initial" blocks -proc_arst # identify modeling of async resets -proc_mux # convert decision trees to multiplexer networks -proc_dff # extract registers from processes -proc_clean # if all went fine, this should remove all the processes -\end{lstlisting} - -\medskip -Many commands can not operate on modules with ``processes'' in them. Usually -a call to {\tt proc} is the first command in the actual synthesis procedure -after design elaboration. -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- Example 1/3} -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_01.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_01.ys} -\end{columns} -\hfil\includegraphics[width=8cm,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/proc_01.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 2/3} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2.5cm]{PRESENTATION_ExSyn/proc_02.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_02.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_02.ys} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 3/3} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -1.5cm]{PRESENTATION_ExSyn/proc_03.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_03.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_03.v} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt opt} command} - -\begin{frame}[fragile]{\subsecname} -The {\tt opt} command implements a series of simple optimizations. It also -is a macro command that calls other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -opt_expr # const folding and simple expression rewriting -opt_merge -nomux # merging identical cells - -do - opt_muxtree # remove never-active branches from multiplexer tree - opt_reduce # consolidate trees of boolean ops to reduce functions - opt_merge # merging identical cells - opt_rmdff # remove/simplify registers with constant inputs - opt_clean # remove unused objects (cells, wires) from design - opt_expr # const folding and simple expression rewriting -while [changed design] -\end{lstlisting} - -The command {\tt clean} can be used as alias for {\tt opt\_clean}. And {\tt ;;} -can be used as shortcut for {\tt clean}. For example: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -proc; opt; memory; opt_expr;; fsm;; -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 1/4} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -0.5cm]{PRESENTATION_ExSyn/opt_01.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_01.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_01.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 2/4} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm 0cm]{PRESENTATION_ExSyn/opt_02.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_02.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_02.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 3/4} -\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2cm]{PRESENTATION_ExSyn/opt_03.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_03.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_03.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 4/4} -\vbox to 0cm{\hskip6cm\includegraphics[width=6cm,trim=0cm 0cm 0cm -3cm]{PRESENTATION_ExSyn/opt_04.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_04.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_04.ys} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{When to use {\tt opt} or {\tt clean}} - -\begin{frame}{\subsecname} -Usually it does not hurt to call {\tt opt} after each regular command in the -synthesis script. But it increases the synthesis time, so it is favourable -to only call {\tt opt} when an improvement can be achieved. - -\bigskip -The designs in {\tt yosys-bigsim} are a good playground for experimenting with -the effects of calling {\tt opt} in various places of the flow. - -\bigskip -It generally is a good idea to call {\tt opt} before inherently expensive -commands such as {\tt sat} or {\tt freduce}, as the possible gain is much -higher in this cases as the possible loss. - -\bigskip -The {\tt clean} command on the other hand is very fast and many commands leave -a mess (dangling signal wires, etc). For example, most commands do not remove -any wires or cells. They just change the connections and depend on a later -call to clean to get rid of the now unused objects. So the occasional {\tt ;;} -is a good idea in every synthesis script. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt memory} command} - -\begin{frame}[fragile]{\subsecname} -In the RTL netlist, memory reads and writes are individual cells. This makes -consolidating the number of ports for a memory easier. The {\tt memory} -transforms memories to an implementation. Per default that is logic for address -decoders and registers. It also is a macro command that calls other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# this merges registers into the memory read- and write cells. -memory_dff - -# this collects all read and write cells for a memory and transforms them -# into one multi-port memory cell. -memory_collect - -# this takes the multi-port memory cell and transforms it to address decoder -# logic and registers. This step is skipped if "memory" is called with -nomap. -memory_map -\end{lstlisting} - -\bigskip -Usually it is preferred to use architecture-specific RAM resources for memory. -For example: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -memory -nomap; techmap -map my_memory_map.v; memory_map -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 1/2} -\vbox to 0cm{\includegraphics[width=0.7\linewidth,trim=0cm 0cm 0cm -10cm]{PRESENTATION_ExSyn/memory_01.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_01.ys} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_01.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsecname{} -- Example 2/2} -\vbox to 0cm{\hfill\includegraphics[width=7.5cm,trim=0cm 0cm 0cm -5cm]{PRESENTATION_ExSyn/memory_02.pdf}\vss} -\vskip-1cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_02.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_02.ys} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt fsm} command} - -\begin{frame}[fragile]{\subsecname{}} -The {\tt fsm} command identifies, extracts, optimizes (re-encodes), and -re-synthesizes finite state machines. It again is a macro that calls -a series of other commands: - -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -fsm_detect # unless got option -nodetect -fsm_extract - -fsm_opt -clean -fsm_opt - -fsm_expand # if got option -expand -clean # if got option -expand -fsm_opt # if got option -expand - -fsm_recode # unless got option -norecode - -fsm_info - -fsm_export # if got option -export -fsm_map # unless got option -nomap -\end{lstlisting} -\end{frame} - -\begin{frame}{\subsecname{} -- details} -Some details on the most important commands from the {\tt fsm\_*} group: - -\bigskip -The {\tt fsm\_detect} command identifies FSM state registers and marks them -with the {\tt (* fsm\_encoding = "auto" *)} attribute, if they do not have the -{\tt fsm\_encoding} set already. Mark registers with {\tt (* fsm\_encoding = -"none" *)} to disable FSM optimization for a register. - -\bigskip -The {\tt fsm\_extract} command replaces the entire FSM (logic and state -registers) with a {\tt \$fsm} cell. - -\bigskip -The commands {\tt fsm\_opt} and {\tt fsm\_recode} can be used to optimize the -FSM. - -\bigskip -Finally the {\tt fsm\_map} command can be used to convert the (optimized) {\tt -\$fsm} cell back to logic and registers. -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt techmap} command} - -\begin{frame}[t]{\subsecname} -\vbox to 0cm{\includegraphics[width=12cm,trim=-15cm 0cm 0cm -20cm]{PRESENTATION_ExSyn/techmap_01.pdf}\vss} -\vskip-0.8cm -The {\tt techmap} command replaces cells with implementations given as -verilog source. For example implementing a 32 bit adder using 16 bit adders: - -\vbox to 0cm{ -\vskip-0.3cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/techmap_01_map.v} -}\vbox to 0cm{ -\vskip-0.5cm -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExSyn/techmap_01.v} -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/techmap_01.ys} -} -\end{frame} - -\begin{frame}[t]{\subsecname{} -- stdcell mapping} -When {\tt techmap} is used without a map file, it uses a built-in map file -to map all RTL cell types to a generic library of built-in logic gates and registers. - -\bigskip -\begin{block}{The built-in logic gate types are:} -{\tt \$\_NOT\_ \$\_AND\_ \$\_OR\_ \$\_XOR\_ \$\_MUX\_} -\end{block} - -\bigskip -\begin{block}{The register types are:} -{\tt \$\_SR\_NN\_ \$\_SR\_NP\_ \$\_SR\_PN\_ \$\_SR\_PP\_ \\ -\$\_DFF\_N\_ \$\_DFF\_P\_ \\ -\$\_DFF\_NN0\_ \$\_DFF\_NN1\_ \$\_DFF\_NP0\_ \$\_DFF\_NP1\_ \\ -\$\_DFF\_PN0\_ \$\_DFF\_PN1\_ \$\_DFF\_PP0\_ \$\_DFF\_PP1\_ \\ -\$\_DFFSR\_NNN\_ \$\_DFFSR\_NNP\_ \$\_DFFSR\_NPN\_ \$\_DFFSR\_NPP\_ \\ -\$\_DFFSR\_PNN\_ \$\_DFFSR\_PNP\_ \$\_DFFSR\_PPN\_ \$\_DFFSR\_PPP\_ \\ -\$\_DLATCH\_N\_ \$\_DLATCH\_P\_} -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{The {\tt abc} command} - -\begin{frame}{\subsecname} -The {\tt abc} command provides an interface to ABC\footnote[frame]{\url{http://www.eecs.berkeley.edu/~alanmi/abc/}}, -an open source tool for low-level logic synthesis. - -\medskip -The {\tt abc} command processes a netlist of internal gate types and can perform: -\begin{itemize} -\item logic minimization (optimization) -\item mapping of logic to standard cell library (liberty format) -\item mapping of logic to k-LUTs (for FPGA synthesis) -\end{itemize} - -\medskip -Optionally {\tt abc} can process registers from one clock domain and perform -sequential optimization (such as register balancing). - -\medskip -ABC is also controlled using scripts. An ABC script can be specified to use -more advanced ABC features. It is also possible to write the design with -{\tt write\_blif} and load the output file into ABC outside of Yosys. -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- Example} -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/abc_01.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/abc_01.ys} -\end{columns} -\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/abc_01.pdf} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Other special-purpose mapping commands} - -\begin{frame}{\subsecname} -\begin{block}{\tt dfflibmap} -This command maps the internal register cell types to the register types -described in a liberty file. -\end{block} - -\bigskip -\begin{block}{\tt hilomap} -Some architectures require special driver cells for driving a constant hi or lo -value. This command replaces simple constants with instances of such driver cells. -\end{block} - -\bigskip -\begin{block}{\tt iopadmap} -Top-level input/outputs must usually be implemented using special I/O-pad cells. -This command inserts this cells to the design. -\end{block} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Example Synthesis Script} - -\begin{frame}[fragile]{\subsecname} -\begin{columns} -\column[t]{4cm} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=ys] -# read and elaborate design -read_verilog cpu_top.v cpu_ctrl.v cpu_regs.v -read_verilog -D WITH_MULT cpu_alu.v -hierarchy -check -top cpu_top - -# high-level synthesis -proc; opt; fsm;; memory -nomap; opt - -# substitute block rams -techmap -map map_rams.v - -# map remaining memories -memory_map - -# low-level synthesis -techmap; opt; flatten;; abc -lut6 -techmap -map map_xl_cells.v - -# add clock buffers -select -set xl_clocks t:FDRE %x:+FDRE[C] t:FDRE %d -iopadmap -inpad BUFGP O:I @xl_clocks - -# add io buffers -select -set xl_nonclocks w:* t:BUFGP %x:+BUFGP[I] %d -iopadmap -outpad OBUF I:O -inpad IBUF O:I @xl_nonclocks - -# write synthesis results -write_edif synth.edif -\end{lstlisting} -\column[t]{6cm} -\vskip1cm -\begin{block}{Teaser / Outlook} -\small\parbox{6cm}{ -The weird {\tt select} expressions at the end of this script are discussed in -the next part (Section 3, ``Advanced Synthesis'') of this presentation.} -\end{block} -\end{columns} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Yosys provides commands for each phase of the synthesis. -\item Each command solves a (more or less) simple problem. -\item Complex commands are often only front-ends to simple commands. -\item {\tt proc; opt; fsm; opt; memory; opt; techmap; opt; abc;;} -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - 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 b647324796f..b27a8d823f4 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 4c84a01db65..61fa6cd7098 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 cf658897d52..b4a858a0134 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 993a9d9e10c..8954ee2548a 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 00000000000..3af2b845158 --- /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 4864d8d5203..4291f997654 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 3b81785dc15..6b67b169149 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 ``/`` 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 `` +command. The stored selections can be used in later select expressions +using the syntax ``@``. + +.. 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 00000000000..1724ba5e321 --- /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 195e50f6421..868aa08fecc 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 00000000000..3ac73fd6fc1 --- /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 18eec664b6a..745e5e2f513 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__`` and + ``_TECHMAP_CONSTVAL__`` can be used to handle constant input values + to cells. +- The former contains 1-bits for all constant input bits on the port. +- The latter contains the constant bits or undef (x) for non-constant bits. +- Example use-cases: + + - Converting arithmetic (for example multiply to shift). + - Identify constant addresses or enable bits in memory interfaces. + +Example: + +.. figure:: ../../images/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__`` can be used to handle shorted inputs. +- Each bit of the port correlates to an ``_TECHMAP_BITS_CONNMAP_`` bits wide + number in ``_TECHMAP_CONNMAP__``. +- Each unique signal bit is assigned its own number. Identical fields in the ``_TECHMAP_CONNMAP__`` parameters mean shorted signal bits. +- The numbers 0-3 are reserved for ``0``, ``1``, ``x``, and ``z`` respectively. +- Example use-cases: + + - Detecting shared clock or control signals in memory interfaces. + - In some cases this can be used for for optimization. + +Example: + +.. figure:: ../../images/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 6a426ff2b1f..9acae2718be 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -15,790 +15,6 @@ \section{Yosys by example -- Advanced Synthesis} \end{itemize} \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Using selections} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Simple selections} - -\begin{frame}[fragile]{\subsubsecname} -Most Yosys commands make use of the ``selection framework'' of Yosys. It can be used -to apply commands only to part of the design. For example: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -delete # will delete the whole design, but - -delete foobar # will only delete the module foobar. -\end{lstlisting} - -\bigskip -The {\tt select} command can be used to create a selection for subsequent -commands. For example: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select foobar # select the module foobar -delete # delete selected objects -select -clear # reset selection (select whole design) -\end{lstlisting} -\end{frame} - -\subsubsection{Selection by object name} - -\begin{frame}[fragile]{\subsubsecname} -The easiest way to select objects is by object name. This is usually only done -in synthesis scripts that are hand-tailored for a specific design. - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select foobar # select module foobar -select foo* # select all modules whose names start with foo -select foo*/bar* # select all objects matching bar* from modules matching foo* -select */clk # select objects named clk from all modules -\end{lstlisting} -\end{frame} - -\subsubsection{Module and design context} - -\begin{frame}[fragile]{\subsubsecname} -Commands can be executed in {\it module\/} or {\it design\/} context. Until now all -commands have been executed in design context. The {\tt cd} command can be used -to switch to module context. - -\bigskip -In module context all commands only effect the active module. Objects in the module -are selected without the {\tt /} prefix. For example: - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -cd foo # switch to module foo -delete bar # delete object foo/bar - -cd mycpu # switch to module mycpu -dump reg_* # print details on all objects whose names start with reg_ - -cd .. # switch back to design -\end{lstlisting} - -\bigskip -Note: Most synthesis scripts never switch to module context. But it is a very powerful -tool for interactive design investigation. -\end{frame} - -\subsubsection{Selecting by object property or type} - -\begin{frame}[fragile]{\subsubsecname} -Special patterns can be used to select by object property or type. For example: - -\bigskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select w:reg_* # select all wires whose names start with reg_ -select a:foobar # select all objects with the attribute foobar set -select a:foobar=42 # select all objects with the attribute foobar set to 42 -select A:blabla # select all modules with the attribute blabla set -select foo/t:$add # select all $add cells from the module foo -\end{lstlisting} - -\bigskip -A complete list of this pattern expressions can be found in the command -reference to the {\tt select} command. -\end{frame} - -\subsubsection{Combining selection} - -\begin{frame}[fragile]{\subsubsecname} -When more than one selection expression is used in one statement, then they are -pushed on a stack. The final elements on the stack are combined into a union: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select t:$dff r:WIDTH>1 # all cells of type $dff and/or with a parameter WIDTH > 1 -\end{lstlisting} - -\bigskip -Special \%-commands can be used to combine the elements on the stack: - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select t:$dff r:WIDTH>1 %i # all cells of type $dff *AND* with a parameter WIDTH > 1 -\end{lstlisting} - -\medskip -\begin{block}{Examples for {\tt \%}-codes (see {\tt help select} for full list)} -{\tt \%u} \dotfill union of top two elements on stack -- pop 2, push 1 \\ -{\tt \%d} \dotfill difference of top two elements on stack -- pop 2, push 1 \\ -{\tt \%i} \dotfill intersection of top two elements on stack -- pop 2, push 1 \\ -{\tt \%n} \dotfill inverse of top element on stack -- pop 1, push 1 \\ -\end{block} -\end{frame} - -\subsubsection{Expanding selections} - -\begin{frame}[fragile]{\subsubsecname} -Selections of cells and wires can be expanded along connections using {\tt \%}-codes -for selecting input cones ({\tt \%ci}), output cones ({\tt \%co}), or both ({\tt \%x}). - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# select all wires that are inputs to $add cells -select t:$add %ci w:* %i -\end{lstlisting} - -\bigskip -Additional constraints such as port names can be specified. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -# select all wires that connect a "Q" output with a "D" input -select c:* %co:+[Q] w:* %i c:* %ci:+[D] w:* %i %i - -# select the multiplexer tree that drives the signal 'state' -select state %ci*:+$mux,$pmux[A,B,Y] -\end{lstlisting} - -\bigskip -See {\tt help select} for full documentation of this expressions. -\end{frame} - -\subsubsection{Incremental selection} - -\begin{frame}[fragile]{\subsubsecname} -Sometimes a selection can most easily be described by a series of add/delete operations. -The commands {\tt select -add} and {\tt select -del} respectively add or remove objects -from the current selection instead of overwriting it. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select -none # start with an empty selection -select -add reg_* # select a bunch of objects -select -del reg_42 # but not this one -select -add state %ci # and add mor stuff -\end{lstlisting} - -\bigskip -Within a select expression the token {\tt \%} can be used to push the previous selection -on the stack. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select t:$add t:$sub # select all $add and $sub cells -select % %ci % %d # select only the input wires to those cells -\end{lstlisting} -\end{frame} - -\subsubsection{Creating selection variables} - -\begin{frame}[fragile]{\subsubsecname} -Selections can be stored under a name with the {\tt select -set } -command. The stored selections can be used in later select expressions -using the syntax {\tt @}. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -select -set cone_a state_a %ci*:-$dff # set @cone_a to the input cone of state_a -select -set cone_b state_b %ci*:-$dff # set @cone_b to the input cone of state_b -select @cone_a @cone_b %i # select the objects that are in both cones -\end{lstlisting} - -\bigskip -Remember that select expressions can also be used directly as arguments to most -commands. Some commands also except a single select argument to some options. -In those cases selection variables must be used to capture more complex selections. - -\medskip -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -dump @cone_a @cone_b - -select -set cone_ab @cone_a @cone_b %i -show -color red @cone_ab -color magenta @cone_a -color blue @cone_b -\end{lstlisting} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- Example} -\begin{columns} -\column[t]{4cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/select.v} -\column[t]{7cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExAdv/select.ys} -\end{columns} -\hfil\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/select.pdf} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Advanced uses of techmap} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Introduction to techmap} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item -The {\tt techmap} command replaces cells in the design with implementations given -as Verilog code (called ``map files''). It can replace Yosys' internal cell -types (such as {\tt \$or}) as well as user-defined cell types. -\medskip\item -Verilog parameters are used extensively to customize the internal cell types. -\medskip\item -Additional special parameters are used by techmap to communicate meta-data to the -map files. -\medskip\item -Special wires are used to instruct techmap how to handle a module in the map file. -\medskip\item -Generate blocks and recursion are powerful tools for writing map files. -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example 1/2} -\vskip-0.2cm -To map the Verilog OR-reduction operator to 3-input OR gates: -\vskip-0.2cm -\begin{columns} -\column[t]{0.35\linewidth} -\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=24]{PRESENTATION_ExAdv/red_or3x1_map.v} -\column[t]{0.65\linewidth} -\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=25]{PRESENTATION_ExAdv/red_or3x1_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example 2/2} -\vbox to 0cm{ -\hfil\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/red_or3x1.pdf} -\vss -} -\begin{columns} -\column[t]{6cm} -\column[t]{4cm} -\vskip-0.6cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, firstline=4, lastline=4, frame=single]{PRESENTATION_ExAdv/red_or3x1_test.ys} -\vskip-0.2cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/red_or3x1_test.v} -\end{columns} -\end{frame} - -\subsubsection{Conditional techmap} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item In some cases only cells with certain properties should be substituted. -\medskip -\item The special wire {\tt \_TECHMAP\_FAIL\_} can be used to disable a module -in the map file for a certain set of parameters. -\medskip -\item The wire {\tt \_TECHMAP\_FAIL\_} must be set to a constant value. If it -is non-zero then the module is disabled for this set of parameters. -\medskip -\item Example use-cases: -\begin{itemize} -\item coarse-grain cell types that only operate on certain bit widths -\item memory resources for different memory geometries (width, depth, ports, etc.) -\end{itemize} -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip-0.5cm -\hfill\includegraphics[width=6cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/sym_mul.pdf} -\vss -} -\vskip-0.5cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/sym_mul_map.v} -\begin{columns} -\column[t]{6cm} -\vskip-0.5cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/sym_mul_test.v} -\column[t]{4cm} -\vskip-0.5cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=4]{PRESENTATION_ExAdv/sym_mul_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Scripting in map modules} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item The special wires {\tt \_TECHMAP\_DO\_*} can be used to run Yosys scripts -in the context of the replacement module. -\medskip -\item The wire that comes first in alphabetical oder is interpreted as string (must -be connected to constants) that is executed as script. Then the wire is removed. Repeat. -\medskip -\item You can even call techmap recursively! -\medskip -\item Example use-cases: -\begin{itemize} -\item Using always blocks in map module: call {\tt proc} -\item Perform expensive optimizations (such as {\tt freduce}) on cells where -this is known to work well. -\item Interacting with custom commands. -\end{itemize} -\end{itemize} - -\scriptsize -PROTIP: Commands such as {\tt shell}, {\tt show -pause}, and {\tt dump} can be use -in the {\tt \_TECHMAP\_DO\_*} scripts for debugging map modules. -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip4.2cm -\hskip0.5cm\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/mymul.pdf} -\vss -} -\vskip-0.6cm -\begin{columns} -\column[t]{6cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/mymul_map.v} -\column[t]{4.2cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/mymul_test.v} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/mymul_test.ys} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, frame=single, language=ys, firstline=7, lastline=12]{PRESENTATION_ExAdv/mymul_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Handling constant inputs} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item The special parameters {\tt \_TECHMAP\_CONSTMSK\_\it \tt \_} and -{\tt \_TECHMAP\_CONSTVAL\_\it \tt \_} can be used to handle constant -input values to cells. -\medskip -\item The former contains 1-bits for all constant input bits on the port. -\medskip -\item The latter contains the constant bits or undef (x) for non-constant bits. -\medskip -\item Example use-cases: -\begin{itemize} -\item Converting arithmetic (for example multiply to shift) -\item Identify constant addresses or enable bits in memory interfaces. -\end{itemize} -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip5.2cm -\hskip6.5cm\includegraphics[width=5cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/mulshift.pdf} -\vss -} -\vskip-0.6cm -\begin{columns} -\column[t]{6cm} -\vskip-0.4cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/mulshift_map.v} -\column[t]{4.2cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/mulshift_test.v} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/mulshift_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Handling shorted inputs} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item The special parameters {\tt \_TECHMAP\_BITS\_CONNMAP\_} and -{\tt \_TECHMAP\_CONNMAP\_\it \tt \_} can be used to handle shorted inputs. -\medskip -\item Each bit of the port correlates to an {\tt \_TECHMAP\_BITS\_CONNMAP\_} bits wide -number in {\tt \_TECHMAP\_CONNMAP\_\it \tt \_}. -\medskip -\item Each unique signal bit is assigned its own number. Identical fields in the {\tt -\_TECHMAP\_CONNMAP\_\it \tt \_} parameters mean shorted signal bits. -\medskip -\item The numbers 0-3 are reserved for {\tt 0}, {\tt 1}, {\tt x}, and {\tt z} respectively. -\medskip -\item Example use-cases: -\begin{itemize} -\item Detecting shared clock or control signals in memory interfaces. -\item In some cases this can be used for for optimization. -\end{itemize} -\end{itemize} -\end{frame} - -\begin{frame}[t]{\subsubsecname{} -- Example} -\vbox to 0cm{ -\vskip4.5cm -\hskip6.5cm\includegraphics[width=5cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/addshift.pdf} -\vss -} -\vskip-0.6cm -\begin{columns} -\column[t]{6cm} -\vskip-0.4cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/addshift_map.v} -\column[t]{4.2cm} -\vskip-0.6cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/addshift_test.v} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/addshift_test.ys} -\end{columns} -\end{frame} - -\subsubsection{Notes on using techmap} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item Don't use positional cell parameters in map modules. -\medskip -\item Don't try to implement basic logic optimization with techmap. \\ -{\small (So the OR-reduce using OR3X1 cells map was actually a bad example.)} -\medskip -\item You can use the {\tt \$\_\,\_}-prefix for internal cell types to avoid -collisions with the user-namespace. But always use two underscores or the -internal consistency checker will trigger on this cells. -\medskip -\item Techmap has two major use cases: -\begin{itemize} -\item Creating good logic-level representation of arithmetic functions. \\ -This also means using dedicated hardware resources such as half- and full-adder -cells in ASICS or dedicated carry logic in FPGAs. -\smallskip -\item Mapping of coarse-grain resources such as block memory or DSP cells. -\end{itemize} -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Coarse-grain synthesis} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\subsubsection{Intro to coarse-grain synthesis} - -\begin{frame}[fragile]{\subsubsecname} -In coarse-grain synthesis the target architecture has cells of the same -complexity or larger complexity than the internal RTL representation. - -For example: -\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog] - wire [15:0] a, b; - wire [31:0] c, y; - assign y = a * b + c; -\end{lstlisting} - -This circuit contains two cells in the RTL representation: one multiplier and -one adder. In some architectures this circuit can be implemented using -a single circuit element, for example an FPGA DSP core. Coarse grain synthesis -is this mapping of groups of circuit elements to larger components. - -\bigskip -Fine-grain synthesis would be matching the circuit elements to smaller -components, such as LUTs, gates, or half- and full-adders. -\end{frame} - -\subsubsection{The extract pass} - -\begin{frame}{\subsubsecname} -\begin{itemize} -\item Like the {\tt techmap} pass, the {\tt extract} pass is called with -a map file. It compares the circuits inside the modules of the map file -with the design and looks for sub-circuits in the design that match any -of the modules in the map file. -\bigskip -\item If a match is found, the {\tt extract} pass will replace the matching -subcircuit with an instance of the module from the map file. -\bigskip -\item In a way the {\tt extract} pass is the inverse of the techmap pass. -\end{itemize} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- Example 1/2} -\vbox to 0cm{ -\vskip2cm -\begin{tikzpicture} - \node at (0,0) {\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_00a.pdf}}; - \node at (3,-3) {\includegraphics[width=8cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_00b.pdf}}; - \draw[yshift=0.2cm,thick,-latex] (1,-1) -- (2,-2); -\end{tikzpicture} -\vss} -\vskip-1.2cm -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/macc_simple_xmap.v} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys] -read_verilog macc_simple_test.v -hierarchy -check -top test - -extract -map macc_simple_xmap.v;; -\end{lstlisting} -\end{columns} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- Example 2/2} -\hfil\begin{tabular}{cc} -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test_01.v}}} & -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test_02.v}}} \\ -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_01a.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_02a.pdf}} \\ -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_01b.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_02b.pdf}} \\ -\end{tabular} -\end{frame} - -\subsubsection{The wrap-extract-unwrap method} - -\begin{frame}{\subsubsecname} -\scriptsize -Often a coarse-grain element has a constant bit-width, but can be used to -implement operations with a smaller bit-width. For example, a 18x25-bit multiplier -can also be used to implement 16x20-bit multiplication. - -\bigskip -A way of mapping such elements in coarse grain synthesis is the wrap-extract-unwrap method: - -\begin{itemize} -\item {\bf wrap} \\ -Identify candidate-cells in the circuit and wrap them in a cell with a constant -wider bit-width using {\tt techmap}. The wrappers use the same parameters as the original cell, so -the information about the original width of the ports is preserved. \\ -Then use the {\tt connwrappers} command to connect up the bit-extended in- and -outputs of the wrapper cells. -\item {\bf extract} \\ -Now all operations are encoded using the same bit-width as the coarse grain element. The {\tt -extract} command can be used to replace circuits with cells of the target architecture. -\item {\bf unwrap} \\ -The remaining wrapper cell can be unwrapped using {\tt techmap}. -\end{itemize} - -\bigskip -The following sides detail an example that shows how to map MACC operations of -arbitrary size to MACC cells with a 18x25-bit multiplier and a 48-bit adder (such as -the Xilinx DSP48 cells). -\end{frame} - -\subsubsection{Example: DSP48\_MACC} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 1/13} -Preconditioning: {\tt macc\_xilinx\_swap\_map.v} \\ -Make sure {\tt A} is the smaller port on all multipliers - -\begin{columns} -\column{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=15]{PRESENTATION_ExAdv/macc_xilinx_swap_map.v} -\column{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=16]{PRESENTATION_ExAdv/macc_xilinx_swap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 2/13} -Wrapping multipliers: {\tt macc\_xilinx\_wrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=23]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=24, lastline=46]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 3/13} -Wrapping adders: {\tt macc\_xilinx\_wrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=48, lastline=67]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=68, lastline=89]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 4/13} -Extract: {\tt macc\_xilinx\_xmap.v} - -\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=1, lastline=17]{PRESENTATION_ExAdv/macc_xilinx_xmap.v} - -.. simply use the same wrapping commands on this module as on the design to create a template for the {\tt extract} command. -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 5/13} -Unwrapping multipliers: {\tt macc\_xilinx\_unwrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=1, lastline=17]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=18, lastline=30]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 6/13} -Unwrapping adders: {\tt macc\_xilinx\_unwrap\_map.v} - -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=32, lastline=48]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=49, lastline=61]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} -\end{columns} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- 7/13} -\hfil\begin{tabular}{cc} -{\tt test1} & {\tt test2} \\ -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=1, lastline=6, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} & -\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=8, lastline=13, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} \\ -$\downarrow$ & $\downarrow$ \\ -\end{tabular} -\vskip-0.5cm -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - read_verilog macc_xilinx_test.v - hierarchy -check -\end{lstlisting} -\vskip-0.5cm -\hfil\begin{tabular}{cc} -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2a.pdf}} \\ -\end{tabular} -\end{frame} - -\begin{frame}[fragile]{\subsubsecname{} -- 8/13} -\hfil\begin{tabular}{cc} -{\tt test1} & {\tt test2} \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2a.pdf}} \\ -$\downarrow$ & $\downarrow$ \\ -\end{tabular} -\vskip-0.2cm -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - techmap -map macc_xilinx_swap_map.v ;; -\end{lstlisting} -\vskip-0.2cm -\hfil\begin{tabular}{cc} -$\downarrow$ & $\downarrow$ \\ -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1b.pdf}} & -\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2b.pdf}} \\ -\end{tabular} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 9/13} -Wrapping in {\tt test1}: -\begin{columns} -\column[t]{5cm} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1b.pdf}}\vss} -\column[t]{6cm} -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -techmap -map macc_xilinx_wrap_map.v - -connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; -\end{lstlisting} -\end{columns} - -\vskip1cm -\hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 10/13} -Wrapping in {\tt test2}: -\begin{columns} -\column[t]{5cm} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2b.pdf}}\vss} -\column[t]{6cm} -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -techmap -map macc_xilinx_wrap_map.v - -connwrappers -unsigned $__mul_wrapper \ - Y Y_WIDTH \ - -unsigned $__add_wrapper \ - Y Y_WIDTH ;; -\end{lstlisting} -\end{columns} - -\vskip1cm -\hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 11/13} -Extract in {\tt test1}: -\begin{columns} -\column[t]{4.5cm} -\vbox to 0cm{ -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -design -push -read_verilog macc_xilinx_xmap.v -techmap -map macc_xilinx_swap_map.v -techmap -map macc_xilinx_wrap_map.v;; -design -save __macc_xilinx_xmap -design -pop -\end{lstlisting} -\vss} -\column[t]{5.5cm} -\vskip-1cm -\begin{lstlisting}[linewidth=5.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -extract -constports -ignore_parameters \ - -map %__macc_xilinx_xmap \ - -swap $__add_wrapper A,B ;; -\end{lstlisting} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf}}\vss} -\end{columns} - -\vskip2cm -\hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1d.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 12/13} -Extract in {\tt test2}: -\begin{columns} -\column[t]{4.5cm} -\vbox to 0cm{ -\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -design -push -read_verilog macc_xilinx_xmap.v -techmap -map macc_xilinx_swap_map.v -techmap -map macc_xilinx_wrap_map.v;; -design -save __macc_xilinx_xmap -design -pop -\end{lstlisting} -\vss} -\column[t]{5.5cm} -\vskip-1cm -\begin{lstlisting}[linewidth=5.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -extract -constports -ignore_parameters \ - -map %__macc_xilinx_xmap \ - -swap $__add_wrapper A,B ;; -\end{lstlisting} -\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf}}\vss} -\end{columns} - -\vskip2cm -\hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf} -\end{frame} - -\begin{frame}[t, fragile]{\subsubsecname{} -- 13/13} -Unwrap in {\tt test2}: - -\hfil\begin{tikzpicture} -\node at (0,0) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf}}; -\node at (0,-4) {\includegraphics[width=8cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2e.pdf}}; -\node at (1,-1.7) {\begin{lstlisting}[linewidth=5.5cm, frame=single, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -techmap -map macc_xilinx_unwrap_map.v ;; -\end{lstlisting}}; -\draw[-latex] (4,-0.7) .. controls (5,-1.7) .. (4,-2.7); -\end{tikzpicture} -\end{frame} - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Automatic design changes} diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex deleted file mode 100644 index 3f5113e3cf4..00000000000 --- a/manual/PRESENTATION_ExOth.tex +++ /dev/null @@ -1,227 +0,0 @@ - -\section{Yosys by example -- Beyond Synthesis} - -\begin{frame} -\sectionpage -\end{frame} - -\begin{frame}{Overview} -This section contains 2 subsections: -\begin{itemize} -\item Interactive Design Investigation -\item Symbolic Model Checking -\end{itemize} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Interactive Design Investigation} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\begin{frame}{\subsecname} -Yosys can also be used to investigate designs (or netlists created -from other tools). - -\begin{itemize} -\item -The selection mechanism (see slides ``Using Selections''), especially patterns such -as {\tt \%ci} and {\tt \%co}, can be used to figure out how parts of the design -are connected. - -\item -Commands such as {\tt submod}, {\tt expose}, {\tt splice}, \dots can be used -to transform the design into an equivalent design that is easier to analyse. - -\item -Commands such as {\tt eval} and {\tt sat} can be used to investigate the -behavior of the circuit. -\end{itemize} -\end{frame} - -\begin{frame}[t, fragile]{Example: Reorganizing a module} -\begin{columns} -\column[t]{4cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExOth/scrambler.v} -\column[t]{7cm} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] -read_verilog scrambler.v - -hierarchy; proc;; - -cd scrambler -submod -name xorshift32 \ - xs %c %ci %D %c %ci:+[D] %D \ - %ci*:-$dff xs %co %ci %d -\end{lstlisting} -\end{columns} - -\hfil\includegraphics[width=11cm,trim=0 0cm 0 1.5cm]{PRESENTATION_ExOth/scrambler_p01.pdf} - -\hfil\includegraphics[width=11cm,trim=0 0cm 0 2cm]{PRESENTATION_ExOth/scrambler_p02.pdf} -\end{frame} - -\begin{frame}[t, fragile]{Example: Analysis of circuit behavior} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] -> read_verilog scrambler.v -> hierarchy; proc;; cd scrambler -> submod -name xorshift32 xs %c %ci %D %c %ci:+[D] %D %ci*:-$dff xs %co %ci %d - -> cd xorshift32 -> rename n2 in -> rename n1 out - -> eval -set in 1 -show out -Eval result: \out = 270369. - -> eval -set in 270369 -show out -Eval result: \out = 67634689. - -> sat -set out 632435482 -Signal Name Dec Hex Bin --------------------- ---------- ---------- ------------------------------------- -\in 745495504 2c6f5bd0 00101100011011110101101111010000 -\out 632435482 25b2331a 00100101101100100011001100011010 -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Symbolic Model Checking} - -\begin{frame} -\subsectionpage -\subsectionpagesuffix -\end{frame} - -\begin{frame}{\subsecname} -Symbolic Model Checking (SMC) is used to formally prove that a circuit has -(or has not) a given property. - -\bigskip -One application is Formal Equivalence Checking: Proving that two circuits -are identical. For example this is a very useful feature when debugging custom -passes in Yosys. - -\bigskip -Other applications include checking if a module conforms to interface -standards. - -\bigskip -The {\tt sat} command in Yosys can be used to perform Symbolic Model Checking. -\end{frame} - -\begin{frame}[t]{Example: Formal Equivalence Checking (1/2)} -Remember the following example? -\vskip1em - -\vbox to 0cm{ -\vskip-0.3cm -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/techmap_01_map.v} -}\vbox to 0cm{ -\vskip-0.5cm -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExSyn/techmap_01.v} -\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/techmap_01.ys}} - -\vskip5cm\hskip5cm -Lets see if it is correct.. -\end{frame} - -\begin{frame}[t, fragile]{Example: Formal Equivalence Checking (2/2)} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] -# read test design -read_verilog techmap_01.v -hierarchy -top test - -# create two version of the design: test_orig and test_mapped -copy test test_orig -rename test test_mapped - -# apply the techmap only to test_mapped -techmap -map techmap_01_map.v test_mapped - -# create a miter circuit to test equivalence -miter -equiv -make_assert -make_outputs test_orig test_mapped miter -flatten miter - -# run equivalence check -sat -verify -prove-asserts -show-inputs -show-outputs miter -\end{lstlisting} - -\dots -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -Solving problem with 945 variables and 2505 clauses.. -SAT proof finished - no model found: SUCCESS! -\end{lstlisting} -\end{frame} - -\begin{frame}[t, fragile]{Example: Symbolic Model Checking (1/2)} -\small -The following AXI4 Stream Master has a bug. But the bug is not exposed if the -slave keeps {\tt tready} asserted all the time. (Something a test bench might do.) - -\medskip -Symbolic Model Checking can be used to expose the bug and find a sequence -of values for {\tt tready} that yield the incorrect behavior. - -\vskip-1em -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{5pt}{6pt}\selectfont, language=verilog]{PRESENTATION_ExOth/axis_master.v} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{5pt}{6pt}\selectfont, language=verilog]{PRESENTATION_ExOth/axis_test.v} -\end{columns} -\end{frame} - -\begin{frame}[t, fragile]{Example: Symbolic Model Checking (2/2)} -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] -read_verilog -sv axis_master.v axis_test.v -hierarchy -top axis_test - -proc; flatten;; -sat -seq 50 -prove-asserts -\end{lstlisting} - -\bigskip -\dots with unmodified {\tt axis\_master.v}: -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -Solving problem with 159344 variables and 442126 clauses.. -SAT proof finished - model found: FAIL! -\end{lstlisting} - -\bigskip -\dots with fixed {\tt axis\_master.v}: -\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] -Solving problem with 159144 variables and 441626 clauses.. -SAT proof finished - no model found: SUCCESS! -\end{lstlisting} -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\subsection{Summary} - -\begin{frame}{\subsecname} -\begin{itemize} -\item Yosys provides useful features beyond synthesis. -\item The commands {\tt sat} and {\tt eval} can be used to analyse the behavior of a circuit. -\item The {\tt sat} command can also be used for symbolic model checking. -\item This can be useful for debugging and testing designs and Yosys extensions alike. -\end{itemize} - -\bigskip -\bigskip -\begin{center} -Questions? -\end{center} - -\bigskip -\bigskip -\begin{center} -\url{https://yosyshq.net/yosys/} -\end{center} -\end{frame} - diff --git a/manual/PRESENTATION_ExOth/.gitignore b/manual/PRESENTATION_ExOth/.gitignore deleted file mode 100644 index cf658897d52..00000000000 --- a/manual/PRESENTATION_ExOth/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.dot 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 d2b33bd1cb6..a7291106e4f 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 b27a8d823f4..45921aa7584 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 6b67b169149..5e5bf8ae43d 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`. diff --git a/manual/.gitignore b/manual/.gitignore deleted file mode 100644 index 110f65b1900..00000000000 --- a/manual/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -*.aux -*.bbl -*.blg -*.idx -*.log -*.out -*.pdf -*.toc -*.snm -*.nav -*.vrb -*.ok diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex deleted file mode 100644 index 9acae2718be..00000000000 --- 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 addc34ed183..00000000000 --- a/manual/clean.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -for f in $( find . -name .gitignore ); do sed -Ee "s,^,find ${f%.gitignore} -name ',; s,$,' | xargs rm -f,;" $f; done | bash -v diff --git a/manual/presentation.sh b/manual/presentation.sh deleted file mode 100755 index ca8a6c93c10..00000000000 --- a/manual/presentation.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -fast_mode=false - -set -- $(getopt fu "$@") -while [ $# -gt 0 ]; do - case "$1" in - -f) - fast_mode=true - ;; - --) - shift - break - ;; - -*) - echo "$0: error - unrecognized option $1" 1>&2 - exit 1 - ;; - *) - break - esac - shift -done - -PDFTEX_OPT="-shell-escape -halt-on-error" - -set -ex - -if ! $fast_mode; then - ! md5sum *.aux *.snm *.nav *.toc > autoloop.old - make -C PRESENTATION_Intro - make -C PRESENTATION_ExSyn - make -C PRESENTATION_ExAdv - make -C PRESENTATION_ExOth - make -C PRESENTATION_Prog -fi - -set -ex - -pdflatex $PDFTEX_OPT presentation.tex - -if ! $fast_mode; then - while - md5sum *.aux *.snm *.nav *.toc > autoloop.new - ! cmp autoloop.old autoloop.new - do - cp autoloop.new autoloop.old - pdflatex $PDFTEX_OPT presentation.tex - done - - rm -f autoloop.old - rm -f autoloop.new -fi - diff --git a/manual/presentation.tex b/manual/presentation.tex deleted file mode 100644 index 7aba33c8b31..00000000000 --- a/manual/presentation.tex +++ /dev/null @@ -1,162 +0,0 @@ -\documentclass{beamer} -\hypersetup{bookmarksdepth=5} - -\usepackage[T1]{fontenc} % required for luximono! -\usepackage{lmodern} -\usepackage[scaled=0.8]{luximono} % typewriter font with bold face - -% To install the luximono font files: -% getnonfreefonts-sys --all or -% getnonfreefonts-sys luximono -% -% when there are trouble you might need to: -% - Create /etc/texmf/updmap.d/99local-luximono.cfg -% containing the single line: Map ul9.map -% - Run update-updmap followed by mktexlsr and updmap-sys -% -% This commands must be executed as root with a root environment -% (i.e. run "sudo su" and then execute the commands in the root -% shell, don't just prefix the commands with "sudo"). - -% formats the text according the set language -\usepackage[english]{babel} -\usepackage{amsmath} -\usepackage{multirow} -\usepackage{booktabs} -\usepackage{listings} -\usepackage{setspace} -\usepackage{skull} -\usepackage{units} - -\usepackage{tikz} -\usetikzlibrary{calc} -\usetikzlibrary{arrows} -\usetikzlibrary{scopes} -\usetikzlibrary{through} -\usetikzlibrary{shapes.geometric} - -\lstset{basicstyle=\ttfamily} - -\def\B#1{{\tt\textbackslash{}#1}} -\def\C#1{\lstinline[language=C++]{#1}} -\def\V#1{\lstinline[language=Verilog]{#1}} - -\lstdefinelanguage{liberty}{ - morecomment=[s]{/*}{*/}, - morekeywords={library,cell,area,pin,direction,function,clocked_on,next_state,clock,ff}, - morestring=[b]", -} - -\lstdefinelanguage{rtlil}{ - morecomment=[l]{\#}, - morekeywords={module,attribute,parameter,wire,memory,auto,width,offset,size,input,output,inout,cell,connect,switch,case,assign,sync,low,high,posedge,negedge,edge,always,update,process,end}, - morestring=[b]", -} - -\lstdefinelanguage{ys}{ - morecomment=[l]{\#}, -} - -\lstset{ - commentstyle=\color{YosysGreen}, -} - -\newenvironment{boxalertenv}{\begin{altenv}% -{\usebeamertemplate{alerted text begin}\usebeamercolor[fg]{alerted text}\usebeamerfont{alerted text}\setlength{\fboxsep}{1pt}\colorbox{bg}} -{\usebeamertemplate{alerted text end}}{\color{.}}{}}{\end{altenv}} - -\newcommand<>{\boxalert}[1]{{% -\begin{boxalertenv}#2{#1}\end{boxalertenv}% -}} - -\newcommand{\subsectionpagesuffix}{ -\vfill\begin{centering} -{\usebeamerfont{subsection name}\usebeamercolor[fg]{subsection name}of \sectionname~\insertsectionnumber} -\vskip1em\par -\setbeamercolor{graybox}{bg=gray} -\begin{beamercolorbox}[sep=8pt,center]{graybox} -\usebeamerfont{subsection title}\insertsection\par -\end{beamercolorbox} -\end{centering}} - -\title{Yosys Open SYnthesis Suite} -\author{Claire Xenia Wolf} -\institute{https://yosyshq.net/yosys/} - -\usetheme{Madrid} -\usecolortheme{seagull} -\beamertemplatenavigationsymbolsempty - -\definecolor{YosysGreen}{RGB}{85,136,102} -\definecolor{MyBlue}{RGB}{85,130,180} - -\setbeamercolor{title}{fg=black,bg=YosysGreen!70} -\setbeamercolor{titlelike}{fg=black,bg=YosysGreen!70} -\setbeamercolor{frametitle}{fg=black,bg=YosysGreen!70} -\setbeamercolor{block title}{fg=black,bg=YosysGreen!70} -\setbeamercolor{item projected}{fg=black,bg=YosysGreen} - -\begin{document} - -\begin{frame} -\titlepage -\end{frame} - -\setcounter{section}{-3} - -\section{Abstract} -\begin{frame}{Abstract} -Yosys is the first full-featured open source software for Verilog HDL -synthesis. It supports most of Verilog-2005 and is well tested with -real-world designs from the ASIC and FPGA world. - -\bigskip -Learn how to use Yosys to create your own custom synthesis flows and -discover why open source HDL synthesis is important for researchers, -hobbyists, educators and engineers alike. - -\bigskip -This presentation covers basic concepts of Yosys, writing synthesis scripts -for a wide range of applications, creating Yosys scripts for various -non-synthesis applications (such as formal equivalence checking) and -writing extensions to Yosys using the C++ API. -\end{frame} - -\section{About me} -\begin{frame}{About me} -Hi! I'm Claire Xenia Wolf. - -\bigskip -I like writing open source software. For example: -\begin{itemize} -\item Yosys -\item OpenSCAD (now maintained by Marius Kintel) -\item SPL (a not very popular scripting language) -\item EmbedVM (a very simple compiler+vm for 8 bit micros) -\item Lib(X)SVF (a library to play SVF/XSVF files over JTAG) -\item ROCK Linux (discontinued since 2010) -\end{itemize} -\end{frame} - -\section{Outline} -\begin{frame}{Outline} -Yosys is an Open Source Verilog synthesis tool, and more. - -\bigskip -Outline of this presentation: -\begin{itemize} -\item Introduction to the field and Yosys -\item Yosys by example: synthesis -\item Yosys by example: advanced synthesis -\item Yosys by example: beyond synthesis -\item Writing Yosys extensions in C++ -\end{itemize} -\end{frame} - -\include{PRESENTATION_Intro} -\include{PRESENTATION_ExSyn} -\include{PRESENTATION_ExAdv} -\include{PRESENTATION_ExOth} -\include{PRESENTATION_Prog} - -\end{document} 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 bca4971e9bd..fb2e603f16c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -59,6 +59,10 @@ ''' } +# 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 9f7ae2ba736..10894e4e8df 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 45921aa7584..7f4f0880b6f 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 0cae4aa0dbd..df335444d6e 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 81d89d7a677..8c9450feb68 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 bc56bbf7762..7f23754b2d5 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 387a3fb1fb0..06eafe4e989 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 5e5bf8ae43d..52898987786 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 1b601acbd4e..225aa23ebb3 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 1724ba5e321..8419ea4a293 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 65eaaa5d59b..961687f798a 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 3ac73fd6fc1..c023109c940 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 025d6f8b7b5..acb7dbaabf1 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 ` 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 cb5b65d8afc..fcfda674637 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 7768c3cc941..8fa9e94dc7c 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 4ed7d910726..a65fedc30f6 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 e8d6fd1a05f..c8b55cb8df4 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 745e5e2f513..a095ef6bfd6 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 fb2e603f16c..a043f0b49d7 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -63,10 +63,13 @@ 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 df335444d6e..0a776393a80 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 0be7f77281d..91a15c12928 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 00000000000..e69de29bb2d diff --git a/docs/util/cmdref.py b/docs/util/cmdref.py new file mode 100644 index 00000000000..175bd20f0a3 --- /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 9ffb17c1a97..c9b9f238a7e 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 8954ee2548a..fc6ba69025c 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 4291f997654..afd84c3c65d 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 e9986ff05f2..a9015e8d558 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 48946f1e1e2..2c5fdcf4c24 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 2ac8e5bed9f..60ca513a831 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 175bd20f0a3..795a3e8ff00 100644 --- a/docs/util/cmdref.py +++ b/docs/util/cmdref.py @@ -52,12 +52,15 @@ 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(' ')) + 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 @@ def get_objects(self): 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 | 295 +++++++++--------- .../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, 399 insertions(+), 385 deletions(-) diff --git a/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst b/docs/source/appendix/APPNOTE_010_Verilog_to_BLIF.rst index d4448895ba0..d8f8fec4615 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 a7291106e4f..3adcc4913e0 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``. - -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. +: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 @@ -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 ``: - @@ -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 `` 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 `` +option. Secondly it is possible to load cell libraries into the design with the ``read_verilog -lib `` command. The 2nd method has the great advantage that the library only needs to be loaded once and can then be used in all -subsequent calls to the ``show`` command. +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 `` 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 `` 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 ``/``. 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 +``/``. 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 ``. It can later be recalled using ``select @``. In fact, the ``@`` expression pushes the stored selection on the stack maintained by -the ``select`` command. So for example +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 e9e44d1cd11..adb551494ba 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 ``. 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 30a522ba3dd..0c3f6636578 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 10894e4e8df..594f7cee859 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 `` providing details for a specific command. ``yosys -H`` or -``yosys -h `` 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 `` providing details for a specific command. ``yosys -H`` +or ``yosys -h `` 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 7f4f0880b6f..e3c105755da 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`. +The weird :cmd:ref:`select` expressions at the end of this script are discussed +later in +:doc:`using_yosys/more_scripting/selections`. diff --git a/docs/source/using_yosys/memory_mapping.rst b/docs/source/using_yosys/memory_mapping.rst index cdc381eed81..41654a0c581 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 `_ diff --git a/docs/source/using_yosys/more_scripting/opt_passes.rst b/docs/source/using_yosys/more_scripting/opt_passes.rst index 06eafe4e989..3fd74256015 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 52898987786..e3a93d16395 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`. +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 c5616336072..ad01d1630c5 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 225aa23ebb3..d7c21154de6 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 8419ea4a293..df351c48669 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 c023109c940..3d8b351253f 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 fcfda674637..fbb82b41630 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 8fa9e94dc7c..6667b8b677b 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 a65fedc30f6..904f8068282 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 ` 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 a095ef6bfd6..64f89777b43 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 3adcc4913e0..698f2da2cb7 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 e53e344d831..0828adf39e4 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 32aa8fc04b9..32879c0d4d9 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 3fd74256015..15f2e20af1d 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 ` 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 868aa08fecc..3d05ea0bfcc 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 fbb82b41630..2c8af3ad361 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 2e6fba0178a..aa77d1ea6b2 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 904f8068282..fa356e7854e 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 c8b55cb8df4..3389d88a042 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 795a3e8ff00..ec146e23173 100644 --- a/docs/util/cmdref.py +++ b/docs/util/cmdref.py @@ -227,7 +227,7 @@ def resolve_xref(self, env, fromdocname, builder, typ, 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 61317f7cd36..7a51385c1b1 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 df351c48669..00000000000 --- 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 3d05ea0bfcc..e2b5b658c56 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 3d8b351253f..00000000000 --- 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 87d9730a431..7e6aba22bcc 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 41654a0c581..21cea531917 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 15f2e20af1d..f8b55885473 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 fa356e7854e..78fa47ba4bf 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 594f7cee859..9ebdc1d9db0 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 e3c105755da..9d48ac71be6 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 8c9450feb68..20add9bb571 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 7f23754b2d5..fde337b288e 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 f8b55885473..4437a4796e3 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 e3a93d16395..2c36778c84f 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 7a51385c1b1..633a8ec774f 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 d7c21154de6..5ef4b5c9094 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 961687f798a..69b7346b569 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 acb7dbaabf1..c1dddfcbbef 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 ` 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 6667b8b677b..cb2f99bb2ba 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 3389d88a042..001e2536c5d 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 64f89777b43..d0aadbd4da5 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 21cea531917..7fd0a3eb964 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 40b78190444..50f03d13cff 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 00000000000..21ede09b493 --- /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 00000000000..57ae8f87a5f --- /dev/null +++ b/docs/source/_static/yosyshq.css @@ -0,0 +1,26 @@ +/* Don't hide the right sidebar as we're placing our fixed links there */ +aside.no-toc { + display: block !important; +} + +/* Colorful headings */ +h1 { + color: var(--color-brand-primary); + } + +h2, h3, h4, h5, h6 { + color: var(--color-brand-content); +} + +/* Use a different color for external links */ +a.external { + color: var(--color-brand-primary) !important; +} + +.wy-table-responsive table td { + white-space: normal; +} + +th { + text-align: left; +} diff --git a/docs/source/appendix/APPNOTE_011_Design_Investigation.rst b/docs/source/appendix/APPNOTE_011_Design_Investigation.rst index 698f2da2cb7..5552408cc85 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 6c9aa167381..9a905c6f2cb 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 ` 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 `. -.. 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 a043f0b49d7..00388749805 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -9,8 +9,8 @@ # 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 @@ } # 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 0c3f6636578..8342b685c66 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 9d48ac71be6..a06ee1e17f1 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 20add9bb571..6a3f8802ec2 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 2c36778c84f..2957a1c2f59 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 633a8ec774f..0bd824b2069 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 5ef4b5c9094..68d023d64cd 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 69b7346b569..b2ec418adc2 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 `). -.. 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 c1dddfcbbef..1c2adc01c63 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 2c8af3ad361..72907c1213d 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 `. -.. 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 78fa47ba4bf..b6b437b90d6 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 d0aadbd4da5..b89ca9cb94f 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 40a8c178f10..00000000000 --- a/docs/static/custom.css +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/docs/static/yosyshq.css b/docs/static/yosyshq.css deleted file mode 100644 index 91a15c12928..00000000000 --- a/docs/static/yosyshq.css +++ /dev/null @@ -1,78 +0,0 @@ -h1, h3, p.topic-title, .content li.toctree-l1 > a { - color: #d6368f !important; -} - -h2, p.admonition-title, dt, .content li.toctree-l2 > a { - color: #4b72b8; -} - -a { - color: #8857a3; -} - -a.current, a:hover, a.external { - color: #d6368f !important; -} - -a.external:hover { - text-decoration: underline; -} - -p { - text-align: justify; -} - -.vp-sidebar a { - color: #d6368f; -} - -.vp-sidebar li li a { - color: #4b72b8; -} - -.vp-sidebar li li li a { - color: #2c3e50; - font-weight: 400; -} - -.vp-sidebar h3 { - padding-left: 1.5rem !important; -} - -.vp-sidebar ul a { - padding-left: 1.5rem !important; -} - -.vp-sidebar ul ul a { - padding-left: 3rem !important; -} - -.vp-sidebar ul ul ul a { - padding-left: 4.5rem !important; -} - -.vp-sidebar .toctree-l1.current a { - border-left: 0.5rem solid #6ecbd7; -} - -.vp-sidebar .toctree-l1 a.current { - border-left: 0.5rem solid #8857a3; -} - -.injected .rst-current-version, .injected dt { - color: #6ecbd7 !important; -} - -.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 5552408cc85..3cbd0eb903d 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 -``'`` 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 ``: - -:``. Each of this boxes has one signal per row on one side -and a common signal for all rows on the other side. The ``:`` tuples -specify which bits of the signals are broken out and connected. So the top row -of the box connecting the signals ``a`` and ``x`` indicates that the bit 0 (i.e. -the range 0:0) from signal ``a`` is connected to bit 1 (i.e. the range 1:1) of -signal ``x``. - -Lines connecting such boxes together and lines connecting such boxes to -cell ports have a slightly different look to emphasise that they are not -actual signal wires but a necessity of the graphical representation. -This distinction seems like a technicality, until one wants to debug a -problem related to the way Yosys internally represents signal vectors, -for example when writing custom Yosys commands. - -Gate level netlists -------------------- - -Finally :numref:`splitnets_libfile` shows two common pitfalls when working with -designs mapped to a cell library. The top figure has two problems: First Yosys -did not have access to the cell library when this diagram was generated, -resulting in all cell ports defaulting to being inputs. This is why all ports -are drawn on the left side the cells are awkwardly arranged in a large column. -Secondly the two-bit vector ``y`` requires breakout-boxes for its individual -bits, resulting in an unnecessary complex diagram. - -For the 2nd diagram Yosys has been given a description of the cell library as -Verilog file containing blackbox modules. There are two ways to load cell -descriptions into Yosys: First the Verilog file for the cell library can be -passed directly to the :cmd:ref:`show` command using the ``-lib `` -option. Secondly it is possible to load cell libraries into the design with the -``read_verilog -lib `` command. The 2nd method has the great advantage -that the library only needs to be loaded once and can then be used in all -subsequent calls to the :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 `` 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 -``/``. 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 0b7f52b1d0b..1677445fa6b 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 9ebdc1d9db0..35015ceb920 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 32879c0d4d9..8fb460613dc 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 00000000000..6eab48bf5e6 --- /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 +``'`` 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 ``: - +:``. Each of this boxes has one signal per row on one side +and a common signal for all rows on the other side. The ``:`` tuples +specify which bits of the signals are broken out and connected. So the top row +of the box connecting the signals ``a`` and ``x`` indicates that the bit 0 (i.e. +the range 0:0) from signal ``a`` is connected to bit 1 (i.e. the range 1:1) of +signal ``x``. + +Lines connecting such boxes together and lines connecting such boxes to cell +ports have a slightly different look to emphasise that they are not actual +signal wires but a necessity of the graphical representation. This distinction +seems like a technicality, until one wants to debug a problem related to the way +Yosys internally represents signal vectors, for example when writing custom +Yosys commands. + +Gate level netlists +^^^^^^^^^^^^^^^^^^^ + +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 `` +option. Secondly it is possible to load cell libraries into the design with the +``read_verilog -lib `` command. The second method has the great +advantage that the library only needs to be loaded once and can then be used in +all subsequent calls to the :cmd:ref:`show` command. + +In addition to that, 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 `` 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 +``/``. 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 2957a1c2f59..b51ea34ea73 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 87581793b35..04ee2945c7c 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 3cbd0eb903d..00000000000 --- 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 -``. It can later be recalled using ``select @``. In fact, the -``@`` expression pushes the stored selection on the stack maintained by -the :cmd:ref:`select` command. So for example - -.. 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 b51ea34ea73..b1a07ca012f 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 +``. It can later be recalled using ``select @``. In fact, the +``@`` expression pushes the stored selection on the stack maintained by +the :cmd:ref:`select` command. So for example + +.. 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 21ede09b493..b08194c0521 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 6eab48bf5e6..e7d5f34879a 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 `` option. Secondly it is possible to load cell libraries into the design with the ``read_verilog -lib `` command. The second method has the great advantage that the library only needs to be loaded once and can then be used in all subsequent calls to the :cmd:ref:`show` command. -In addition to that, 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 e7d5f34879a..06b93bb9053 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 b1a07ca012f..78b20ea3593 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 - -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 +.. role:: yoscrypt(code) + :language: yoscrypt - 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 ``/`` prefix. For example: .. code:: yoscrypt @@ -62,233 +74,102 @@ module are selected without the ``/`` 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``). - -.. 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 `` -command. The stored selections can be used in later select expressions -using the syntax ``@``. - -.. 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 -~~~~~~~~~~~~~~~~~~~~~~~~ +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.) -.. 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 + + 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` - show prod - show prod %ci - show prod %ci %ci - show prod %ci %ci %ci +.. 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 ``. It can later be recalled using ``select @``. In fact, the ``@`` expression pushes the stored selection on the stack maintained by -the :cmd:ref:`select` command. So for example - -.. 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 a93930be0c9..0fa2e94b9de 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 61fa6cd7098..d0e41561aad 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 0fa2e94b9de..da2e8e2dc8d 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 138e934e337..24b24015a0e 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 | 654 +++++++++--------- .../appendix/APPNOTE_012_Verilog_to_BTOR.rst | 570 +++++++-------- 5 files changed, 637 insertions(+), 590 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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

g>bmqs(epqQ{TO`LwmaQv(A=jPRo8FTcbM{Jn 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 z%0A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

<7q6BY9~J7k$3m`H11>W(_aUPAPd6rv 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 + +.. + Installation + ============ -Yosys written in C++ (using features from C++11) and is tested on modern -Linux. It should compile fine on most UNIX systems with a C++11 -compiler. The README file contains useful information on building Yosys -and its prerequisites. + Yosys written in C++ (using features from C++11) and is tested on modern + Linux. It should compile fine on most UNIX systems with a C++11 + compiler. The README file contains useful information on building Yosys + and its prerequisites. -Yosys is a large and feature-rich program with a couple of dependencies. -It is, however, possible to deactivate some of the dependencies in the -Makefile, resulting in features in Yosys becoming unavailable. When -problems with building Yosys are encountered, a user who is only -interested in the features of Yosys that are discussed in this -Application Note may deactivate TCL, Qt and MiniSAT support in the -Makefile and may opt against building yosys-abc. + Yosys is a large and feature-rich program with a couple of dependencies. + It is, however, possible to deactivate some of the dependencies in the + Makefile, resulting in features in Yosys becoming unavailable. When + problems with building Yosys are encountered, a user who is only + interested in the features of Yosys that are discussed in this + Application Note may deactivate TCL, Qt and MiniSAT support in the + Makefile and may opt against building yosys-abc. -This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_ from 2013-11-23. -The Verilog sources used for the examples are taken from `yosys-bigsim`_, a -collection of real-world designs used for regression testing Yosys. + This Application Note is based on `Yosys GIT`_ `Rev. e216e0e`_ from 2013-11-23. + The Verilog sources used for the examples are taken from `yosys-bigsim`_, a + collection of real-world designs used for regression testing Yosys. -.. _Yosys GIT: https://github.com/YosysHQ/yosys + .. _Yosys GIT: https://github.com/YosysHQ/yosys -.. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e + .. _Rev. e216e0e: https://github.com/YosysHQ/yosys/tree/e216e0e -.. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim + .. _yosys-bigsim: https://github.com/YosysHQ/yosys-bigsim -Getting started -=============== + Getting started + =============== -We start our tour with the Navré processor from yosys-bigsim. The `Navré -processor`_ is an Open Source AVR clone. It is a single module (softusb_navre) -in a single design file (softusb_navre.v). It also is using only features that -map nicely to the BLIF format, for example it only uses synchronous resets. + We start our tour with the Navré processor from yosys-bigsim. The `Navré + processor`_ is an Open Source AVR clone. It is a single module (softusb_navre) + in a single design file (softusb_navre.v). It also is using only features that + map nicely to the BLIF format, for example it only uses synchronous resets. -.. _Navré processor: http://opencores.org/projects/navre - -Converting softusb_navre.v to softusb_navre.blif could not be easier: + .. _Navré processor: http://opencores.org/projects/navre + + Converting softusb_navre.v to softusb_navre.blif could not be easier: -.. code:: sh + .. code:: sh - yosys -o softusb_navre.blif -S softusb_navre.v + yosys -o softusb_navre.blif -S softusb_navre.v -Behind the scenes Yosys is controlled by synthesis scripts that execute -commands that operate on Yosys' internal state. For example, the -o -softusb_navre.blif option just adds the command write_blif -softusb_navre.blif to the end of the script. Likewise a file on the -command line – softusb_navre.v in this case – adds the command -read_verilog softusb_navre.v to the beginning of the synthesis script. -In both cases the file type is detected from the file extension. + Behind the scenes Yosys is controlled by synthesis scripts that execute + commands that operate on Yosys' internal state. For example, the -o + softusb_navre.blif option just adds the command write_blif + softusb_navre.blif to the end of the script. Likewise a file on the + command line – softusb_navre.v in this case – adds the command + read_verilog softusb_navre.v to the beginning of the synthesis script. + In both cases the file type is detected from the file extension. -Finally the option -S instantiates a built-in default synthesis script. -Instead of using -S one could also specify the synthesis commands for -the script on the command line using the -p option, either using -individual options for each command or by passing one big command string -with a semicolon-separated list of commands. But in most cases it is -more convenient to use an actual script file. + Finally the option -S instantiates a built-in default synthesis script. + Instead of using -S one could also specify the synthesis commands for + the script on the command line using the -p option, either using + individual options for each command or by passing one big command string + with a semicolon-separated list of commands. But in most cases it is + more convenient to use an actual script file. -Using a synthesis script -======================== + Using a synthesis script + ======================== -With a script file we have better control over Yosys. The following -script file replicates what the command from the last section did: + With a script file we have better control over Yosys. The following + script file replicates what the command from the last section did: -.. code:: yoscrypt + .. code:: yoscrypt - read_verilog softusb_navre.v - hierarchy - proc; opt; memory; opt; techmap; opt - write_blif softusb_navre.blif - -The first and last line obviously read the Verilog file and write the -BLIF file. - -The 2nd line checks the design hierarchy and instantiates parametrized -versions of the modules in the design, if necessary. In the case of this -simple design this is a no-op. However, as a general rule a synthesis -script should always contain this command as first command after reading -the input files. - -The 3rd line does most of the actual work: - -- The command opt is the Yosys' built-in optimizer. It can perform some - simple optimizations such as const-folding and removing unconnected - parts of the design. It is common practice to call opt after each - major step in the synthesis procedure. In cases where too much - optimization is not appreciated (for example when analyzing a - design), it is recommended to call clean instead of opt. - -- The command proc converts processes (Yosys' internal representation - of Verilog always- and initial-blocks) to circuits of multiplexers - and storage elements (various types of flip-flops). - -- The command memory converts Yosys' internal representations of arrays - and array accesses to multi-port block memories, and then maps this - block memories to address decoders and flip-flops, unless the option - -nomap is used, in which case the multi-port block memories stay in - the design and can then be mapped to architecture-specific memory - primitives using other commands. - -- The command techmap turns a high-level circuit with coarse grain - cells such as wide adders and multipliers to a fine-grain circuit of - simple logic primitives and single-bit storage elements. The command - does that by substituting the complex cells by circuits of simpler - cells. It is possible to provide a custom set of rules for this - process in the form of a Verilog source file, as we will see in the - next section. - -Now Yosys can be run with the filename of the synthesis script as -argument: - -.. code:: sh - - yosys softusb_navre.ys - -Now that we are using a synthesis script we can easily modify how Yosys -synthesizes the design. The first thing we should customize is the call -to the hierarchy command: - -Whenever it is known that there are no implicit blackboxes in the -design, i.e. modules that are referenced but are not defined, the -hierarchy command should be called with the -check option. This will -then cause synthesis to fail when implicit blackboxes are found in the -design. - -The 2nd thing we can improve regarding the hierarchy command is that we -can tell it the name of the top level module of the design hierarchy. It -will then automatically remove all modules that are not referenced from -this top level module. - -For many designs it is also desired to optimize the encodings for the -finite state machines (FSMs) in the design. The fsm command finds FSMs, -extracts them, performs some basic optimizations and then generate a -circuit from the extracted and optimized description. It would also be -possible to tell the fsm command to leave the FSMs in their extracted -form, so they can be further processed using custom commands. But in -this case we don't want that. - -So now we have the final synthesis script for generating a BLIF file for -the Navré CPU: - -.. code:: yoscrypt - - read_verilog softusb_navre.v - hierarchy -check -top softusb_navre - proc; opt; memory; opt; fsm; opt; techmap; opt - write_blif softusb_navre.blif - -Advanced example: The Amber23 ARMv2a CPU -======================================== - -Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on -the Verilog code that is included in `yosys-bigsim`_. - -.. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber - -.. code-block:: yoscrypt - :caption: `amber23.ys` - :name: amber23.ys - - read_verilog a23_alu.v - read_verilog a23_barrel_shift_fpga.v - read_verilog a23_barrel_shift.v - read_verilog a23_cache.v - read_verilog a23_coprocessor.v - read_verilog a23_core.v - read_verilog a23_decode.v - read_verilog a23_execute.v - read_verilog a23_fetch.v - read_verilog a23_multiply.v - read_verilog a23_ram_register_bank.v - read_verilog a23_register_bank.v - read_verilog a23_wishbone.v - read_verilog generic_sram_byte_en.v - read_verilog generic_sram_line_en.v - hierarchy -check -top a23_core - add -global_input globrst 1 - proc -global_arst globrst - techmap -map adff2dff.v - opt; memory; opt; fsm; opt; techmap - write_blif amber23.blif - -The problem with this core is that it contains no dedicated reset logic. Instead -the coding techniques shown in :numref:`glob_arst` are used to define reset -values for the global asynchronous reset in an FPGA implementation. This design -can not be expressed in BLIF as it is. Instead we need to use a synthesis script -that transforms this form to synchronous resets that can be expressed in BLIF. - -(Note that there is no problem if this coding techniques are used to model ROM, -where the register is initialized using this syntax but is never updated -otherwise.) - -:numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17 -the add command is used to add a 1-bit wide global input signal with the name -``globrst``. That means that an input with that name is added to each module in the -design hierarchy and then all module instantiations are altered so that this new -signal is connected throughout the whole design hierarchy. - -.. code-block:: verilog - :caption: Implicit coding of global asynchronous resets - :name: glob_arst - - reg [7:0] a = 13, b; - initial b = 37; - -.. code-block:: verilog - :caption: `adff2dff.v` - :name: adff2dff.v - - (* techmap_celltype = "$adff" *) - module adff2dff (CLK, ARST, D, Q); - - parameter WIDTH = 1; - parameter CLK_POLARITY = 1; - parameter ARST_POLARITY = 1; - parameter ARST_VALUE = 0; - - input CLK, ARST; - input [WIDTH-1:0] D; - output reg [WIDTH-1:0] Q; - - wire [1023:0] _TECHMAP_DO_ = "proc"; - - wire _TECHMAP_FAIL_ = - !CLK_POLARITY || !ARST_POLARITY; - - always @(posedge CLK) - if (ARST) - Q <= ARST_VALUE; - else - Q <= D; - - endmodule - -In line 18 the :cmd:ref:`proc` command is called. But in this script the signal -name globrst is passed to the command as a global reset signal for resetting the -registers to their assigned initial values. - -Finally in line 19 the techmap command is used to replace all instances of -flip-flops with asynchronous resets with flip-flops with synchronous resets. The -map file used for this is shown in :numref:`adff2dff.v`. Note how the -``techmap_celltype`` attribute is used in line 1 to tell the techmap command -which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines -15 and 16 (which evaluates to a constant value) determines if the parameter set -is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire -in line 13 provides a mini synthesis-script to be used to process this cell. - -.. code-block:: c - :caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled - using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a - -mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx`` - set and booted with a custom setup routine written in ARM assembler. - :name: sieve - - #include - #include - - #define BITMAP_SIZE 64 - #define OUTPORT 0x10000000 - - static uint32_t bitmap[BITMAP_SIZE/32]; - - static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); } - static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; } - static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; } - - int main() { - uint32_t i, j, k; - output(2); - for (i = 0; i < BITMAP_SIZE; i++) { - if (bitmap_get(i)) continue; - output(3+2*i); - for (j = 2*(3+2*i);; j += 3+2*i) { - if (j%2 == 0) continue; - k = (j-3)/2; - if (k >= BITMAP_SIZE) break; - bitmap_set(k); - } - } - output(0); - return 0; - } - -Verification of the Amber23 CPU -=============================== - -The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and -:numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled -with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It -successfully executed the program shown in :numref:`sieve` in the test-bench. - -For simulation the BLIF file was converted back to Verilog using `ABC`_. So this -test includes the successful transformation of the BLIF file into ABC's internal -format as well. - -.. _ABC: https://github.com/berkeley-abc/abc - -The only thing left to write about the simulation itself is that it probably was -one of the most energy inefficient and time consuming ways of successfully -calculating the first 31 primes the author has ever conducted. - -Limitations -=========== - -At the time of this writing Yosys does not support multi-dimensional memories, -does not support writing to individual bits of array elements, does not support -initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only -limited support for tristate logic, to name just a few limitations. - -That being said, Yosys can synthesize an overwhelming majority of real-world -Verilog RTL code. The remaining cases can usually be modified to be compatible -with Yosys quite easily. - -The various designs in yosys-bigsim are a good place to look for examples of -what is within the capabilities of Yosys. - -Conclusion -========== - -Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one -is to provide an easy gateway from high-level Verilog code to low-level logic -circuits. - -The command line option ``-S`` can be used to quickly synthesize Verilog code to -BLIF files without a hassle. - -With custom synthesis scripts it becomes possible to easily perform high-level -optimizations, such as re-encoding FSMs. In some extreme cases, such as the -Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a -design to fit a certain need without actually touching the RTL code. + read_verilog softusb_navre.v + hierarchy + proc; opt; memory; opt; techmap; opt + write_blif softusb_navre.blif + + The first and last line obviously read the Verilog file and write the + BLIF file. + + The 2nd line checks the design hierarchy and instantiates parametrized + versions of the modules in the design, if necessary. In the case of this + simple design this is a no-op. However, as a general rule a synthesis + script should always contain this command as first command after reading + the input files. + + The 3rd line does most of the actual work: + + - The command opt is the Yosys' built-in optimizer. It can perform some + simple optimizations such as const-folding and removing unconnected + parts of the design. It is common practice to call opt after each + major step in the synthesis procedure. In cases where too much + optimization is not appreciated (for example when analyzing a + design), it is recommended to call clean instead of opt. + + - The command proc converts processes (Yosys' internal representation + of Verilog always- and initial-blocks) to circuits of multiplexers + and storage elements (various types of flip-flops). + + - The command memory converts Yosys' internal representations of arrays + and array accesses to multi-port block memories, and then maps this + block memories to address decoders and flip-flops, unless the option + -nomap is used, in which case the multi-port block memories stay in + the design and can then be mapped to architecture-specific memory + primitives using other commands. + + - The command techmap turns a high-level circuit with coarse grain + cells such as wide adders and multipliers to a fine-grain circuit of + simple logic primitives and single-bit storage elements. The command + does that by substituting the complex cells by circuits of simpler + cells. It is possible to provide a custom set of rules for this + process in the form of a Verilog source file, as we will see in the + next section. + + Now Yosys can be run with the filename of the synthesis script as + argument: + + .. code:: sh + + yosys softusb_navre.ys + + Now that we are using a synthesis script we can easily modify how Yosys + synthesizes the design. The first thing we should customize is the call + to the hierarchy command: + + Whenever it is known that there are no implicit blackboxes in the + design, i.e. modules that are referenced but are not defined, the + hierarchy command should be called with the -check option. This will + then cause synthesis to fail when implicit blackboxes are found in the + design. + + The 2nd thing we can improve regarding the hierarchy command is that we + can tell it the name of the top level module of the design hierarchy. It + will then automatically remove all modules that are not referenced from + this top level module. + + For many designs it is also desired to optimize the encodings for the + finite state machines (FSMs) in the design. The fsm command finds FSMs, + extracts them, performs some basic optimizations and then generate a + circuit from the extracted and optimized description. It would also be + possible to tell the fsm command to leave the FSMs in their extracted + form, so they can be further processed using custom commands. But in + this case we don't want that. + + So now we have the final synthesis script for generating a BLIF file for + the Navré CPU: + + .. code:: yoscrypt + + read_verilog softusb_navre.v + hierarchy -check -top softusb_navre + proc; opt; memory; opt; fsm; opt; techmap; opt + write_blif softusb_navre.blif + + Advanced example: The Amber23 ARMv2a CPU + ======================================== + + Our 2nd example is the `Amber23 ARMv2a CPU`_. Once again we base our example on + the Verilog code that is included in `yosys-bigsim`_. + + .. _Amber23 ARMv2a CPU: http://opencores.org/projects/amber + + .. code-block:: yoscrypt + :caption: `amber23.ys` + :name: amber23.ys + + read_verilog a23_alu.v + read_verilog a23_barrel_shift_fpga.v + read_verilog a23_barrel_shift.v + read_verilog a23_cache.v + read_verilog a23_coprocessor.v + read_verilog a23_core.v + read_verilog a23_decode.v + read_verilog a23_execute.v + read_verilog a23_fetch.v + read_verilog a23_multiply.v + read_verilog a23_ram_register_bank.v + read_verilog a23_register_bank.v + read_verilog a23_wishbone.v + read_verilog generic_sram_byte_en.v + read_verilog generic_sram_line_en.v + hierarchy -check -top a23_core + add -global_input globrst 1 + proc -global_arst globrst + techmap -map adff2dff.v + opt; memory; opt; fsm; opt; techmap + write_blif amber23.blif + + The problem with this core is that it contains no dedicated reset logic. Instead + the coding techniques shown in :numref:`glob_arst` are used to define reset + values for the global asynchronous reset in an FPGA implementation. This design + can not be expressed in BLIF as it is. Instead we need to use a synthesis script + that transforms this form to synchronous resets that can be expressed in BLIF. + + (Note that there is no problem if this coding techniques are used to model ROM, + where the register is initialized using this syntax but is never updated + otherwise.) + + :numref:`amber23.ys` shows the synthesis script for the Amber23 core. In line 17 + the add command is used to add a 1-bit wide global input signal with the name + ``globrst``. That means that an input with that name is added to each module in the + design hierarchy and then all module instantiations are altered so that this new + signal is connected throughout the whole design hierarchy. + + .. code-block:: verilog + :caption: Implicit coding of global asynchronous resets + :name: glob_arst + + reg [7:0] a = 13, b; + initial b = 37; + + .. code-block:: verilog + :caption: `adff2dff.v` + :name: adff2dff.v + + (* techmap_celltype = "$adff" *) + module adff2dff (CLK, ARST, D, Q); + + parameter WIDTH = 1; + parameter CLK_POLARITY = 1; + parameter ARST_POLARITY = 1; + parameter ARST_VALUE = 0; + + input CLK, ARST; + input [WIDTH-1:0] D; + output reg [WIDTH-1:0] Q; + + wire [1023:0] _TECHMAP_DO_ = "proc"; + + wire _TECHMAP_FAIL_ = + !CLK_POLARITY || !ARST_POLARITY; + + always @(posedge CLK) + if (ARST) + Q <= ARST_VALUE; + else + Q <= D; + + endmodule + + In line 18 the :cmd:ref:`proc` command is called. But in this script the signal + name globrst is passed to the command as a global reset signal for resetting the + registers to their assigned initial values. + + Finally in line 19 the techmap command is used to replace all instances of + flip-flops with asynchronous resets with flip-flops with synchronous resets. The + map file used for this is shown in :numref:`adff2dff.v`. Note how the + ``techmap_celltype`` attribute is used in line 1 to tell the techmap command + which cells to replace in the design, how the ``_TECHMAP_FAIL_`` wire in lines + 15 and 16 (which evaluates to a constant value) determines if the parameter set + is compatible with this replacement circuit, and how the ``_TECHMAP_DO_`` wire + in line 13 provides a mini synthesis-script to be used to process this cell. + + .. code-block:: c + :caption: Test program for the Amber23 CPU (Sieve of Eratosthenes). Compiled + using GCC 4.6.3 for ARM with ``-Os -marm -march=armv2a + -mno-thumb-interwork -ffreestanding``, linked with ``--fix-v4bx`` + set and booted with a custom setup routine written in ARM assembler. + :name: sieve + + #include + #include + + #define BITMAP_SIZE 64 + #define OUTPORT 0x10000000 + + static uint32_t bitmap[BITMAP_SIZE/32]; + + static void bitmap_set(uint32_t idx) { bitmap[idx/32] |= 1 << (idx % 32); } + static bool bitmap_get(uint32_t idx) { return (bitmap[idx/32] & (1 << (idx % 32))) != 0; } + static void output(uint32_t val) { *((volatile uint32_t*)OUTPORT) = val; } + + int main() { + uint32_t i, j, k; + output(2); + for (i = 0; i < BITMAP_SIZE; i++) { + if (bitmap_get(i)) continue; + output(3+2*i); + for (j = 2*(3+2*i);; j += 3+2*i) { + if (j%2 == 0) continue; + k = (j-3)/2; + if (k >= BITMAP_SIZE) break; + bitmap_set(k); + } + } + output(0); + return 0; + } + + Verification of the Amber23 CPU + =============================== + + The BLIF file for the Amber23 core, generated using :numref:`amber23.ys` and + :numref:`adff2dff.v` and the version of the Amber23 RTL source that is bundled + with yosys-bigsim, was verified using the test-bench from yosys-bigsim. It + successfully executed the program shown in :numref:`sieve` in the test-bench. + + For simulation the BLIF file was converted back to Verilog using `ABC`_. So this + test includes the successful transformation of the BLIF file into ABC's internal + format as well. + + .. _ABC: https://github.com/berkeley-abc/abc + + The only thing left to write about the simulation itself is that it probably was + one of the most energy inefficient and time consuming ways of successfully + calculating the first 31 primes the author has ever conducted. + + Limitations + =========== + + At the time of this writing Yosys does not support multi-dimensional memories, + does not support writing to individual bits of array elements, does not support + initialization of arrays with ``$readmemb`` and ``$readmemh``, and has only + limited support for tristate logic, to name just a few limitations. + + That being said, Yosys can synthesize an overwhelming majority of real-world + Verilog RTL code. The remaining cases can usually be modified to be compatible + with Yosys quite easily. + + The various designs in yosys-bigsim are a good place to look for examples of + what is within the capabilities of Yosys. + + Conclusion + ========== + + Yosys is a feature-rich Verilog-2005 synthesis tool. It has many uses, but one + is to provide an easy gateway from high-level Verilog code to low-level logic + circuits. + + The command line option ``-S`` can be used to quickly synthesize Verilog code to + BLIF files without a hassle. + + With custom synthesis scripts it becomes possible to easily perform high-level + optimizations, such as re-encoding FSMs. In some extreme cases, such as the + Amber23 ARMv2 CPU, the more advanced Yosys features can be used to change a + design to fit a certain need without actually touching the RTL code. diff --git a/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst index adb551494ba..1874b014813 100644 --- a/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst +++ b/docs/source/appendix/APPNOTE_012_Verilog_to_BTOR.rst @@ -1,333 +1,353 @@ +:orphan: + ==================================== 012: Converting Verilog to BTOR page ==================================== -Installation -============ +Abstract +======== + +Verilog-2005 is a powerful Hardware Description Language (HDL) that can be used +to easily create complex designs from small HDL code. BTOR is a bit-precise +word-level format for model checking. It is a simple format and easy to parse. +It allows to model the model checking problem over the theory of bit-vectors +with one-dimensional arrays, thus enabling to model Verilog designs with +registers and memories. Yosys is an Open-Source Verilog synthesis tool that can +be used to convert Verilog designs with simple assertions to BTOR format. + +Download +======== + +This document was originally published in November 2013: +:download:`Converting Verilog to BTOR PDF` + +.. + Installation + ============ -Yosys written in C++ (using features from C++11) and is tested on modern Linux. -It should compile fine on most UNIX systems with a C++11 compiler. The README -file contains useful information on building Yosys and its prerequisites. + Yosys written in C++ (using features from C++11) and is tested on modern Linux. + It should compile fine on most UNIX systems with a C++11 compiler. The README + file contains useful information on building Yosys and its prerequisites. -Yosys is a large and feature-rich program with some dependencies. For this work, -we may deactivate other extra features such as TCL and ABC support in the -Makefile. + Yosys is a large and feature-rich program with some dependencies. For this work, + we may deactivate other extra features such as TCL and ABC support in the + Makefile. -This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04. + This Application Note is based on `Yosys GIT`_ `Rev. 082550f` from 2015-04-04. -.. _Yosys GIT: https://github.com/YosysHQ/yosys + .. _Yosys GIT: https://github.com/YosysHQ/yosys -.. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f + .. _Rev. 082550f: https://github.com/YosysHQ/yosys/tree/082550f -Quick start -=========== + Quick start + =========== -We assume that the Verilog design is synthesizable and we also assume that the -design does not have multi-dimensional memories. As BTOR implicitly initializes -registers to zero value and memories stay uninitialized, we assume that the -Verilog design does not contain initial blocks. For more details about the BTOR -format, please refer to :cite:p:`btor`. + We assume that the Verilog design is synthesizable and we also assume that the + design does not have multi-dimensional memories. As BTOR implicitly initializes + registers to zero value and memories stay uninitialized, we assume that the + Verilog design does not contain initial blocks. For more details about the BTOR + format, please refer to :cite:p:`btor`. -We provide a shell script ``verilog2btor.sh`` which can be used to convert a -Verilog design to BTOR. The script can be found in the ``backends/btor`` -directory. The following example shows its usage: + We provide a shell script ``verilog2btor.sh`` which can be used to convert a + Verilog design to BTOR. The script can be found in the ``backends/btor`` + directory. The following example shows its usage: -.. code:: sh + .. code:: sh - verilog2btor.sh fsm.v fsm.btor test + verilog2btor.sh fsm.v fsm.btor test -The script ``verilog2btor.sh`` takes three parameters. In the above example, the -first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor`` -is the file name of BTOR output, and the third parameter ``test`` is the name of -top module in the design. + The script ``verilog2btor.sh`` takes three parameters. In the above example, the + first parameter ``fsm.v`` is the input design, the second parameter ``fsm.btor`` + is the file name of BTOR output, and the third parameter ``test`` is the name of + top module in the design. -To specify the properties (that need to be checked), we have two -options: + To specify the properties (that need to be checked), we have two + options: -- We can use the Verilog ``assert`` statement in the procedural block or module - body of the Verilog design, as shown in :numref:`specifying_property_assert`. - This is the preferred option. + - We can use the Verilog ``assert`` statement in the procedural block or module + body of the Verilog design, as shown in :numref:`specifying_property_assert`. + This is the preferred option. -- We can use a single-bit output wire, whose name starts with ``safety``. The - value of this output wire needs to be driven low when the property is met, - i.e. the solver will try to find a model that makes the safety pin go high. - This is demonstrated in :numref:`specifying_property_output`. + - We can use a single-bit output wire, whose name starts with ``safety``. The + value of this output wire needs to be driven low when the property is met, + i.e. the solver will try to find a model that makes the safety pin go high. + This is demonstrated in :numref:`specifying_property_output`. -.. code-block:: verilog - :caption: Specifying property in Verilog design with ``assert`` - :name: specifying_property_assert + .. code-block:: verilog + :caption: Specifying property in Verilog design with ``assert`` + :name: specifying_property_assert - module test(input clk, input rst, output y); + module test(input clk, input rst, output y); - reg [2:0] state; + reg [2:0] state; - always @(posedge clk) begin - if (rst || state == 3) begin - state <= 0; - end else begin - assert(state < 3); - state <= state + 1; - end - end + always @(posedge clk) begin + if (rst || state == 3) begin + state <= 0; + end else begin + assert(state < 3); + state <= state + 1; + end + end - assign y = state[2]; + assign y = state[2]; - assert property (y !== 1'b1); + assert property (y !== 1'b1); - endmodule + endmodule -.. code-block:: verilog - :caption: Specifying property in Verilog design with output wire - :name: specifying_property_output + .. code-block:: verilog + :caption: Specifying property in Verilog design with output wire + :name: specifying_property_output - module test(input clk, input rst, - output y, output safety1); + module test(input clk, input rst, + output y, output safety1); - reg [2:0] state; + reg [2:0] state; - always @(posedge clk) begin - if (rst || state == 3) - state <= 0; - else - state <= state + 1; - end + always @(posedge clk) begin + if (rst || state == 3) + state <= 0; + else + state <= state + 1; + end - assign y = state[2]; + assign y = state[2]; - assign safety1 = !(y !== 1'b1); + assign safety1 = !(y !== 1'b1); - endmodule + endmodule -We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file: + We can run `Boolector`_ ``1.4.1`` [1]_ on the generated BTOR file: -.. _Boolector: http://fmv.jku.at/boolector/ + .. _Boolector: http://fmv.jku.at/boolector/ -.. code:: sh + .. code:: sh - $ boolector fsm.btor - unsat + $ boolector fsm.btor + unsat -We can also use `nuXmv`_, but on BTOR designs it does not support memories yet. -With the next release of nuXmv, we will be also able to verify designs with -memories. + We can also use `nuXmv`_, but on BTOR designs it does not support memories yet. + With the next release of nuXmv, we will be also able to verify designs with + memories. -.. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php + .. _nuXmv: https://es-static.fbk.eu/tools/nuxmv/index.php -Detailed flow -============= + Detailed flow + ============= -Yosys is able to synthesize Verilog designs up to the gate level. We are -interested in keeping registers and memories when synthesizing the design. For -this purpose, we describe a customized Yosys synthesis flow, that is also -provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows -the Yosys commands that are executed by ``verilog2btor.sh``. + Yosys is able to synthesize Verilog designs up to the gate level. We are + interested in keeping registers and memories when synthesizing the design. For + this purpose, we describe a customized Yosys synthesis flow, that is also + provided by the ``verilog2btor.sh`` script. :numref:`btor_script_memory` shows + the Yosys commands that are executed by ``verilog2btor.sh``. -.. code-block:: yoscrypt - :caption: Synthesis Flow for BTOR with memories - :name: btor_script_memory + .. code-block:: yoscrypt + :caption: Synthesis Flow for BTOR with memories + :name: btor_script_memory - read_verilog -sv $1; - hierarchy -top $3; hierarchy -libdir $DIR; - hierarchy -check; - proc; opt; - opt_expr -mux_undef; opt; - rename -hide;;; - splice; opt; - memory_dff -wr_only; memory_collect;; - flatten;; - memory_unpack; - splitnets -driver; - setundef -zero -undriven; - opt;;; - write_btor $2; + read_verilog -sv $1; + hierarchy -top $3; hierarchy -libdir $DIR; + hierarchy -check; + proc; opt; + opt_expr -mux_undef; opt; + rename -hide;;; + splice; opt; + memory_dff -wr_only; memory_collect;; + flatten;; + memory_unpack; + splitnets -driver; + setundef -zero -undriven; + opt;;; + write_btor $2; -Here is short description of what is happening in the script line by -line: + Here is short description of what is happening in the script line by + line: -#. Reading the input file. + #. Reading the input file. -#. Setting the top module in the hierarchy and trying to read automatically the - files which are given as ``include`` in the file read in first line. + #. Setting the top module in the hierarchy and trying to read automatically the + files which are given as ``include`` in the file read in first line. -#. Checking the design hierarchy. + #. Checking the design hierarchy. -#. Converting processes to multiplexers (muxs) and flip-flops. + #. Converting processes to multiplexers (muxs) and flip-flops. -#. Removing undef signals from muxs. + #. Removing undef signals from muxs. -#. Hiding all signal names that are not used as module ports. + #. Hiding all signal names that are not used as module ports. -#. Explicit type conversion, by introducing slice and concat cells in the - circuit. + #. Explicit type conversion, by introducing slice and concat cells in the + circuit. -#. Converting write memories to synchronous memories, and collecting the - memories to multi-port memories. + #. Converting write memories to synchronous memories, and collecting the + memories to multi-port memories. -#. Flattening the design to get only one module. + #. Flattening the design to get only one module. -#. Separating read and write memories. + #. Separating read and write memories. -#. Splitting the signals that are partially assigned + #. Splitting the signals that are partially assigned -#. Setting undef to zero value. + #. Setting undef to zero value. -#. Final optimization pass. + #. Final optimization pass. -#. Writing BTOR file. + #. Writing BTOR file. -For detailed description of the commands mentioned above, please refer -to the Yosys documentation, or run ``yosys -h ``. - -The script presented earlier can be easily modified to have a BTOR file that -does not contain memories. This is done by removing the line number 8 and 10, -and introduces a new command :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. + For detailed description of the commands mentioned above, please refer + to the Yosys documentation, or run ``yosys -h ``. + + The script presented earlier can be easily modified to have a BTOR file that + does not contain memories. This is done by removing the line number 8 and 10, + and introduces a new command :cmd:ref:`memory` at line number 8. + :numref:`btor_script_without_memory` shows the modified Yosys script file: + + .. code-block:: sh + :caption: Synthesis Flow for BTOR without memories + :name: btor_script_without_memory + + read_verilog -sv $1; + hierarchy -top $3; hierarchy -libdir $DIR; + hierarchy -check; + proc; opt; + opt_expr -mux_undef; opt; + rename -hide;;; + splice; opt; + memory;; + flatten;; + splitnets -driver; + setundef -zero -undriven; + opt;;; + write_btor $2; + + Example + ======= + + Here is an example Verilog design that we want to convert to BTOR: + + .. code-block:: verilog + :caption: Example - Verilog Design + :name: example_verilog + + module array(input clk); + + reg [7:0] counter; + reg [7:0] mem [7:0]; + + always @(posedge clk) begin + counter <= counter + 8'd1; + mem[counter] <= counter; + end + + assert property (!(counter > 8'd0) || + mem[counter - 8'd1] == counter - 8'd1); + + endmodule + + The generated BTOR file that contain memories, using the script shown in + :numref:`btor_memory`: + + .. code-block:: + :caption: Example - Converted BTOR with memory + :name: btor_memory + + 1 var 1 clk + 2 array 8 3 + 3 var 8 $auto$rename.cc:150:execute$20 + 4 const 8 00000001 + 5 sub 8 3 4 + 6 slice 3 5 2 0 + 7 read 8 2 6 + 8 slice 3 3 2 0 + 9 add 8 3 4 + 10 const 8 00000000 + 11 ugt 1 3 10 + 12 not 1 11 + 13 const 8 11111111 + 14 slice 1 13 0 0 + 15 one 1 + 16 eq 1 1 15 + 17 and 1 16 14 + 18 write 8 3 2 8 3 + 19 acond 8 3 17 18 2 + 20 anext 8 3 2 19 + 21 eq 1 7 5 + 22 or 1 12 21 + 23 const 1 1 + 24 one 1 + 25 eq 1 23 24 + 26 cond 1 25 22 24 + 27 root 1 -26 + 28 cond 8 1 9 3 + 29 next 8 3 28 + + And the BTOR file obtained by the script shown in + :numref:`btor_without_memory`, which expands the memory into individual + elements: + + .. code-block:: + :caption: Example - Converted BTOR with memory + :name: btor_without_memory + + 1 var 1 clk + 2 var 8 mem[0] + 3 var 8 $auto$rename.cc:150:execute$20 + 4 slice 3 3 2 0 + 5 slice 1 4 0 0 + 6 not 1 5 + 7 slice 1 4 1 1 + 8 not 1 7 + 9 slice 1 4 2 2 + 10 not 1 9 + 11 and 1 8 10 + 12 and 1 6 11 + 13 cond 8 12 3 2 + 14 cond 8 1 13 2 + 15 next 8 2 14 + 16 const 8 00000001 + 17 add 8 3 16 + 18 const 8 00000000 + 19 ugt 1 3 18 + 20 not 1 19 + 21 var 8 mem[2] + 22 and 1 7 10 + 23 and 1 6 22 + 24 cond 8 23 3 21 + 25 cond 8 1 24 21 + 26 next 8 21 25 + 27 sub 8 3 16 + + ... + + 54 cond 1 53 50 52 + 55 root 1 -54 + + ... + + 77 cond 8 76 3 44 + 78 cond 8 1 77 44 + 79 next 8 44 78 + + Limitations + =========== + + BTOR does not support initialization of memories and registers, i.e. they are + implicitly initialized to value zero, so the initial block for memories need to + be removed when converting to BTOR. It should also be kept in consideration that + BTOR does not support the ``x`` or ``z`` values of Verilog. + + Another thing to bear in mind is that Yosys will convert multi-dimensional + memories to one-dimensional memories and address decoders. Therefore + out-of-bounds memory accesses can yield unexpected results. + + Conclusion + ========== + + Using the described flow, we can use Yosys to generate word-level verification + benchmarks with or without memories from Verilog designs. + + .. [1] + Newer version of Boolector do not support sequential models. + Boolector 1.4.1 can be built with picosat-951. Newer versions of + picosat have an incompatible API. 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 06b93bb9053..7d4243faffb 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 ad01d1630c5..4e6a2cce1c1 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 2f443c041da..86163464800 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 9071abfd1b3..a80e8f53569 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 a80e8f53569..41570b086fe 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 6a3f8802ec2..62c76584dd7 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 4437a4796e3..f3c9c92f92d 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 68d023d64cd..ec9f2b8d0b2 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 a7f1d843b62..8b5c1068120 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 da2e8e2dc8d..62485f150ab 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 86163464800..a77eb8b3ffc 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 41570b086fe..6b2d04d7186 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 d0e41561aad..f0a7795b641 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 $( 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 0b8cb96dd2e..8418aefdeb0 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 4e6a2cce1c1..2ac717f0523 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 fc6ba69025c..00000000000 --- 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 3af2b845158..00000000000 --- 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 afd84c3c65d..00000000000 --- 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 8db0a88a5fb..00000000000 --- 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 b4a858a0134..00000000000 --- 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 c3cbb8c5185..00000000000 --- 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 49c63008081..00000000000 --- 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="{{ A| B| Y}|$g0\nNOR|{}}" ]; -c11 [ shape=record, label="{{ A| Y}|$g1\nNOT|{}}" ]; -c12 [ shape=record, label="{{ A| Y}|$g2\nNOT|{}}" ]; -c13 [ shape=record, label="{{ A| B| Y}|$g3\nNOR|{}}" ]; -x0 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x0:e -> c13:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c14 [ shape=record, label="{{ A| B| Y}|$g4\nNOR|{}}" ]; -x1 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x1:e -> c14:p8:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -x2 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x2:e -> c14:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -n1 [ shape=diamond, label="$n4" ]; -n1:e -> c10:p9:w [color="black", label=""]; -n1:e -> c14:p7:w [color="black", label=""]; -n2 [ shape=diamond, label="$n5" ]; -n2:e -> c11:p9:w [color="black", label=""]; -n2:e -> c13:p7:w [color="black", label=""]; -n3 [ shape=diamond, label="$n6_1" ]; -n3:e -> c12:p9:w [color="black", label=""]; -n3:e -> c13:p8:w [color="black", label=""]; -n4:e -> c10:p8:w [color="black", label=""]; -n4:e -> c12:p7:w [color="black", label=""]; -n5:e -> c10:p7:w [color="black", label=""]; -n5:e -> c11:p7:w [color="black", label=""]; -n6:e -> x0:s0:w [color="black", label=""]; -n6:e -> x1:s0:w [color="black", label=""]; -n6:e -> x2:s0:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot b/docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot deleted file mode 100644 index ea6f4403ca8..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/cmos_01.dot +++ /dev/null @@ -1,23 +0,0 @@ -digraph "cmos_demo" { -rankdir="LR"; -remincross=true; -n4 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="y[0]", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="y[1]", color="black", fontcolor="black" ]; -c11 [ shape=record, label="{{ A| B}|$g0\nNOR|{ Y}}" ]; -c12 [ shape=record, label="{{ A}|$g1\nNOT|{ Y}}" ]; -c13 [ shape=record, label="{{ A}|$g2\nNOT|{ Y}}" ]; -c14 [ shape=record, label="{{ A| B}|$g3\nNOR|{ Y}}" ]; -c15 [ shape=record, label="{{ A| B}|$g4\nNOR|{ Y}}" ]; -c11:p10:e -> c15:p8:w [color="black", label=""]; -c12:p10:e -> c14:p8:w [color="black", label=""]; -c13:p10:e -> c14:p9:w [color="black", label=""]; -n4:e -> c11:p9:w [color="black", label=""]; -n4:e -> c13:p8:w [color="black", label=""]; -n5:e -> c11:p8:w [color="black", label=""]; -n5:e -> c12:p8:w [color="black", label=""]; -c15:p10:e -> n6:w [color="black", label=""]; -c14:p10:e -> n7:w [color="black", label=""]; -n7:e -> c15:p9:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_00.dot b/docs/source/APPNOTE_011_Design_Investigation/example_00.dot deleted file mode 100644 index 1e23ed0ead3..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_00.dot +++ /dev/null @@ -1,23 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -n4 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c12 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -v0 [ label="2'00" ]; -c14 [ shape=record, label="{{ A| B| S}|$3\n$mux|{ Y}}" ]; -p1 [shape=box, style=rounded, label="PROC $1\nexample.v:3"]; -c12:p11:e -> c14:p10:w [color="black", style="setlinewidth(3)", label=""]; -c14:p11:e -> p1:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c12:p9:w [color="black", label=""]; -n5:e -> c12:p10:w [color="black", label=""]; -n6:e -> c14:p13:w [color="black", label=""]; -n6:e -> p1:w [color="black", label=""]; -n7:e -> p1:w [color="black", label=""]; -p1:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -n8:e -> p1:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c14:p9:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_01.dot b/docs/source/APPNOTE_011_Design_Investigation/example_01.dot deleted file mode 100644 index e89292b51ac..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_01.dot +++ /dev/null @@ -1,33 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -n6 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n9 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n10 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c14 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -c18 [ shape=record, label="{{ CLK| D}|$7\n$dff|{ Q}}" ]; -c20 [ shape=record, label="{{ A| B| S}|$5\n$mux|{ Y}}" ]; -v0 [ label="2'00" ]; -c21 [ shape=record, label="{{ A| B| S}|$3\n$mux|{ Y}}" ]; -x1 [shape=box, style=rounded, label="BUF"]; -x2 [shape=box, style=rounded, label="BUF"]; -n1 [ shape=diamond, label="$0\\y[1:0]" ]; -x2:e:e -> n1:w [color="black", style="setlinewidth(3)", label=""]; -c18:p17:e -> n10:w [color="black", style="setlinewidth(3)", label=""]; -n10:e -> c20:p11:w [color="black", style="setlinewidth(3)", label=""]; -c14:p13:e -> c21:p12:w [color="black", style="setlinewidth(3)", label=""]; -n3 [ shape=point ]; -c20:p13:e -> n3:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c18:p16:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> x2:w:w [color="black", style="setlinewidth(3)", label=""]; -x1:e:e -> c20:p19:w [color="black", label=""]; -c21:p13:e -> c20:p12:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c14:p11:w [color="black", label=""]; -n7:e -> c14:p12:w [color="black", label=""]; -n8:e -> c21:p19:w [color="black", label=""]; -n8:e -> x1:w:w [color="black", label=""]; -n9:e -> c18:p15:w [color="black", label=""]; -v0:e -> c21:p11:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_02.dot b/docs/source/APPNOTE_011_Design_Investigation/example_02.dot deleted file mode 100644 index f950ed2ed2c..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_02.dot +++ /dev/null @@ -1,20 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -n3 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c11 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -c15 [ shape=record, label="{{ CLK| D}|$7\n$dff|{ Q}}" ]; -c17 [ shape=record, label="{{ A| B| S}|$5\n$mux|{ Y}}" ]; -c17:p10:e -> c15:p13:w [color="black", style="setlinewidth(3)", label=""]; -c11:p10:e -> c17:p9:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c11:p8:w [color="black", label=""]; -n4:e -> c11:p9:w [color="black", label=""]; -n5:e -> c17:p16:w [color="black", label=""]; -n6:e -> c15:p12:w [color="black", label=""]; -c15:p14:e -> n7:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c17:p8:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/example_03.dot b/docs/source/APPNOTE_011_Design_Investigation/example_03.dot deleted file mode 100644 index e19d24af78a..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/example_03.dot +++ /dev/null @@ -1,11 +0,0 @@ -digraph "example" { -rankdir="LR"; -remincross=true; -v0 [ label="a" ]; -v1 [ label="b" ]; -v2 [ label="$2_Y" ]; -c4 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -v0:e -> c4:p1:w [color="black", label=""]; -v1:e -> c4:p2:w [color="black", label=""]; -c4:p3:e -> v2:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/make.sh b/docs/source/APPNOTE_011_Design_Investigation/make.sh deleted file mode 100644 index 3845dac6b31..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/make.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -ex -if false; then - rm -f *.dot - ../../yosys example.ys - ../../yosys -p 'proc; opt; show -format dot -prefix splice' splice.v - ../../yosys -p 'techmap; abc -liberty ../../techlibs/cmos/cmos_cells.lib;; show -format dot -prefix cmos_00' cmos.v - ../../yosys -p 'techmap; splitnets -ports; abc -liberty ../../techlibs/cmos/cmos_cells.lib;; show -lib ../../techlibs/cmos/cmos_cells.v -format dot -prefix cmos_01' cmos.v - ../../yosys -p 'opt; cd sumprod; select a:sumstuff; show -format dot -prefix sumprod_00' sumprod.v - ../../yosys -p 'opt; cd sumprod; select a:sumstuff %x; show -format dot -prefix sumprod_01' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod; show -format dot -prefix sumprod_02' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod %ci; show -format dot -prefix sumprod_03' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod %ci2; show -format dot -prefix sumprod_04' sumprod.v - ../../yosys -p 'opt; cd sumprod; select prod %ci3; show -format dot -prefix sumprod_05' sumprod.v - ../../yosys -p 'proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_00' memdemo.v - ../../yosys -p 'proc; opt; memory; opt; cd memdemo; show -format dot -prefix memdemo_01 y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff' memdemo.v - ../../yosys submod.ys - sed -i '/^label=/ d;' *.dot -fi -for dot_file in *.dot; do - pdf_file=${dot_file%.dot}.pdf - dot -Tpdf -o $pdf_file $dot_file -done diff --git a/docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot b/docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot deleted file mode 100644 index 0336a9aac2a..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/memdemo_00.dot +++ /dev/null @@ -1,138 +0,0 @@ -digraph "memdemo" { -rankdir="LR"; -remincross=true; -n24 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n25 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n26 [ shape=diamond, label="mem[0]", color="black", fontcolor="black" ]; -n27 [ shape=diamond, label="mem[1]", color="black", fontcolor="black" ]; -n28 [ shape=diamond, label="mem[2]", color="black", fontcolor="black" ]; -n29 [ shape=diamond, label="mem[3]", color="black", fontcolor="black" ]; -n30 [ shape=diamond, label="s1", color="black", fontcolor="black" ]; -n31 [ shape=diamond, label="s2", color="black", fontcolor="black" ]; -n32 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c36 [ shape=record, label="{{ A| B}|$28\n$add|{ Y}}" ]; -c37 [ shape=record, label="{{ A| B}|$31\n$add|{ Y}}" ]; -c38 [ shape=record, label="{{ A| B}|$34\n$add|{ Y}}" ]; -c39 [ shape=record, label="{{ A| B}|$37\n$add|{ Y}}" ]; -c41 [ shape=record, label="{{ A| B| S}|$110\n$mux|{ Y}}" ]; -x0 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x0:e -> c41:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c42 [ shape=record, label="{{ A| B| S}|$113\n$mux|{ Y}}" ]; -x1 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x1:e -> c42:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c43 [ shape=record, label="{{ A| B| S}|$116\n$mux|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x2:e -> c43:p40:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -v3 [ label="1'1" ]; -c44 [ shape=record, label="{{ A| B}|$145\n$and|{ Y}}" ]; -v4 [ label="1'1" ]; -c45 [ shape=record, label="{{ A| B}|$175\n$and|{ Y}}" ]; -v5 [ label="1'1" ]; -c46 [ shape=record, label="{{ A| B}|$205\n$and|{ Y}}" ]; -v6 [ label="1'1" ]; -c47 [ shape=record, label="{{ A| B}|$235\n$and|{ Y}}" ]; -v7 [ label="2'00" ]; -c48 [ shape=record, label="{{ A| B}|$143\n$eq|{ Y}}" ]; -v8 [ label="2'01" ]; -c49 [ shape=record, label="{{ A| B}|$173\n$eq|{ Y}}" ]; -v9 [ label="2'10" ]; -c50 [ shape=record, label="{{ A| B}|$203\n$eq|{ Y}}" ]; -v10 [ label="2'11" ]; -c51 [ shape=record, label="{{ A| B}|$233\n$eq|{ Y}}" ]; -c52 [ shape=record, label="{{ A| B| S}|$147\n$mux|{ Y}}" ]; -c53 [ shape=record, label="{{ A| B| S}|$177\n$mux|{ Y}}" ]; -c54 [ shape=record, label="{{ A| B| S}|$207\n$mux|{ Y}}" ]; -c55 [ shape=record, label="{{ A| B| S}|$237\n$mux|{ Y}}" ]; -c59 [ shape=record, label="{{ CLK| D}|$66\n$dff|{ Q}}" ]; -c60 [ shape=record, label="{{ CLK| D}|$68\n$dff|{ Q}}" ]; -c61 [ shape=record, label="{{ CLK| D}|$70\n$dff|{ Q}}" ]; -c62 [ shape=record, label="{{ CLK| D}|$72\n$dff|{ Q}}" ]; -c63 [ shape=record, label="{{ CLK| D}|$59\n$dff|{ Q}}" ]; -c64 [ shape=record, label="{{ CLK| D}|$63\n$dff|{ Q}}" ]; -c65 [ shape=record, label="{{ CLK| D}|$64\n$dff|{ Q}}" ]; -c66 [ shape=record, label="{{ A}|$39\n$reduce_bool|{ Y}}" ]; -v11 [ label="4'0000" ]; -c67 [ shape=record, label="{{ A| B| S}|$40\n$mux|{ Y}}" ]; -x12 [ shape=record, style=rounded, label=" 3:2 - 1:0 | 1:0 - 1:0 " ]; -c67:p35:e -> x12:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c68 [ shape=record, label="{{ A| B}|$38\n$xor|{ Y}}" ]; -x13 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x13:e -> c68:p33:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c36:p35:e -> c52:p33:w [color="black", style="setlinewidth(3)", label=""]; -c44:p35:e -> c52:p40:w [color="black", label=""]; -c45:p35:e -> c53:p40:w [color="black", label=""]; -c46:p35:e -> c54:p40:w [color="black", label=""]; -c47:p35:e -> c55:p40:w [color="black", label=""]; -c48:p35:e -> c44:p33:w [color="black", label=""]; -c49:p35:e -> c45:p33:w [color="black", label=""]; -c50:p35:e -> c46:p33:w [color="black", label=""]; -c51:p35:e -> c47:p33:w [color="black", label=""]; -c52:p35:e -> c59:p57:w [color="black", style="setlinewidth(3)", label=""]; -c53:p35:e -> c60:p57:w [color="black", style="setlinewidth(3)", label=""]; -c37:p35:e -> c53:p33:w [color="black", style="setlinewidth(3)", label=""]; -c54:p35:e -> c61:p57:w [color="black", style="setlinewidth(3)", label=""]; -c55:p35:e -> c62:p57:w [color="black", style="setlinewidth(3)", label=""]; -c66:p35:e -> c67:p40:w [color="black", label=""]; -c68:p35:e -> c67:p34:w [color="black", style="setlinewidth(3)", label=""]; -n24:e -> c59:p56:w [color="black", label=""]; -n24:e -> c60:p56:w [color="black", label=""]; -n24:e -> c61:p56:w [color="black", label=""]; -n24:e -> c62:p56:w [color="black", label=""]; -n24:e -> c63:p56:w [color="black", label=""]; -n24:e -> c64:p56:w [color="black", label=""]; -n24:e -> c65:p56:w [color="black", label=""]; -n25:e -> c52:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c53:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c54:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c55:p34:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c66:p33:w [color="black", style="setlinewidth(3)", label=""]; -n25:e -> c68:p34:w [color="black", style="setlinewidth(3)", label=""]; -c59:p58:e -> n26:w [color="black", style="setlinewidth(3)", label=""]; -n26:e -> c38:p34:w [color="black", style="setlinewidth(3)", label=""]; -n26:e -> c39:p33:w [color="black", style="setlinewidth(3)", label=""]; -n26:e -> c42:p33:w [color="black", style="setlinewidth(3)", label=""]; -c60:p58:e -> n27:w [color="black", style="setlinewidth(3)", label=""]; -n27:e -> c36:p33:w [color="black", style="setlinewidth(3)", label=""]; -n27:e -> c39:p34:w [color="black", style="setlinewidth(3)", label=""]; -n27:e -> c42:p34:w [color="black", style="setlinewidth(3)", label=""]; -c61:p58:e -> n28:w [color="black", style="setlinewidth(3)", label=""]; -n28:e -> c36:p34:w [color="black", style="setlinewidth(3)", label=""]; -n28:e -> c37:p33:w [color="black", style="setlinewidth(3)", label=""]; -n28:e -> c43:p33:w [color="black", style="setlinewidth(3)", label=""]; -c62:p58:e -> n29:w [color="black", style="setlinewidth(3)", label=""]; -n29:e -> c37:p34:w [color="black", style="setlinewidth(3)", label=""]; -n29:e -> c38:p33:w [color="black", style="setlinewidth(3)", label=""]; -n29:e -> c43:p34:w [color="black", style="setlinewidth(3)", label=""]; -c38:p35:e -> c54:p33:w [color="black", style="setlinewidth(3)", label=""]; -c63:p58:e -> n30:w [color="black", style="setlinewidth(3)", label=""]; -n30:e -> x13:s1:w [color="black", style="setlinewidth(3)", label=""]; -c64:p58:e -> n31:w [color="black", style="setlinewidth(3)", label=""]; -n31:e -> x13:s0:w [color="black", style="setlinewidth(3)", label=""]; -c65:p58:e -> n32:w [color="black", style="setlinewidth(3)", label=""]; -c39:p35:e -> c55:p33:w [color="black", style="setlinewidth(3)", label=""]; -n5 [ shape=point ]; -x12:s0:e -> n5:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c48:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c49:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c50:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c51:p34:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c63:p57:w [color="black", style="setlinewidth(3)", label=""]; -n6 [ shape=point ]; -x12:s1:e -> n6:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c64:p57:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x0:s0:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x1:s0:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x2:s0:w [color="black", style="setlinewidth(3)", label=""]; -c41:p35:e -> c65:p57:w [color="black", style="setlinewidth(3)", label=""]; -c42:p35:e -> c41:p33:w [color="black", style="setlinewidth(3)", label=""]; -c43:p35:e -> c41:p34:w [color="black", style="setlinewidth(3)", label=""]; -v10:e -> c51:p33:w [color="black", style="setlinewidth(3)", label=""]; -v11:e -> c67:p33:w [color="black", style="setlinewidth(3)", label=""]; -v3:e -> c44:p34:w [color="black", label=""]; -v4:e -> c45:p34:w [color="black", label=""]; -v5:e -> c46:p34:w [color="black", label=""]; -v6:e -> c47:p34:w [color="black", label=""]; -v7:e -> c48:p33:w [color="black", style="setlinewidth(3)", label=""]; -v8:e -> c49:p33:w [color="black", style="setlinewidth(3)", label=""]; -v9:e -> c50:p33:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot b/docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot deleted file mode 100644 index 2ad92c78b2f..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/memdemo_01.dot +++ /dev/null @@ -1,29 +0,0 @@ -digraph "memdemo" { -rankdir="LR"; -remincross=true; -n4 [ shape=diamond, label="mem[0]", color="black", fontcolor="black" ]; -n5 [ shape=diamond, label="mem[1]", color="black", fontcolor="black" ]; -n6 [ shape=diamond, label="mem[2]", color="black", fontcolor="black" ]; -n7 [ shape=diamond, label="mem[3]", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -v0 [ label="$0\\s2[1:0] [1]" ]; -c13 [ shape=record, label="{{ A| B| S}|$110\n$mux|{ Y}}" ]; -v1 [ label="$0\\s2[1:0] [0]" ]; -c14 [ shape=record, label="{{ A| B| S}|$113\n$mux|{ Y}}" ]; -v2 [ label="$0\\s2[1:0] [0]" ]; -c15 [ shape=record, label="{{ A| B| S}|$116\n$mux|{ Y}}" ]; -v3 [ label="clk" ]; -c19 [ shape=record, label="{{ CLK| D}|$64\n$dff|{ Q}}" ]; -c13:p12:e -> c19:p17:w [color="black", style="setlinewidth(3)", label=""]; -c14:p12:e -> c13:p9:w [color="black", style="setlinewidth(3)", label=""]; -c15:p12:e -> c13:p10:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c14:p9:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c14:p10:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c15:p9:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c15:p10:w [color="black", style="setlinewidth(3)", label=""]; -c19:p18:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c13:p11:w [color="black", label=""]; -v1:e -> c14:p11:w [color="black", label=""]; -v2:e -> c15:p11:w [color="black", label=""]; -v3:e -> c19:p16:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/splice.dot b/docs/source/APPNOTE_011_Design_Investigation/splice.dot deleted file mode 100644 index 4657feed116..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/splice.dot +++ /dev/null @@ -1,39 +0,0 @@ -digraph "splice_demo" { -rankdir="LR"; -remincross=true; -n1 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n2 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="e", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="f", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="x", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c11 [ shape=record, label="{{ A}|$2\n$neg|{ Y}}" ]; -x0 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x0:e -> c11:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -x1 [ shape=record, style=rounded, label=" 3:0 - 7:4 " ]; -c11:p10:e -> x1:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c12 [ shape=record, label="{{ A}|$1\n$not|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x2:e -> c12:p9:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -x3 [ shape=record, style=rounded, label=" 3:2 - 1:0 | 1:0 - 3:2 " ]; -c12:p10:e -> x3:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -x4 [ shape=record, style=rounded, label=" 0:0 - 1:1 | 1:1 - 0:0 " ]; -x5 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x6 [ shape=record, style=rounded, label=" 3:0 - 11:8 " ]; -x5:e -> x6:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -n1:e -> x4:s0:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> x4:s1:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> x5:s1:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> x5:s0:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> x0:s1:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> x0:s0:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> x2:s1:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x2:s0:w [color="black", style="setlinewidth(3)", label=""]; -x4:e -> n7:w [color="black", style="setlinewidth(3)", label=""]; -x1:s0:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -x3:s0:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -x3:s1:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -x6:s0:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_00.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_00.dot deleted file mode 100644 index 2e55268ee10..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_00.dot +++ /dev/null @@ -1,45 +0,0 @@ -digraph "memdemo" { -rankdir="LR"; -remincross=true; -n5 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n7 [ shape=diamond, label="mem[0]", color="black", fontcolor="black" ]; -n8 [ shape=diamond, label="mem[1]", color="black", fontcolor="black" ]; -n9 [ shape=diamond, label="mem[2]", color="black", fontcolor="black" ]; -n10 [ shape=diamond, label="mem[3]", color="black", fontcolor="black" ]; -n11 [ shape=diamond, label="s1", color="black", fontcolor="black" ]; -n12 [ shape=diamond, label="s2", color="black", fontcolor="black" ]; -n13 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c17 [ shape=record, label="{{ CLK| D}|$59\n$dff|{ Q}}" ]; -c18 [ shape=record, label="{{ CLK| D}|$63\n$dff|{ Q}}" ]; -c20 [ shape=record, label="{{ clk| mem[0]| mem[1]| mem[2]| mem[3]| n1}|outstage\noutstage|{ y}}" ]; -c21 [ shape=record, label="{{ clk| d| n1}|scramble\nscramble|{ mem[0]| mem[1]| mem[2]| mem[3]}}" ]; -c23 [ shape=record, label="{{ d| s1| s2}|selstage\nselstage|{ n1| n2}}" ]; -n1 [ shape=point ]; -c23:p19:e -> n1:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> c17:p15:w [color="black", style="setlinewidth(3)", label=""]; -n1:e -> c21:p19:w [color="black", style="setlinewidth(3)", label=""]; -c21:p10:e -> n10:w [color="black", style="setlinewidth(3)", label=""]; -n10:e -> c20:p10:w [color="black", style="setlinewidth(3)", label=""]; -c17:p16:e -> n11:w [color="black", style="setlinewidth(3)", label=""]; -n11:e -> c23:p11:w [color="black", style="setlinewidth(3)", label=""]; -c18:p16:e -> n12:w [color="black", style="setlinewidth(3)", label=""]; -n12:e -> c23:p12:w [color="black", style="setlinewidth(3)", label=""]; -c20:p13:e -> n13:w [color="black", style="setlinewidth(3)", label=""]; -n2 [ shape=point ]; -c23:p22:e -> n2:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c18:p15:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c20:p19:w [color="black", style="setlinewidth(3)", label=""]; -n5:e -> c17:p14:w [color="black", label=""]; -n5:e -> c18:p14:w [color="black", label=""]; -n5:e -> c20:p5:w [color="black", label=""]; -n5:e -> c21:p5:w [color="black", label=""]; -n6:e -> c21:p6:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c23:p6:w [color="black", style="setlinewidth(3)", label=""]; -c21:p7:e -> n7:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c20:p7:w [color="black", style="setlinewidth(3)", label=""]; -c21:p8:e -> n8:w [color="black", style="setlinewidth(3)", label=""]; -n8:e -> c20:p8:w [color="black", style="setlinewidth(3)", label=""]; -c21:p9:e -> n9:w [color="black", style="setlinewidth(3)", label=""]; -n9:e -> c20:p9:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_01.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_01.dot deleted file mode 100644 index f8f8c008ac6..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_01.dot +++ /dev/null @@ -1,87 +0,0 @@ -digraph "scramble" { -rankdir="LR"; -remincross=true; -n17 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n18 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n19 [ shape=octagon, label="mem[0]", color="black", fontcolor="black" ]; -n20 [ shape=octagon, label="mem[1]", color="black", fontcolor="black" ]; -n21 [ shape=octagon, label="mem[2]", color="black", fontcolor="black" ]; -n22 [ shape=octagon, label="mem[3]", color="black", fontcolor="black" ]; -n23 [ shape=octagon, label="n1", color="black", fontcolor="black" ]; -c27 [ shape=record, label="{{ A| B}|$28\n$add|{ Y}}" ]; -c28 [ shape=record, label="{{ A| B}|$31\n$add|{ Y}}" ]; -c29 [ shape=record, label="{{ A| B}|$34\n$add|{ Y}}" ]; -c30 [ shape=record, label="{{ A| B}|$37\n$add|{ Y}}" ]; -v0 [ label="1'1" ]; -c31 [ shape=record, label="{{ A| B}|$145\n$and|{ Y}}" ]; -v1 [ label="1'1" ]; -c32 [ shape=record, label="{{ A| B}|$175\n$and|{ Y}}" ]; -v2 [ label="1'1" ]; -c33 [ shape=record, label="{{ A| B}|$205\n$and|{ Y}}" ]; -v3 [ label="1'1" ]; -c34 [ shape=record, label="{{ A| B}|$235\n$and|{ Y}}" ]; -v4 [ label="2'00" ]; -c35 [ shape=record, label="{{ A| B}|$143\n$eq|{ Y}}" ]; -v5 [ label="2'01" ]; -c36 [ shape=record, label="{{ A| B}|$173\n$eq|{ Y}}" ]; -v6 [ label="2'10" ]; -c37 [ shape=record, label="{{ A| B}|$203\n$eq|{ Y}}" ]; -v7 [ label="2'11" ]; -c38 [ shape=record, label="{{ A| B}|$233\n$eq|{ Y}}" ]; -c40 [ shape=record, label="{{ A| B| S}|$147\n$mux|{ Y}}" ]; -c41 [ shape=record, label="{{ A| B| S}|$177\n$mux|{ Y}}" ]; -c42 [ shape=record, label="{{ A| B| S}|$207\n$mux|{ Y}}" ]; -c43 [ shape=record, label="{{ A| B| S}|$237\n$mux|{ Y}}" ]; -c47 [ shape=record, label="{{ CLK| D}|$66\n$dff|{ Q}}" ]; -c48 [ shape=record, label="{{ CLK| D}|$68\n$dff|{ Q}}" ]; -c49 [ shape=record, label="{{ CLK| D}|$70\n$dff|{ Q}}" ]; -c50 [ shape=record, label="{{ CLK| D}|$72\n$dff|{ Q}}" ]; -c27:p26:e -> c40:p24:w [color="black", style="setlinewidth(3)", label=""]; -c36:p26:e -> c32:p24:w [color="black", label=""]; -c37:p26:e -> c33:p24:w [color="black", label=""]; -c38:p26:e -> c34:p24:w [color="black", label=""]; -c40:p26:e -> c47:p45:w [color="black", style="setlinewidth(3)", label=""]; -c41:p26:e -> c48:p45:w [color="black", style="setlinewidth(3)", label=""]; -c42:p26:e -> c49:p45:w [color="black", style="setlinewidth(3)", label=""]; -c43:p26:e -> c50:p45:w [color="black", style="setlinewidth(3)", label=""]; -n17:e -> c47:p44:w [color="black", label=""]; -n17:e -> c48:p44:w [color="black", label=""]; -n17:e -> c49:p44:w [color="black", label=""]; -n17:e -> c50:p44:w [color="black", label=""]; -n18:e -> c40:p25:w [color="black", style="setlinewidth(3)", label=""]; -n18:e -> c41:p25:w [color="black", style="setlinewidth(3)", label=""]; -n18:e -> c42:p25:w [color="black", style="setlinewidth(3)", label=""]; -n18:e -> c43:p25:w [color="black", style="setlinewidth(3)", label=""]; -c47:p46:e -> n19:w [color="black", style="setlinewidth(3)", label=""]; -n19:e -> c29:p25:w [color="black", style="setlinewidth(3)", label=""]; -n19:e -> c30:p24:w [color="black", style="setlinewidth(3)", label=""]; -c28:p26:e -> c41:p24:w [color="black", style="setlinewidth(3)", label=""]; -c48:p46:e -> n20:w [color="black", style="setlinewidth(3)", label=""]; -n20:e -> c27:p24:w [color="black", style="setlinewidth(3)", label=""]; -n20:e -> c30:p25:w [color="black", style="setlinewidth(3)", label=""]; -c49:p46:e -> n21:w [color="black", style="setlinewidth(3)", label=""]; -n21:e -> c27:p25:w [color="black", style="setlinewidth(3)", label=""]; -n21:e -> c28:p24:w [color="black", style="setlinewidth(3)", label=""]; -c50:p46:e -> n22:w [color="black", style="setlinewidth(3)", label=""]; -n22:e -> c28:p25:w [color="black", style="setlinewidth(3)", label=""]; -n22:e -> c29:p24:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c35:p25:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c36:p25:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c37:p25:w [color="black", style="setlinewidth(3)", label=""]; -n23:e -> c38:p25:w [color="black", style="setlinewidth(3)", label=""]; -c29:p26:e -> c42:p24:w [color="black", style="setlinewidth(3)", label=""]; -c30:p26:e -> c43:p24:w [color="black", style="setlinewidth(3)", label=""]; -c31:p26:e -> c40:p39:w [color="black", label=""]; -c32:p26:e -> c41:p39:w [color="black", label=""]; -c33:p26:e -> c42:p39:w [color="black", label=""]; -c34:p26:e -> c43:p39:w [color="black", label=""]; -c35:p26:e -> c31:p24:w [color="black", label=""]; -v0:e -> c31:p25:w [color="black", label=""]; -v1:e -> c32:p25:w [color="black", label=""]; -v2:e -> c33:p25:w [color="black", label=""]; -v3:e -> c34:p25:w [color="black", label=""]; -v4:e -> c35:p24:w [color="black", style="setlinewidth(3)", label=""]; -v5:e -> c36:p24:w [color="black", style="setlinewidth(3)", label=""]; -v6:e -> c37:p24:w [color="black", style="setlinewidth(3)", label=""]; -v7:e -> c38:p24:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_02.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_02.dot deleted file mode 100644 index 1a672c484f1..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_02.dot +++ /dev/null @@ -1,33 +0,0 @@ -digraph "outstage" { -rankdir="LR"; -remincross=true; -n4 [ shape=octagon, label="clk", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="mem[0]", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="mem[1]", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="mem[2]", color="black", fontcolor="black" ]; -n8 [ shape=octagon, label="mem[3]", color="black", fontcolor="black" ]; -n9 [ shape=octagon, label="n1", color="black", fontcolor="black" ]; -n10 [ shape=octagon, label="y", color="black", fontcolor="black" ]; -c15 [ shape=record, label="{{ A| B| S}|$110\n$mux|{ Y}}" ]; -x0 [ shape=record, style=rounded, label=" 1:1 - 0:0 " ]; -x0:e -> c15:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c16 [ shape=record, label="{{ A| B| S}|$113\n$mux|{ Y}}" ]; -x1 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x1:e -> c16:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c17 [ shape=record, label="{{ A| B| S}|$116\n$mux|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 0:0 - 0:0 " ]; -x2:e -> c17:p13:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", label=""]; -c21 [ shape=record, label="{{ CLK| D}|$64\n$dff|{ Q}}" ]; -c15:p14:e -> c21:p19:w [color="black", style="setlinewidth(3)", label=""]; -c21:p20:e -> n10:w [color="black", style="setlinewidth(3)", label=""]; -c16:p14:e -> c15:p11:w [color="black", style="setlinewidth(3)", label=""]; -c17:p14:e -> c15:p12:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c21:p18:w [color="black", label=""]; -n5:e -> c16:p11:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> c16:p12:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> c17:p11:w [color="black", style="setlinewidth(3)", label=""]; -n8:e -> c17:p12:w [color="black", style="setlinewidth(3)", label=""]; -n9:e -> x0:s0:w [color="black", label=""]; -n9:e -> x1:s0:w [color="black", label=""]; -n9:e -> x2:s0:w [color="black", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/submod_03.dot b/docs/source/APPNOTE_011_Design_Investigation/submod_03.dot deleted file mode 100644 index 0dbbe3baa17..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/submod_03.dot +++ /dev/null @@ -1,26 +0,0 @@ -digraph "selstage" { -rankdir="LR"; -remincross=true; -n3 [ shape=octagon, label="d", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="n1", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="n2", color="black", fontcolor="black" ]; -n6 [ shape=octagon, label="s1", color="black", fontcolor="black" ]; -n7 [ shape=octagon, label="s2", color="black", fontcolor="black" ]; -c10 [ shape=record, label="{{ A}|$39\n$reduce_bool|{ Y}}" ]; -v0 [ label="4'0000" ]; -c13 [ shape=record, label="{{ A| B| S}|$40\n$mux|{ Y}}" ]; -x1 [ shape=record, style=rounded, label=" 3:2 - 1:0 | 1:0 - 1:0 " ]; -c13:p9:e -> x1:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c14 [ shape=record, label="{{ A| B}|$38\n$xor|{ Y}}" ]; -x2 [ shape=record, style=rounded, label=" 1:0 - 3:2 | 1:0 - 1:0 " ]; -x2:e -> c14:p8:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, color="black", style="setlinewidth(3)", label=""]; -c10:p9:e -> c13:p12:w [color="black", label=""]; -c14:p9:e -> c13:p11:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c10:p8:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c14:p11:w [color="black", style="setlinewidth(3)", label=""]; -x1:s0:e -> n4:w [color="black", style="setlinewidth(3)", label=""]; -x1:s1:e -> n5:w [color="black", style="setlinewidth(3)", label=""]; -n6:e -> x2:s1:w [color="black", style="setlinewidth(3)", label=""]; -n7:e -> x2:s0:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c13:p8:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot deleted file mode 100644 index 06522dcc9ef..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_00.dot +++ /dev/null @@ -1,18 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -v0 [ label="a" ]; -v1 [ label="b" ]; -v2 [ label="$1_Y" ]; -c4 [ shape=record, label="{{ A| B}|$1\n$add|{ Y}}" ]; -v3 [ label="$1_Y" ]; -v4 [ label="c" ]; -v5 [ label="sum" ]; -c5 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -v0:e -> c4:p1:w [color="black", style="setlinewidth(3)", label=""]; -v1:e -> c4:p2:w [color="black", style="setlinewidth(3)", label=""]; -c4:p3:e -> v2:w [color="black", style="setlinewidth(3)", label=""]; -v3:e -> c5:p1:w [color="black", style="setlinewidth(3)", label=""]; -v4:e -> c5:p2:w [color="black", style="setlinewidth(3)", label=""]; -c5:p3:e -> v5:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot deleted file mode 100644 index aefe7a6da93..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_01.dot +++ /dev/null @@ -1,15 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n2 [ shape=octagon, label="a", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="b", color="black", fontcolor="black" ]; -n4 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n5 [ shape=octagon, label="sum", color="black", fontcolor="black" ]; -c9 [ shape=record, label="{{ A| B}|$1\n$add|{ Y}}" ]; -c10 [ shape=record, label="{{ A| B}|$2\n$add|{ Y}}" ]; -c9:p8:e -> c10:p6:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c9:p6:w [color="black", style="setlinewidth(3)", label=""]; -n3:e -> c9:p7:w [color="black", style="setlinewidth(3)", label=""]; -n4:e -> c10:p7:w [color="black", style="setlinewidth(3)", label=""]; -c10:p8:e -> n5:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot deleted file mode 100644 index 4646c994786..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_02.dot +++ /dev/null @@ -1,5 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n1 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot deleted file mode 100644 index dcfea2b5609..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_03.dot +++ /dev/null @@ -1,11 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n1 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -v0 [ label="$3_Y" ]; -v1 [ label="c" ]; -c5 [ shape=record, label="{{ A| B}|$4\n$mul|{ Y}}" ]; -c5:p4:e -> n1:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c5:p2:w [color="black", style="setlinewidth(3)", label=""]; -v1:e -> c5:p3:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot deleted file mode 100644 index e77c41aa2e1..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_04.dot +++ /dev/null @@ -1,11 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n2 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -c7 [ shape=record, label="{{ A| B}|$4\n$mul|{ Y}}" ]; -n1 [ shape=diamond, label="$3_Y" ]; -n1:e -> c7:p4:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c7:p5:w [color="black", style="setlinewidth(3)", label=""]; -c7:p6:e -> n3:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot b/docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot deleted file mode 100644 index b544412909c..00000000000 --- a/docs/source/APPNOTE_011_Design_Investigation/sumprod_05.dot +++ /dev/null @@ -1,15 +0,0 @@ -digraph "sumprod" { -rankdir="LR"; -remincross=true; -n2 [ shape=octagon, label="c", color="black", fontcolor="black" ]; -n3 [ shape=octagon, label="prod", color="black", fontcolor="black" ]; -v0 [ label="a" ]; -v1 [ label="b" ]; -c7 [ shape=record, label="{{ A| B}|$3\n$mul|{ Y}}" ]; -c8 [ shape=record, label="{{ A| B}|$4\n$mul|{ Y}}" ]; -c7:p6:e -> c8:p4:w [color="black", style="setlinewidth(3)", label=""]; -n2:e -> c8:p5:w [color="black", style="setlinewidth(3)", label=""]; -c8:p6:e -> n3:w [color="black", style="setlinewidth(3)", label=""]; -v0:e -> c7:p4:w [color="black", style="setlinewidth(3)", label=""]; -v1:e -> c7:p5:w [color="black", style="setlinewidth(3)", label=""]; -} diff --git a/docs/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 19663ac7733..a55d017d9d6 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 00000000000..91ec83288a4 --- /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 00000000000..1e942555816 --- /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 2ef14c56e5f..f14caa6f738 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 00000000000..384ce12a95f --- /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 9832c104b3d..565ce90a3f3 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 00000000000..9cc4fc58d5d --- /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 00000000000..b48972fd995 --- /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 c08f1106a25..c15691b3353 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 c5dac49eb9b..79daaf0c429 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 48203e31992..b7176fdc49a 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 b9234603494..891b8177b89 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 0c07e7e877c..f19bee64a95 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 8342b685c66..8fecb498551 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 a06ee1e17f1..d04419ec196 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 7d4243faffb..a16d3cd5790 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 78b20ea3593..b0fcb7b1827 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 0bd824b2069..88e7a14793b 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 ec9f2b8d0b2..06ab9a82087 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 b89ca9cb94f..a2f360a2cb2 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 | 78 +++++++----------- 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 | 46 +++++------ 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, 132 insertions(+), 238 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 50f03d13cff..d7bfd8e956a 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 831b036e993..00000000000 --- 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 c4a3c6e379b..00000000000 --- 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 9669ef841b0..00000000000 --- 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 3d48b46e5a5..00000000000 --- 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 f0a7795b641..955805f9c58 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) -FORCE: -../../resources/%: FORCE - @$(MAKE) -C $@ - @mkdir -p res/$* - @cp --update -t res/$* $@*.dot - -TEX_SOURCE:= $(wildcard *.tex) -DOT_LOC:= ../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) +# 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' -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 +# find all code example makefiles +.PHONY: examples +CODE_EXAMPLES := ../code_examples/*/Makefile +examples: $(CODE_EXAMPLES) -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)) +# target to convert specified dot file(s) +.PHONY: convert +TARG_DOT ?= +convert: $(TARG_DOT:.dot=.pdf) $(TARG_DOT:.dot=.svg) -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 $@ $< +# use empty FORCE target because .PHONY ignores % expansion, using find allows +# us to generate everything in one pass, since we don't know all of the possible +# outputs until the sub-makes run +FORCE: +../%/Makefile: FORCE + @make -C $(@D) dots + @mkdir -p $* + @find $(@D) -name *.dot -exec cp -u {} -t $* \; + @find $* -name *.dot -printf "%p " | xargs -i make --no-print-directory convert TARG_DOT="{}" -res/%.pdf: res/%.dot - TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' dot -Tpdf -o $@ $< +# find and build all tex files +.PHONY: all_tex +TEX_FILES := $(wildcard **/*.tex) +all_tex: $(TEX_FILES:.tex=.pdf) $(TEX_FILES:.tex=.svg) -011/%.pdf: 011/%.tex - cd 011 && TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001' pdflatex $()ey%I^36pzH3PMC=W3x;CytlM_mtkc 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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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

HU{k&m%w6VoHjJQ;kJm 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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 zcmb7~^F$uOC8eahJ7hsXU_nYjLO>c}>F%YwJ0zu95Tsja1eR`81bMH| z`~Cy(4?DZ}e9k#DbMNe&^F4E;^mJ75acFQ*P*CvI)szfSP*5d--?iA7Ks%MX%nN*> zdKjoGpwvy$9RL^T_VU{DC@75yxcAl=z%}TdnyCj03c=vN59)|(g)IsSYqq+QypfOP zNiN7d&G_%5?CY&)N}(8(tU%BWU4`&e+!#N{rgHd`?PRToKhhf>XZl78e5<=1=K)u~mQzba!(^GT% zd{CGY;>E3uQ`OL*_h!3&w8dnShnr{UDjFwd$g;?7#=QB__;(@ngQc-4+wD-tn1{`) zuGsk9j<&^@-8$6^0}I2(sqg2!LRE@G>g($hnNO$@#8xXS)X5qBRstH@Nv4*Tc|`D3 zi0nonvg#yShc9x60S?(X(8Gym^Q5l${Ju|mmbGAl=Yt}32tH-WPPPJTWxg~9d3 z4Y2|%wXdHat~@3NM%0o(EDhk8h=leFSd5?2(b3VQL`8umBZ3h61nkzu&A>EeSs#^tgQ6t`FSIzw%`JkSP=D&UaN?66Srep zBIAiFX57$&{7)7zSW7s78e!IO3=SisTi8@{Dppj1LZ%yDzw&VAHoE$r)`5Fad7$96 zWxX|hbW^5Ejc{)`&cYTkOi4}&`@t|L8~(*Q1$Inz#dPsj`+KxSxJ6`Kl-+?K1$IfA>R4S&92qdLuTtOGU0|F5>6{x|;xLw<(Ns zc2`z={O%`?WP~9jR^yb*Z=nlCyUU#qoK>G0`ch5u`-lG0AW+Jo(CnmL2$Oe5)a4sptO0QhNp;D(r~Om#^KvIx8xjq3!?hk2IJYn_`_gbsBX4WOs$-m|@W#L9#My)G5n)?z za&C8Se!Oc!t zo}6!r=Y5B)^9z>~@6QJW8|6OA= zfv+nT;x|Ye5a(a6-v+x}Dvc<`@S%k};(#Te6?WA@-$PI4Wldlf+2aCkmgtC2Q;5Y} zgeg9Yr6ywhWMeqgJ8qcv`($xSHE9~N&EUAh&)ZO>EE3=Lh4)7lVw2n)@v`}o?yW65 ziL+^Hmu+b>L>N;IROqkJW8}puf!2&J@t_Y?8CS#c*RU)DVYNj*Bmej~YVWObv^0nB z<(S`1XvrS9Rz=YH-;DLI=WdBVl+FY10GQ(+~0Et41J_7HA0>Tw{ho6yP-OpVLF86mdOhgFtUQd{`AA;HXeUc&ZvFoZ=isi}-C)RHPjMmB%sOZ{AfQwnp>3D+`29NX7|k<8w8psck^ zejG2=zk@n^maus2J)Py9YS5cNg#=|uukB6m;FP&qPHA71G??nSHcYInTN>@QUAh5m zP3?~NJTf*?I88unXS1s@j+Kv(-~x29t%7mGWttx&ZfG8oZ|1E;Nr)dPV-X&$so^GR z;?vR_*5pdS^7EH&yWg|`-ux%A9)%B+-hVvweGXiHq2ntp5g>#vB%%%;Dk4s8wk&PW zelwh(_csLB1^c)-dv=fGXNihba7*H@%8wv2%t$*Ery*U6A0iUrNnbo1;Ov7<&QCn; zUr<&lGH%Ey_)2*c9VGrpXX6_@ELp%_iin}1kBM(Y2TS56CME`l4WSDX-u5SAy)~M1 zww$g39cCAEL0i}v-jkop*&vdE?F}10AyPM1HJu4}$8%@M1_j)+5$E1 z{=wEBH&h$qB^vDH4~N5-t(QYSc0XZ~)vYauz}q|c(3EW?6TRgk<6a0BLYW0Pi2{29 z%|oGY2*xJ~67P|c9G91Ink^|PpIa<#3U#Ycy=Fa0o|MosIQ1OJD-`c>ye);5+NgU~ zb?86mozW30jvG>G6-}pw>H<+Oq^wZ?N=#Okkpo9JGA`Y%JWfe%w)m{9z|o1pY=`p9 z$Jfu2E5$GBULo(UtTic>^%D2JEj1{14B1^%p_Q66ZA;BtucLRB@>*6=E1$Nw+ z&#X+bD8!3E?xfzZq_$%8*94Tuq;4qJ#d~}4r7QWa0R%mlv~|1$#SSjTVH-r9)@l%_ zW`#vaH#A+SDCje7b&+{&QXKbZnMyU(ZoeQbA|l2ukeZqrKRuqzN-WqeY; zAp^+@mO{)}uRKS&rN|9~jfe|@CDV#2X4D}*vBd*ThJsF{|B0CaanXza756t8GC5KH zCnf>JTb%zKQmKa6l{3?6dy-Hv>|i$>8+|N}))^Rp&J&F5V2F4A>qljx;rLj~gZQ6i z1$lZdy`#&2mLda9&7>2?|1AIAE3bl%nEx!%$0rdjWdHSP288;=ban|4Zh}4*tLp^+R|?*m27bijR}0M;~mOr0ZO=RDZdi~^Pz?;C*DfX3^h8jxUI zK$!yE#okxcOaLg;009jYGua6!YXW~Pbg;yCKp6}I_CSc|Cm3u5f|H(0-GDqs1MJYj zU6=z!&HTWlsRZm$Vsz+%XHYhMXo4{(Xc#jvpkVak1+$=Fl5)8a9wwTCqGF@@u ztFg6cRWodCY+C~`+;-1{WO4iX;q}jcFk~c7VFm97C?b`M5(n4rk*g!Z=Y03Oi+lP*Kq=)os-n_kGnp(bCdrNsH6?_`>jl zC%WgH7wMnmWRe-e`9`SfjMO%Ja%bZ6MAL%TZ$5l@E+r*ZlMZrqJ>z-4sU^8t~X)Y!0ROWRw&!ap#M^gCk3-{!~cCr?Mz?f#Wth?43?s(L0?&OpkwWN5kst z`P;CK!nN&GnaU&`Km7h+qbpy=!-tWmpczuyaC>v&S6btxcY+Uluv(YDur44(4M5Sr z)ohe??d2?sV6;mV)vr)iXH)SJTj6WTFZ>pWAOvo*%>@{ z#y^ZZ@?B-o(J}gDr(dCGJgF%=7lrXwzEnaI?lU6z2Kku!L7gCE-3b9BBjb#)%NG;B zWU7T}Jb1YC(BkSdc?B>JcNY_BNJxm(8$>w7$V=#JrDJ8$-15pW_29>F3y`2i?n@e> z<5zZpu!+iSk?pf$-nQ(?$tg6i3~PKN!~V_#&g@2@H`#-58{5@k;>wP&JXlRR{ti8xX&fbKwl zJH16!^BE`2U=inps7=k>-KxDa>e|1T#_?Q>+VQZAMi(KwRg%*hmR zd;dxgU!ADGF{-IJpcca8Ey`aq%M`Hy_Ex-dZe43_1Wk1e-~LHdCY3Nj|2HOVh8jBE zR|zd`yB$r0)6l<%&~^vko)2VJAyabqcHWX!Hy%j(+gJ0M42@!L7jBU3#uqim@*)l* zibcg*E$j*$mJ3Q$5(=xSMN+#)Fv$=-7sPq+|-t3$|^2?T~h*CS=j}9 zg$ZGZ7m$DaGW}inc<~7tdhvK9QS(e``=@g0ueIuYo3$oY;!BecdEwV03ERuDNxuer z>j;G23XpHuJYKl8^E*7n?71Yq<)yOrm7`A-R`co9drzndNorBBWtLz!BY$wW9ArRj zo(3aaSsC(fg!0bP5^h#bh=d&ly3s}MCxy_%7eu{H%6MZa}0)Hx` zw9@Bypj(@7%EkIzs!Ls^5}pe54AtrFeiV{lQ`OpWXgGF2_RSINR+lxeeDQda=Wh_Y zM(gp;EVX23s&;kj?=Nj9N7FN#ZKQVtDM#XUssWVl8SP3&TG@D%@Yi#?VAZmoU{$HJ z!K3f7XJ+^L)Kr_lu`M(2uraTF=}pU(8W#%R&8dh5&*Sh0k&}~_PSO&Qt2X>p^Fzlw zg>pMQWl=nzudOD&h`?C(vZgB9pu+H;Q@jnolpE}5_gWIC0ZY<=H5IYvl_+%y3$Dom z$?QL0%xAGdE(f#+q%Wr+86^=EYXy&yP6@c@4nJv1MwFg<9Q)VY*%H5)JP0A=;8R-M z_58YI&+K!+4ZgEwv;4Cbk;#x@=gV@W_}J@+3^yy3-*)OI*8hB~t%aS3+ueoVteTBO z8-0Y9>2Z&H?`+Prhj*9&YVHYkv&obwaEo@D49ju^?%F-!8ifhzel<7hRF~ES9zR~z zwEzRd3ck+vDxJ=zk39Zr=SJM^7#!h>eP^`4HM&3IhHRqkmR91r!#@kX>Ppyb_ldiC zp6ac(Fi5~jI`38|n#1vcPkY%jbZLJyrtn-Q|A9i3{xf-7E7wRHY+rk~?%eYzvg!%i zryr=OLH8Uo--}d#-!CO4yZT1w7XI!M7Kw`}5{}0l=i_G9SS7ELw*FRUz8>?oI&kP* zFUXS^V|cmQi&WH3Y)@hpU;0k6@VM(tnY4XR4V9qdu4pMhdb(VjI(kfrEB-_hePYwH zLHWVUbUVa4J0r62{ z?;8q=Zr47OKhgT`8XZq4H=+>z znv!EJW^vo%&PEL}@gk5vwlG9x(qreU=0rl{eGK`b8(S z2fZz@ITR?rdCZUUSHVkha50w(z(mfP3ftGa6Wi;c<#w6BbaJf74tCPWwUCH$^NJU0 z5NBdS)z{ab5GB1G(tlQ{LbDp1rq>+(0#;jD6XM6?Er`9?m?d~K_ZM@9_@tIw0_Xb2 z=9f%*5!$(dvZ(&zc(TLM(NS8Veqn|?DSdX8KXDZBOlrZoEulh{tQH~^?c1^~EMa4Z z9GBI!j>NAMh4HVmC^b|14ytN#XGCJyHl6La-5z$BNde~8P7u10|2Y2TtD_fO4_7@f&BPx*W|_Nd@n{4t;@gV7cZi4HIUhSD_KT5X`^Fe3`{K%%7@4^kFL@QGMjLfl`cD? zqMBY6ub}3D5M~eyulMpM-Z+v0NjR`vmF+o|4M{ncp-Q--h`g@r6i-N->MuJ7(6>1- zNk_M+G<&ZnEZl0EvVPh)t8SXisz)O`;ww5Rks{=?Df^GvlTTmKA10!{!3*MqMW6oXu8cD#R#5`!(fm$~8MzSo?2ey7i8?)PZAcD56npi~Oc@#q=J$uk6J3c^RHDd5TV4|Zum=&t<}Z&m!Gp?O?Dj33YUPn`QtJZ-K7piU)WIz7}oEBhZuz3*>=9&31z0~}S( z0Cd0RaQdGm>Uex3F0b;x5k6S22#S`MMgb!PphFT-)?)OJqi#d(MwVmK|2dzM0i0*| z6?IWi*og)#bp(tFj2Sa2)Noz{%onIaN{j=2OMxYU${(@@4R@-k;W(4Mzo?lH zEHw@&)8NNUiZ+~s0cA%rfSm>goB@DEyn%S$hQOA9Y$etdU?*JM`U}7gbFjz|3*3#E z`HzeG<}(7^zjGA$8q;3bD=YpcqDl`<%(8T z1w{Fl^dGe$IATCx8j%*Ehr`3w!O>$-? zC;I-`S;EdpLbe8VtDK1I-S_E@NItFkiN1M!F=#d_na@f+`%fhcyX0>o!XM1LV()^H zgNm)N%uFh`$%^c-Fmy6^=)`Tz{vvx;op7vOi_}#J9Dz5f!Xb z9eD(>8KjeYe{Z*_q5-KP(B;%MV0aYu zui9SYMzQaym9Vh>GSnk&U#U+MN3)JDgCZ?@WDI9q&kPd%@Zpd0bJ)hn5*C_2mR#{n zWZxVS2;pBhg}%_BZq@R^@pGN+z}$DkA4+fG%Z|%jlmD1V==$oWi&??%^+!8TtXt`@1n#w^t_|14mmYAw4|-%09K!5a-0VqZC`RnL+1S(_YoEXV$g0*V|I!|CrmW^d_G7-qh}gEO5ucDIUZy8tlM%_!y05nN7LUxQ z3WIJ^HWsLm7qN@Wi=p<1^xKRoX*xeynpARfsuFi~gfAy|D%%#-R2+wEO;1xhi-eeZ zQK&4gzhJE=DlFr1m(xQ*gvAn@I3TEQbH38mXqde(J)k8anSJ9NkP0GsY2cphkmb(q z5+;OWBU#1C(x0MS*Dp zi1GQQf#LsPDviO8nVnB%l|GkF6#i@m9SjGhTd)+CslPF=X?JS=0Uqz~4u#~k(?whn zusA9wD`yKWhCQ>E<|Msv0}73*P8v?dcfO`xals1o6b#{vJV8qL(LOU+P!Vo|!G;I% z$!r}^Tb}g0znNg?n63xRouAUe?@0FXe{|hs3R)BNECofjWZc1V7KUfTN+YA9iAmQM z*7HpyNg2!h9pt}Q3^gvqG@S3$zoW4zpnpzYKSdXkmCJKpKQ!^Hs*^EKHxmZ>+%wEE zRi|{I7&I`>v_ASu6qlzL^FA*(LOlx){IVNI(%YY~{LhHhw-^cYzur=_aV#oz@4VH> ziWuF+a^d~`Mnmj@5yU|;h>AL6@$SFSnr{Zdp&j-!+K(i!AKW4@`P=YPqyG1dAv1vZ z$AL}UQz32=7c((pr|RfrbR;Khx5u?zmWA_q(Y3Acz|gAm z6`n1~$^nLdavNsK_=du)N%{H2T{Bgql|*O2gJ6&6V^HSLX}g-WhvI{_tp43WNJ+v_ za;bCDBN};*65{x#{n>Uv&B|{QiO*M5%rE@;^PE7Oq~nI^ES%z_$6EjD{dao~RO+5u zEpM|p-wMCGx(s$MUkpxp=3){rxltF=e6Y%5g+sxrJ;GZ}X=PD&!M6Ko5otQr1B+9Q z-M?{f#HO`*%{BE%*`%W{kFR6PX8pI>sO-&|Etg2Nf9ax?)T{d$njK(A73W^>>zrQG zsFF6k(yP^Dq{qiB*Mg+)sJ*&nJN2=lVJJ|?vEbN#__m4;D~hu#o> zjvaXk6;zT$=PzGy(VbVuC*V+l?jWhD-g4`IqsI>9peXK69Tc5J&R1gE?M4Uijy4on zEBNmH+lSc6jvG504-aE5ehv!khPs`PK6mr2v}F`(J5@Pgb2HhWqk7?1@bb(B$vOGGxH$qdjcqqL=2>i=`$%qHUz=aAu`MRLG-EhH%;U%5 zKf|ForD(1P zi;4rSfN3qFBikaZK(Rhh#N1DFV#M7(P)>)HM14wKW)lVzDu9hgHVg#jb0GJ zg^zr^A3T2^q%Ith>dbLFp{)?^o>o^URe4X#t@qG8t5o+({`b=yr3JeS)@sE<835ez zz{WhOAR06kc*7g~DfLSF;eyA>CE&zW=XfnC%tW<2T#?j%=lxP?W-}6nphj(Iq>kUF z>@-L`&m<}tZKI&-4_UW_A;H8ikbR8I;9=0&aO0{mKnh?W{rE{ z_{2cjvCZ5SxlF>K)mgvK2WWtXQP#XA!}&Xz2-n`f6y@(gu#VCSr)GMOvYO%2SG|K- zz3{t$jNNQYD78(ojlLzs#f#kssm@Z^I#>}ZEGk1`cx|Xv`eL(8Q8$(FW&Iz4l8uEz z4r2^V|BE;SexIkuGNmTx=OUH-1}y{hMhUXvW<7sj-)PWRa86iyj;6xFeB zMf+%q)0)>4@I3y&5Cz~k&r@(=q4Kr&9!JZ`ameI#*I{VjROOYx`kX7SNxfIQ(Vu{* zZ)a=hKOkMWX_P|{Nsnj!zyaO7U@h)K|H`oGYE-d~Q<-Dpj|$O@ysY@hNbInqL3#yG z5;%ykHsWT)>Jt$-4Om_n1!k5CHXk9$_6EzWM~l~4T*9j9Wf(KpPt6`V4Nj%9!yHOIJ8H2vc zSLGeyxlgp{$09BXqh4d@&Ox46wYJW~B%KXS*d5}!WMl${YLfOcL1SpU1$A0s;bGBQ zkmjItJA14O(ri(jKRw+6CIfsXm29Bfn**Ns1sdN@?(s9`0wNO=;}~Q6%I@}Q@mMAS zPQB}13=GVu>K2wYhXxU0S~>7cUOq=z-ohmM8cK1GY^MN8d@{%^D)ZLq3;MVY+bG~; z;Tcl%g~MOo05}dTFR`Daga~vuOa5U*H=eV8jnT-28m6nT#ahQ-?1958UzoPvl2KnM zL*B_fr!qmv$e7Qw5B^jJOrs(;{b#up(WkMnuOB<$*m!tkrh1A%B1jNyz83OPcl4aJ z<*V3R^fXc-9{?#@%U4EGEMKW)-$zT;wh2}UHMEK$Wc1jPt~||5&*Ul9xOcQxvB%@B sGbvDYDWOzl%6$Oa{$GoMa?j}DSaD}(G#>%HyM&^ytfN$?VD<5T0GH@JQUCw| 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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 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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