2023-12-06 18:04:46 -06:00
|
|
|
Synthesis starter
|
|
|
|
-----------------
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
This page will be a guided walkthrough of the prepackaged iCE40 FPGA synthesis
|
|
|
|
script - :cmd:ref:`synth_ice40`. We will take a simple design through each
|
|
|
|
step, looking at the commands being called and what they do to the design. While
|
|
|
|
:cmd:ref:`synth_ice40` is specific to the iCE40 platform, most of the operations
|
|
|
|
we will be discussing are common across the majority of FPGA synthesis scripts.
|
|
|
|
Thus, this document will provide a good foundational understanding of how
|
|
|
|
synthesis in Yosys is performed, regardless of the actual architecture being
|
|
|
|
used.
|
|
|
|
|
|
|
|
.. seealso:: Advanced usage docs for
|
|
|
|
:doc:`/using_yosys/synthesis/synth`
|
2023-12-06 22:14:21 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
Demo design
|
|
|
|
~~~~~~~~~~~
|
2023-12-06 18:04:46 -06:00
|
|
|
|
|
|
|
.. role:: yoscrypt(code)
|
|
|
|
:language: yoscrypt
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
First, let's quickly look at the design we'll be synthesizing:
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
.. todo:: reconsider including the whole (~77 line) design like this
|
|
|
|
|
|
|
|
.. literalinclude:: /code_examples/example_synth/example.v
|
2023-12-06 18:04:46 -06:00
|
|
|
:language: Verilog
|
|
|
|
:linenos:
|
2023-12-13 21:21:52 -06:00
|
|
|
:caption: ``example.v``
|
|
|
|
:name: example-v
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
.. todo:: example.v description
|
2023-12-06 18:04:46 -06:00
|
|
|
|
|
|
|
Loading the design
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Let's load the design into Yosys. From the command line, we can call ``yosys
|
2023-12-13 21:21:52 -06:00
|
|
|
example.v``. This will open an interactive Yosys shell session and immediately
|
|
|
|
parse the code from ``example.v`` and convert it into an Abstract Syntax Tree
|
2023-12-06 18:04:46 -06:00
|
|
|
(AST). If you are interested in how this happens, there is more information in
|
|
|
|
the document, :doc:`/yosys_internals/flow/verilog_frontend`. For now, suffice
|
|
|
|
it to say that we do this to simplify further processing of the design. You
|
|
|
|
should see something like the following:
|
|
|
|
|
|
|
|
.. code:: console
|
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
$ yosys example.v
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
-- Parsing `example.v' using frontend ` -vlog2k' --
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
1. Executing Verilog-2005 frontend: example.v
|
|
|
|
Parsing Verilog input from `example.v' to AST representation.
|
|
|
|
Storing AST representation for module `$abstract\example'.
|
|
|
|
Storing AST representation for module `$abstract\control'.
|
|
|
|
Storing AST representation for module `$abstract\data'.
|
2023-12-06 18:04:46 -06:00
|
|
|
Successfully finished Verilog frontend.
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. seealso:: Advanced usage docs for
|
|
|
|
:doc:`/using_yosys/more_scripting/load_design`
|
|
|
|
|
|
|
|
Elaboration
|
|
|
|
~~~~~~~~~~~
|
|
|
|
|
2023-12-06 18:04:46 -06:00
|
|
|
Now that we are in the interactive shell, we can call Yosys commands directly.
|
2023-12-13 21:21:52 -06:00
|
|
|
Our overall goal is to call :yoscrypt:`synth_ice40 -top example`, but for now we
|
2023-12-13 16:30:51 -06:00
|
|
|
can run each of the commands individually for a better sense of how each part
|
2023-12-13 21:21:52 -06:00
|
|
|
contributes to the flow. We will also start with just a single module;
|
|
|
|
``control``.
|
|
|
|
|
|
|
|
At the bottom of the :cmd:ref:`help` output for
|
2023-12-13 16:30:51 -06:00
|
|
|
:cmd:ref:`synth_ice40` is the complete list of commands called by this script.
|
|
|
|
Let's start with the section labeled ``begin``:
|
|
|
|
|
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: begin:
|
|
|
|
:end-before: flatten:
|
|
|
|
:dedent:
|
|
|
|
:caption: ``begin`` section
|
2023-12-13 21:21:52 -06:00
|
|
|
:name: synth_begin
|
2023-12-13 16:30:51 -06:00
|
|
|
|
|
|
|
: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.
|
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
The control module
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy
|
|
|
|
-top control`. This command declares that the top level module is ``control``,
|
|
|
|
and everything else can be discarded.
|
|
|
|
|
|
|
|
.. literalinclude:: /code_examples/example_synth/example.v
|
|
|
|
:language: Verilog
|
|
|
|
:start-at: module control
|
|
|
|
:end-at: endmodule //control
|
|
|
|
:lineno-match:
|
|
|
|
:caption: ``control`` module source
|
|
|
|
:name: control-v
|
2023-12-06 18:04:46 -06:00
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
:cmd:ref:`hierarchy` should always be the first command after the design has
|
|
|
|
been read.
|
|
|
|
|
|
|
|
.. use doscon for a console-like display that supports the `yosys> [command]` format.
|
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
.. literalinclude:: /code_examples/example_synth/example.out
|
|
|
|
:language: doscon
|
|
|
|
:start-at: yosys> hierarchy -top control
|
|
|
|
:end-before: yosys> show
|
|
|
|
:caption: :yoscrypt:`hierarchy -top control` output
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
Our ``control`` circuit now looks like this:
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
.. figure:: /_images/code_examples/example_synth/control_hier.*
|
2023-12-06 18:04:46 -06:00
|
|
|
:class: width-helper
|
2023-12-13 21:21:52 -06:00
|
|
|
:name: control_hier
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
``control`` module after :cmd:ref:`hierarchy`
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
Notice that block that says "PROC" in :ref:`control_hier`? Simple operations
|
|
|
|
like ``addr + 1'b1`` can be extracted from our ``always @`` block in
|
|
|
|
:ref:`control-v`. This gives us the two ``$add`` cells we see. But control
|
|
|
|
logic (like the ``if .. else``) and memory elements (like the ``addr <= 0``) are
|
2023-12-13 16:30:51 -06:00
|
|
|
not so straightforward. To handle these, let us now introduce the next command:
|
2023-12-06 18:04:46 -06:00
|
|
|
:doc:`/cmd/proc`.
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
:cmd:ref:`proc` is a macro command like :cmd:ref:`synth_ice40`. Rather than
|
2023-12-13 21:21:52 -06:00
|
|
|
modifying the design directly, it instead calls a series of other commands. In
|
2023-12-13 16:30:51 -06:00
|
|
|
the case of :cmd:ref:`proc`, these sub-commands work to convert the behavioral
|
2023-12-13 21:21:52 -06:00
|
|
|
logic of processes into multiplexers and registers. Let's see what happens when
|
|
|
|
we run it.
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
.. figure:: /_images/code_examples/example_synth/control_proc.*
|
2023-12-06 18:04:46 -06:00
|
|
|
:class: width-helper
|
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
``control`` module after :cmd:ref:`proc`
|
|
|
|
|
|
|
|
The ``if`` statements are now modeled with ``$mux`` cells, while the registers
|
|
|
|
use ``$dff`` cells. If we look at the terminal output we can also see all of
|
|
|
|
the different ``proc_*`` commands being called. We will look at each of these
|
|
|
|
in more detail in :doc:`/using_yosys/synthesis/proc`.
|
|
|
|
|
|
|
|
The full example
|
|
|
|
^^^^^^^^^^^^^^^^
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
Let's now go back and check on our full design by using :yoscrypt:`hierarchy
|
|
|
|
-check -top example`. By passing the ``-check`` option there we are also
|
|
|
|
telling the :cmd:ref:`hierarchy` command that if the design includes any
|
|
|
|
non-blackbox modules without an implementation it should return an error.
|
|
|
|
|
|
|
|
Note that if we tried to run this command now then we would get an error. This
|
|
|
|
is because we already removed all of the modules other than ``control``. We
|
|
|
|
could restart our shell session, but instead let's use two new commands:
|
|
|
|
|
|
|
|
- :doc:`/cmd/design`, and
|
|
|
|
- :doc:`/cmd/read_verilog`.
|
|
|
|
|
|
|
|
.. literalinclude:: /code_examples/example_synth/example.out
|
|
|
|
:language: doscon
|
|
|
|
:start-at: design -reset
|
|
|
|
:end-before: yosys> show
|
|
|
|
:caption: reloading ``example.v`` and running :yoscrypt:`hierarchy -check -top example`
|
|
|
|
|
|
|
|
Notice how this time we didn't see any of those `$abstract` modules? That's
|
|
|
|
because when we ran ``yosys example.v``, the first command Yosys called was
|
|
|
|
:yoscrypt:`read_verilog -defer example.v`. The ``-defer`` option there tells
|
|
|
|
:cmd:ref:`read_verilog` only read the abstract syntax tree and defer actual
|
|
|
|
compilation to a later :cmd:ref:`hierarchy` command. This is useful in cases
|
|
|
|
where the default parameters of modules yield invalid or not synthesizable code,
|
|
|
|
which is why Yosys does this automatically and is one of the reasons why
|
|
|
|
hierarchy should always be the first command after loading the design. If we
|
|
|
|
know that our design won't run into this issue, we can skip the ``-defer``.
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
The number before a command's output increments with each command run. Don't
|
|
|
|
worry if your numbers don't match ours! The output you are seeing comes from
|
|
|
|
the same script that was used to generate the images in this document,
|
|
|
|
included in the source as ``example.ys``. There are extra commands being run
|
|
|
|
which you don't see, but feel free to try them yourself, or play around with
|
|
|
|
different commands. You can always start over with a clean slate by calling
|
|
|
|
``exit`` or hitting ``ctrl+c`` (i.e. SIGINT) and re-launching the Yosys
|
|
|
|
interactive terminal.
|
|
|
|
|
|
|
|
.. figure:: /_images/code_examples/example_synth/example_hier.*
|
|
|
|
:class: width-helper
|
|
|
|
:name: example_hier
|
|
|
|
|
|
|
|
``example`` module after :cmd:ref:`hierarchy`
|
|
|
|
|
|
|
|
We can also run :cmd:ref:`proc` now, although we won't actually see any change
|
|
|
|
in this top view.
|
|
|
|
|
|
|
|
.. TODO:: more on why :cmd:ref:`hierarchy` is important
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. seealso:: Advanced usage docs for
|
|
|
|
:doc:`/using_yosys/synthesis/proc`
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
Flattening
|
|
|
|
~~~~~~~~~~
|
2023-12-06 18:04:46 -06:00
|
|
|
|
|
|
|
At this stage of a synthesis flow there are a few other commands we could run.
|
2023-12-13 21:21:52 -06:00
|
|
|
In :cmd:ref:`synth_ice40` we get these:
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: flatten:
|
|
|
|
:end-before: coarse:
|
|
|
|
:dedent:
|
2023-12-13 21:21:52 -06:00
|
|
|
:name: synth_flatten
|
2023-12-13 16:30:51 -06:00
|
|
|
:caption: ``flatten`` section
|
|
|
|
|
2023-12-13 21:21:52 -06:00
|
|
|
First off is :cmd:ref:`synth_flatten`. Flattening the design like this can
|
|
|
|
allow for optimizations between modules which would otherwise be missed. We
|
|
|
|
will skip this command for now because it makes the design schematic quite
|
|
|
|
large. If you would like to see for yourself, you can do so with
|
|
|
|
:doc:`/cmd/show`. Note that the :cmd:ref:`show` command only works with a
|
|
|
|
single module, so you may need to call it with :yoscrypt:`show example`.
|
|
|
|
|
|
|
|
Depending on the target architecture, we might also see commands such as
|
|
|
|
:cmd:ref:`tribuf` with the ``-logic`` option and :cmd:ref:`deminout`. These
|
|
|
|
remove tristate and inout constructs respectively, replacing them with logic
|
|
|
|
suitable for mapping to an FPGA.
|
2023-12-07 16:19:12 -06:00
|
|
|
|
2023-12-06 18:04:46 -06:00
|
|
|
The coarse-grain representation
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
At this stage, the design is in coarse-grain representation. It still looks
|
2023-12-13 16:30:51 -06:00
|
|
|
recognizable, and cells are word-level operators with parametrizable width. This
|
|
|
|
is the stage of synthesis where we do things like const propagation, expression
|
2023-12-06 18:04:46 -06:00
|
|
|
rewriting, and trimming unused parts of wires.
|
|
|
|
|
|
|
|
This is also where we convert our FSMs and hard blocks like DSPs or memories.
|
|
|
|
Such elements have to be inferred from patterns in the design and there are
|
|
|
|
special passes for each. Detection of these patterns can also be affected by
|
|
|
|
optimizations and other transformations done previously.
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
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
|
2023-12-13 21:21:52 -06:00
|
|
|
:name: synth_coarse
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
While the iCE40 flow had a :ref:`synth_flatten` and put :cmd:ref:`proc` in
|
|
|
|
the :ref:`synth_begin`, some synthesis scripts will instead include these in
|
|
|
|
the :ref:`synth_coarse` section.
|
2023-12-13 16:30:51 -06:00
|
|
|
|
2023-12-11 17:05:45 -06:00
|
|
|
.. TODO:: talk more about DSPs (and their associated commands)
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. TODO:: example_syth ``coarse`` section
|
|
|
|
|
2023-12-06 18:04:46 -06:00
|
|
|
Some of the commands we might use here are:
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
- :doc:`/cmd/opt_expr`,
|
|
|
|
- :doc:`/cmd/opt_clean`,
|
|
|
|
- :doc:`/cmd/check`,
|
|
|
|
- :doc:`/cmd/opt`,
|
2023-12-06 18:04:46 -06:00
|
|
|
- :doc:`/cmd/fsm`,
|
|
|
|
- :doc:`/cmd/wreduce`,
|
|
|
|
- :doc:`/cmd/peepopt`,
|
2023-12-13 16:30:51 -06:00
|
|
|
- :doc:`/cmd/memory`,
|
2023-12-06 22:14:21 -06:00
|
|
|
- :doc:`/cmd/pmuxtree`,
|
2023-12-06 18:04:46 -06:00
|
|
|
- :doc:`/cmd/alumacc`, and
|
|
|
|
- :doc:`/cmd/share`.
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. seealso:: Advanced usage docs for
|
|
|
|
:doc:`/using_yosys/synthesis/fsm`,
|
|
|
|
:doc:`/using_yosys/synthesis/memory`, and
|
|
|
|
:doc:`/using_yosys/synthesis/opt`
|
2023-12-07 14:46:02 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
Hardware mapping
|
|
|
|
~~~~~~~~~~~~~~~~
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. TODO:: example_synth hardware mapping sections
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: map_ram:
|
|
|
|
:end-before: map_ffram:
|
|
|
|
:dedent:
|
|
|
|
:name: map_ram
|
|
|
|
:caption: ``map_ram`` section
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: map_ffram:
|
|
|
|
:end-before: map_gates:
|
|
|
|
:dedent:
|
|
|
|
:name: map_ffram
|
|
|
|
:caption: ``map_ffram`` section
|
2023-12-07 14:46:02 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: map_gates:
|
|
|
|
:end-before: map_ffs:
|
|
|
|
:dedent:
|
|
|
|
:name: map_gates
|
|
|
|
:caption: ``map_gates`` section
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: map_ffs:
|
|
|
|
:end-before: map_luts:
|
|
|
|
:dedent:
|
|
|
|
:name: map_ffs
|
|
|
|
:caption: ``map_ffs`` section
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: map_luts:
|
|
|
|
:end-before: map_cells:
|
|
|
|
:dedent:
|
|
|
|
:name: map_luts
|
|
|
|
:caption: ``map_luts`` section
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
|
|
|
:language: yoscrypt
|
|
|
|
:start-after: map_cells:
|
|
|
|
:end-before: check:
|
|
|
|
:dedent:
|
|
|
|
:name: map_cells
|
|
|
|
:caption: ``map_cells`` section
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-06 22:14:21 -06:00
|
|
|
:cmd:ref:`dfflibmap`
|
|
|
|
This command maps the internal register cell types to the register types
|
|
|
|
described in a liberty file.
|
|
|
|
|
|
|
|
:cmd:ref:`hilomap`
|
|
|
|
Some architectures require special driver cells for driving a constant hi or
|
|
|
|
lo value. This command replaces simple constants with instances of such
|
|
|
|
driver cells.
|
|
|
|
|
|
|
|
:cmd:ref:`iopadmap`
|
|
|
|
Top-level input/outputs must usually be implemented using special I/O-pad
|
|
|
|
cells. This command inserts such cells to the design.
|
|
|
|
|
|
|
|
:cmd:ref:`dfflegalize`
|
|
|
|
Specify a set of supported FF cells/cell groups and convert all FFs to them.
|
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. seealso:: Advanced usage docs for
|
|
|
|
:doc:`/yosys_internals/techmap`, and
|
|
|
|
:doc:`/using_yosys/synthesis/memory`.
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
Final steps
|
|
|
|
~~~~~~~~~~~~
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. TODO:: example_synth final steps (check section and outputting)
|
2023-12-06 18:04:46 -06:00
|
|
|
|
2023-12-13 16:30:51 -06:00
|
|
|
.. literalinclude:: /cmd/synth_ice40.rst
|
2023-12-06 18:04:46 -06:00
|
|
|
:language: yoscrypt
|
2023-12-13 16:30:51 -06:00
|
|
|
:start-after: check:
|
|
|
|
:end-before: blif:
|
|
|
|
:dedent:
|
|
|
|
:name: check
|
|
|
|
:caption: ``check`` section
|
|
|
|
|
|
|
|
- :doc:`/cmd/check`
|
|
|
|
- :doc:`/cmd/autoname`
|
|
|
|
- :doc:`/cmd/stat`
|