Merge pull request #284 from lnis-uofu/tutorials

Tutorials
This commit is contained in:
tangxifan 2021-04-19 16:00:16 -06:00 committed by GitHub
commit f7767ff4df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 355 additions and 16 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -10,3 +10,4 @@ Architecture Modeling
quick_start
user_defined_temp_tutorial
open_cell_libraries_tutorial
spypads_tutorial

View File

@ -17,7 +17,7 @@ Create and Verify the OpenFPGA Circuit Model
.. note:: In this tutorial, we focus on binding a 2-input **OR** gate from a standard cell library to a circuit model in OpenFPGA's architecture description file. Note that the approach can be generalized to any circuit model.
For this tutorial, we start with an example where the HDL netlist of an 2-input **OR** gate that is auto-generated by OpenFPGA. After updating the architecture file, the auto-generated HDL netlist by OpenFPGA will directly instantiate a standard cell from the open-source Skywater 130nm PDK library.
For this tutorial, we start with an example where the HDL netlist of an 2-input **OR** gate that is auto-generated by OpenFPGA. After updating the architecture file, the auto-generated HDL netlist created by OpenFPGA will directly instantiate a standard cell from the open-source Skywater 130nm PDK library.
To follow along, go to the root directory of OpenFPGA and enter:
.. code-block:: bash
@ -205,7 +205,7 @@ We have now finished creating the control and viewing the important sections for
Clone Skywater PDK into OpenFPGA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We will be using the open-source Skywater PDK to aid us in creating our circuit model. We start by cloning the Skywater PDK github repository into the OpenFPGA root directory.
We will be using the open-source Skywater PDK to create our circuit model. We start by cloning the Skywater PDK github repository into the OpenFPGA root directory.
Run the following command in the root directory of OpenFPGA:
.. code-block:: bash
@ -223,15 +223,15 @@ This will take some time to complete due to the size of the libraries. Once the
Create and Verify the Standard Cell Library Circuit Model
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To create the circuit model, we will modify the ``k6_frac_N10_adder_chain_40nm_openfpga.xml`` OpenFPGA architecture file. We will remove the circuit model
for OpenFPGA's **OR2** gate, replace the circuit model with one referencing the Skywater cell library, and modify the LUT that references the old **OR2**
To create the circuit model, we will modify the ``k6_frac_N10_adder_chain_40nm_openfpga.xml`` OpenFPGA architecture file by removing the circuit model
for OpenFPGA's **OR2** gate, replacing the circuit model with one referencing the Skywater cell library, and modifying the LUT that references the old **OR2**
circuit model to reference our new circuit model. We begin by running the following command in the root directory:
.. code-block:: bash
vi openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml
We begin the circuit model creation process by replacing **LINE67** to **LINE81** with the following:
We continue the circuit model creation process by replacing **LINE67** to **LINE81** with the following:
.. code-block:: xml
@ -246,8 +246,11 @@ We begin the circuit model creation process by replacing **LINE67** to **LINE81*
.. note:: The name of the circuit model must be consistent with the standard cell!
The most significant differences from the control in this section are changing the ``name`` and ``prefix`` to match the module name from Skywater's cell library and including a path
to the verilog file using ``verilog_netlist``. The second change to ``k6_frac_N10_adder_chain_40nm_openfpga.xml`` is at **LINE160**, where we will be replacing the line with the following:
The most significant differences from the OpenFPGA Circuit Model in this section are:
- Change the ``name`` and ``prefix`` to match the module name from Skywater's cell library
- Include a path to the verilog file using ``verilog_netlist``.
The second change to ``k6_frac_N10_adder_chain_40nm_openfpga.xml`` is at **LINE160**, where we will be replacing the line with the following:
.. code-block:: xml
@ -288,7 +291,7 @@ Replace all the text within ``iverilog_output.txt`` with the following:
iverilog -o compiled_and2 ./SRC/and2_include_netlists.v -s and2_top_formal_verification_random_tb -I ${OPENFPGA_PATH}/skywater-pdk/libraries/sky130_fd_sc_ls/latest/cells/or2
We can now manually rerun IVerilog, a tutorial on manually running IVerilog can be found at our From Verilog to `Verification`_ tutorial. From the root
We can now manually rerun IVerilog, a tutorial on manually running IVerilog can be found at our :ref:`from_verilog_to_verification` tutorial. From the root
directory, run the following commands:
.. code-block:: bash
@ -299,7 +302,7 @@ directory, run the following commands:
vvp compiled_and2
With IVerilog complete, we can verify the cell library has been bound correctly by viewing the ``luts.v`` file and the waveforms with GTKWave.
With IVerilog complete, we can verify that the cell library has been bound correctly by viewing the ``luts.v`` file and the waveforms with GTKWave.
From the root directory, view the ``luts.v`` file with this command:
@ -471,10 +474,12 @@ The simulation waveforms should look similar to the following :numref:`fig_custo
Simulation Waveforms with Skywater PDK Circuit Model
We have now verified that the Skywater PDK Cell Library has been instantiated and bound to the OpenFPGA architecture file. If you have any problems, please reach out to us.
We have now verified that the Skywater PDK Cell Library has been instantiated and bound to the OpenFPGA architecture file. If you have any problems, please :ref:`contact` us.
.. _Verification: https://openfpga.readthedocs.io/en/master/tutorials/design_flow/verilog2verification/
.. _PDK: https://github.com/google/skywater-pdk
.. _GTKWave: https://github.com/gtkwave/gtkwave

View File

@ -0,0 +1,332 @@
Creating Spypads Using XML Syntax
=================================
Introduction
~~~~~~~~~~~~
**In this tutorial, we will**
- Show the XML syntax for global outputs
- Showcase an example with spypads
- Modify an existing architecture to incorporate spypads
- Verify correctness through GTKWave
Through this tutorial, we will show how to create spypads in OpenFPGA.
Spypads are physical output pins on a FPGA chip through which you can read out internal signals when doing silicon-level debugging. The XML syntax for spypads and other
global signals can be found on our :ref:`circuit_library` documentation page.
To create a spypad, the ``port type`` needs to be set to **output** and ``is_global`` and ``is_io`` need to be set to **true**:
.. code-block:: xml
<port type="output" is_global="true" is_io="true"/>
When the port is syntactically correct, the outputs are independently wired from different instances to separated FPGA outputs and would physically look like :ref:`fig_gpout_ports`
Pre-Built Spypads
~~~~~~~~~~~~~~~~~
An OpenFPGA architecture file that contains spypads and has a task that references it is the `k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml <https://github.com/lnis-uofu/OpenFPGA/blob/tutorials/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml>`_
file. We can view ``k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml`` by entering the following command at the root directory of OpenFPGA:
.. code-block:: bash
emacs openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml
In this architecture file, the output ports of a 6-input Look-Up Table (LUT) are defined as spypads using the XML syntax ``is_global`` and ``is_io``. As a result, all of the outputs from the 6-input LUT will be visible in the top-level module. The output ports to the 6-input LUT are declared from **LINE181** to **LINE183** and belong to the ``frac_lut6_spypad`` ``circuit_model`` that begins at **LINE172**.
.. code-block:: xml
<circuit_model type="lut" name="frac_lut6_spypad" prefix="frac_lut6_spypad" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<lut_intermediate_buffer exist="true" circuit_model_name="buf4" location_map="-1-1-"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="6" tri_state_map="----11" circuit_model_name="OR2"/>
LINE181 <port type="output" prefix="lut4_out" size="4" lut_frac_level="4" lut_output_mask="0,1,2,3" is_global="true" is_io="true"/>
LINE182 <port type="output" prefix="lut5_out" size="2" lut_frac_level="5" lut_output_mask="0,1" is_global="true" is_io="true"/>
LINE183 <port type="output" prefix="lut6_out" size="1" lut_output_mask="0" is_global="true" is_io="true"/>
<port type="sram" prefix="sram" size="64"/>
<port type="sram" prefix="mode" size="2" mode_select="true" circuit_model_name="DFFR" default_val="1"/>
</circuit_model>
The spypads are instantiated in the top-level verilog module ``fpga_top.v``. ``fpga_top.v`` is automatically generated when we run our task from the OpenFPGA root
directory. However, we need to modify the task configuration file to run the **full testbench** instead of the **formal testbench** to view the spypads' waveforms in
GTKWave.
.. note:: To read about the differences between the **formal testbench** and the **full testbench**, please visit our page on testbenches: :ref:`testbench`.
To open the task configuration file, run this command from the root directory of OpenFPGA:
.. code-block:: bash
emacs openfpga_flow/tasks/fpga_verilog/spypad/config/task.conf
The last line of the task configuration file (**LINE44**) sets the **formal testbench** to be the desired testbench. To use the **full testbench**, comment out **LINE44**.
The file will look like this when finished:
.. code-block:: python
:linenos:
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=vpr_blif
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_spypad_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
# Cannot pass automatically. Need change in .v file to match ports
# When passed, we can replace the and2 benchmark
#bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/test_mode_low/test_mode_low.blif
[SYNTHESIS_PARAM]
bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
#bench0_top = test_mode_low
#bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/test_mode_low/test_mode_low.act
#bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/test_mode_low/test_mode_low.v
bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
#vpr_fpga_verilog_formal_verification_top_netlist=
Our OpenFPGA task will now run the full testbench. We run the task with the following command from the root directory of OpenFPGA:
.. code-block:: bash
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/spypad --debug --show_thread_logs
.. note:: Python 3.8 or later is required to run this task
We can now see the instantiation of these spypads in ``fpga_top.v`` and ``luts.v``. We will start by viewing ``luts.v`` with the following command:
.. code-block:: bash
emacs openfpga_flow/tasks/fpga_verilog/spypad/latest/k6_frac_N10_tileable_adder_register_scan_chain_depop50_spypad_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/sub_module/luts.verilog
The spypads are coming from the ``frac_lut6_spypad`` circuit model. In ``luts.v``, the ``frac_lut6_spypad`` module is defined around **LINE150** and looks as follows:
.. code-block:: verilog
module frac_lut6_spypad(in,
sram,
sram_inv,
mode,
mode_inv,
lut4_out,
lut5_out,
lut6_out);
//----- INPUT PORTS -----
input [0:5] in;
//----- INPUT PORTS -----
input [0:63] sram;
//----- INPUT PORTS -----
input [0:63] sram_inv;
//----- INPUT PORTS -----
input [0:1] mode;
//----- INPUT PORTS -----
input [0:1] mode_inv;
//----- OUTPUT PORTS -----
output [0:3] lut4_out;
//----- OUTPUT PORTS -----
output [0:1] lut5_out;
//----- OUTPUT PORTS -----
output [0:0] lut6_out;
The ``fpga_top.v`` file has some similarities. We can view the ``fpga_top.v`` file by running the following command:
.. code-block:: bash
emacs openfpga_flow/tasks/fpga_verilog/spypad/latest/k6_frac_N10_tileable_adder_register_scan_chain_depop50_spypad_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/fpga_top.v
If we look at the module definition and ports of ``fpga_top.v`` we should see the following:
.. code-block:: verilog
module fpga_top(pReset,
prog_clk,
TESTEN,
set,
reset,
clk,
gfpga_pad_frac_lut6_spypad_lut4_out,
gfpga_pad_frac_lut6_spypad_lut5_out,
gfpga_pad_frac_lut6_spypad_lut6_out,
gfpga_pad_GPIO_PAD,
ccff_head,
ccff_tail);
//----- GLOBAL PORTS -----
input [0:0] pReset;
//----- GLOBAL PORTS -----
input [0:0] prog_clk;
//----- GLOBAL PORTS -----
input [0:0] TESTEN;
//----- GLOBAL PORTS -----
input [0:0] set;
//----- GLOBAL PORTS -----
input [0:0] reset;
//----- GLOBAL PORTS -----
input [0:0] clk;
//----- GPOUT PORTS -----
output [0:3] gfpga_pad_frac_lut6_spypad_lut4_out;
//----- GPOUT PORTS -----
output [0:1] gfpga_pad_frac_lut6_spypad_lut5_out;
//----- GPOUT PORTS -----
output [0:0] gfpga_pad_frac_lut6_spypad_lut6_out;
//----- GPIO PORTS -----
inout [0:7] gfpga_pad_GPIO_PAD;
//----- INPUT PORTS -----
input [0:0] ccff_head;
//----- OUTPUT PORTS -----
output [0:0] ccff_tail;
Using :ref:`fig_gpout_ports` as a guide, we can relate our task like :numref:`fig_gpout_example`
.. _fig_gpout_example:
.. figure:: ./figures/lut6_Example_Spypad.svg
:scale: 100%
An illustrative example of the ``lut6`` spypad sourced from inside a logic element.
We can view testbench waveforms with GTKWave by running the following command from the root directory:
.. code-block:: bash
gtkwave openfpga_flow/tasks/fpga_verilog/spypad/latest/k6_frac_N10_tileable_adder_register_scan_chain_depop50_spypad_40nm/and2/MIN_ROUTE_CHAN_WIDTH/and2_formal.vcd &
.. note:: Information on GTKWave can be found on our documentation page located here: :ref:`from_verilog_to_verification`
The waveforms will appear similar to :numref:`fig_spypad_waves`
.. _fig_spypad_waves:
.. figure:: ./figures/spypad_waveforms.png
:width: 100%
Waveforms of ``frac_lut6`` spypads
Building Spypads
~~~~~~~~~~~~~~~~
We will modify the `k6_frac_N10_adder_chain_40nm_openfpga.xml <https://github.com/lnis-uofu/OpenFPGA/blob/tutorials/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml>`_ file found in OpenFPGA to expose the **sumout** output from the **ADDF** module. We can start modifying
the file by running the following command:
.. code-block:: bash
emacs openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml
Replace **LINE214** with the following:
.. code-block:: xml
<port type="output" prefix="sumout" lib_name="SUM" size="1" is_global=”true” is_io=”true”/>
**sumout** is now a global output. **sumout** will show up in the ``fpga_top.v`` file and will have waveforms in GTKWave if we run the **full testbench**. To run the
**full testbench**, we have to modify the ``hard_adder`` configuration file:
.. code-block:: bash
emacs openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf
Comment out the last line of the file to run the **full testbench**:
.. code-block:: python
#vpr_fpga_verilog_formal_verification_top_netlist=
We now run the task to see our changes:
.. code-block:: bash
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/adder/hard_adder --debug --show_thread_logs
We can view the global ports in ``fpga_top.v`` by running the following command:
.. code-block:: bash
emacs openfpga_flow/tasks/fpga_verilog/adder/hard_adder/run064/k6_frac_N10_tileable_adder_chain_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/fpga_top.v
The ``fpga_top.v`` should have the following in its module definition:
.. code-block:: verilog
module fpga_top(pReset,
prog_clk,
set,
reset,
clk,
gfpga_pad_ADDF_sumout,
gfpga_pad_GPIO_PAD,
ccff_head,
ccff_tail);
//----- GLOBAL PORTS -----
input [0:0] pReset;
//----- GLOBAL PORTS -----
input [0:0] prog_clk;
//----- GLOBAL PORTS -----
input [0:0] set;
//----- GLOBAL PORTS -----
input [0:0] reset;
//----- GLOBAL PORTS -----
input [0:0] clk;
//----- GPOUT PORTS -----
output [0:19] gfpga_pad_ADDF_sumout;
The architecture will now look like :numref:`fig_addf_example`
.. _fig_addf_example:
.. figure:: ./figures/ADDF_Example_Spypad.svg
:scale: 100%
An illustrative example of the sumout spypad sourced from an adder inside a logic element. There are 10 logic elements in a CLB, and we are looking at the 1st logic element.
We can view the waveform by running GTKWave:
.. code-block:: bash
gtkwave openfpga_flow/tasks/fpga_verilog/adder/hard_adder/latest/k6_frac_N10_tileable_adder_chain_40nm/and2/MIN_ROUTE_CHAN_WIDTH/and2_formal.vcd &
The waveform should have some changes to its value. An example of what it may look like is displayed in :numref:`fig_spy_adder`
.. _fig_spy_adder:
.. figure:: ./figures/spyadder_waveform.png
:width: 100%
Waveforms of ``sumout`` spypad
Conclusion
~~~~~~~~~~
In this tutorial, we have shown how to build spypads into OpenFPGA Architectures using XML Syntax. If you have any issues, feel free to :ref:`contact` us.

View File

@ -5,9 +5,9 @@ Introduction and Setup
**In this tutorial, we will**
- Provide the motivation for generating the user_defined_template.v verilog file
- Go through a generated user_defined_template.v file to demonstrate how to use it
Through this example, we will show how and when to use the ``user_defined_template.v`` file.
Through this tutorial, we will show how and when to use the :ref:`user_defined_template.v <fabric_netlists>` file.
For this example, we are using a modified version of the hard adder task that comes with OpenFPGA.
To begin the tutorial, we start with a modified version of the hard adder task that comes with OpenFPGA.
To follow along, go to the root directory of OpenFPGA and enter:
.. code-block:: bash
@ -74,7 +74,7 @@ This error can be resolved by replacing the **LINE187** of ``k6_frac_N10_adder_c
<circuit_model type="hard_logic" name="ADDF" prefix="ADDF" is_default="true" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/adder.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/adder.v">
The above line provides a path to generate the ``user_defined_template.v`` file.
The above line provides a path to generate the :ref:`user_defined_template.v <fabric_netlists>` file.
Now we can return to the root directory and run this command again:
.. code-block:: bash
@ -85,7 +85,7 @@ The task should now complete without any errors.
Fixing the Error with user_defined_template.v
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The `user_defined_template.v`_ file can be found starting from the root directory and entering:
The :ref:`user_defined_template.v <fabric_netlists>` file can be found starting from the root directory and entering:
.. code-block:: bash
@ -167,4 +167,3 @@ Finally, rerun this command from the OpenFPGA root directory to ensure it is wor
python3 openfpga_flow/scripts_run_fpga_task.py fpga_verilog/adder/hard_adder --debug --show_thread_logs
.. _user_defined_template.v: https://openfpga--274.org.readthedocs.build/en/274/manual/fpga_verilog/fabric_netlist/#cmdoption-arg-user_defined_templates.v