From 5f01e5e7a7dfff485bf56aa442f04925efc24a63 Mon Sep 17 00:00:00 2001 From: bbleaptrot <35536624+bbleaptrot@users.noreply.github.com> Date: Fri, 2 Apr 2021 09:54:54 -0600 Subject: [PATCH] Update file --- .../open_cell_libraries_tutorial.rst | 354 +++++++++++++++--- 1 file changed, 304 insertions(+), 50 deletions(-) diff --git a/docs/source/tutorials/arch_modeling/open_cell_libraries_tutorial.rst b/docs/source/tutorials/arch_modeling/open_cell_libraries_tutorial.rst index 391aea66f..bae8011a4 100644 --- a/docs/source/tutorials/arch_modeling/open_cell_libraries_tutorial.rst +++ b/docs/source/tutorials/arch_modeling/open_cell_libraries_tutorial.rst @@ -1,62 +1,186 @@ -Using Open-source Cell Libraries with OpenFPGA Architectures -============================================================ +Build an FPGA fabric using Standard Cell Libraries +================================================== Introduction ~~~~~~~~~~~~ **In this tutorial, we will** - - Clone the Skywater Processor Development Kit into the OpenFPGA root directory - - Use Skywater's PDK cell library to create an OR Gate circuit model for OpenFPGA - - Verify that the cell library file was correctly bound into the selected architecture file by looking at auto-generated OpenFPGA files and checking simulation waveforms in GTKWave -Through this example, we will show how to bind open-source cell library files with OpenFPGA Architectures. + - Showcase how to create an architecture description based on standard cells, using OpenFPGA's circuit modeling language + - Use Skywater's Processor Development Kit (``PDK``_) cell library to create an OR Gate circuit model for OpenFPGA + - Verify that the standard cell library file was correctly bound into the selected architecture file by looking at auto-generated OpenFPGA files and checking simulation waveforms in GTKWave +Through this example, we will show how to bind standard cell library files with OpenFPGA Architectures. -Create and Verify the Control Circuit Model -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -For this tutorial, we will first create a control that we will use to compare the final product of this tutorial with. The final product will be an **OR2** circuit model referencing Skywater's PDK cell library. +.. note:: We showcase the methodology by considering the open-source Skywater 130nm PDK so that users can easily reproduce the results. + +Create and Verify the OpenFPGA Circuit Model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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. To follow along, go to the root directory of OpenFPGA and enter: .. code-block:: bash python3 openfpga_flow/scripts_run_fpga_task.py fpga_verilog/adder/hard_adder --debug --show_thread_logs -This will run a prebuilt task with OpenFPGA cell libraries. When the task is finished, there will be many auto-generated files to look through. For this tutorial, we are interested -in the ``luts.v`` and ``and2_formal.vcd`` files. The ``luts.v`` file will eventually have the changes we will implement in the tutorial, -and the ``and2_formal.vcd`` file will have the resulting waveforms from the simulation run by the task. To open the ``luts.v`` file, run the following command: +This will run a prebuilt task with OpenFPGA cell libraries. When the task is finished, there will be many auto-generated files to look through. For this tutorial, we are interested in the ``luts.v`` and ``and2_formal.vcd`` files. The **OR2** gate is used as a control circuit in the **lut6** circuit model, and the ``and2_formal.vcd`` file will have the resulting waveforms from the simulation run by the task. To open the ``luts.v`` file, run the following command: .. code-block:: bash vi openfpga_flow/tasks/fpga_verilog/adder/hard_adder/latest/k6_frac_N10_tileable_adder_chain_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/sub_module/luts.v -The ``luts.v`` file represents a Look Up Table within the OpenFPGA architecture. The important lines of this file for the tutorial are **LINE58**, **LINE59**, and **LINE72** to **LINE80**. +.. note:: Users can find full details about netlist organization in our documentation: https://openfpga.readthedocs.io/en/master/manual/fpga_verilog/fabric_netlist/ + +The ``luts.v`` file represents a Look Up Table within the OpenFPGA architecture. The important lines of this file for the tutorial are highlighted below. These lines show the instantiation of OpenFPGA's **OR2** cell library. -**LINE58**: - .. code-block:: verilog + :emphasize-lines: 58,59,72,73,74,75,76,77,78,79,80 + + //------------------------------------------- + // FPGA Synthesizable Verilog Netlist + // Description: Look-Up Tables + // Author: Xifan TANG + // Organization: University of Utah + // Date: Tue Mar 30 15:25:03 2021 + //------------------------------------------- + //----- Time scale ----- + `timescale 1ns / 1ps + + //----- Default net type ----- + `default_nettype none + + // ----- Verilog module for frac_lut6 ----- + module frac_lut6(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; + + //----- BEGIN wire-connection ports ----- + wire [0:5] in; + wire [0:3] lut4_out; + wire [0:1] lut5_out; + wire [0:0] lut6_out; + //----- END wire-connection ports ----- + + + //----- BEGIN Registered ports ----- + //----- END Registered ports ----- + + + wire [0:0] INVTX1_0_out; + wire [0:0] INVTX1_1_out; + wire [0:0] INVTX1_2_out; + wire [0:0] INVTX1_3_out; + wire [0:0] INVTX1_4_out; + wire [0:0] INVTX1_5_out; wire [0:0] OR2_0_out; - -**LINE59**: - -.. code-block:: verilog - wire [0:0] OR2_1_out; + wire [0:0] buf4_0_out; + wire [0:0] buf4_1_out; + wire [0:0] buf4_2_out; + wire [0:0] buf4_3_out; + wire [0:0] buf4_4_out; + wire [0:0] buf4_5_out; + + // ----- BEGIN Local short connections ----- + // ----- END Local short connections ----- + // ----- BEGIN Local output short connections ----- + // ----- END Local output short connections ----- + + OR2 OR2_0_ ( + .a(mode[0:0]), + .b(in[4]), + .out(OR2_0_out)); + + OR2 OR2_1_ ( + .a(mode[1]), + .b(in[5]), + .out(OR2_1_out)); + + INVTX1 INVTX1_0_ ( + .in(in[0:0]), + .out(INVTX1_0_out)); + + INVTX1 INVTX1_1_ ( + .in(in[1]), + .out(INVTX1_1_out)); + + INVTX1 INVTX1_2_ ( + .in(in[2]), + .out(INVTX1_2_out)); + + INVTX1 INVTX1_3_ ( + .in(in[3]), + .out(INVTX1_3_out)); + + INVTX1 INVTX1_4_ ( + .in(OR2_0_out), + .out(INVTX1_4_out)); + + INVTX1 INVTX1_5_ ( + .in(OR2_1_out), + .out(INVTX1_5_out)); + + buf4 buf4_0_ ( + .in(in[0:0]), + .out(buf4_0_out)); + + buf4 buf4_1_ ( + .in(in[1]), + .out(buf4_1_out)); + + buf4 buf4_2_ ( + .in(in[2]), + .out(buf4_2_out)); + + buf4 buf4_3_ ( + .in(in[3]), + .out(buf4_3_out)); + + buf4 buf4_4_ ( + .in(OR2_0_out), + .out(buf4_4_out)); + + buf4 buf4_5_ ( + .in(OR2_1_out), + .out(buf4_5_out)); + + frac_lut6_mux frac_lut6_mux_0_ ( + .in(sram[0:63]), + .sram({buf4_0_out, buf4_1_out, buf4_2_out, buf4_3_out, buf4_4_out, buf4_5_out}), + .sram_inv({INVTX1_0_out, INVTX1_1_out, INVTX1_2_out, INVTX1_3_out, INVTX1_4_out, INVTX1_5_out}), + .lut4_out(lut4_out[0:3]), + .lut5_out(lut5_out[0:1]), + .lut6_out(lut6_out)); + + endmodule + // ----- END Verilog module for frac_lut6 ----- + + //----- Default net type ----- + `default_nettype none -**LINE72** to **LINE80**: -.. code-block:: verilog - - OR2 OR2_0_ ( - .a(mode[0:0]), - .b(in[4]), - .out(OR2_0_out)); - - OR2 OR2_1_ ( - .a(mode[1]), - .b(in[5]), - .out(OR2_1_out)); - -We will also need to look at the control's simulation waveforms. Viewing the waveforms is done through GTKWave with the following command: +We will also need to look at the control's simulation waveforms. Viewing the waveforms is done through ``GTKWave``_ with the following command: .. code-block:: bash @@ -92,8 +216,8 @@ Once the repository has been cloned, we need to build the cell libraries by runn This will take some time to complete due to the size of the libraries. Once the libraries are made, creating the circuit model can begin. -Create and Verify the Cell Library Circuit Model -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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** @@ -160,7 +284,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 From Verilog to ``Verification``_ tutorial. From the root directory, run the following commands: .. code-block:: bash @@ -182,24 +306,150 @@ From the root directory, view the ``luts.v`` file with this command: Scrolling through ``luts.v``, this should be present in the file: .. code-block:: verilog - + :emphasize-lines: 58,59,72,73,74,75,76,77,78,79,80 + //------------------------------------------- + // FPGA Synthesizable Verilog Netlist + // Description: Look-Up Tables + // Author: Xifan TANG + // Organization: University of Utah + // Date: Tue Mar 30 20:25:06 2021 + //------------------------------------------- + //----- Time scale ----- + `timescale 1ns / 1ps + + //----- Default net type ----- + `default_nettype none + + // ----- Verilog module for frac_lut6 ----- + module frac_lut6(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; + + //----- BEGIN wire-connection ports ----- + wire [0:5] in; + wire [0:3] lut4_out; + wire [0:1] lut5_out; + wire [0:0] lut6_out; + //----- END wire-connection ports ----- + + + //----- BEGIN Registered ports ----- + //----- END Registered ports ----- + + + wire [0:0] INVTX1_0_out; + wire [0:0] INVTX1_1_out; + wire [0:0] INVTX1_2_out; + wire [0:0] INVTX1_3_out; + wire [0:0] INVTX1_4_out; + wire [0:0] INVTX1_5_out; + wire [0:0] buf4_0_out; + wire [0:0] buf4_1_out; + wire [0:0] buf4_2_out; + wire [0:0] buf4_3_out; + wire [0:0] buf4_4_out; + wire [0:0] buf4_5_out; wire [0:0] sky130_fd_sc_ls__or2_1_0_X; wire [0:0] sky130_fd_sc_ls__or2_1_1_X; - + // ----- BEGIN Local short connections ----- // ----- END Local short connections ----- // ----- BEGIN Local output short connections ----- // ----- END Local output short connections ----- + + sky130_fd_sc_ls__or2_1 sky130_fd_sc_ls__or2_1_0_ ( + .A(mode[0:0]), + .B(in[4]), + .X(sky130_fd_sc_ls__or2_1_0_X)); + + sky130_fd_sc_ls__or2_1 sky130_fd_sc_ls__or2_1_1_ ( + .A(mode[1]), + .B(in[5]), + .X(sky130_fd_sc_ls__or2_1_1_X)); + + INVTX1 INVTX1_0_ ( + .in(in[0:0]), + .out(INVTX1_0_out)); + + INVTX1 INVTX1_1_ ( + .in(in[1]), + .out(INVTX1_1_out)); + + INVTX1 INVTX1_2_ ( + .in(in[2]), + .out(INVTX1_2_out)); + + INVTX1 INVTX1_3_ ( + .in(in[3]), + .out(INVTX1_3_out)); + + INVTX1 INVTX1_4_ ( + .in(sky130_fd_sc_ls__or2_1_0_X), + .out(INVTX1_4_out)); + + INVTX1 INVTX1_5_ ( + .in(sky130_fd_sc_ls__or2_1_1_X), + .out(INVTX1_5_out)); + + buf4 buf4_0_ ( + .in(in[0:0]), + .out(buf4_0_out)); + + buf4 buf4_1_ ( + .in(in[1]), + .out(buf4_1_out)); + + buf4 buf4_2_ ( + .in(in[2]), + .out(buf4_2_out)); + + buf4 buf4_3_ ( + .in(in[3]), + .out(buf4_3_out)); + + buf4 buf4_4_ ( + .in(sky130_fd_sc_ls__or2_1_0_X), + .out(buf4_4_out)); + + buf4 buf4_5_ ( + .in(sky130_fd_sc_ls__or2_1_1_X), + .out(buf4_5_out)); + + frac_lut6_mux frac_lut6_mux_0_ ( + .in(sram[0:63]), + .sram({buf4_0_out, buf4_1_out, buf4_2_out, buf4_3_out, buf4_4_out, buf4_5_out}), + .sram_inv({INVTX1_0_out, INVTX1_1_out, INVTX1_2_out, INVTX1_3_out, INVTX1_4_out, INVTX1_5_out}), + .lut4_out(lut4_out[0:3]), + .lut5_out(lut5_out[0:1]), + .lut6_out(lut6_out)); + + endmodule + // ----- END Verilog module for frac_lut6 ----- + + //----- Default net type ----- + `default_nettype none - sky130_fd_sc_ls__or2_1 sky130_fd_sc_ls__or2_1_0_ ( - .A(mode[0:0]), - .B(in[4]), - .X(sky130_fd_sc_ls__or2_1_0_X)); - - sky130_fd_sc_ls__or2_1 sky130_fd_sc_ls__or2_1_1_ ( - .A(mode[1]), - .B(in[5]), - .X(sky130_fd_sc_ls__or2_1_1_X)); We can check the waveforms as well to see if they are similar with the command: @@ -216,6 +466,10 @@ The simulation waveforms should look similar to the following :numref:`fig_custo Custom Circuit Model's Simulation Waveforms -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, reach out to us on github. +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. -.. _From Verilog to Verification: https://openfpga.readthedocs.io/en/master/tutorials/design_flow/verilog2verification/ +.. _Verification: https://openfpga.readthedocs.io/en/master/tutorials/design_flow/verilog2verification/ + +.. _PDK: https://github.com/google/skywater-pdk + +.. _GTKWave: https://github.com/gtkwave/gtkwave