mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Initial synth_ice40 example
Overall structure in place to match the iCE40 flow. Still needs a new example design, and more text for the later sections (which the counter doesn't cover).
This commit is contained in:
		
							parent
							
								
									3a153f99db
								
							
						
					
					
						commit
						6d1caf6134
					
				
					 2 changed files with 155 additions and 117 deletions
				
			
		|  | @ -1,21 +1,17 @@ | ||||||
| Synthesis starter | Synthesis starter | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
| ..  | This page will be a guided walkthrough of the prepackaged iCE40 FPGA synthesis | ||||||
|    Typical phases of a synthesis flow are as follows: | script - :cmd:ref:`synth_ice40`.  We will take a simple design through each | ||||||
|  | step, looking at the commands being called and what they do to the design. While | ||||||
|  | :cmd:ref:`synth_ice40` is specific to the iCE40 platform, most of the operations | ||||||
|  | we will be discussing are common across the majority of FPGA synthesis scripts. | ||||||
|  | Thus, this document will provide a good foundational understanding of how | ||||||
|  | synthesis in Yosys is performed, regardless of the actual architecture being | ||||||
|  | used. | ||||||
| 
 | 
 | ||||||
|    - Reading and elaborating the design | .. seealso:: Advanced usage docs for | ||||||
|    - Higher-level synthesis and optimization |    :doc:`/using_yosys/synthesis/synth` | ||||||
| 
 |  | ||||||
|    - Converting ``always``-blocks to logic and registers |  | ||||||
|    - Perform coarse-grain optimizations (resource sharing, const folding, ...) |  | ||||||
|    - Handling of memories and other coarse-grain blocks |  | ||||||
|    - Extracting and optimizing finite state machines |  | ||||||
| 
 |  | ||||||
|    - Convert remaining logic to bit-level logic functions |  | ||||||
|    - Perform optimizations on bit-level logic functions |  | ||||||
|    - Map bit-level logic gates and registers to cell library |  | ||||||
|    - Write results to output file |  | ||||||
| 
 | 
 | ||||||
| A simple counter | A simple counter | ||||||
| ~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~ | ||||||
|  | @ -23,24 +19,15 @@ A simple counter | ||||||
| .. role:: yoscrypt(code) | .. role:: yoscrypt(code) | ||||||
|    :language: yoscrypt |    :language: yoscrypt | ||||||
| 
 | 
 | ||||||
| .. TODO:: move current example synth as mapping to cell libraries | .. TODO:: replace counter.v with a (slightly) more complex design  | ||||||
|  |    which includes hard blocks and maybe an FSM | ||||||
| 
 | 
 | ||||||
|    replace with a walk through of synth_ice40 | First, let's quickly look at the design we'll be synthesizing: | ||||||
| 
 |  | ||||||
| This section covers an `example project`_ available in |  | ||||||
| ``docs/source/code_examples/intro/``.  The project contains a simple ASIC |  | ||||||
| synthesis script (``counter.ys``), a digital design written in Verilog |  | ||||||
| (``counter.v``), and a simple CMOS cell library (``mycells.lib``). |  | ||||||
| 
 |  | ||||||
| .. _example project: https://github.com/YosysHQ/yosys/tree/krys/docs/docs/source/code_examples/intro |  | ||||||
| 
 |  | ||||||
| First, let's quickly look at the design: |  | ||||||
| 
 | 
 | ||||||
| .. literalinclude:: /code_examples/intro/counter.v | .. literalinclude:: /code_examples/intro/counter.v | ||||||
|    :language: Verilog |    :language: Verilog | ||||||
|    :caption: ``docs/source/code_examples/intro/counter.v`` |    :caption: ``docs/source/code_examples/intro/counter.v`` | ||||||
|    :linenos: |    :linenos: | ||||||
|    :name: counter-v |  | ||||||
| 
 | 
 | ||||||
| This is a simple counter with reset and enable.  If the reset signal, ``rst``, | This is a simple counter with reset and enable.  If the reset signal, ``rst``, | ||||||
| is high then the counter will reset to 0.  Otherwise, if the enable signal, | is high then the counter will reset to 0.  Otherwise, if the enable signal, | ||||||
|  | @ -69,14 +56,40 @@ should see something like the following: | ||||||
|    Storing AST representation for module `$abstract\counter'. |    Storing AST representation for module `$abstract\counter'. | ||||||
|    Successfully finished Verilog frontend. |    Successfully finished Verilog frontend. | ||||||
| 
 | 
 | ||||||
|  | .. seealso:: Advanced usage docs for | ||||||
|  |    :doc:`/using_yosys/more_scripting/load_design` | ||||||
|  | 
 | ||||||
|  | Elaboration | ||||||
|  | ~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
| Now that we are in the interactive shell, we can call Yosys commands directly. | Now that we are in the interactive shell, we can call Yosys commands directly. | ||||||
| Let's run :yoscrypt:`hierarchy -check -top counter`.  This command declares that | Our overall goal is to call :yoscrypt:`synth_ice40 -top counter`, but for now we | ||||||
| the top level module is ``counter``, and that we want to expand it and any other | can run each of the commands individually for a better sense of how each part | ||||||
| modules it may use.  Any other modules which were loaded are then discarded, | contributes to the flow.  At the bottom of the :cmd:ref:`help` output for | ||||||
| stopping the following commands from trying to work on them.  By passing the | :cmd:ref:`synth_ice40` is the complete list of commands called by this script. | ||||||
| ``-check`` option there we are also telling the :cmd:ref:`hierarchy` command | Let's start with the section labeled ``begin``: | ||||||
| that if the design includes any non-blackbox modules without an implementation | 
 | ||||||
| it should return an error. | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
|  |    :language: yoscrypt | ||||||
|  |    :start-after: begin: | ||||||
|  |    :end-before: flatten: | ||||||
|  |    :dedent: | ||||||
|  |    :caption: ``begin`` section | ||||||
|  | 
 | ||||||
|  | :yoscrypt:`read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v` loads the | ||||||
|  | iCE40 cell models which allows us to include platform specific IP blocks in our | ||||||
|  | design.  PLLs are a common example of this, where we might need to reference | ||||||
|  | ``SB_PLL40_CORE`` directly rather than being able to rely on mapping passes | ||||||
|  | later.  Since our simple design doesn't use any of these IP blocks, we can safely | ||||||
|  | skip this command. | ||||||
|  | 
 | ||||||
|  | Let's instead start with run :yoscrypt:`hierarchy -check -top counter`.  This | ||||||
|  | command declares that the top level module is ``counter``, and that we want to | ||||||
|  | expand it and any other modules it may use.  Any other modules which were loaded | ||||||
|  | are then discarded, preventing the subsequent commands from trying to work on | ||||||
|  | them. By passing the ``-check`` option there we are also telling the | ||||||
|  | :cmd:ref:`hierarchy` command that if the design includes any non-blackbox | ||||||
|  | modules without an implementation it should return an error. | ||||||
| 
 | 
 | ||||||
| .. TODO:: more on why :cmd:ref:`hierarchy` is important | .. TODO:: more on why :cmd:ref:`hierarchy` is important | ||||||
| 
 | 
 | ||||||
|  | @ -108,27 +121,22 @@ Our circuit now looks like this: | ||||||
| 
 | 
 | ||||||
| .. figure:: /_images/code_examples/intro/counter_00.* | .. figure:: /_images/code_examples/intro/counter_00.* | ||||||
|    :class: width-helper |    :class: width-helper | ||||||
|    :name: counter-hierarchy |  | ||||||
| 
 | 
 | ||||||
|    ``counter`` module after :cmd:ref:`hierarchy` |    ``counter`` module after :cmd:ref:`hierarchy` | ||||||
| 
 | 
 | ||||||
| .. seealso:: Advanced usage docs for :doc:`/using_yosys/more_scripting/load_design` |  | ||||||
| 
 |  | ||||||
| Elaboration |  | ||||||
| ~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
| Notice that block that says "PROC" in :ref:`counter-hierarchy`?  Simple | Notice that block that says "PROC" in :ref:`counter-hierarchy`?  Simple | ||||||
| operations like ``count + 2'd1`` can be extracted from our ``always @`` block in | operations like ``count + 2'd1`` can be extracted from our ``always @`` block in | ||||||
| :ref:`counter-v`.  This gives us the ``$add`` cell we see.  But control logic, | :ref:`counter-v`.  This gives us the ``$add`` cell we see.  But control logic | ||||||
| like the ``if .. else``; and memory elements, like the ``count <='2d0``; are not | (like the ``if .. else``) and memory elements (like the ``count <='2d0``) are | ||||||
| so straightforward. To handle these, let us now introduce a new command: | not so straightforward. To handle these, let us now introduce the next command: | ||||||
| :doc:`/cmd/proc`. | :doc:`/cmd/proc`. | ||||||
| 
 | 
 | ||||||
| :cmd:ref:`proc` is a macro command; running a series of other commands which | :cmd:ref:`proc` is a macro command like :cmd:ref:`synth_ice40`.  Rather than | ||||||
| work to convert the behavioral logic of processes into multiplexers and | processing our design itself, it instead calls a series of other commands.  In | ||||||
| registers.  We go into more detail on :cmd:ref:`proc` later in | the case of :cmd:ref:`proc`, these sub-commands work to convert the behavioral | ||||||
| :doc:`/using_yosys/synthesis/proc`, but for now let's see what happens when we | logic of processes into multiplexers and registers.  We go into more detail on | ||||||
| run it. | :cmd:ref:`proc` later in :doc:`/using_yosys/synthesis/proc`, but for now let's | ||||||
|  | see what happens when we run it. | ||||||
| 
 | 
 | ||||||
| .. figure:: /_images/code_examples/intro/counter_proc.* | .. figure:: /_images/code_examples/intro/counter_proc.* | ||||||
|    :class: width-helper |    :class: width-helper | ||||||
|  | @ -136,40 +144,42 @@ run it. | ||||||
|    ``counter`` module after :cmd:ref:`proc` |    ``counter`` module after :cmd:ref:`proc` | ||||||
| 
 | 
 | ||||||
| The ``if`` statements are now modeled with ``$mux`` cells, and the memory | The ``if`` statements are now modeled with ``$mux`` cells, and the memory | ||||||
| consists of a ``$dff`` cell.  That's getting a bit messy now, so let's chuck in | consists of a ``$dff`` cell. | ||||||
| a call to :cmd:ref:`opt`. |  | ||||||
| 
 | 
 | ||||||
| .. figure:: /_images/code_examples/intro/counter_01.* | .. seealso:: Advanced usage docs for | ||||||
|    :class: width-helper |    :doc:`/using_yosys/synthesis/proc` | ||||||
| 
 | 
 | ||||||
|    ``counter`` module after :cmd:ref:`opt` | Flattening | ||||||
| 
 | ~~~~~~~~~~ | ||||||
| Much better.  We can now see that the ``$dff`` and ``$mux`` cells have been |  | ||||||
| replaced with a single ``$sdffe``, using the built-in enable and reset ports |  | ||||||
| instead. |  | ||||||
| 
 |  | ||||||
| .. TODO:: a bit more on :cmd:ref:`opt` here |  | ||||||
| 
 | 
 | ||||||
| At this stage of a synthesis flow there are a few other commands we could run. | At this stage of a synthesis flow there are a few other commands we could run. | ||||||
| First off is :cmd:ref:`flatten`.  If we had any modules within our ``counter``, | First off is :cmd:ref:`flatten`.  If we had any modules within our ``counter``, | ||||||
| this would replace them with their implementation.  Flattening the design like | this would replace them with their implementation.  Flattening the design like | ||||||
| this can allow for optimizations between modules which would otherwise be | this can allow for optimizations between modules which would otherwise be | ||||||
| missed.  Next is :doc:`/cmd/check`. | missed. | ||||||
| 
 | 
 | ||||||
| Depending on the target architecture, we might also run commands such as | Depending on the target architecture, we might also run commands such as | ||||||
| :cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`.  These | :cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`.  These | ||||||
| remove tristate and inout constructs respectively, replacing them with logic | remove tristate and inout constructs respectively, replacing them with logic | ||||||
| suitable for mapping to an FPGA. | suitable for mapping to an FPGA. | ||||||
| 
 | 
 | ||||||
| .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/proc` | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
|  |    :language: yoscrypt | ||||||
|  |    :start-after: flatten: | ||||||
|  |    :end-before: coarse: | ||||||
|  |    :dedent: | ||||||
|  |    :name: flatten | ||||||
|  |    :caption: ``flatten`` section | ||||||
|  | 
 | ||||||
|  | The iCE40 flow puts these commands into thier own :ref:`flatten`, | ||||||
|  | while some synthesis scripts will instead include them in the next section. | ||||||
| 
 | 
 | ||||||
| The coarse-grain representation | The coarse-grain representation | ||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
| 
 | 
 | ||||||
| At this stage, the design is in coarse-grain representation.  It still looks | At this stage, the design is in coarse-grain representation.  It still looks | ||||||
| recognizable, and cells are word-level operators with parametrizable width. | recognizable, and cells are word-level operators with parametrizable width. This | ||||||
| There isn't much else we can do for our ``counter`` example, but this is the | is the stage of synthesis where we do things like const propagation, expression | ||||||
| stage of synthesis where we do things like const propagation, expression |  | ||||||
| rewriting, and trimming unused parts of wires. | rewriting, and trimming unused parts of wires. | ||||||
| 
 | 
 | ||||||
| This is also where we convert our FSMs and hard blocks like DSPs or memories. | This is also where we convert our FSMs and hard blocks like DSPs or memories. | ||||||
|  | @ -177,59 +187,90 @@ Such elements have to be inferred from patterns in the design and there are | ||||||
| special passes for each.  Detection of these patterns can also be affected by | special passes for each.  Detection of these patterns can also be affected by | ||||||
| optimizations and other transformations done previously. | optimizations and other transformations done previously. | ||||||
| 
 | 
 | ||||||
|  | In the iCE40 flow we get all the following commands: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
|  |    :language: yoscrypt | ||||||
|  |    :start-after: coarse: | ||||||
|  |    :end-before: map_ram: | ||||||
|  |    :dedent: | ||||||
|  |    :caption: ``coarse`` section | ||||||
|  | 
 | ||||||
| .. TODO:: talk more about DSPs (and their associated commands) | .. TODO:: talk more about DSPs (and their associated commands) | ||||||
| 
 | 
 | ||||||
|  | .. TODO:: example_syth ``coarse`` section | ||||||
|  | 
 | ||||||
| Some of the commands we might use here are: | Some of the commands we might use here are: | ||||||
| 
 | 
 | ||||||
|  | - :doc:`/cmd/opt_expr`, | ||||||
|  | - :doc:`/cmd/opt_clean`, | ||||||
|  | - :doc:`/cmd/check`, | ||||||
|  | - :doc:`/cmd/opt`, | ||||||
| - :doc:`/cmd/fsm`, | - :doc:`/cmd/fsm`, | ||||||
| - :doc:`/cmd/memory`, |  | ||||||
| - :doc:`/cmd/wreduce`, | - :doc:`/cmd/wreduce`, | ||||||
| - :doc:`/cmd/peepopt`, | - :doc:`/cmd/peepopt`, | ||||||
|  | - :doc:`/cmd/memory`, | ||||||
| - :doc:`/cmd/pmuxtree`, | - :doc:`/cmd/pmuxtree`, | ||||||
| - :doc:`/cmd/alumacc`, and | - :doc:`/cmd/alumacc`, and | ||||||
| - :doc:`/cmd/share`. | - :doc:`/cmd/share`. | ||||||
| 
 | 
 | ||||||
| .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/fsm`, and  | .. seealso:: Advanced usage docs for | ||||||
|    :doc:`/using_yosys/synthesis/memory` |    :doc:`/using_yosys/synthesis/fsm`, | ||||||
|  |    :doc:`/using_yosys/synthesis/memory`, and | ||||||
|  |    :doc:`/using_yosys/synthesis/opt` | ||||||
| 
 | 
 | ||||||
| Logic gate mapping | Hardware mapping | ||||||
| ~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~ | ||||||
| 
 | 
 | ||||||
| .. TODO:: example_synth mapping to gates | .. TODO:: example_synth hardware mapping sections | ||||||
| 
 | 
 | ||||||
| :yoscrypt:`techmap` - Map coarse-grain RTL cells (adders, etc.) to fine-grain | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
| logic gates (AND, OR, NOT, etc.). |    :language: yoscrypt | ||||||
|  |    :start-after: map_ram: | ||||||
|  |    :end-before: map_ffram: | ||||||
|  |    :dedent: | ||||||
|  |    :name: map_ram | ||||||
|  |    :caption: ``map_ram`` section | ||||||
| 
 | 
 | ||||||
| When :cmd:ref:`techmap` is used without a map file, it uses a built-in map file | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
| to map all RTL cell types to a generic library of built-in logic gates and |    :language: yoscrypt | ||||||
| registers. |    :start-after: map_ffram: | ||||||
|  |    :end-before: map_gates: | ||||||
|  |    :dedent: | ||||||
|  |    :name: map_ffram | ||||||
|  |    :caption: ``map_ffram`` section | ||||||
| 
 | 
 | ||||||
| The built-in logic gate types are: ``$_NOT_``, ``$_AND_``, ``$_OR_``, | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
| ``$_XOR_``, and ``$_MUX_``. |    :language: yoscrypt | ||||||
|  |    :start-after: map_gates: | ||||||
|  |    :end-before: map_ffs: | ||||||
|  |    :dedent: | ||||||
|  |    :name: map_gates | ||||||
|  |    :caption: ``map_gates`` section | ||||||
| 
 | 
 | ||||||
| See :doc:`/yosys_internals/formats/cell_library` for more about the internal | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
| cells used. |    :language: yoscrypt | ||||||
|  |    :start-after: map_ffs: | ||||||
|  |    :end-before: map_luts: | ||||||
|  |    :dedent: | ||||||
|  |    :name: map_ffs | ||||||
|  |    :caption: ``map_ffs`` section | ||||||
| 
 | 
 | ||||||
| .. figure:: /_images/code_examples/intro/counter_02.* | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
|    :class: width-helper |    :language: yoscrypt | ||||||
|  |    :start-after: map_luts: | ||||||
|  |    :end-before: map_cells: | ||||||
|  |    :dedent: | ||||||
|  |    :name: map_luts | ||||||
|  |    :caption: ``map_luts`` section | ||||||
| 
 | 
 | ||||||
|    ``counter`` after :cmd:ref:`techmap` | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
| 
 |    :language: yoscrypt | ||||||
| Mapping to hardware |    :start-after: map_cells: | ||||||
| ~~~~~~~~~~~~~~~~~~~ |    :end-before: check: | ||||||
| 
 |    :dedent: | ||||||
| .. TODO:: example_synth mapping to hardware |    :name: map_cells | ||||||
| 
 |    :caption: ``map_cells`` section | ||||||
| :ref:`cmos_lib` |  | ||||||
| 
 |  | ||||||
| #. :yoscrypt:`dfflibmap -liberty mycells.lib` - Map registers to available |  | ||||||
|    hardware flip-flops. |  | ||||||
| #. :yoscrypt:`abc -liberty mycells.lib` - Map logic to available hardware gates. |  | ||||||
| 
 |  | ||||||
| .. figure:: /_images/code_examples/intro/counter_03.* |  | ||||||
|    :class: width-helper |  | ||||||
| 
 |  | ||||||
|    ``counter`` after hardware cell mapping |  | ||||||
| 
 | 
 | ||||||
| :cmd:ref:`dfflibmap` | :cmd:ref:`dfflibmap` | ||||||
|     This command maps the internal register cell types to the register types |     This command maps the internal register cell types to the register types | ||||||
|  | @ -247,28 +288,23 @@ Mapping to hardware | ||||||
| :cmd:ref:`dfflegalize` | :cmd:ref:`dfflegalize` | ||||||
|     Specify a set of supported FF cells/cell groups and convert all FFs to them. |     Specify a set of supported FF cells/cell groups and convert all FFs to them. | ||||||
| 
 | 
 | ||||||
| .. seealso:: Advanced usage docs for :doc:`/yosys_internals/techmap` | .. seealso:: Advanced usage docs for | ||||||
|  |    :doc:`/yosys_internals/techmap`, and | ||||||
|  |    :doc:`/using_yosys/synthesis/memory`. | ||||||
| 
 | 
 | ||||||
| .. _cmos_lib: | Final steps | ||||||
|  | ~~~~~~~~~~~~ | ||||||
| 
 | 
 | ||||||
| The CMOS cell library | .. TODO:: example_synth final steps (check section and outputting) | ||||||
| ^^^^^^^^^^^^^^^^^^^^^ |  | ||||||
| 
 | 
 | ||||||
| .. literalinclude:: /code_examples/intro/mycells.lib | .. literalinclude:: /cmd/synth_ice40.rst | ||||||
|    :language: Liberty |  | ||||||
|    :caption: ``docs/source/code_examples/intro/mycells.lib`` |  | ||||||
| 
 |  | ||||||
| The script file |  | ||||||
| ~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
| #. :yoscrypt:`read_verilog -defer counter.v` |  | ||||||
| #. :yoscrypt:`clean` - Clean up the design (just the last step of |  | ||||||
|    :cmd:ref:`opt`). |  | ||||||
| #. :yoscrypt:`write_verilog synth.v` - Write final synthesis result to output |  | ||||||
|    file. |  | ||||||
| 
 |  | ||||||
| .. literalinclude:: /code_examples/intro/counter.ys |  | ||||||
|    :language: yoscrypt |    :language: yoscrypt | ||||||
|    :caption: ``docs/source/code_examples/intro/counter.ys`` |    :start-after: check: | ||||||
|  |    :end-before: blif: | ||||||
|  |    :dedent: | ||||||
|  |    :name: check | ||||||
|  |    :caption: ``check`` section | ||||||
| 
 | 
 | ||||||
| .. seealso:: Advanced usage docs for :doc:`/using_yosys/synthesis/synth` | - :doc:`/cmd/check` | ||||||
|  | - :doc:`/cmd/autoname` | ||||||
|  | - :doc:`/cmd/stat` | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ | ||||||
| 
 | 
 | ||||||
| .. todo:: less academic, check text is coherent | .. todo:: less academic, check text is coherent | ||||||
| 
 | 
 | ||||||
|  | .. TODO:: can we split some of this into synthesis/techmap ? | ||||||
|  | 
 | ||||||
| Technology mapping  | Technology mapping  | ||||||
| ================== | ================== | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue