From eb5da87d526575daed900905023aa755004697d9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:59:03 +1300 Subject: [PATCH] example_synth: hardware mapping Filling out the hardware mapping sections, and actually highlighting the changes in schematics instead of just the memory block. Also includes Part 4 of the coarse-grain rep, looking at `memory_collect` and putting the `synth_ice40 -top fifo -run :map_ram` command in its own (sub)section. Includes a `no_rw_check` section label in `memory.rst` for reference (because I can't remember how to reference by heading). Not sure about the opt output after map_ram section which has an open TODO, and the final steps section is also still open. --- docs/source/code_examples/fifo/fifo.out | 49 +--------- docs/source/code_examples/fifo/fifo.ys | 2 +- docs/source/code_examples/fifo/fifo_map.ys | 38 ++++---- docs/source/getting_started/example_synth.rst | 91 +++++++++++++------ docs/source/using_yosys/synthesis/memory.rst | 2 + 5 files changed, 88 insertions(+), 94 deletions(-) diff --git a/docs/source/code_examples/fifo/fifo.out b/docs/source/code_examples/fifo/fifo.out index 47b867da1..a1a7c08f2 100644 --- a/docs/source/code_examples/fifo/fifo.out +++ b/docs/source/code_examples/fifo/fifo.out @@ -374,56 +374,9 @@ yosys> show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc Writing dot description to `rdata_alumacc.dot'. Dumping selected parts of module fifo to page 1. -yosys> memory -nomap - -23. Executing MEMORY pass. - -yosys> opt_mem - -23.1. Executing OPT_MEM pass (optimize memories). -Performed a total of 0 transformations. - -yosys> opt_mem_priority - -23.2. Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations). -Performed a total of 0 transformations. - -yosys> opt_mem_feedback - -23.3. Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths). - -yosys> memory_bmux2rom - -23.4. Executing MEMORY_BMUX2ROM pass (converting muxes to ROMs). - -yosys> memory_dff - -23.5. Executing MEMORY_DFF pass (merging $dff cells to $memrd). - -yosys> opt_clean - -23.6. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. -Removed 1 unused cells and 9 unused wires. - - -yosys> memory_share - -23.7. Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells). - -yosys> opt_mem_widen - -23.8. Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide). -Performed a total of 0 transformations. - -yosys> opt_clean - -23.9. Executing OPT_CLEAN pass (remove unused cells and wires). -Finding unused cells or wires in module \fifo.. - yosys> memory_collect -23.10. Executing MEMORY_COLLECT pass (generating $mem cells). +23. Executing MEMORY_COLLECT pass (generating $mem cells). yosys> select -set new_cells t:$mem_v2 diff --git a/docs/source/code_examples/fifo/fifo.ys b/docs/source/code_examples/fifo/fifo.ys index d181ca1fe..497481166 100644 --- a/docs/source/code_examples/fifo/fifo.ys +++ b/docs/source/code_examples/fifo/fifo.ys @@ -65,7 +65,7 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdat # ======================================================== -memory -nomap +memory_collect # or use the following commands: # design -reset # read_verilog fifo.v diff --git a/docs/source/code_examples/fifo/fifo_map.ys b/docs/source/code_examples/fifo/fifo_map.ys index 42403d1c0..00c1f08ad 100644 --- a/docs/source/code_examples/fifo/fifo_map.ys +++ b/docs/source/code_examples/fifo/fifo_map.ys @@ -5,41 +5,43 @@ synth_ice40 -top fifo -run begin:map_ram # ======================================================== synth_ice40 -top fifo -run map_ram:map_ffram -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path +select -set mem t:SB_RAM40_4K +select -set remap @mem %ci:+SB_RAM40_4K[RADDR] @mem %co %% +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 @mem -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ram @rdata_path # ======================================================== synth_ice40 -top fifo -run map_ffram:map_gates -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path +select -set mem t:SB_RAM40_4K +select -set remap @mem %co @mem %d +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 @mem -color cornflowerblue @remap -notitle -format dot -prefix rdata_map_ffram @rdata_path # ======================================================== synth_ice40 -top fifo -run map_gates:map_ffs -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +select -set multibit t:$_MUX_ t:$_DFFE_*_ +select -set alu t:$_OR_ t:$_NOT_ t:$lut %% %ci %% w:fifo_reader.addr %d i:* %d +show -color maroon3 @multibit -color cornflowerblue @alu -notitle -format dot -prefix rdata_map_gates @rdata_path # ======================================================== synth_ice40 -top fifo -run map_ffs:map_luts -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +select -set dff t:SB_DFFER +select -set primitives t:$_AND_ %ci i:* %d +show -color maroon3 @dff -color cornflowerblue @primitives -notitle -format dot -prefix rdata_map_ffs @rdata_path # ======================================================== synth_ice40 -top fifo -run map_luts:map_cells -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 t:SB_CARRY -color cornflowerblue t:$lut -notitle -format dot -prefix rdata_map_luts @rdata_path # ======================================================== synth_ice40 -top fifo -run map_cells: -select -set new_cells t:SB_RAM40_4K -select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %% -show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @rdata_path +select -set rdata_path t:SB_RAM40_4K %ci*:-SB_RAM40_4K[WCLKE,WDATA,WADDR,WE] t:SB_RAM40_4K %co* %% +show -color maroon3 t:SB_LUT* -notitle -format dot -prefix rdata_map_cells @rdata_path diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index eb4f099d6..82c6bdf0e 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -508,20 +508,39 @@ see produce the following changes in our example design: ``rdata`` output after :cmd:ref:`alumacc` -.. TODO:: discuss :cmd:ref:`memory_collect` and ``$mem_v2`` +The other new command in this part is :doc:`/cmd/memory`. :cmd:ref:`memory` is +another macro command which we examine in more detail in +:doc:`/using_yosys/synthesis/memory`. For this document, let us focus just on +the step most relevant to our example: :cmd:ref:`memory_collect`. Up until this +point, our memory reads and our memory writes have been totally disjoint cells; +operating on the same memory only in the abstract. :cmd:ref:`memory_collect` +combines all of the reads and writes for a memory block into a single cell. .. figure:: /_images/code_examples/fifo/rdata_coarse.* :class: width-helper :name: rdata_coarse - ``rdata`` output after :yoscrypt:`memory -nomap` + ``rdata`` output after :cmd:ref:`memory_collect` -We could also have gotten here by running :yoscrypt:`synth_ice40 -top fifo -run -begin:map_ram` after loading the design. +Looking at the schematic after running :cmd:ref:`memory_collect` we see that our +``$memrd_v2`` cell has been replaced with a ``$mem_v2`` cell named ``data``, the +same name that we used in :ref:`fifo-v`. Where before we had a single set of +signals for address and enable, we now have one set for reading (``RD_*``) and +one for writing (``WR_*``), as well as both ``WR_DATA`` input and ``RD_DATA`` +output. .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/memory` +Final note +^^^^^^^^^^ + +Having now reached the end of the the coarse-grain representation, we could also +have gotten here by running :yoscrypt:`synth_ice40 -top fifo -run :map_ram` +after loading the design. The :yoscrypt:`-run :` option +with an empty ```` starts from the :ref:`synth_begin`, while the +```` runs up to but including the :ref:`map_ram`. + Hardware mapping ~~~~~~~~~~~~~~~~ @@ -535,8 +554,6 @@ Memory blocks Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, :cmd:ref:`memory_map`, and :cmd:ref:`techmap`. -.. TODO:: ``$mem_v2`` -> ``SB_RAM40_4K`` - .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_ram: @@ -551,6 +568,16 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, ``rdata`` output after :ref:`map_ram` +:ref:`map_ram` converts the generic ``$mem_v2`` into the iCE40 ``SB_RAM40_4K`` +(highlighted). We can also see the memory address has been remapped, and the +data bits have been reordered (or swizzled). There is also now a ``$mux`` cell +controlling the value of ``rdata``. In :ref:`fifo-v` we wrote our memory as +read-before-write, however the ``SB_RAM40_4K`` has undefined behaviour when +reading from and writing to the same address in the same cycle. As a result, +extra logic is added so that the generated circuit matches the behaviour of the +verilog. :ref:`no_rw_check` describes how we could change our verilog to match +our hardware instead. + .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt :start-after: map_ffram: @@ -565,6 +592,8 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, ``rdata`` output after :ref:`map_ffram` +.. TODO:: what even is this opt output + .. seealso:: Advanced usage docs for - :doc:`/using_yosys/synthesis/techmap_synth` @@ -573,9 +602,11 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap`, Arithmetic ^^^^^^^^^^ -Uses :cmd:ref:`techmap`. - -.. TODO:: example_synth/Arithmetic +Uses :cmd:ref:`techmap` to map basic arithmetic logic to hardware. This sees +somewhat of an explosion in cells as multi-bit ``$mux`` and ``$adffe`` are +replaced with single-bit ``$_MUX_`` and ``$_DFFE_PP0P_`` cells, while the +``$alu`` is replaced with primitive ``$_OR_`` and ``$_NOT_`` gates and a +``$lut`` cell. .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -598,9 +629,13 @@ Flip-flops ^^^^^^^^^^ Convert FFs to the types supported in hardware with :cmd:ref:`dfflegalize`, and -then use :cmd:ref:`techmap` to map them. We also run :cmd:ref:`simplemap` here -to convert any remaining cells which could not be mapped to hardware into -gate-level primitives. +then use :cmd:ref:`techmap` to map them. In our example, this converts the +``$_DFFE_PP0P_`` cells to ``SB_DFFER``. + +We also run :cmd:ref:`simplemap` here to convert any remaining cells which could +not be mapped to hardware into gate-level primitives. This includes optimizing +``$_MUX_`` cells where one of the inputs is a constant ``1'0``, replacing it +instead with an ``$_AND_`` cell. .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -622,9 +657,10 @@ gate-level primitives. LUTs ^^^^ -:cmd:ref:`abc` and :cmd:ref:`techmap` are used to map LUTs. Note that the iCE40 -flow uses :cmd:ref:`abc` rather than :cmd:ref:`abc9`. For more on what these -do, and what the difference between these two commands are, refer to +:cmd:ref:`abc` and :cmd:ref:`techmap` are used to map LUTs; converting primitive +cell types to use ``$lut`` and ``SB_CARRY`` cells. Note that the iCE40 flow +uses :cmd:ref:`abc9` rather than :cmd:ref:`abc`. For more on what these do, and +what the difference between these two commands are, refer to :doc:`/using_yosys/synthesis/abc`. .. literalinclude:: /cmd/synth_ice40.rst @@ -641,15 +677,8 @@ do, and what the difference between these two commands are, refer to ``rdata`` output after :ref:`map_luts` -.. seealso:: Advanced usage docs for - - - :doc:`/using_yosys/synthesis/techmap_synth` - - :doc:`/using_yosys/synthesis/abc` - -Other cells -^^^^^^^^^^^ - -Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. +Finally we use :cmd:ref:`techmap` to map the generic ``$lut`` cells to iCE40 +``SB_LUT4`` cells. .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt @@ -665,7 +694,15 @@ Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. ``rdata`` output after :ref:`map_cells` -.. TODO:: example_synth other cells +.. seealso:: Advanced usage docs for + + - :doc:`/using_yosys/synthesis/techmap_synth` + - :doc:`/using_yosys/synthesis/abc` + +Other cells +^^^^^^^^^^^ + +The following commands may also be used for mapping other cells: :cmd:ref:`hilomap` Some architectures require special driver cells for driving a constant hi or @@ -676,8 +713,8 @@ Seems to be wide LUTs into individual LUTs using :cmd:ref:`techmap`. Top-level input/outputs must usually be implemented using special I/O-pad cells. This command inserts such cells to the design. -.. seealso:: Advanced usage docs for - :doc:`/yosys_internals/techmap` +These commands tend to either be in the :ref:`map_cells` or after the +:ref:`check` depending on the flow. Final steps ~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 499f73d5a..71da211d5 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -253,6 +253,8 @@ Synchronous SDP read first read_data <= mem[read_addr]; end +.. _no_rw_check: + Synchronous SDP with undefined collision behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~