Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QuickStart] Yosys/Parmys Update #2776

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 95 additions & 60 deletions doc/src/quickstart/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
VTR Quick Start
###############

This is a quick introduction to VTR which covers how to run VTR and some of its associated tools (:ref:`VPR`, :ref:`odin_ii`, :ref:`ABC`).
This is a quick introduction to VTR which covers how to run VTR and some of its associated tools (:ref:`VPR`, :ref:`Parmys`, :ref:`ABC`).

Setting Up VTR
==============
Expand Down Expand Up @@ -48,14 +48,6 @@ On most unix-like systems you can run:

> make

The default front-end for VTR is :ref:`Parmys<parmys>`, but you can build with ODIN II instead using the command below. This is required to run :ref:`Synthesizing with ODIN II<synthesizing_with_odin_ii>`.

.. code-block:: bash

> make CMAKE_PARAMS="-DWITH_ODIN=on"

from the VTR root directory (hereafter referred to as :term:`$VTR_ROOT`) to build VTR.

.. note::

In the VTR documentation lines starting with ``>`` (like ``> make`` above), indicate a command (i.e. ``make``) to run from your terminal.
Expand Down Expand Up @@ -198,7 +190,7 @@ As an exercise try the following:

.. figure:: tseng_blk1.png

Input (blue)/output (red) nets of block ``n_n3199`` (highlighted green).
Input (blue)/output (red) nets of block ``n_n3226`` (highlighted green).

.. note::
If you do not provide :option:`--analysis <vpr --analysis>`, VPR will re-implement the circuit from scratch.
Expand Down Expand Up @@ -239,52 +231,32 @@ Let's start by making a fresh directory for us to work in:

Next we need to run the three main sets of tools:

* :ref:`odin_ii` performs 'synthesis' which converts our behavioural Verilog (``.v`` file) into a circuit netlist (``.blif`` file) consisting of logic equations and FPGA architecture primitives (Flip-Flops, adders etc.),
* :ref:`Parmys` performs 'synthesis' which converts our behavioural Verilog (``.v`` file) into a circuit netlist (``.blif`` file) consisting of logic equations and FPGA architecture primitives (Flip-Flops, adders etc.),
* :ref:`ABC` performs 'logic optimization' which simplifies the circuit logic, and 'technology mapping' which converts logic equations into the Look-Up-Tables (LUTs) available on an FPGA, and
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved
* :ref:`VPR` which performs packing, placement and routing of the circuit to implement it on the targeted FPGA architecture.

.. _synthesizing_with_odin_ii:
Synthesizing with ODIN II
.. _synthesizing_with_parmys:
Synthesizing with Parmys
~~~~~~~~~~~~~~~~~~~~~~~~~

First we'll run ODIN II on our Verilog file to synthesize it into a circuit netlist, providing the options:
To synthesize our Verilog file into a circuit netlist, we will utilize the `run_vtr_flow.py` script, which streamlines the process. This command synthesizes the provided Verilog file (`blink.v`) while targeting the specified FPGA architecture (`EArch.xml`).

* ``-a $VTR_ROOT/vtr_flow/arch/timing/EArch.xml`` which specifies what FPGA architecture we are targeting,
* ``-V $VTR_ROOT/doc/src/quickstart/blink.v`` which specifies the verilog file we want to synthesize, and
* ``-o blink.odin.blif`` which specifies the name of the generated ``.blif`` circuit netlist.

The resulting command is:
The command is as follows:

.. code-block:: bash

> $VTR_ROOT/odin_ii/odin_ii \
-a $VTR_ROOT/vtr_flow/arch/timing/EArch.xml \
-V $VTR_ROOT/doc/src/quickstart/blink.v \
-o blink.odin.blif

which when run should end with something like::

Total time: 14.7ms
Odin ran with exit status: 0
Odin II took 0.01 seconds (max_rss 5.1 MiB)

where ``Odin ran with exit status: 0`` indicates Odin successfully synthesized our verilog.
> $VTR_ROOT/vtr_flow/scripts/run_vtr_flow.py \
$VTR_ROOT/doc/src/quickstart/blink.v \
$VTR_ROOT/vtr_flow/arch/timing/EArch.xml \
-start parmys -end parmys

We can now take a look at the circuit which ODIN produced (``blink.odin.blif``).
The file is long and likely harder to follow than our code in ``blink.v``; however it implements the same functionality.
Some interesting highlights are shown below:
When executed, the output should indicate successful synthesis, similar to:

.. literalinclude:: blink.odin.blif
:lines: 14,40
:caption: Instantiations of rising-edge triggered Latches (i.e. Flip-Flops) in ``blink.odin.blif`` (implements part of ``r_counter`` in blink.v)
EArch/blink OK (took 0.16 seconds, overall memory peak 20.00 MiB consumed by parmys run)

.. literalinclude:: blink.odin.blif
:lines: 17-19,21-22
:caption: Adder primitive instantiations in ``blink.odin.blif``, used to perform addition (implements part of the ``+`` operator in blink.v)
This output confirms that the synthesis was successful and provides information on the duration and memory usage during the process.

.. literalinclude:: blink.odin.blif
:lines: 45-50
:caption: Logic equation (.names truth-table) in ``blink.odin.blif``, implementing logical OR (implements part of the ``<`` operator in blink.v)
We can now take a look at the circuit which Parmys produced (``blink.parmys.blif``).

.. seealso:: For more information on the BLIF file format see :ref:`blif_format`.

Expand All @@ -297,9 +269,9 @@ Next, we'll optimize and technology map our circuit using ABC, providing the opt

We'll use the following, simple ABC commands::

ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved
read blink.odin.blif; #Read the circuit synthesized by ODIN
read blink.parmys.blif; #Read the circuit synthesized by Parmys
if -K 6; #Technology map to 6 input LUTs (6-LUTs)
write_hie blink.odin.blif blink.abc_no_clock.blif #Write new circuit to blink.abc_no_clock.blif
write_hie blink.parmys.blif blink.abc_no_clock.blif #Write new circuit to blink.abc_no_clock.blif

.. note:: Usually you should use a more complicated script (such as that used by :ref:`run_vtr_flow`) to ensure ABC optitmizes your circuit well.

Expand All @@ -308,17 +280,18 @@ The corresponding command to run is:
.. code-block:: bash

> $VTR_ROOT/abc/abc \
-c 'read blink.odin.blif; if -K 6; write_hie blink.odin.blif blink.abc_no_clock.blif'
-c 'read ~/vtr_work/quickstart/blink_manual/temp/blink.parmys.blif; if -K 6; write_hie ~/vtr_work/quickstart/blink_manual/temp/blink.parmys.blif ~/vtr_work/quickstart/blink_manual/temp/blink.abc_no_clock.blif'


When run, ABC's output should look similar to::

ABC command line: "read blink.odin.blif; if -K 6; write_hie blink.odin.blif blink.abc_no_clock.blif".
ABC command line: "read blink.parmys.blif; if -K 6; write_hie blink.parmys.blif blink.abc_no_clock.blif".

Hierarchy reader converted 6 instances of blackboxes.
The network was strashed and balanced before FPGA mapping.
Hierarchy writer reintroduced 6 instances of blackboxes.

If we now inspect the produced BLIF file (``blink.abc_no_clock.blif``) we see that ABC was able to significantly simplify and optimize the circuit's logic (compared to ``blink.odin.blif``):
If we now inspect the produced BLIF file (``blink.abc_no_clock.blif``) we see that ABC was able to significantly simplify and optimize the circuit's logic (compared to ``blink.parmys.blif``):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look at the two files and see if this is true. Are the number of .names significantly different? Confirm they are different a bit at least. We shouldn't say it is significantly simpler / optimized unless it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just double checked and that seems to be an error on my part as the number of .names are the same. Thanks for catching that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I think we should just simplify then to show running parmys in this section, without abc or the clock relabelling (we can leave those in the Odin-II section). If you can confirm the clock relabeling is not called for the parmys flow in run_vtr_flow that would be ideal -- then we can confidently remove it from this section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure thing. It does not appear to be called in run_vtr_flow.

My initial confusion stemmed from reading the Parmys paper, which states, "the Parmys pass is called to perform partial mapping according to the target architecture, and then a series of optimization and logic mappings are performed to convert all the remaining Yosys internal types to primitives. Next, the output is passed to ABC and VPR stages."

This led me to believe that running only the Parmys part of the flow would require a separate invocation of ABC since we are executing the command with both -start parmys and -end parmys, it explicitly skips the ABC.

I will update the PR and also wait for final confirmation by the added members

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you were right and I was wrong @ZohairZaidi ! After talking to Ken Kent at UNB, it does seem we need to run ABC and the clock add/removal script after Parmys. So I think your original edits were right. Can you run the flow to check exactly what happens in run_vtr_flow with parmys? I think it runs ABC and the clock recovery script after all, so we should document them again.

I also think we should change the order of the text. After saying how to run vpr, I think we should say how to use run_vtr_flow with parmys to synthesize, place and route a circuit. Then we can have a "running manually" section to dig more into how to run each tool. Finally we can have the existing Odin II section.


.. literalinclude:: blink.abc_no_clock.blif
:linenos:
Expand All @@ -332,14 +305,14 @@ However, there is an issue with the above BLIF produced by ABC: the latches (ris

Re-inserting clocks
^^^^^^^^^^^^^^^^^^^
We will restore the clock information by running a script which will transfer that information from the original ODIN BLIF file (writing it to the new file ``blink.pre-vpr.blif``):
We will restore the clock information by running a script which will transfer that information from the original Parmys BLIF file (writing it to the new file ``blink.pre-vpr.blif``):
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: bash

> $VTR_ROOT/vtr_flow/scripts/restore_multiclock_latch.pl \
blink.odin.blif \
blink.abc_no_clock.blif \
blink.pre-vpr.blif
~/vtr_work/quickstart/blink_manual/temp/blink.parmys.blif \
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved
~/vtr_work/quickstart/blink_manual/temp/blink.abc_no_clock.blif \
~/vtr_work/quickstart/blink_manual/temp/blink.pre-vpr.blif

If we inspect ``blink.pre-vpr.blif`` we now see that the clock (``blink^clk``) has been restored to the Flip-Flops:

Expand Down Expand Up @@ -370,7 +343,7 @@ The resulting command is:

> $VTR_ROOT/vpr/vpr \
$VTR_ROOT/vtr_flow/arch/timing/EArch.xml \
blink --circuit_file blink.pre-vpr.blif \
~/vtr_work/quickstart/blink_manual/temp/blink.pre-vpr.blif \
--route_chan_width 100

and after VPR finishes we should see the resulting implementation files:
Expand All @@ -387,7 +360,7 @@ We can then view the implementation as usual by appending ``--analysis --disp on

> $VTR_ROOT/vpr/vpr \
$VTR_ROOT/vtr_flow/arch/timing/EArch.xml \
blink --circuit_file blink.pre-vpr.blif \
~/vtr_work/quickstart/blink_manual/temp/blink.pre-vpr.blif \
--route_chan_width 100 \
--analysis --disp on

Expand Down Expand Up @@ -440,16 +413,16 @@ which should produce output similar to::

EArch/blink OK (took 0.26 seconds)

There are also multiple log files (including for ABC, ODIN and VPR), which by convention the script names with the ``.out`` suffix:
There are also multiple log files (including for ABC, Parmys and VPR), which by convention the script names with the ``.out`` suffix:
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: bash

> ls *.out

0_blackboxing_latch.out odin.out report_clocks.abc.out vanilla_restore_clocks.out
0_blackboxing_latch.out parmys.out report_clocks.abc.out vanilla_restore_clocks.out
abc0.out report_clk.out restore_latch0.out vpr.out

With the main log files of interest including the ODIN log file (``odin.out``), log files produced by ABC (e.g. ``abc0.out``), and the VPR log file (``vpr.out``).
With the main log files of interest including the Parmys log file (``parmys.out``), log files produced by ABC (e.g. ``abc0.out``), and the VPR log file (``vpr.out``).

.. note::

Expand All @@ -462,10 +435,10 @@ You will also see there are several BLIF files produced:

> ls *.blif

0_blink.abc.blif 0_blink.raw.abc.blif blink.odin.blif
0_blink.odin.blif blink.abc.blif blink.pre-vpr.blif
0_blink.abc.blif 0_blink.raw.abc.blif blink.parmys.blif
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved
0_blink.parmys.blif blink.abc.blif blink.pre-vpr.blif

With the main files of interest being ``blink.odin.blif`` (netlist produced by ODIN), ``blink.abc.blif`` (final netlist produced by ABC after clock restoration), ``blink.pre-vpr.blif`` netlist used by VPR (usually identical to ``blink.abc.blif``).
With the main files of interest being ``blink.parmys.blif`` (netlist produced by Parmys), ``blink.abc.blif`` (final netlist produced by ABC after clock restoration), ``blink.pre-vpr.blif`` netlist used by VPR (usually identical to ``blink.abc.blif``).

Like before, we can also see the implementation files generated by VPR:

Expand All @@ -485,6 +458,68 @@ which we can visualize with:
--route_chan_width 100 \
--analysis --disp on

Manually Running VTR with ODIN II
----------------------------------
Let's start by making a new directory for us to work in:
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: bash

> mkdir -p ~/vtr_work/quickstart/blink_manual
> cd ~/vtr_work/quickstart/blink_manual

To synthesize your Verilog design with ODIN II, you need to build VTR with the following command:

.. code-block:: bash

> make CMAKE_PARAMS="-DWITH_ODIN=on"
ZohairZaidi marked this conversation as resolved.
Show resolved Hide resolved

This step enables ODIN II support in the VTR build process, which is essential for the subsequent synthesis operations.


Next, run ODIN II on your Verilog file to synthesize it into a circuit netlist. Use the command below, specifying the required options:

* ``-a $VTR_ROOT/vtr_flow/arch/timing/EArch.xml`` which specifies what FPGA architecture we are targeting,
* ``-V $VTR_ROOT/doc/src/quickstart/blink.v`` which specifies the verilog file we want to synthesize, and
* ``-o blink.odin.blif`` which specifies the name of the generated ``.blif`` circuit netlist.

The resulting command is:

.. code-block:: bash

> $VTR_ROOT/odin_ii/odin_ii \
-a $VTR_ROOT/vtr_flow/arch/timing/EArch.xml \
-V $VTR_ROOT/doc/src/quickstart/blink.v \
-o blink.odin.blif

After running the command, you should see an output similar to the following::

Total time: 14.7ms
Odin ran with exit status: 0
Odin II took 0.01 seconds (max_rss 5.1 MiB)

where ``Odin ran with exit status: 0`` indicates Odin successfully synthesized our verilog.

We can now take a look at the circuit which ODIN produced (``blink.odin.blif``).
The file is long and likely harder to follow than our code in ``blink.v``; however it implements the same functionality.
Some interesting highlights are shown below:

.. literalinclude:: blink.odin.blif
:lines: 14,40
:caption: Instantiations of rising-edge triggered Latches (i.e. Flip-Flops) in ``blink.odin.blif`` (implements part of ``r_counter`` in blink.v)

.. literalinclude:: blink.odin.blif
:lines: 17-19,21-22
:caption: Adder primitive instantiations in ``blink.odin.blif``, used to perform addition (implements part of the ``+`` operator in blink.v)

.. literalinclude:: blink.odin.blif
:lines: 45-50
:caption: Logic equation (.names truth-table) in ``blink.odin.blif``, implementing logical OR (implements part of the ``<`` operator in blink.v)

.. seealso:: For more information on the BLIF file format see :ref:`blif_format`.


After synthesizing the netlist, you can proceed to follow the steps outlined in the section titled :ref:'Optimizing and Technology Mapping with ABC' using the generated `blink.odin.blif` file instead of `blink.parmys.blif`.

Next Steps
==========
Now that you've finished the VTR quickstart, you're ready to start experimenting and using VTR.
Expand Down
Binary file modified doc/src/quickstart/tseng_blk1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified doc/src/quickstart/tseng_nets.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.