docs: work on example_synth

Split hardware mapping from `fifo.ys` into `fifo_map.ys`.  Reduces size of `fifo.out` log and allows separate yosys calls in the makefile.

Some tidy up and minor changes in `fifo.ys` for better discussion.
Filled out note on `clean` (changed from `opt_clean`) and introduced `;;`.
Highlighted `$memrd` and added a paragraph about it.
More detail on the flatten and merging of `fifo_reader` block.
Brief discussion on the changes from `$memrd` to `$memrd_v2`.
This commit is contained in:
Krystine Sherwin 2024-01-03 11:47:33 +13:00
parent 50d8c1b258
commit 9f1c445fbf
No known key found for this signature in database
5 changed files with 159 additions and 1774 deletions

View File

@ -3,17 +3,21 @@ PROGRAM_PREFIX :=
YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys
DOT_NAMES = addr_gen_hier addr_gen_proc addr_gen_clean DOT_NAMES = addr_gen_hier addr_gen_proc addr_gen_clean
DOT_NAMES += rdata_proc rdata_flat rdata_adffe rdata_memrdv2 rdata_alumacc DOT_NAMES += rdata_proc rdata_flat rdata_adffe rdata_memrdv2 rdata_alumacc rdata_coarse
DOT_NAMES += rdata_coarse rdata_map_ram rdata_map_ffram rdata_map_gates MAPDOT_NAMES = rdata_map_ram rdata_map_ffram rdata_map_gates
DOT_NAMES += rdata_map_ffs rdata_map_luts rdata_map_cells MAPDOT_NAMES += rdata_map_ffs rdata_map_luts rdata_map_cells
DOTS := $(addsuffix .dot,$(DOT_NAMES)) DOTS := $(addsuffix .dot,$(DOT_NAMES))
MAPDOTS := $(addsuffix .dot,$(MAPDOT_NAMES))
dots: $(DOTS) fifo.out dots: $(DOTS) $(MAPDOTS) fifo.out
$(DOTS) fifo.out: fifo.v fifo.ys $(DOTS) fifo.out: fifo.v fifo.ys
$(YOSYS) fifo.ys -l fifo.out -Q -T $(YOSYS) fifo.ys -l fifo.out -Q -T
$(MAPDOTS): fifo.v fifo_map.ys
$(YOSYS) fifo_map.ys
.PHONY: clean .PHONY: clean
clean: clean:
rm -f *.dot rm -f *.dot

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ select -set new_cells t:$mux t:*dff
show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc show -color maroon3 @new_cells -notitle -format dot -prefix addr_gen_proc
# ======================================================== # ========================================================
opt_clean clean
show -notitle -format dot -prefix addr_gen_clean show -notitle -format dot -prefix addr_gen_clean
# ======================================================== # ========================================================
@ -26,12 +26,15 @@ design -reset
read_verilog fifo.v read_verilog fifo.v
hierarchy -check -top fifo hierarchy -check -top fifo
proc proc
show -color maroon3 c:fifo_reader -notitle -format dot -prefix rdata_proc o:rdata %ci* select -set new_cells t:$memrd
show -color maroon3 c:fifo_reader -color cornflowerblue @new_cells -notitle -format dot -prefix rdata_proc o:rdata %ci*
# ======================================================== # ========================================================
flatten;; flatten;;
show -notitle -format dot -prefix rdata_flat o:rdata %ci* select -set rdata_path o:rdata %ci*
select -set new_cells @rdata_path o:rdata %ci3 %d i:* %d
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_flat @rdata_path
# ======================================================== # ========================================================
@ -53,54 +56,7 @@ show -color maroon3 @new_cells -notitle -format dot -prefix rdata_alumacc o:rdat
# ======================================================== # ========================================================
design -reset memory -nomap
read_verilog fifo.v
synth_ice40 -top fifo -run begin:map_ram
select -set new_cells t:$mem_v2 select -set new_cells t:$mem_v2
select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @new_cells %co* %% select -set rdata_path @new_cells %ci*:-$mem_v2[WR_DATA,WR_ADDR,WR_EN] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path show -color maroon3 @new_cells -notitle -format dot -prefix rdata_coarse @rdata_path
# turn command echoes off to avoid randomly generated abc file names
echo off
# ========================================================
synth_ice40 -top fifo -run map_ram:map_ffram
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_ffram:map_gates
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_gates:map_ffs
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_ffs:map_luts
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_luts:map_cells
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_cells:
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @rdata_path

View File

@ -0,0 +1,45 @@
read_verilog fifo.v
synth_ice40 -top fifo -run begin:map_ram
# this point should be the same as rdata_coarse
# ========================================================
synth_ice40 -top fifo -run map_ram:map_ffram
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ram @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_ffram:map_gates
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffram @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_gates:map_ffs
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_gates @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_ffs:map_luts
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_ffs @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_luts:map_cells
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_luts @rdata_path
# ========================================================
synth_ice40 -top fifo -run map_cells:
select -set new_cells t:SB_RAM40_4K
select -set rdata_path @new_cells %ci*:-SB_RAM40_4K[WDATA,WADDR,WE] @new_cells %co* %%
show -color maroon3 @new_cells -notitle -format dot -prefix rdata_map_cells @rdata_path

View File

@ -149,25 +149,29 @@ each of these in more detail in :doc:`/using_yosys/synthesis/proc`.
:doc:`/cmd/opt_expr` :doc:`/cmd/opt_expr`
- by default called at the end of :cmd:ref:`proc` - by default called at the end of :cmd:ref:`proc`
- can be disabled with ``-noopt``
- done here for... reasons?
Notice how in the top left of :ref:`addr_gen_proc` we have a floating wire, Notice how in the top left of :ref:`addr_gen_proc` we have a floating wire,
generated from the initial assignment of 0 to the ``addr`` wire. However, this generated from the initial assignment of 0 to the ``addr`` wire. However, this
initial assignment is not synthesizable, so this will need to be cleaned up initial assignment is not synthesizable, so this will need to be cleaned up
before we can generate the physical hardware. We can do this now by calling before we can generate the physical hardware. We can do this now by calling
:cmd:ref:`opt_clean`: :cmd:ref:`clean`:
.. figure:: /_images/code_examples/fifo/addr_gen_clean.* .. figure:: /_images/code_examples/fifo/addr_gen_clean.*
:class: width-helper :class: width-helper
:name: addr_gen_clean :name: addr_gen_clean
``addr_gen`` module after :cmd:ref:`opt_clean` ``addr_gen`` module after :cmd:ref:`clean`
.. TODO:: more on opt_clean .. note::
:doc:`/cmd/opt_clean`
- :cmd:ref:`clean` for short, ``;;`` for even shorter :doc:`/cmd/clean` can also be called with two semicolons after any command,
- final command of :cmd:ref:`opt` for example we could have called :yoscrypt:`proc;;` instead of
- can run at any time :yoscrypt:`proc` and then :yoscrypt:`clean`. It is generally beneficial to
run :cmd:ref:`clean` after each command as a quick way of removing
disconnected parts of the circuit which have been left over. You may notice
some scripts will end each line with ``;;``.
.. todo:: consider a brief glossary for terms like adff .. todo:: consider a brief glossary for terms like adff
@ -231,11 +235,15 @@ command only works with a single module, so you may need to call it with
The highlighted ``fifo_reader`` block contains an instance of the The highlighted ``fifo_reader`` block contains an instance of the
:ref:`addr_gen_proc` that we looked at earlier. Notice how the type is shown as :ref:`addr_gen_proc` that we looked at earlier. Notice how the type is shown as
``$paramod\\addr_gen\\MAX_DATA=s32'...``. This is a "parametric module"; an ``$paramod\\addr_gen\\MAX_DATA=s32'...``. This is a "parametric module": an
instance of the ``addr_gen`` module with the ``MAX_DATA`` set to the given instance of the ``addr_gen`` module with the ``MAX_DATA`` parameter set to the
value. given value.
.. TODO:: comment on ``$memrd`` The other highlighted block is a ``$memrd`` cell. At this stage of synthesis we
don't yet know what type of memory is going to be implemented, but we *do* know
that ``rdata <= data[raddr];`` could be implemented as a read from memory. Note
that the ``$memrd`` cell here is asynchronous, with both the clock and enable
signal undefined; shown with the ``1'x`` inputs.
.. seealso:: Advanced usage docs for .. seealso:: Advanced usage docs for
:doc:`/using_yosys/synthesis/proc` :doc:`/using_yosys/synthesis/proc`
@ -261,7 +269,7 @@ optimizations between modules which would otherwise be missed. Let's run
.. literalinclude:: /code_examples/fifo/fifo.out .. literalinclude:: /code_examples/fifo/fifo.out
:language: doscon :language: doscon
:start-at: yosys> flatten :start-at: yosys> flatten
:end-before: yosys> show :end-before: yosys> select
:name: flat_clean :name: flat_clean
:caption: output of :yoscrypt:`flatten;;` :caption: output of :yoscrypt:`flatten;;`
@ -271,16 +279,24 @@ optimizations between modules which would otherwise be missed. Let's run
``rdata`` output after :yoscrypt:`flatten;;` ``rdata`` output after :yoscrypt:`flatten;;`
We can now see both :ref:`rdata_proc` and :ref:`addr_gen_proc` together. Note .. role:: yoterm(code)
that in the :ref:`flat_clean` we see above has two separate calls: one to :language: doscon
:cmd:ref:`flatten` and one to :cmd:ref:`clean`. In an interactive terminal the
output of both commands will be combined into the single `yosys> flatten;;`
output.
Depending on the target architecture, we might also see commands such as The pieces have moved around a bit, but we can see :ref:`addr_gen_proc` from
:cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`. These earlier has replaced the ``fifo_reader`` block in :ref:`rdata_proc`. We can
remove tristate and inout constructs respectively, replacing them with logic also see that the ``addr`` output has been renamed to ``fifo_reader.addr`` and
suitable for mapping to an FPGA. merged with the ``raddr`` wire feeding into the ``$memrd`` cell. This wire
merging happened during the call to :cmd:ref:`clean` which we can see in the
:ref:`flat_clean`. Note that in an interactive terminal the outputs of
:cmd:ref:`flatten` and :cmd:ref:`clean` will be combined into a single
:yoterm:`yosys> flatten;;` output.
Depending on the target architecture, this stage of synthesis might also see
commands such as :cmd:ref:`tribuf` with the ``-logic`` option and
:cmd:ref:`deminout`. These remove tristate and inout constructs respectively,
replacing them with logic suitable for mapping to an FPGA. Since we do not have
any such constructs in our example running these commands does not change our
design.
The coarse-grain representation The coarse-grain representation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -314,18 +330,18 @@ In the iCE40 flow, we start with the following commands:
:caption: ``coarse`` section (part 1) :caption: ``coarse`` section (part 1)
:name: synth_coarse1 :name: synth_coarse1
The first few commands are relatively straightforward, and we've already come We've already come across :cmd:ref:`opt_expr`, and :cmd:ref:`opt_clean` is the
across :cmd:ref:`opt_clean` and :cmd:ref:`opt_expr`. The :cmd:ref:`check` pass same as :cmd:ref:`clean` but with more verbose output. The :cmd:ref:`check`
identifies a few obvious problems which will cause errors later. Calling it pass identifies a few obvious problems which will cause errors later. Calling
here lets us fail faster rather than wasting time on something we know is it here lets us fail faster rather than wasting time on something we know is
impossible. impossible.
Next up is :yoscrypt:`opt -nodffe -nosdff` performing a set of simple Next up is :yoscrypt:`opt -nodffe -nosdff` performing a set of simple
optimizations on the design. This command also ensures that only a specific optimizations on the design. This command also ensures that only a specific
subset of FF types are included, in preparation for the next command: subset of FF types are included, in preparation for the next command:
:doc:`/cmd/fsm`. Both :cmd:ref:`opt` and :cmd:ref:`fsm` are macro commands :doc:`/cmd/fsm`. Both :cmd:ref:`opt` and :cmd:ref:`fsm` are macro commands
which are explored in more detail in :doc:`/using_yosys/synthesis/fsm` and which are explored in more detail in :doc:`/using_yosys/synthesis/opt` and
:doc:`/using_yosys/synthesis/opt` respectively. :doc:`/using_yosys/synthesis/fsm` respectively.
Up until now, the data path for ``rdata`` has remained the same since Up until now, the data path for ``rdata`` has remained the same since
:ref:`rdata_flat`. However the next call to :cmd:ref:`opt` does cause a change. :ref:`rdata_flat`. However the next call to :cmd:ref:`opt` does cause a change.
@ -384,7 +400,10 @@ Our next command to run is
``rdata`` output after :cmd:ref:`memory_dff` ``rdata`` output after :cmd:ref:`memory_dff`
As the title suggests, :cmd:ref:`memory_dff` has merged the output ``$dff`` into As the title suggests, :cmd:ref:`memory_dff` has merged the output ``$dff`` into
the ``$memrd`` cell and converted it to a ``$memrd_v2`` (highlighted). the ``$memrd`` cell and converted it to a ``$memrd_v2`` (highlighted). This has
also connected the ``CLK`` port to the ``clk`` input as it is now a synchronous
memory read with appropriate enable (``EN=1'1``) and reset (``ARST=1'0`` and
``SRST=1'0``) inputs.
.. seealso:: Advanced usage docs for .. seealso:: Advanced usage docs for