diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..3fc3bad --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,90 @@ +name: linux_build + +# Run CI on +# - each push +# - each pull request +# - scheduled weekly +on: + push: + pull_request: + schedule: + - cron: '0 0 * * 0 ' # weekly + +# Environment variables +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + MAKEFLAGS: "-j8" + +# Multiple job to tests +jobs: + # Test the compilation compatibility + linux_build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + + # Branch on different OS and settings + strategy: + fail-fast: false + matrix: + config: + - { + name: "Quick Test: GCC-8 (Ubuntu 18.04)", + artifact: "OpenFPGA-basic-tests-ubuntu-18.04-gcc8-build.7z", + os: ubuntu-18.04, + cc: "gcc-8", cxx: "g++-8", + reg_script: "quick_test.sh" + } + + # Define the steps to run the build job + steps: + - name: Checkout Skywater-OpenFPGA repo + uses: actions/checkout@v2 + + - name: Checkout OpenFPGA repo + uses: actions/checkout@v2 + with: + repository: LNIS-Projects/OpenFPGA + path: OpenFPGA + + - name: Install dependency + run: source ./.github/workflows/install_dependency.sh + + - name: Checkout CMake version + run: cmake --version + + - name: Checkout iVerilog version + run: | + iverilog -V + vvp -V + + - name: Create CMake build environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{runner.workspace}}/OpenFPGA/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{runner.workspace}}/OpenFPGA/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: | + export CC=${{ matrix.config.cc }} + export CXX=${{ matrix.config.cxx }} + cmake $GITHUB_WORKSPACE/OpenFPGA -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{runner.workspace}}/OpenFPGA/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: | + cmake --build . --config $BUILD_TYPE + + - name: ${{matrix.config.name}} + if: contains(matrix.config.name, 'Quick Test') + shell: bash + # Execute the test. + run: source ./.github/workflows/${{matrix.config.reg_script}} diff --git a/.github/workflows/install_dependency.sh b/.github/workflows/install_dependency.sh new file mode 100644 index 0000000..0e663ef --- /dev/null +++ b/.github/workflows/install_dependency.sh @@ -0,0 +1,48 @@ +# Install all the dependency for OpenFPGA in Ubuntu-18.04 +sudo apt-get update +sudo apt-get install autoconf +sudo apt-get install automake +sudo apt-get install bash +sudo apt-get install bison +sudo apt-get install build-essential +sudo apt-get install cmake +sudo apt-get install ccache +sudo apt-get install ctags +sudo apt-get install curl +sudo apt-get install doxygen +sudo apt-get install flex +sudo apt-get install fontconfig +sudo apt-get install gdb +sudo apt-get install git +sudo apt-get install gperf +sudo apt-get install iverilog +sudo apt-get install libcairo2-dev +sudo apt-get install libevent-dev +sudo apt-get install libfontconfig1-dev +sudo apt-get install liblist-moreutils-perl +sudo apt-get install libncurses5-dev +sudo apt-get install libx11-dev +sudo apt-get install libxft-dev +sudo apt-get install libxml++2.6-dev +sudo apt-get install perl +sudo apt-get install python +sudo apt-get install python-lxml +sudo apt-get install texinfo +sudo apt-get install time +sudo apt-get install valgrind +sudo apt-get install zip +sudo apt-get install qt5-default +sudo apt-get install clang-format-7 +# Add all the supported compilers +sudo apt-get install g++-5 +sudo apt-get install gcc-5 +sudo apt-get install g++-6 +sudo apt-get install gcc-6 +sudo apt-get install g++-7 +sudo apt-get install gcc-7 +sudo apt-get install g++-8 +sudo apt-get install gcc-8 +sudo apt-get install g++-9 +sudo apt-get install gcc-9 +sudo apt-get install clang-6.0 +sudo apt-get install clang-8 diff --git a/.github/workflows/quick_test.sh b/.github/workflows/quick_test.sh new file mode 100755 index 0000000..3927dcc --- /dev/null +++ b/.github/workflows/quick_test.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +############################################### +# OpenFPGA Shell with VPR8 +############################################## + +############################################## +# Initialize the repository +# - Generate final version of architecture files +# - Run FPGA tasks to validate netlist generations +python3 SCRIPT/repo_setup.py --openfpga_root_path ./OpenFPGA + +############################################## +# Generate post-PnR testbenches +python3 TESTBENCH/common/generate_post_pnr_testbenches.py --pre_pnr_testbench_dir_name ./TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc --pin_assignment_file ./HDL/common/caravel_wrapper_pin_assignment_v1.0.json +python3 TESTBENCH/common/generate_post_pnr_testbenches.py --pre_pnr_testbench_dir_name ./TESTBENCH/k4_N8_reset_caravel_io_FPGA_12x12_fdhd_cc --pin_assignment_file ./HDL/common/caravel_wrapper_pin_assignment_v1.1.json +python3 TESTBENCH/common/generate_post_pnr_testbenches.py --pre_pnr_testbench_dir_name ./TESTBENCH/k4_N8_softadder_caravel_io_FPGA_12x12_fdhd_cc --pin_assignment_file ./HDL/common/caravel_wrapper_pin_assignment_v1.0.json +python3 TESTBENCH/common/generate_post_pnr_testbenches.py --pre_pnr_testbench_dir_name ./TESTBENCH/k4_N8_reset_softadder_caravel_io_FPGA_12x12_fdhd_cc --pin_assignment_file ./HDL/common/caravel_wrapper_pin_assignment_v1.1.json diff --git a/ARCH/openfpga_arch_template/k4_frac_N8_reset_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/ARCH/openfpga_arch_template/k4_frac_N8_reset_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml index 969420e..e4f1ad5 100644 --- a/ARCH/openfpga_arch_template/k4_frac_N8_reset_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +++ b/ARCH/openfpga_arch_template/k4_frac_N8_reset_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -181,7 +181,7 @@ - + diff --git a/ARCH/openfpga_arch_template/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/ARCH/openfpga_arch_template/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml new file mode 100644 index 0000000..97989e2 --- /dev/null +++ b/ARCH/openfpga_arch_template/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + + + + 10e-12 5e-12 + + + 10e-12 5e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ARCH/openfpga_arch_template/ql_ap3_8x8_arch_vpr_routing_skywater130nm_fdhd_cc_openfpga.xml b/ARCH/openfpga_arch_template/ql_ap3_8x8_arch_vpr_routing_skywater130nm_fdhd_cc_openfpga.xml index e451f26..f588f71 100644 --- a/ARCH/openfpga_arch_template/ql_ap3_8x8_arch_vpr_routing_skywater130nm_fdhd_cc_openfpga.xml +++ b/ARCH/openfpga_arch_template/ql_ap3_8x8_arch_vpr_routing_skywater130nm_fdhd_cc_openfpga.xml @@ -187,6 +187,16 @@ + + + + + + + + + + @@ -220,7 +230,7 @@ - + diff --git a/ARCH/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml b/ARCH/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml new file mode 100644 index 0000000..07c6ba8 --- /dev/null +++ b/ARCH/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml @@ -0,0 +1,737 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + io_top.outpad io_top.inpad + + + + + + + + + + + + io_right.outpad io_right.inpad + + + + + + + + + + + + io_bottom.outpad io_bottom.inpad + + + + + + + + + + + + io_left.outpad io_left.inpad + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clb.clk clb.reset + clb.reg_in clb.sc_in clb.cin clb.O[7:0] clb.I0 clb.I0i clb.I1 clb.I1i clb.I2 clb.I2i clb.I3 clb.I3i + clb.O[15:8] clb.I4 clb.I4i clb.I5 clb.I5i clb.I6 clb.I6i clb.I7 clb.I7i + clb.reg_out clb.sc_out clb.cout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 1 + 1 + + + + 1 1 1 + 1 1 + + + + 1 1 1 1 1 + 1 1 1 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 235e-12 + 235e-12 + 235e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 261e-12 + 261e-12 + 261e-12 + 261e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ARCH/vpr_arch/ql_ap3_8x8_arch_vpr_routing.xml b/ARCH/vpr_arch/ql_ap3_8x8_arch_vpr_routing.xml index 8af0977..163b9e2 100644 --- a/ARCH/vpr_arch/ql_ap3_8x8_arch_vpr_routing.xml +++ b/ARCH/vpr_arch/ql_ap3_8x8_arch_vpr_routing.xml @@ -27,14 +27,14 @@ - + - - - - + + + + - + @@ -304,22 +304,21 @@ - - - - - + + + + + - - - - - - - - - + + + + + + + + diff --git a/DOC/source/arch/figures/fpga_io_switch.svg b/DOC/source/arch/figures/fpga_io_switch.svg index 273f7d5..3caaabf 100644 --- a/DOC/source/arch/figures/fpga_io_switch.svg +++ b/DOC/source/arch/figures/fpga_io_switch.svg @@ -33,10 +33,10 @@ - Produced by OmniGraffle 7.18\n2020-11-21 01:05:14 +0000 - - switch - + Produced by OmniGraffle 7.18\n2020-11-29 03:10:55 +0000 + + v1.0 + base @@ -319,7 +319,7 @@ - IO_ISOL_N -> Caravel GPIO[1] + IO_ISOL_N <- Caravel GPIO[1] TEST_EN <- Caravel GPIO[0] diff --git a/HDL/common/README.md b/HDL/common/README.md new file mode 100644 index 0000000..01a748d --- /dev/null +++ b/HDL/common/README.md @@ -0,0 +1,10 @@ +# Skywater PDK +This directory contains the HDL netlists and code generator for FPGA fabrics. + +- **caravel_fpga_wrapper_hd.v**: The wrapper for FPGA fabric to interface the Caravel SoC, which is technology mapped to the Skywater 130nm Foundry High-Density Standard Cell Library. **This file is automatically generated by a Python script** +- **caravel_defines.v**: The parameters required for Caravel wrapper HDL codes +- **caravel_fpga_wrapper_hd_template.v**: The template HDL codes for the wrapper +- **digital_io_hd.v**: the I/O cell used by High-density FPGA, which is technology mapped to the Skywater 130nm Foundry High-Density Standard Cell Library. +- **sky130_fd_sc_hd_wrapper.v**: Wrapper codes for the standard cells from the Skywater 130nm Foundry High-Density Standard Cell Library +- **skywater_function_verification.v**: Include pre-processing flags to enable functional verification for FPGAs +- **wrapper_lines_generator.py**: Python script to generate the wrapper *caravel\_fpga\_wrapper\_hd.v* diff --git a/HDL/common/caravel_fpga_wrapper_hd.v b/HDL/common/caravel_fpga_wrapper_hd.v index 99d15e4..d237172 100644 --- a/HDL/common/caravel_fpga_wrapper_hd.v +++ b/HDL/common/caravel_fpga_wrapper_hd.v @@ -1,422 +1,3 @@ -/* - *------------------------------------------------------------- - * - * A wrapper for the FPGA IP to fit the I/O interface of Caravel SoC - * - * The wrapper is a technology mapped netlist where the mode-switch - * multiplexers are mapped to the Skywater 130nm - * High-Density (HD) standard cells - * - *------------------------------------------------------------- - */ - -module fpga_top ( - // Fixed I/O interface from Caravel SoC definition - // DO NOT CHANGE!!! - inout vdda1, // User area 1 3.3V supply - inout vdda2, // User area 2 3.3V supply - inout vssa1, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V supply - inout vccd2, // User area 2 1.8v supply - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground - - // Wishbone Slave ports (WB MI A) - input wb_clk_i, - input wb_rst_i, - input wbs_stb_i, - input wbs_cyc_i, - input wbs_we_i, - input [3:0] wbs_sel_i, - input [31:0] wbs_dat_i, - input [31:0] wbs_adr_i, - output wbs_ack_o, - output [31:0] wbs_dat_o, - - // Logic Analyzer Signals - input [127:0] la_data_in, - output [127:0] la_data_out, - input [127:0] la_oen, - - // IOs - input [37:0] io_in, - output [37:0] io_out, - output [37:0] io_oeb -); - - // Modelsim does NOT like redefining wires that already in the - // input/output ports. The follow lines may be needed when - // `default_nettype none - // is enabled - //wire [`MPRJ_IO_PADS-1:0] io_in; - //wire [`MPRJ_IO_PADS-1:0] io_out; - //wire [`MPRJ_IO_PADS-1:0] io_oeb; - - // FPGA wires - wire prog_clk; - wire Test_en; - wire io_isol_n; - wire clk; - wire [0:143] gfpga_pad_EMBEDDED_IO_HD_SOC_IN; - wire [0:143] gfpga_pad_EMBEDDED_IO_HD_SOC_OUT; - wire [0:143] gfpga_pad_EMBEDDED_IO_HD_SOC_DIR; - wire ccff_head; - wire ccff_tail; - wire sc_head; - wire sc_tail; - - // Switch between wishbone and logic analyzer - wire wb_la_switch; - wire wb_la_switch_b; - - // Inverted switch signal to drive tri-state buffers - // Use drive strength 8 as we will have 33 output pins which is driven by - // the buffers - sky130_fd_sc_hd__inv_8 WB_LA_SWITCH_INV (.A(la_wb_switch), .Y(la_wb_switch_b)); - - // Wire-bond TOP side I/O of FPGA to LEFT-side of Caravel interface - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[0] = io_in[24]; - assign io_out[24] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[0]; - assign io_oeb[24] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[0]; - - // Wire-bond TOP side I/O of FPGA to TOP-side of Caravel interface - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[1:9] = io_in[23:15]; - assign io_out[23:15] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[1:9]; - assign io_oeb[23:15] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[1:9]; - - // Wire-bond TOP side I/O of FPGA to RIGHT-side of Caravel interface - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[10:11] = io_in[14:13]; - assign io_out[14:13] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[10:11]; - assign io_oeb[14:13] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[10:11]; - - // Wire-bond RIGHT side I/O of FPGA to RIGHT-side of Caravel interface - assign ccff_head = io_in[12]; - assign io_out[12] = 1'b0; - assign io_oeb[12] = 1'b1; - - assign io_out[11] = sc_tail; - assign io_oeb[11] = 1'b0; - - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[12:20] = io_in[10:2]; - assign io_out[10:2] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[12:20]; - assign io_oeb[10:2] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[12:20]; - - assign io_isol_n = io_in[1]; - assign io_out[1] = 1'b0; - assign io_oeb[1] = 1'b1; - - assign Test_en = io_in[0]; - assign io_out[0] = 1'b0; - assign io_oeb[0] = 1'b1; - - // Wire-bond RIGHT, BOTTOM, LEFT side I/O of FPGA to BOTTOM-side of Caravel interface - // Autogenerate code start - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_135_MUX (.S(wb_la_switch), .A1(wb_clk_i), .A0(la_data_in[13]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[135])); - assign la_data_out[13] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[135]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_134_MUX (.S(wb_la_switch), .A1(wb_rst_i), .A0(la_data_in[14]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[134])); - assign la_data_out[14] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[134]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[133] = la_data_in[15]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_133_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[133]), .Z(wbs_ack_o)); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_133_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[133]), .Z(la_data_out[15])); - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_132_MUX (.S(wb_la_switch), .A1(wbs_cyc_i), .A0(la_data_in[16]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[132])); - assign la_data_out[16] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[132]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_131_MUX (.S(wb_la_switch), .A1(wbs_stb_i), .A0(la_data_in[17]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[131])); - assign la_data_out[17] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[131]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_130_MUX (.S(wb_la_switch), .A1(wbs_we_i), .A0(la_data_in[18]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[130])); - assign la_data_out[18] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[130]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_129_MUX (.S(wb_la_switch), .A1(wbs_sel_i[0]), .A0(la_data_in[19]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[129])); - assign la_data_out[19] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[129]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_128_MUX (.S(wb_la_switch), .A1(wbs_sel_i[1]), .A0(la_data_in[20]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[128])); - assign la_data_out[20] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[128]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_127_MUX (.S(wb_la_switch), .A1(wbs_sel_i[2]), .A0(la_data_in[21]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[127])); - assign la_data_out[21] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[127]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_126_MUX (.S(wb_la_switch), .A1(wbs_sel_i[3]), .A0(la_data_in[22]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[126])); - assign la_data_out[22] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[126]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_125_MUX (.S(wb_la_switch), .A1(wbs_adr_i[0]), .A0(la_data_in[23]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[125])); - assign la_data_out[23] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[125]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_124_MUX (.S(wb_la_switch), .A1(wbs_adr_i[1]), .A0(la_data_in[24]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[124])); - assign la_data_out[24] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[124]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_123_MUX (.S(wb_la_switch), .A1(wbs_adr_i[2]), .A0(la_data_in[25]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[123])); - assign la_data_out[25] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[123]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_122_MUX (.S(wb_la_switch), .A1(wbs_adr_i[3]), .A0(la_data_in[26]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[122])); - assign la_data_out[26] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[122]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_121_MUX (.S(wb_la_switch), .A1(wbs_adr_i[4]), .A0(la_data_in[27]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[121])); - assign la_data_out[27] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[121]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_120_MUX (.S(wb_la_switch), .A1(wbs_adr_i[5]), .A0(la_data_in[28]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[120])); - assign la_data_out[28] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[120]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_119_MUX (.S(wb_la_switch), .A1(wbs_adr_i[6]), .A0(la_data_in[29]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[119])); - assign la_data_out[29] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[119]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_118_MUX (.S(wb_la_switch), .A1(wbs_adr_i[7]), .A0(la_data_in[30]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[118])); - assign la_data_out[30] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[118]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_117_MUX (.S(wb_la_switch), .A1(wbs_adr_i[8]), .A0(la_data_in[31]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[117])); - assign la_data_out[31] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[117]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_116_MUX (.S(wb_la_switch), .A1(wbs_adr_i[9]), .A0(la_data_in[32]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[116])); - assign la_data_out[32] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[116]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_115_MUX (.S(wb_la_switch), .A1(wbs_adr_i[10]), .A0(la_data_in[33]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[115])); - assign la_data_out[33] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[115]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_114_MUX (.S(wb_la_switch), .A1(wbs_adr_i[11]), .A0(la_data_in[34]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[114])); - assign la_data_out[34] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[114]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_113_MUX (.S(wb_la_switch), .A1(wbs_adr_i[12]), .A0(la_data_in[35]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[113])); - assign la_data_out[35] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[113]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_112_MUX (.S(wb_la_switch), .A1(wbs_adr_i[13]), .A0(la_data_in[36]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[112])); - assign la_data_out[36] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[112]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_111_MUX (.S(wb_la_switch), .A1(wbs_adr_i[14]), .A0(la_data_in[37]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[111])); - assign la_data_out[37] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[111]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_110_MUX (.S(wb_la_switch), .A1(wbs_adr_i[15]), .A0(la_data_in[38]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[110])); - assign la_data_out[38] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[110]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_109_MUX (.S(wb_la_switch), .A1(wbs_adr_i[16]), .A0(la_data_in[39]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[109])); - assign la_data_out[39] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[109]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_108_MUX (.S(wb_la_switch), .A1(wbs_adr_i[17]), .A0(la_data_in[40]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[108])); - assign la_data_out[40] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[108]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_107_MUX (.S(wb_la_switch), .A1(wbs_adr_i[18]), .A0(la_data_in[41]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[107])); - assign la_data_out[41] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[107]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_106_MUX (.S(wb_la_switch), .A1(wbs_adr_i[19]), .A0(la_data_in[42]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[106])); - assign la_data_out[42] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[106]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_105_MUX (.S(wb_la_switch), .A1(wbs_adr_i[20]), .A0(la_data_in[43]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[105])); - assign la_data_out[43] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[105]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_104_MUX (.S(wb_la_switch), .A1(wbs_adr_i[21]), .A0(la_data_in[44]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[104])); - assign la_data_out[44] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[104]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_103_MUX (.S(wb_la_switch), .A1(wbs_adr_i[22]), .A0(la_data_in[45]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[103])); - assign la_data_out[45] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[103]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_102_MUX (.S(wb_la_switch), .A1(wbs_adr_i[23]), .A0(la_data_in[46]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[102])); - assign la_data_out[46] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[102]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_101_MUX (.S(wb_la_switch), .A1(wbs_adr_i[24]), .A0(la_data_in[47]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[101])); - assign la_data_out[47] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[101]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_100_MUX (.S(wb_la_switch), .A1(wbs_adr_i[25]), .A0(la_data_in[48]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[100])); - assign la_data_out[48] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[100]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_99_MUX (.S(wb_la_switch), .A1(wbs_adr_i[26]), .A0(la_data_in[49]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[99])); - assign la_data_out[49] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[99]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_98_MUX (.S(wb_la_switch), .A1(wbs_adr_i[27]), .A0(la_data_in[50]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[98])); - assign la_data_out[50] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[98]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_97_MUX (.S(wb_la_switch), .A1(wbs_adr_i[28]), .A0(la_data_in[51]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[97])); - assign la_data_out[51] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[97]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_96_MUX (.S(wb_la_switch), .A1(wbs_adr_i[29]), .A0(la_data_in[52]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[96])); - assign la_data_out[52] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[96]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_95_MUX (.S(wb_la_switch), .A1(wbs_adr_i[30]), .A0(la_data_in[53]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[95])); - assign la_data_out[53] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[95]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_94_MUX (.S(wb_la_switch), .A1(wbs_adr_i[31]), .A0(la_data_in[54]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[94])); - assign la_data_out[54] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[94]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_93_MUX (.S(wb_la_switch), .A1(wbs_dat_i[0]), .A0(la_data_in[55]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[93])); - assign la_data_out[55] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[93]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_92_MUX (.S(wb_la_switch), .A1(wbs_dat_i[1]), .A0(la_data_in[56]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[92])); - assign la_data_out[56] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[92]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_91_MUX (.S(wb_la_switch), .A1(wbs_dat_i[2]), .A0(la_data_in[57]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[91])); - assign la_data_out[57] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[91]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_90_MUX (.S(wb_la_switch), .A1(wbs_dat_i[3]), .A0(la_data_in[58]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[90])); - assign la_data_out[58] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[90]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_89_MUX (.S(wb_la_switch), .A1(wbs_dat_i[4]), .A0(la_data_in[59]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[89])); - assign la_data_out[59] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[89]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_88_MUX (.S(wb_la_switch), .A1(wbs_dat_i[5]), .A0(la_data_in[60]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[88])); - assign la_data_out[60] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[88]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_87_MUX (.S(wb_la_switch), .A1(wbs_dat_i[6]), .A0(la_data_in[61]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[87])); - assign la_data_out[61] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[87]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_86_MUX (.S(wb_la_switch), .A1(wbs_dat_i[7]), .A0(la_data_in[62]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[86])); - assign la_data_out[62] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[86]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_85_MUX (.S(wb_la_switch), .A1(wbs_dat_i[8]), .A0(la_data_in[63]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[85])); - assign la_data_out[63] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[85]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_84_MUX (.S(wb_la_switch), .A1(wbs_dat_i[9]), .A0(la_data_in[64]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[84])); - assign la_data_out[64] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[84]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_83_MUX (.S(wb_la_switch), .A1(wbs_dat_i[10]), .A0(la_data_in[65]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[83])); - assign la_data_out[65] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[83]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_82_MUX (.S(wb_la_switch), .A1(wbs_dat_i[11]), .A0(la_data_in[66]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[82])); - assign la_data_out[66] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[82]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_81_MUX (.S(wb_la_switch), .A1(wbs_dat_i[12]), .A0(la_data_in[67]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[81])); - assign la_data_out[67] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[81]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_80_MUX (.S(wb_la_switch), .A1(wbs_dat_i[13]), .A0(la_data_in[68]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[80])); - assign la_data_out[68] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[80]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_79_MUX (.S(wb_la_switch), .A1(wbs_dat_i[14]), .A0(la_data_in[69]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[79])); - assign la_data_out[69] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[79]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_78_MUX (.S(wb_la_switch), .A1(wbs_dat_i[15]), .A0(la_data_in[70]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[78])); - assign la_data_out[70] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[78]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_77_MUX (.S(wb_la_switch), .A1(wbs_dat_i[16]), .A0(la_data_in[71]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[77])); - assign la_data_out[71] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[77]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_76_MUX (.S(wb_la_switch), .A1(wbs_dat_i[17]), .A0(la_data_in[72]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[76])); - assign la_data_out[72] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[76]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_75_MUX (.S(wb_la_switch), .A1(wbs_dat_i[18]), .A0(la_data_in[73]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[75])); - assign la_data_out[73] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[75]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_74_MUX (.S(wb_la_switch), .A1(wbs_dat_i[19]), .A0(la_data_in[74]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[74])); - assign la_data_out[74] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[74]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_73_MUX (.S(wb_la_switch), .A1(wbs_dat_i[20]), .A0(la_data_in[75]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[73])); - assign la_data_out[75] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[73]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_72_MUX (.S(wb_la_switch), .A1(wbs_dat_i[21]), .A0(la_data_in[76]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[72])); - assign la_data_out[76] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[72]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_71_MUX (.S(wb_la_switch), .A1(wbs_dat_i[22]), .A0(la_data_in[77]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[71])); - assign la_data_out[77] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[71]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_70_MUX (.S(wb_la_switch), .A1(wbs_dat_i[23]), .A0(la_data_in[78]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[70])); - assign la_data_out[78] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[70]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_69_MUX (.S(wb_la_switch), .A1(wbs_dat_i[24]), .A0(la_data_in[79]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[69])); - assign la_data_out[79] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[69]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_68_MUX (.S(wb_la_switch), .A1(wbs_dat_i[25]), .A0(la_data_in[80]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[68])); - assign la_data_out[80] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[68]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_67_MUX (.S(wb_la_switch), .A1(wbs_dat_i[26]), .A0(la_data_in[81]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[67])); - assign la_data_out[81] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[67]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_66_MUX (.S(wb_la_switch), .A1(wbs_dat_i[27]), .A0(la_data_in[82]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[66])); - assign la_data_out[82] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[66]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_65_MUX (.S(wb_la_switch), .A1(wbs_dat_i[28]), .A0(la_data_in[83]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[65])); - assign la_data_out[83] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[65]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_64_MUX (.S(wb_la_switch), .A1(wbs_dat_i[29]), .A0(la_data_in[84]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[64])); - assign la_data_out[84] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[64]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_63_MUX (.S(wb_la_switch), .A1(wbs_dat_i[30]), .A0(la_data_in[85]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[63])); - assign la_data_out[85] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[63]; - sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_62_MUX (.S(wb_la_switch), .A1(wbs_dat_i[31]), .A0(la_data_in[86]), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[62])); - assign la_data_out[86] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[62]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[61] = la_data_in[87]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_61_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[61]), .Z(wbs_dat_o[0])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_61_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[61]), .Z(la_data_out[87])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[60] = la_data_in[88]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_60_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[60]), .Z(wbs_dat_o[1])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_60_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[60]), .Z(la_data_out[88])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[59] = la_data_in[89]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_59_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[59]), .Z(wbs_dat_o[2])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_59_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[59]), .Z(la_data_out[89])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[58] = la_data_in[90]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_58_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[58]), .Z(wbs_dat_o[3])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_58_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[58]), .Z(la_data_out[90])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[57] = la_data_in[91]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_57_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[57]), .Z(wbs_dat_o[4])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_57_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[57]), .Z(la_data_out[91])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[56] = la_data_in[92]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_56_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[56]), .Z(wbs_dat_o[5])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_56_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[56]), .Z(la_data_out[92])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[55] = la_data_in[93]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_55_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[55]), .Z(wbs_dat_o[6])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_55_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[55]), .Z(la_data_out[93])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[54] = la_data_in[94]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_54_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[54]), .Z(wbs_dat_o[7])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_54_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[54]), .Z(la_data_out[94])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[53] = la_data_in[95]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_53_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[53]), .Z(wbs_dat_o[8])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_53_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[53]), .Z(la_data_out[95])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[52] = la_data_in[96]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_52_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[52]), .Z(wbs_dat_o[9])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_52_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[52]), .Z(la_data_out[96])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[51] = la_data_in[97]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_51_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[51]), .Z(wbs_dat_o[10])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_51_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[51]), .Z(la_data_out[97])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[50] = la_data_in[98]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_50_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[50]), .Z(wbs_dat_o[11])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_50_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[50]), .Z(la_data_out[98])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[49] = la_data_in[99]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_49_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[49]), .Z(wbs_dat_o[12])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_49_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[49]), .Z(la_data_out[99])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[48] = la_data_in[100]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_48_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[48]), .Z(wbs_dat_o[13])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_48_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[48]), .Z(la_data_out[100])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[47] = la_data_in[101]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_47_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[47]), .Z(wbs_dat_o[14])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_47_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[47]), .Z(la_data_out[101])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[46] = la_data_in[102]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_46_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[46]), .Z(wbs_dat_o[15])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_46_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[46]), .Z(la_data_out[102])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[45] = la_data_in[103]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_45_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[45]), .Z(wbs_dat_o[16])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_45_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[45]), .Z(la_data_out[103])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[44] = la_data_in[104]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_44_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[44]), .Z(wbs_dat_o[17])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_44_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[44]), .Z(la_data_out[104])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[43] = la_data_in[105]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_43_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[43]), .Z(wbs_dat_o[18])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_43_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[43]), .Z(la_data_out[105])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[42] = la_data_in[106]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_42_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[42]), .Z(wbs_dat_o[19])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_42_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[42]), .Z(la_data_out[106])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[41] = la_data_in[107]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_41_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[41]), .Z(wbs_dat_o[20])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_41_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[41]), .Z(la_data_out[107])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[40] = la_data_in[108]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_40_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[40]), .Z(wbs_dat_o[21])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_40_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[40]), .Z(la_data_out[108])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[39] = la_data_in[109]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_39_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[39]), .Z(wbs_dat_o[22])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_39_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[39]), .Z(la_data_out[109])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[38] = la_data_in[110]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_38_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[38]), .Z(wbs_dat_o[23])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_38_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[38]), .Z(la_data_out[110])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[37] = la_data_in[111]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_37_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[37]), .Z(wbs_dat_o[24])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_37_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[37]), .Z(la_data_out[111])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[36] = la_data_in[112]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_36_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[36]), .Z(wbs_dat_o[25])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_36_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[36]), .Z(la_data_out[112])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[35] = la_data_in[113]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_35_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[35]), .Z(wbs_dat_o[26])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_35_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[35]), .Z(la_data_out[113])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[34] = la_data_in[114]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_34_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[34]), .Z(wbs_dat_o[27])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_34_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[34]), .Z(la_data_out[114])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[33] = la_data_in[115]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_33_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[33]), .Z(wbs_dat_o[28])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_33_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[33]), .Z(la_data_out[115])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[32] = la_data_in[116]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_32_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[32]), .Z(wbs_dat_o[29])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_32_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[32]), .Z(la_data_out[116])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[31] = la_data_in[117]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_31_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[31]), .Z(wbs_dat_o[30])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_31_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[31]), .Z(la_data_out[117])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[30] = la_data_in[118]; - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_30_DEMUX_WB (.TE_B(wb_la_switch_b), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[30]), .Z(wbs_dat_o[31])); - sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_30_DEMUX_LA (.TE_B(wb_la_switch), .A(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[30]), .Z(la_data_out[118])); - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[29] = la_data_in[119]; - assign la_data_out[119] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[29]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[28] = la_data_in[120]; - assign la_data_out[120] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[28]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[27] = la_data_in[121]; - assign la_data_out[121] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[27]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[26] = la_data_in[122]; - assign la_data_out[122] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[26]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[25] = la_data_in[123]; - assign la_data_out[123] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[25]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[24] = la_data_in[124]; - assign la_data_out[124] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[24]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[23] = la_data_in[125]; - assign la_data_out[125] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[23]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[22] = la_data_in[126]; - assign la_data_out[126] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[22]; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[21] = la_data_in[127]; - assign la_data_out[127] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[21]; - // Autogenerate code end - - // Wire-bond LEFT side I/O of FPGA to LEFT-side of Caravel interface - assign prog_clk = io_in[37]; - assign io_out[37] = 1'b0; - assign io_oeb[37] = 1'b1; - - // FPGA clock port can be driven by either wishbone clock or an GPIO - assign clk = io_in[36]; - assign io_out[36] = 1'b0; - assign io_oeb[36] = 1'b1; - - assign io_out[35] = ccff_tail; - assign io_oeb[35] = 1'b0; - - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[136:143] = io_in[34:27]; - assign io_out[34:27] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[136:143]; - assign io_oeb[34:27] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[136:143]; - - assign sc_head = io_in[26]; - assign io_out[26] = 1'b0; - assign io_oeb[26] = 1'b1; - - // I/O[25] is reserved for a switch between wishbone interface - // and logic analyzer - assign wb_la_switch = io_in[25]; - assign io_out[25] = 1'b0; - assign io_oeb[25] = 1'b1; - - // TODO: Connect spypad from FPGA to logic analyzer ports - - fpga_core fpga_core_uut(.prog_clk(prog_clk), - .Test_en(Test_en), - .clk(clk), - .IO_ISOL_N(io_isol_n), - .gfpga_pad_EMBEDDED_IO_HD_SOC_IN(gfpga_pad_EMBEDDED_IO_HD_SOC_IN), - .gfpga_pad_EMBEDDED_IO_HD_SOC_OUT(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT), - .gfpga_pad_EMBEDDED_IO_HD_SOC_DIR(gfpga_pad_EMBEDDED_IO_HD_SOC_DIR), - .ccff_head(ccff_head), - .ccff_tail(ccff_tail), - .sc_head(sc_head), - .sc_tail(sc_tail) - ); - -endmodule +version https://git-lfs.github.com/spec/v1 +oid sha256:92abd3ec319ae191207d8b23efed64587c83e3e48c573e7ca4ba6407c65e73fb +size 37715 diff --git a/HDL/common/caravel_fpga_wrapper_hd_template.v b/HDL/common/caravel_fpga_wrapper_hd_template.v index a3395bb..5c0d458 100644 --- a/HDL/common/caravel_fpga_wrapper_hd_template.v +++ b/HDL/common/caravel_fpga_wrapper_hd_template.v @@ -1,159 +1,3 @@ -/* - *------------------------------------------------------------- - * - * A wrapper for the FPGA IP to fit the I/O interface of Caravel SoC - * - * The wrapper is a technology mapped netlist where the mode-switch - * multiplexers are mapped to the Skywater 130nm - * High-Density (HD) standard cells - * - *------------------------------------------------------------- - */ - -module fpga_top ( - // Fixed I/O interface from Caravel SoC definition - // DO NOT CHANGE!!! - inout vdda1, // User area 1 3.3V supply - inout vdda2, // User area 2 3.3V supply - inout vssa1, // User area 1 analog ground - inout vssa2, // User area 2 analog ground - inout vccd1, // User area 1 1.8V supply - inout vccd2, // User area 2 1.8v supply - inout vssd1, // User area 1 digital ground - inout vssd2, // User area 2 digital ground - - // Wishbone Slave ports (WB MI A) - input wb_clk_i, - input wb_rst_i, - input wbs_stb_i, - input wbs_cyc_i, - input wbs_we_i, - input [3:0] wbs_sel_i, - input [31:0] wbs_dat_i, - input [31:0] wbs_adr_i, - output wbs_ack_o, - output [31:0] wbs_dat_o, - - // Logic Analyzer Signals - input [127:0] la_data_in, - output [127:0] la_data_out, - input [127:0] la_oen, - - // IOs - input [37:0] io_in, - output [37:0] io_out, - output [37:0] io_oeb -); - - // Modelsim does NOT like redefining wires that already in the - // input/output ports. The follow lines may be needed when - // `default_nettype none - // is enabled - //wire [`MPRJ_IO_PADS-1:0] io_in; - //wire [`MPRJ_IO_PADS-1:0] io_out; - //wire [`MPRJ_IO_PADS-1:0] io_oeb; - - // FPGA wires - wire prog_clk; - wire Test_en; - wire io_isol_n; - wire clk; - wire [0:143] gfpga_pad_EMBEDDED_IO_HD_SOC_IN; - wire [0:143] gfpga_pad_EMBEDDED_IO_HD_SOC_OUT; - wire [0:143] gfpga_pad_EMBEDDED_IO_HD_SOC_DIR; - wire ccff_head; - wire ccff_tail; - wire sc_head; - wire sc_tail; - - // Switch between wishbone and logic analyzer - wire wb_la_switch; - wire wb_la_switch_b; - - // Inverted switch signal to drive tri-state buffers - // Use drive strength 8 as we will have 33 output pins which is driven by - // the buffers - sky130_fd_sc_hd__inv_8 WB_LA_SWITCH_INV (.A(la_wb_switch), .Y(la_wb_switch_b)); - - // Wire-bond TOP side I/O of FPGA to LEFT-side of Caravel interface - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[0] = io_in[24]; - assign io_out[24] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[0]; - assign io_oeb[24] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[0]; - - // Wire-bond TOP side I/O of FPGA to TOP-side of Caravel interface - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[1:9] = io_in[23:15]; - assign io_out[23:15] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[1:9]; - assign io_oeb[23:15] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[1:9]; - - // Wire-bond TOP side I/O of FPGA to RIGHT-side of Caravel interface - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[10:11] = io_in[14:13]; - assign io_out[14:13] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[10:11]; - assign io_oeb[14:13] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[10:11]; - - // Wire-bond RIGHT side I/O of FPGA to RIGHT-side of Caravel interface - assign ccff_head = io_in[12]; - assign io_out[12] = 1'b0; - assign io_oeb[12] = 1'b1; - - assign io_out[11] = sc_tail; - assign io_oeb[11] = 1'b0; - - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[12:20] = io_in[10:2]; - assign io_out[10:2] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[12:20]; - assign io_oeb[10:2] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[12:20]; - - assign io_isol_n = io_in[1]; - assign io_out[1] = 1'b0; - assign io_oeb[1] = 1'b1; - - assign Test_en = io_in[0]; - assign io_out[0] = 1'b0; - assign io_oeb[0] = 1'b1; - - // Wire-bond RIGHT, BOTTOM, LEFT side I/O of FPGA to BOTTOM-side of Caravel interface - // Autogenerate code start - // Autogenerate code end - - // Wire-bond LEFT side I/O of FPGA to LEFT-side of Caravel interface - assign prog_clk = io_in[37]; - assign io_out[37] = 1'b0; - assign io_oeb[37] = 1'b1; - - // FPGA clock port can be driven by either wishbone clock or an GPIO - assign clk = io_in[36]; - assign io_out[36] = 1'b0; - assign io_oeb[36] = 1'b1; - - assign io_out[35] = ccff_tail; - assign io_oeb[35] = 1'b0; - - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[136:143] = io_in[34:27]; - assign io_out[34:27] = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[136:143]; - assign io_oeb[34:27] = gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[136:143]; - - assign sc_head = io_in[26]; - assign io_out[26] = 1'b0; - assign io_oeb[26] = 1'b1; - - // I/O[25] is reserved for a switch between wishbone interface - // and logic analyzer - assign wb_la_switch = io_in[25]; - assign io_out[25] = 1'b0; - assign io_oeb[25] = 1'b1; - - // TODO: Connect spypad from FPGA to logic analyzer ports - - fpga_core fpga_core_uut(.prog_clk(prog_clk), - .Test_en(Test_en), - .clk(clk), - .IO_ISOL_N(io_isol_n), - .gfpga_pad_EMBEDDED_IO_HD_SOC_IN(gfpga_pad_EMBEDDED_IO_HD_SOC_IN), - .gfpga_pad_EMBEDDED_IO_HD_SOC_OUT(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT), - .gfpga_pad_EMBEDDED_IO_HD_SOC_DIR(gfpga_pad_EMBEDDED_IO_HD_SOC_DIR), - .ccff_head(ccff_head), - .ccff_tail(ccff_tail), - .sc_head(sc_head), - .sc_tail(sc_tail) - ); - -endmodule +version https://git-lfs.github.com/spec/v1 +oid sha256:f1a4fa593e880caa1e6b1c8dac904ae9c9718fcf9d3711bcb006455643e22f97 +size 3246 diff --git a/HDL/common/caravel_wrapper_pin_assignment_v1.0.json b/HDL/common/caravel_wrapper_pin_assignment_v1.0.json new file mode 100644 index 0000000..b9cb0ff --- /dev/null +++ b/HDL/common/caravel_wrapper_pin_assignment_v1.0.json @@ -0,0 +1,163 @@ +{ + "caravel_gpio_input_name": "io_in", + "caravel_gpio_output_name": "io_out", + "caravel_gpio_direction_name": "io_oeb", + "caravel_logic_analyzer_input_name": "la_data_in", + "caravel_logic_analyzer_output_name": "la_data_out", + "caravel_logic_analyzer_direction_name": "la_oen", + "caravel_wishbone_clock_input_name": "wb_clk_i", + "caravel_wishbone_reset_input_name": "wb_rst_i", + "caravel_wishbone_ack_output_name": "wbs_ack_o", + "caravel_wishbone_cyc_input_name": "wbs_cyc_i", + "caravel_wishbone_stb_input_name": "wbs_stb_i", + "caravel_wishbone_we_input_name": "wbs_we_i", + "caravel_wishbone_sel_input_name": "wbs_sel_i", + "caravel_wishbone_address_input_name": "wbs_adr_i", + "caravel_wishbone_data_input_name": "wbs_dat_i", + "caravel_wishbone_data_output_name": "wbs_dat_o", + "fpga_gpio_input_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_IN", + "fpga_gpio_output_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT", + "fpga_gpio_direction_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_DIR", + "mode_switch_pin_name": "wb_la_switch", + "inverted_mode_switch_pin_name": "wb_la_switch_b", + "pins": [ + { + "fpga_pin_type": "io", + "fpga_pin_index": "0:11", + "caravel_pin_type": ["gpio"], + "caravel_pin_index": ["24:13"] + }, + { + "fpga_pin_type": "ccff_head", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["12:12"] + }, + { + "fpga_pin_type": "sc_tail", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["output"], + "caravel_pin_index": ["11:11"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "12:20", + "caravel_pin_type": ["gpio"], + "caravel_pin_index": ["10:2"] + }, + { + "fpga_pin_type": "IO_ISOL_N", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["1:1"] + }, + { + "fpga_pin_type": "Test_en", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "21:23", + "caravel_pin_type": ["logic_analyzer_io"], + "caravel_pin_index": ["127:125"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "24:29", + "caravel_pin_type": ["logic_analyzer_io"], + "caravel_pin_index": ["124:119"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "30:61", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_data_output"], + "caravel_pin_index": ["118:87", "0:31"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "62:93", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_data_input"], + "caravel_pin_index": ["86:55", "0:31"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "94:125", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_address_input"], + "caravel_pin_index": ["54:23", "0:31"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "126:129", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_sel_input"], + "caravel_pin_index": ["22:19", "0:3"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "130:130", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_we_input"], + "caravel_pin_index": ["18:18", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "131:131", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_stb_input"], + "caravel_pin_index": ["17:17", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "132:132", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_cyc_input"], + "caravel_pin_index": ["16:16", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "133:133", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_ack_output"], + "caravel_pin_index": ["15:15", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "134:134", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_reset_input"], + "caravel_pin_index": ["14:14", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "135:135", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_clock_input"], + "caravel_pin_index": ["13:13", "0:0"] + }, + { + "fpga_pin_type": "prog_clk", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["37:37"] + }, + { + "fpga_pin_type": "clk", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["36:36"] + }, + { + "fpga_pin_type": "ccff_tail", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["output"], + "caravel_pin_index": ["35:35"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "136:143", + "caravel_pin_type": ["gpio"], + "caravel_pin_index": ["34:27"] + }, + { + "fpga_pin_type": "sc_head", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["26:26"] + } + ] +} diff --git a/HDL/common/caravel_wrapper_pin_assignment_v1.1.json b/HDL/common/caravel_wrapper_pin_assignment_v1.1.json new file mode 100644 index 0000000..abbff5b --- /dev/null +++ b/HDL/common/caravel_wrapper_pin_assignment_v1.1.json @@ -0,0 +1,175 @@ +{ + "caravel_gpio_input_name": "io_in", + "caravel_gpio_output_name": "io_out", + "caravel_gpio_direction_name": "io_oeb", + "caravel_logic_analyzer_input_name": "la_data_in", + "caravel_logic_analyzer_output_name": "la_data_out", + "caravel_logic_analyzer_direction_name": "la_oen", + "caravel_wishbone_clock_input_name": "wb_clk_i", + "caravel_wishbone_reset_input_name": "wb_rst_i", + "caravel_wishbone_ack_output_name": "wbs_ack_o", + "caravel_wishbone_cyc_input_name": "wbs_cyc_i", + "caravel_wishbone_stb_input_name": "wbs_stb_i", + "caravel_wishbone_we_input_name": "wbs_we_i", + "caravel_wishbone_sel_input_name": "wbs_sel_i", + "caravel_wishbone_address_input_name": "wbs_adr_i", + "caravel_wishbone_data_input_name": "wbs_dat_i", + "caravel_wishbone_data_output_name": "wbs_dat_o", + "fpga_gpio_input_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_IN", + "fpga_gpio_output_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT", + "fpga_gpio_direction_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_DIR", + "mode_switch_pin_name": "wb_la_switch", + "inverted_mode_switch_pin_name": "wb_la_switch_b", + "pins": [ + { + "fpga_pin_type": "io", + "fpga_pin_index": "0:11", + "caravel_pin_type": ["gpio"], + "caravel_pin_index": ["24:13"] + }, + { + "fpga_pin_type": "ccff_head", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["12:12"] + }, + { + "fpga_pin_type": "sc_tail", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["output"], + "caravel_pin_index": ["11:11"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "12:18", + "caravel_pin_type": ["gpio"], + "caravel_pin_index": ["10:4"] + }, + { + "fpga_pin_type": "prog_reset", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["3:3"] + }, + { + "fpga_pin_type": "reset", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["2:2"] + }, + { + "fpga_pin_type": "IO_ISOL_N", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["1:1"] + }, + { + "fpga_pin_type": "Test_en", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "19:23", + "caravel_pin_type": ["logic_analyzer_io"], + "caravel_pin_index": ["127:123"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "24:29", + "caravel_pin_type": ["logic_analyzer_io"], + "caravel_pin_index": ["122:117"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "30:61", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_data_output"], + "caravel_pin_index": ["116:85", "0:31"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "62:93", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_data_input"], + "caravel_pin_index": ["84:53", "0:31"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "94:125", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_address_input"], + "caravel_pin_index": ["52:21", "0:31"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "126:129", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_sel_input"], + "caravel_pin_index": ["20:17", "0:3"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "130:130", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_we_input"], + "caravel_pin_index": ["16:16", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "131:131", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_stb_input"], + "caravel_pin_index": ["15:15", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "132:132", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_cyc_input"], + "caravel_pin_index": ["14:14", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "133:133", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_ack_output"], + "caravel_pin_index": ["13:13", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "134:134", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_reset_input"], + "caravel_pin_index": ["12:12", "0:0"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "135:135", + "caravel_pin_type": ["logic_analyzer_io", "wishbone_clock_input"], + "caravel_pin_index": ["11:11", "0:0"] + }, + { + "fpga_pin_type": "prog_clk", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["37:37"] + }, + { + "fpga_pin_type": "clk", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["36:36"] + }, + { + "fpga_pin_type": "ccff_tail", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["output"], + "caravel_pin_index": ["35:35"] + }, + { + "fpga_pin_type": "io", + "fpga_pin_index": "136:143", + "caravel_pin_type": ["gpio"], + "caravel_pin_index": ["34:27"] + }, + { + "fpga_pin_type": "sc_head", + "fpga_pin_index": "0:0", + "caravel_pin_type": ["input"], + "caravel_pin_index": ["26:26"] + } + ] +} diff --git a/HDL/common/wrapper_lines_generator.py b/HDL/common/wrapper_lines_generator.py index 334b2c3..a4808f1 100644 --- a/HDL/common/wrapper_lines_generator.py +++ b/HDL/common/wrapper_lines_generator.py @@ -12,6 +12,7 @@ import shutil import re import argparse import logging +import json ##################################################################### # Initialize logger @@ -26,111 +27,214 @@ parser = argparse.ArgumentParser( description='Generator for technology-mapped wrapper') parser.add_argument('--template_netlist', default='caravel_fpga_wrapper_hd_template.v', help='Specify template verilog netlist') +parser.add_argument('--pin_assignment_file', required=True, + help='Specify the json file constaining pin assignment information') parser.add_argument('--output_verilog', default='caravel_fpga_wrapper_hd.v', help='Specify output verilog file path') args = parser.parse_args() ##################################################################### -# Define Wishbone interface pin sequence -# The list start from left-side of the wrapper to the right side -# Target FPGA gpio start from 135, 134 ... +# Check options: +# - Input json file must be valid +# Otherwise, error out ##################################################################### -wishbone_pins = ['wb_clk_i', 'wb_rst_i', - 'wbs_ack_o', 'wbs_cyc_i', - 'wbs_stb_i', 'wbs_we_i'] - -wishbone_pins.extend([f"wbs_sel_i[{i}]" for i in range(4)]) -wishbone_pins.extend([f"wbs_adr_i[{i}]" for i in range(32)]) -wishbone_pins.extend([f"wbs_dat_i[{i}]" for i in range(32)]) -wishbone_pins.extend([f"wbs_dat_o[{i}]" for i in range(32)]) +if not isfile(args.pin_assignment_file): + logging.error("Invalid pin assignment file: " + args.pin_assignment_file + "\nFile does not exist!\n") + exit(1) ##################################################################### -# Define Logic Analyzer interface pin sequence -# The list start from left-side of the wrapper to the right side -# Target FPGA gpio start from 135, 134 ... +# Parse the json file ##################################################################### -logic_analyzer_pins = [] -for ipin in range(13, 128): - logic_analyzer_pins.append(["la_data_in[" + str(ipin) + "]", - "la_data_out[" + str(ipin) + "]", "la_oen[" + str(ipin) + "]"]) +json_file = open(args.pin_assignment_file, "r") +pin_data = json.load(json_file) + +##################################################################### +# A function to parse pin range from json data +# JSON pin range format is LSB:MSB +# Return pin range format is [LSB, MSB] as a list +##################################################################### +def parse_json_pin_range(json_range) : + pin_range_str = json_range.split(':') + assert(2 == len(pin_range_str)) + # If the range is in decend order, we will decrease the MSB by 1 + if (int(pin_range_str[0]) > int(pin_range_str[1])) : + return range(int(pin_range_str[0]), int(pin_range_str[1]) - 1, -1) + # If the range is in acend order, we will increase the MSB by 1 + return range(int(pin_range_str[0]), int(pin_range_str[1]) + 1) ##################################################################### # Generate wrapper lines ##################################################################### netlist_lines = [] -num_wishbone_pins = len(wishbone_pins) -num_logic_analyzer_pins = len(logic_analyzer_pins) -num_gpio_pins = 135 - 21 + 1 -print("Number of Wishbone pins: " + str(num_wishbone_pins)) -print("Number of logic analyzer pins: " + str(num_logic_analyzer_pins)) -print("Number of gpio pins: " + str(num_gpio_pins)) +# Walk through the array containing the pin information +for pin_info in pin_data['pins']: + # Deposit a tab to respect the HDL coding indent + curr_line = "" + # TODO: Check codes that ensure the pin index should match + assert(0 < len(pin_info['caravel_pin_type'])) + assert(0 < len(pin_info['caravel_pin_index'])) + # + # Branch on the types of connnections: + # - FPGA I/O to Caravel GPIO + if (("io" == pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("gpio" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + # Connect all the input, output and direction port + # FPGA input <- Caravel input + curr_line = "assign " + pin_data['fpga_gpio_input_name'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_gpio_input_name'] + "[" + str(indices[1]) + "];"; + netlist_lines.append(" " + curr_line + "\n") + # FPGA output -> Caravel output + curr_line = "assign " + pin_data['caravel_gpio_output_name'] + "[" + str(indices[1]) + "] = " \ + + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "];"; + netlist_lines.append(" " + curr_line + "\n") + # FPGA direction -> Caravel direction + curr_line = "assign " + pin_data['caravel_gpio_direction_name'] + "[" + str(indices[1]) + "] = " \ + + pin_data['fpga_gpio_direction_name'] + "[" + str(indices[0]) + "];"; + netlist_lines.append(" " + curr_line + "\n") -assert num_wishbone_pins < num_logic_analyzer_pins -assert num_logic_analyzer_pins == num_gpio_pins + # - FPGA control input ports to Caravel GPIO + if (("io" != pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("input" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + # Connect the FPGA input port to the Caravel input + curr_line = "assign " + pin_info['fpga_pin_type'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_gpio_input_name'] + "[" + str(indices[1]) + "];"; + netlist_lines.append(" " + curr_line + "\n") + # Tie Caravel output port to logic '0' + curr_line = "assign " + pin_data['caravel_gpio_output_name'] + "[" + str(indices[1]) + "] = 1'b0;" + netlist_lines.append(" " + curr_line + "\n") + # Tie Caravel direction port to logic '1' + curr_line = "assign " + pin_data['caravel_gpio_direction_name'] + "[" + str(indices[1]) + "] = 1'b1;" + netlist_lines.append(" " + curr_line + "\n") -for ipin in range(0, num_gpio_pins): - curr_line = "" - if ((ipin < num_wishbone_pins) and (ipin < num_logic_analyzer_pins)): - # If this is an input pin of wishbone interface, whose postfix is '_i', we use MUX - # otherwise, this is an output pin, we just wire the input to logic analyzer - if ((wishbone_pins[ipin].endswith("_i")) or (re.search(r'_i\[\d+\]$', wishbone_pins[ipin], re.M | re.I))): - ############################################################## - # SOC INPUT will be directly driven by either - # - the Wishbone input - # or - # - the logic analyzer input - # through a multiplexer controlled by the signal 'wb_la_switch - curr_line = " " + "sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_" + str(135 - ipin) + "_MUX (.S(wb_la_switch), .A1(" + str( - wishbone_pins[ipin]) + "), .A0(" + str(logic_analyzer_pins[ipin][0]) + "), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(135 - ipin) + "]));" - netlist_lines.append(curr_line + "\n") - ############################################################## - # SOC OUTPUT will drive an output of logic analyzer - # since this I/O is going to interface a Wishbone input only - curr_line = " " + "assign " + \ - str(logic_analyzer_pins[ipin][1]) + \ - " = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];" - netlist_lines.append(curr_line + "\n") - elif ((wishbone_pins[ipin].endswith("_o")) or (re.search(r'_o\[\d+\]$', wishbone_pins[ipin], re.M | re.I))): - ############################################################## - # SOC INPUT will be directly driven by logic analyzer - # since this I/O is going to interface a Wishbone output only - curr_line = " " + "assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str( - 135 - ipin) + "] = " + str(logic_analyzer_pins[ipin][0]) + ";" - netlist_lines.append(curr_line + "\n") - ############################################################## - # SOC OUTPUT will drive the Wishbone output through a tri-state buffer - # As the buffer is enabled by logic '0', we use the inverted 'wb_la_switch' - curr_line = " " + "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(135 - ipin) + "_DEMUX_WB (" + \ - ".TE_B(wb_la_switch_b), " + \ - ".A(" + "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "]), " + \ - ".Z(" + str(wishbone_pins[ipin]) + ")" + \ - ");" - netlist_lines.append(curr_line + "\n") - ############################################################## - # SOC OUTPUT will also drive the Logic Analyzer output through a tri-state buffer - # As the buffer is enabled by logic '0', we use the 'wb_la_switch' - curr_line = " " + "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(135 - ipin) + "_DEMUX_LA (" + \ - ".TE_B(wb_la_switch), " + \ - ".A(" + "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "]), " + \ - ".Z(" + str(logic_analyzer_pins[ipin][1]) + ")" + \ - ");" - netlist_lines.append(curr_line + "\n") + # - FPGA control output ports to Caravel GPIO + if (("io" != pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("output" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + # Bypass the Caravel input + # Connect Caravel output port to FPGA control output + curr_line = "assign " + pin_data['caravel_gpio_output_name'] + "[" + str(indices[1]) + "] = " \ + + pin_info['fpga_pin_type'] + "[" + str(indices[0]) + "];"; + netlist_lines.append(" " + curr_line + "\n") + # Tie Caravel direction port to logic '0' + curr_line = "assign " + pin_data['caravel_gpio_direction_name'] + "[" + str(indices[1]) + "] = 1'b0;" + netlist_lines.append(" " + curr_line + "\n") - elif ((ipin >= num_wishbone_pins) and (ipin < num_logic_analyzer_pins)): + # - FPGA I/O ports to Caravel logic analyzer I/O only + if (("io" == pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("logic_analyzer_io" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + ############################################################## + # SOC INPUT will be directly driven by logic analyzer + # since this I/O is going to interface logic analyzer input only + curr_line = "assign " + pin_data['fpga_gpio_input_name'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_logic_analyzer_input_name'] + "[" + str(indices[1]) + "]" + ";" + netlist_lines.append(" " + curr_line + "\n") + ############################################################## + # SOC OUTPUT will directly drive logic analyzer + # since this I/O is going to interface logic analyzer output only + curr_line = "assign " + pin_data['caravel_logic_analyzer_output_name'] + "[" + str(indices[1]) + "]" \ + + " = " + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "];" + netlist_lines.append(" " + curr_line + "\n") + + # - FPGA I/O ports to Caravel logic analyzer I/O and Wishbone interface + if (("io" == pin_info['fpga_pin_type']) \ + and (2 == len(pin_info['caravel_pin_type'])) \ + and ("logic_analyzer_io" == pin_info['caravel_pin_type'][0]) \ + and (pin_info['caravel_pin_type'][1].startswith("wishbone"))): + # Should have only 2 port in caravel + assert(2 == len(pin_info['caravel_pin_type'])) + assert(2 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + la_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + wb_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][1]) + assert(len(list(fpga_io_pin_range)) == len(list(la_io_pin_range))) + assert(len(list(fpga_io_pin_range)) == len(list(wb_io_pin_range))) + + # If this is an input pin of wishbone interface, whose postfix is '_i', we use MUX + # otherwise, this is an output pin, we just wire the input to logic analyzer + if (pin_info['caravel_pin_type'][1].endswith("_input")): + for indices in zip(list(fpga_io_pin_range), list(la_io_pin_range), list(wb_io_pin_range)) : + ############################################################## + # SOC INPUT will be directly driven by either + # - the Wishbone input + # or + # - the logic analyzer input + # through a multiplexer controlled by the signal 'wb_la_switch + curr_line = "sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_" + str(indices[0]) + "_MUX (" \ + + ".S(" + pin_data['mode_switch_pin_name'] + "), " \ + + ".A1(" + pin_data['caravel_' + pin_info['caravel_pin_type'][1] + '_name'] + "[" + str(indices[2]) + "]), " \ + + ".A0(" + pin_data['caravel_logic_analyzer_input_name'] + "[" + str(indices[1]) + "]), " \ + + ".X(" + pin_data['fpga_gpio_input_name'] + "[" + str(indices[0]) + "])" \ + + ");" + netlist_lines.append(" " + curr_line + "\n") + ############################################################## + # SOC OUTPUT will drive an output of logic analyzer + # since this I/O is going to interface a Wishbone input only + curr_line = "assign " + pin_data['caravel_logic_analyzer_output_name'] + "[" + str(indices[1]) + "]" \ + + " = " + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "];" + netlist_lines.append(" " + curr_line + "\n") + elif (pin_info['caravel_pin_type'][1].endswith("_output")): + for indices in zip(list(fpga_io_pin_range), list(la_io_pin_range), list(wb_io_pin_range)) : ############################################################## # SOC INPUT will be directly driven by logic analyzer - # since this I/O is going to interface logic analyzer input only - curr_line = " " + "assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str( - 135 - ipin) + "] = " + str(logic_analyzer_pins[ipin][0]) + ";" - netlist_lines.append(curr_line + "\n") + # since this I/O is going to interface a Wishbone output only + curr_line = "assign " + pin_data['fpga_gpio_input_name'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_logic_analyzer_input_name'] + "[" + str(indices[1]) + "];" + netlist_lines.append(" " + curr_line + "\n") ############################################################## - # SOC OUTPUT will directly drive logic analyzer - # since this I/O is going to interface logic analyzer output only - curr_line = " " + "assign " + \ - str(logic_analyzer_pins[ipin][1]) + \ - " = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];" - netlist_lines.append(curr_line + "\n") + # SOC OUTPUT will drive the Wishbone output through a tri-state buffer + # As the buffer is enabled by logic '0', we use the inverted 'wb_la_switch' + curr_line = "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(indices[0]) + "_DEMUX_WB (" \ + + ".TE_B(" + pin_data['inverted_mode_switch_pin_name'] + "), " \ + + ".A(" + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "]), " \ + + ".Z(" + pin_data['caravel_' + pin_info['caravel_pin_type'][1] + '_name'] + "[" + str(indices[2]) + "])" \ + + ");" + netlist_lines.append(" " + curr_line + "\n") + ############################################################## + # SOC OUTPUT will also drive the Logic Analyzer output through a tri-state buffer + # As the buffer is enabled by logic '0', we use the 'wb_la_switch' + curr_line = "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(indices[0]) + "_DEMUX_LA (" \ + + ".TE_B(" + pin_data['mode_switch_pin_name'] + "), " \ + + ".A(" + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "]), " \ + + ".Z(" + pin_data['caravel_logic_analyzer_output_name'] + "[" + str(indices[1]) + "])" \ + + ");" + netlist_lines.append(" " + curr_line + "\n") if isfile(args.output_verilog): os.remove(args.output_verilog) diff --git a/MSIM/README.md b/MSIM/README.md new file mode 100644 index 0000000..902de3e --- /dev/null +++ b/MSIM/README.md @@ -0,0 +1,12 @@ +# Skywater PDK +This directory is the workspace for running Mentor Modelsim simulations for FPGA fabrics +Please keep this directory clean and organize as follows: +- Each task-run should be placed in a separated directory +- **common**: include commonly used scripts for post-PnR verification +- READMD is the only file allowed in the directory, others should be sub-directories. + +* Quick Example to run simulations for task-run + +``` +python3 run_post_pnr_msim_task.py --testbench_dir_name ../../TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc --task_name k4_N8_caravel_io_FPGA_12x12_fdhd_cc +``` diff --git a/MSIM/common/modelsim_proc.tcl b/MSIM/common/modelsim_proc.tcl index 69972b7..5fd24ba 100644 --- a/MSIM/common/modelsim_proc.tcl +++ b/MSIM/common/modelsim_proc.tcl @@ -9,14 +9,14 @@ proc create_project_with_close {projectname modelsim_path} { #Get the current project name set project_env [project env] if {$project_env eq ""} { - #If string empty (no project) - create_project $projectname $modelsim_path - } else { - #If string not empty (a project is loaded so clsoe it first) - project close - create_project $projectname $modelsim_path - } + #If string empty (no project) + create_project $projectname $modelsim_path + } else { + #If string not empty (a project is loaded so clsoe it first) + project close + create_project $projectname $modelsim_path } +} proc add_files_project {verilog_files} { #Get the length of the list @@ -30,11 +30,9 @@ proc add_files_project {verilog_files} { proc add_waves {top_tb} { add wave -position insertpoint sim:/$top_tb/* } -proc runsim {simtime unit} { - run $simtime $unit -} + #Top procedure to create enw project -proc top_create_new_project {projectname verilog_files modelsim_path simtime unit top_tb} { +proc top_create_new_project {projectname verilog_files modelsim_path top_tb} { #Create the project create_project_with_close $projectname $modelsim_path #Add the verilog files @@ -42,30 +40,12 @@ proc top_create_new_project {projectname verilog_files modelsim_path simtime uni #Compile all the files set myFiles [project filenames] foreach x $myFiles { - vlog +define+ENABLE_TIMING +define+ENABLE_SIGNAL_INITIALIZATION $x + vlog +define+ENABLE_SIGNAL_INITIALIZATION $x } #Start the simulation vsim $projectname.$top_tb -voptargs=+acc #Add the waves add_waves $top_tb #run the simulation - runsim $simtime $unit - #Fit the window view - wave zoom full -} -#Top proc to recompile files and re run the simulation -proc top_rerun_sim {simtime unit top_tb} { - #Save actual format - set myLoc [pwd] - write format wave -window .main_pane.wave.interior.cs.body.pw.wf $myLoc/relaunch.do - quit -sim - #Compile updated verilog files - set myFiles [project filenames] - foreach x $myFiles { - vlog +define+ENABLE_TIMING +define+ENABLE_SIGNAL_INITIALIZATION $x - } - set projectname K4n4_test_fpga_msim - vsim $projectname.$top_tb -voptargs=+acc -do relaunch.do - #run the simulation - run $simtime $unit + run -all } diff --git a/MSIM/common/run_post_pnr_msim_task.py b/MSIM/common/run_post_pnr_msim_task.py new file mode 100644 index 0000000..09b538e --- /dev/null +++ b/MSIM/common/run_post_pnr_msim_task.py @@ -0,0 +1,76 @@ +##################################################################### +# Python script to run ModelSim simulations for all the post-pnr testbenches +# in a project directory +# This script will +# - Collect all the testbenches in a given directory +# For instance: +# ../k4_arch/pre_pnr/verilog_testbenches/and2_post_pnr_include_netlist.v +# - Use run_post_pnr_msim_test.py to run Modelsim simulations and check results +##################################################################### + +import os +from os.path import dirname, abspath +import shutil +import re +import argparse +import logging +import subprocess +import glob + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) + +##################################################################### +# Parse the options +##################################################################### +parser = argparse.ArgumentParser(description='Run a ModelSim verification task for a tape-out FPGA') +parser.add_argument('--testbench_dir_name', required=True, + help='Specify the directory path for the Verilog testbenches') +parser.add_argument('--task_name', required=True, + help='Specify the directory path for the Verilog testbenches') +args = parser.parse_args() + +##################################################################### +# Walk through the parent directory and find all the pre-PnR testbenches +##################################################################### +logging.info("Finding testbenches..."); + +testbench_dir_abspath = abspath(args.testbench_dir_name) + "/postpnr/verilog_testbench"; + +testbench_files = [] +for globbed_file in glob.glob(testbench_dir_abspath + "/*_include_netlists.v"): + testbench_files.append(globbed_file) + +logging.info("Found " + str(len(testbench_files)) + " testbenches") + +##################################################################### +# Try to create the directory of Modelsim projects +##################################################################### +parent_dir_abspath = dirname(dirname(abspath(__file__))) +msim_task_dir_abspath = abspath(parent_dir_abspath + "/" + args.task_name) + "/postpnr/verilog_testbench"; +os.makedirs(msim_task_dir_abspath, exist_ok=True) + +##################################################################### +# Run ModelSim simulations for each testbench +##################################################################### +logging.info("Running Modelsim simulations..."); + +num_sim_finished = 0 + +msim_testrun_script_abspath = os.path.abspath(__file__) +msim_testrun_script_abspath = re.sub(os.path.basename(msim_testrun_script_abspath), "run_post_pnr_msim_test.py", msim_testrun_script_abspath) + +for testbench_file in testbench_files: + # Find testbench name + testbench_name = re.findall("(\w+)_include_netlists.v", os.path.basename(testbench_file))[0] + cmd = "python3 " + msim_testrun_script_abspath \ + + " --verilog_testbench " + testbench_file \ + + " --project_path " + msim_task_dir_abspath + "/" + testbench_name \ + + " --testbench_name " + testbench_name + "_autocheck_top_tb" + subprocess.run(cmd, shell=True, check=True) + num_sim_finished += 1 + +logging.info("Done") +logging.info("Finish " + str(num_sim_finished) + " ModelSim simulations") diff --git a/MSIM/common/run_post_pnr_msim_test.py b/MSIM/common/run_post_pnr_msim_test.py new file mode 100644 index 0000000..54d5e25 --- /dev/null +++ b/MSIM/common/run_post_pnr_msim_test.py @@ -0,0 +1,147 @@ +##################################################################### +# Python script to execute modelsim simulation for a given testbench netlist +# This script will +# - Create the tcl script to enable modelsim simulation +# - Run modelsim simulation +# - Analyze output log files and return succeed or failure +##################################################################### + +import os +from os.path import dirname, abspath, isfile +import shutil +import re +import argparse +import logging +import subprocess + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) + +##################################################################### +# Parse the options +##################################################################### +parser = argparse.ArgumentParser(description='Run ModelSim verification for a testbench') +parser.add_argument('--verilog_testbench', required=True, + help='Specify the file path for the Verilog testbench as input') +parser.add_argument('--project_path', required=True, + help='Specify the file path to create the ModelSim project') +parser.add_argument('--testbench_name', required=True, + help='Specify the top-level module of the testbench') +args = parser.parse_args() + +##################################################################### +# Check options: +# - Input testbench file must be valid +# Otherwise, error out +# - If the modelsim project path does not exist, create it +##################################################################### +if not isfile(args.verilog_testbench): + logging.error("Invalid Verilog testbench: " + args.verilog_testbench + "\nFile does not exist!\n") + exit(1) + +project_abs_path = os.path.abspath(args.project_path) +if not os.path.isdir(project_abs_path): + logging.debug("Creating ModelSim project directory : " + project_abs_path + " ...\n") + os.makedirs(project_abs_path, exist_ok=True) + logging.debug("Done\n") + +##################################################################### +# Create the Tcl script for Modelsim +##################################################################### +# Get modelsim process tcl file path +msim_proc_tcl_path = os.path.abspath(__file__) +msim_proc_tcl_path = re.sub(os.path.basename(msim_proc_tcl_path), "modelsim_proc.tcl", msim_proc_tcl_path) +if not isfile(msim_proc_tcl_path): + logging.error("Invalid process script for ModelSim: " + msim_proc_tcl_path + "\nFile does not exist!\n") + exit(1) + +# Create output file handler +tcl_file_path = project_abs_path + "/" + os.path.basename(args.testbench_name) + ".tcl" +logging.debug("Generating Tcl script for ModelSim: " + tcl_file_path) +tcl_file = open(tcl_file_path, "w") + +# A string buffer to write tcl content +tcl_lines = [] + +tcl_lines.append("echo \"==============================\"") +tcl_lines.append("pwd") +tcl_lines.append("echo \"==============================\"") +tcl_lines.append("\n") +tcl_lines.append("set project_name " + args.testbench_name) +tcl_lines.append("set top_tb " + args.testbench_name) +tcl_lines.append("\n") +tcl_lines.append("set project_path \"" + project_abs_path + "\"") +tcl_lines.append("set verilog_files \"" + os.path.abspath(args.verilog_testbench) + "\"") +tcl_lines.append("\n") +tcl_lines.append("source " + msim_proc_tcl_path) +tcl_lines.append("\n") +tcl_lines.append("try {") +tcl_lines.append("\ttop_create_new_project $project_name $verilog_files $project_path $top_tb") +tcl_lines.append("} finally {") +tcl_lines.append("\tquit") +tcl_lines.append("}") + +for line in tcl_lines: + tcl_file.write(line + "\n") + +tcl_file.close() +logging.debug("Done") + +##################################################################### +# Run ModelSim simulation +##################################################################### +curr_dir = os.getcwd() +# Change to the project directory +os.chdir(project_abs_path) +logging.debug("Changed to directory: " + project_abs_path) + +# Run ModelSim +vsim_log_file_path = project_abs_path + "/vsim_run_log" +vsim_bin = "/uusoc/facility/cad_tools/Mentor/modelsim10.7b/modeltech/bin/vsim" +vsim_cmd = vsim_bin + " -c -do " + os.path.abspath(tcl_file_path) + " > " + vsim_log_file_path +logging.debug("Running modelsim by : " + vsim_cmd) +subprocess.run(vsim_cmd, shell=True, check=True) + +# Go back to current directory +os.chdir(curr_dir) + +##################################################################### +# Parse log files and report any errors +##################################################################### +vsim_log_file = open(vsim_log_file_path, "r") + +# Error counter +num_err = 0 +num_err_lines_found = 0 +verification_passed = False + +for line in vsim_log_file: + # Check errors from self-testing testbench output + if line.startswith("# Simulation finish with") : + num_sim_err = int(re.findall("# Simulation finish with(\s+)(\d+) errors", line)[0][1]) + num_err_lines_found = num_err_lines_found + 1 + if (0 < num_sim_err) : + logging.error("Simulation failed with " + str(num_sim_err) + " errors!\n") + # Add to total errors + num_err = num_err + num_sim_err + # Check total errors by Modelsim + if line.startswith("# Errors:") : + num_msim_err = int(re.findall("# Errors:(\s)(\d+),", line)[0][1]) + num_err_lines_found = num_err_lines_found + 1 + num_err = num_err + num_msim_err + +vsim_log_file.close() + +if (0 == num_err_lines_found) : + logging.error("No error lines found!Something wrong in setting up modelsim simulation\n") +elif (0 < num_err) : + logging.error("ModelSim failed with " + str(num_err) + " errors!\n") +else : + verification_passed = True + +if (verification_passed) : + logging.info(args.testbench_name + "...[Passed]\n") +else : + logging.error(args.testbench_name + "...[Failed]\n") diff --git a/README.md b/README.md index f2de4f1..b7a4b0a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# skywater-openfpga +# Skywater + OpenFPGA: Open-Source FPGAs +[![linux_build](https://github.com/LNIS-Projects/skywater-openfpga/workflows/linux_build/badge.svg)](https://github.com/LNIS-Projects/skywater-openfpga/actions) +[![Documentation Status](https://readthedocs.org/projects/skywater-openfpga/badge/?version=latest)](https://skywater-openfpga.readthedocs.io/en/latest/?badge=latest) + +## Introduction + FPGA tape-outs using the open-source Skywater 130nm PDK and OpenFPGA ## Quick Start diff --git a/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_fabric/config/task_template.conf b/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_fabric/config/task_template.conf new file mode 100644 index 0000000..523fd1c --- /dev/null +++ b/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_fabric/config/task_template.conf @@ -0,0 +1,38 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = 1*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${SKYWATER_OPENFPGA_HOME}/SCRIPT/openfpga_shell_script/skywater_generate_fabric_using_key_example_script.openfpga +openfpga_arch_file=${SKYWATER_OPENFPGA_HOME}/ARCH/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${SKYWATER_OPENFPGA_HOME}/SCRIPT/openfpga_simulation_setting/efpga_12x12_sim_openfpga.xml +openfpga_vpr_device_layout=12x12 +openfpga_vpr_route_chan_width=40 +openfpga_verilog_output_dir=${SKYWATER_OPENFPGA_HOME}/HDL/k4_N8_reset_softadder_caravel_io_FPGA_12x12_fdhd_cc +openfpga_sdc_output_dir=${SKYWATER_OPENFPGA_HOME}/SDC/k4_N8_reset_softadder_caravel_io_FPGA_12x12_fdhd_cc +external_fabric_key_file=${SKYWATER_OPENFPGA_HOME}/ARCH/fabric_key/fabric_key_12x12.xml + +[ARCHITECTURES] +arch0=${SKYWATER_OPENFPGA_HOME}/ARCH/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/and2/and2.v + +[SYNTHESIS_PARAM] +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= diff --git a/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_sdc/config/task_template.conf b/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_sdc/config/task_template.conf new file mode 100644 index 0000000..a358b71 --- /dev/null +++ b/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_sdc/config/task_template.conf @@ -0,0 +1,37 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = 1*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${SKYWATER_OPENFPGA_HOME}/SCRIPT/openfpga_shell_script/skywater_generate_sdc_using_key_example_script.openfpga +openfpga_arch_file=${SKYWATER_OPENFPGA_HOME}/ARCH/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${SKYWATER_OPENFPGA_HOME}/SCRIPT/openfpga_simulation_setting/efpga_12x12_sim_openfpga.xml +openfpga_vpr_device_layout=12x12 +openfpga_vpr_route_chan_width=40 +openfpga_sdc_output_dir=${SKYWATER_OPENFPGA_HOME}/SDC/k4_N8_reset_softadder_caravel_io_FPGA_12x12_fdhd_cc +external_fabric_key_file=${SKYWATER_OPENFPGA_HOME}/ARCH/fabric_key/fabric_key_12x12.xml + +[ARCHITECTURES] +arch0=${SKYWATER_OPENFPGA_HOME}/ARCH/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/and2/and2.v + +[SYNTHESIS_PARAM] +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= diff --git a/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_testbench/config/task_template.conf b/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_testbench/config/task_template.conf new file mode 100644 index 0000000..6e5a9cb --- /dev/null +++ b/SCRIPT/skywater_openfpga_task/k4_N8_reset_softadder_caravel_cc_fdhd_12x12/generate_testbench/config/task_template.conf @@ -0,0 +1,54 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = 1*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${SKYWATER_OPENFPGA_HOME}/SCRIPT/openfpga_shell_script/skywater_generate_testbench_using_key_example_script.openfpga +openfpga_arch_file=${SKYWATER_OPENFPGA_HOME}/ARCH/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${SKYWATER_OPENFPGA_HOME}/SCRIPT/openfpga_simulation_setting/efpga_12x12_sim_openfpga.xml +openfpga_vpr_device_layout=12x12 +openfpga_vpr_route_chan_width=40 +openfpga_verilog_output_dir=${SKYWATER_OPENFPGA_HOME}/TESTBENCH/k4_N8_reset_softadder_caravel_io_FPGA_12x12_fdhd_cc/prepnr +openfpga_fabric_verilog_netlist=${SKYWATER_OPENFPGA_HOME}/HDL/k4_N8_reset_softadder_caravel_io_FPGA_12x12_fdhd_cc/SRC/fabric_netlists.v +external_fabric_key_file=${SKYWATER_OPENFPGA_HOME}/ARCH/fabric_key/fabric_key_12x12.xml + +[ARCHITECTURES] +arch0=${SKYWATER_OPENFPGA_HOME}/ARCH/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/and2/and2.v +bench1=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/and2_latch/and2_latch.v +bench2=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/bin2bcd/bin2bcd.v +bench3=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/counter/counter.v +bench4=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/routing_test/routing_test.v +# RS decoder needs 1.5k LUT4, exceeding device capacity +#bench5=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/rs_decoder/rtl/rs_decoder.v +bench6=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/simon_bit_serial/rtl/*.v +bench7=${SKYWATER_OPENFPGA_HOME}/BENCHMARK/and2_or2/and2_or2.v + +[SYNTHESIS_PARAM] +bench0_top = and2 +bench1_top = and2_latch +bench2_top = bin2bcd +bench3_top = counter +bench4_top = routing_test +# RS decoder needs 1.5k LUT4, exceeding device capacity +#bench5_top = rs_decoder_top +bench6_top = top_module +bench7_top = and2_or2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= diff --git a/TESTBENCH/common/ccff_test_post_pnr.v b/TESTBENCH/common/ccff_test_post_pnr.v new file mode 100644 index 0000000..a1ab2ec --- /dev/null +++ b/TESTBENCH/common/ccff_test_post_pnr.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b539cd91f8c0e2abca88387354c6cf211da149bf609b80671680fa9117611912 +size 5905 diff --git a/TESTBENCH/common/generate_post_pnr_testbenches.py b/TESTBENCH/common/generate_post_pnr_testbenches.py index 441b300..51c06f7 100644 --- a/TESTBENCH/common/generate_post_pnr_testbenches.py +++ b/TESTBENCH/common/generate_post_pnr_testbenches.py @@ -25,56 +25,75 @@ import glob ##################################################################### logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) +##################################################################### +# Parse the options +##################################################################### +parser = argparse.ArgumentParser(description='Generate post-PnR testbenches for a given directory') +parser.add_argument('--pre_pnr_testbench_dir_name', required=True, + help='Specify the directory path for the pre-PnR Verilog testbenches') +parser.add_argument('--pin_assignment_file', required=True, + help='Specify the file path to the pin assignment JSON description as input') +args = parser.parse_args() + ##################################################################### # Walk through the parent directory and find all the pre-PnR testbenches ##################################################################### logging.info("Finding pre-PnR testbenches..."); -parent_dirpath = dirname(dirname(abspath(__file__))) +script_base_dir_abspath = dirname(os.path.abspath(__file__)) +pre_pnr_testbench_dir_abspath = abspath(args.pre_pnr_testbench_dir_name) + "/prepnr/verilog_testbench"; # Count how many testbenches have been converted num_converted_testbenches = 0 # Collect the pre-PnR testbenches to be converted pre_pnr_testbench_files = [] -post_pnr_testbench_dirs = [] -for root, dirs, files in os.walk(parent_dirpath): - for dir_name in dirs: - # Skip 'common' directory as the testbenches inside are already converted - # Also skip any hidden directories - if ((dir_name == "common") or (dir_name.startswith("."))): - continue; - # Find the testbenches in the fixed location of the tree - curr_pre_pnr_testbench_dir_path = os.path.join(root, dir_name + "/prepnr/verilog_testbench") - # Add to list - logging.info("Checking directory: " + str(curr_pre_pnr_testbench_dir_path)) - for globbed_file in glob.glob(curr_pre_pnr_testbench_dir_path + "/*_autocheck_top_tb.v"): - pre_pnr_testbench_files.append(globbed_file) - # If we have testbenches to convert, try to create the directory of post-pnr testbenches - curr_post_pnr_testbench_dir_path = os.path.join(root, dir_name + "/postpnr/verilog_testbench") - post_pnr_testbench_dirs.append(curr_post_pnr_testbench_dir_path) + +# Add to list +for globbed_file in glob.glob(pre_pnr_testbench_dir_abspath + "/*_autocheck_top_tb.v"): + pre_pnr_testbench_files.append(globbed_file) +# If we have testbenches to convert, try to create the directory of post-pnr testbenches +post_pnr_testbench_dir_abspath = abspath(args.pre_pnr_testbench_dir_name) + "/postpnr/verilog_testbench"; logging.info("Found " + str(len(pre_pnr_testbench_files)) + " pre-PnR testbenches") ##################################################################### # Try to create the directory of post-pnr testbenches ##################################################################### -for post_pnr_testbench_dir in post_pnr_testbench_dirs: - os.makedirs(curr_post_pnr_testbench_dir_path, exist_ok=True) +os.makedirs(post_pnr_testbench_dir_abspath, exist_ok=True) ##################################################################### # Convert pre-PnR testbenches to post-PnR testbenches ##################################################################### logging.info("Converting pre-PnR testbench to post-PnR testbench..."); for curr_pre_pnr_testbench_file in pre_pnr_testbench_files: - logging.info("\nProcessing " + curr_pre_pnr_testbench_file + " testbench:\n") + logging.info("Processing " + curr_pre_pnr_testbench_file + " testbench:") curr_post_pnr_testbench_file = re.sub("_autocheck_top_tb.v$", "_post_pnr_autocheck_top_tb.v", curr_pre_pnr_testbench_file) curr_post_pnr_testbench_file = re.sub("\/prepnr\/", "\/postpnr\/", curr_post_pnr_testbench_file) - cmd = "python3 ./post_pnr_testbench_converter.py " \ + cmd = "python3 " + script_base_dir_abspath + "/post_pnr_testbench_converter.py " \ + " --pre_pnr_testbench " + curr_pre_pnr_testbench_file \ + " --post_pnr_testbench " + curr_post_pnr_testbench_file subprocess.run(cmd, shell=True, check=True) num_converted_testbenches += 1 + logging.info("Done") + +logging.info("\nConverted " + str(num_converted_testbenches) + " testbenches.") + +##################################################################### +# Convert post-PnR testbenches to wrapper testbenches +##################################################################### +logging.info("Converting pre-PnR testbench to post-PnR testbench..."); +for curr_pre_pnr_testbench_file in pre_pnr_testbench_files: + curr_post_pnr_testbench_file = re.sub("_autocheck_top_tb.v$", "_post_pnr_autocheck_top_tb.v", curr_pre_pnr_testbench_file) + curr_post_pnr_testbench_file = re.sub("\/prepnr\/", "\/postpnr\/", curr_post_pnr_testbench_file) + curr_wrapper_testbench_file = re.sub("_autocheck_top_tb.v$", "_wrapper_autocheck_top_tb.v", curr_post_pnr_testbench_file) + logging.info("Processing " + curr_post_pnr_testbench_file + " testbench:") + cmd = "python3 " + script_base_dir_abspath + "/post_pnr_wrapper_testbench_converter.py " \ + + " --post_pnr_testbench " + curr_post_pnr_testbench_file \ + + " --pin_assignment_file " + args.pin_assignment_file \ + + " --wrapper_testbench " + curr_wrapper_testbench_file + subprocess.run(cmd, shell=True, check=True) + num_converted_testbenches += 1 + logging.info("Done") -logging.info("Done") logging.info("\nConverted " + str(num_converted_testbenches) + " testbenches.") diff --git a/TESTBENCH/common/post_pnr_ccff_test.v b/TESTBENCH/common/post_pnr_ccff_test.v deleted file mode 100644 index a8e44df..0000000 --- a/TESTBENCH/common/post_pnr_ccff_test.v +++ /dev/null @@ -1,197 +0,0 @@ -//------------------------------------------- -// Verilog Testbench for Verifying -// Configuration Chain of a FPGA -// Description: This test is applicable to FPGAs which have 1 configuration -// chain. It will feed a pulse to the head of the configuration chain and -// check if the pulse is outputted by the tail of the configuration chain -// in a given time period -// -// Note: This test bench is tuned for the post PnR netlists -// Author: Xifan TANG -// Organization: University of Utah -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// Design parameter for FPGA I/O sizes -//`define FPGA_IO_SIZE 144 -// -// Design parameter for FPGA bitstream sizes -//`define FPGA_BITSTREAM_SIZE 65656 - -module post_pnr_ccff_test; -// ----- Local wires for global ports of FPGA fabric ----- -wire [0:0] prog_clk; -wire [0:0] Test_en; -wire [0:0] clk; - -// ----- Local wires for I/Os of FPGA fabric ----- - -wire [0:`FPGA_IO_SIZE - 1] gfpga_pad_EMBEDDED_IO_SOC_IN; -wire [0:`FPGA_IO_SIZE - 1] gfpga_pad_EMBEDDED_IO_SOC_OUT; -wire [0:`FPGA_IO_SIZE - 1] gfpga_pad_EMBEDDED_IO_SOC_DIR; - -wire [0:0] prog_clock; -reg [0:0] prog_clock_reg; -wire [0:0] op_clock; -reg [0:0] op_clock_reg; -reg [0:0] prog_reset; -reg [0:0] prog_set; -reg [0:0] greset; -reg [0:0] gset; -// ---- Configuration-chain head ----- -reg [0:0] ccff_head; -// ---- Configuration-chain tail ----- -wire [0:0] ccff_tail; - -// ---- Scan-chain head ----- -wire [0:0] sc_head; -// ---- Scan-chain tail ----- -wire [0:0] sc_tail; - -wire [0:0] IO_ISOL_N; - -// ----- Counters for error checking ----- -integer num_prog_cycles = 0; -integer num_errors = 0; -integer num_checked_points = 0; - -// Indicate when configuration should be finished -reg config_done = 0; - -initial - begin - config_done = 1'b0; - end - -// ----- Begin raw programming clock signal generation ----- -initial - begin - prog_clock_reg[0] = 1'b0; - end -always - begin - #5 prog_clock_reg[0] = ~prog_clock_reg[0]; - end - -// ----- End raw programming clock signal generation ----- - -// ----- Actual programming clock is triggered only when config_done and prog_reset are disabled ----- - assign prog_clock[0] = prog_clock_reg[0] & (~prog_reset[0]); - -// ----- Begin raw operating clock signal generation ----- -initial - begin - op_clock_reg[0] = 1'b0; - end - -// ----- End raw operating clock signal generation ----- -// ----- Actual operating clock is triggered only when config_done is enabled ----- - assign op_clock[0] = op_clock_reg[0]; - -// ----- Begin programming reset signal generation ----- -initial - begin - prog_reset[0] = 1'b1; - #10 prog_reset[0] = 1'b0; - end - -// ----- End programming reset signal generation ----- - -// ----- Begin programming set signal generation ----- -initial - begin - prog_set[0] = 1'b1; - #10 prog_set[0] = 1'b0; - end - -// ----- End programming set signal generation ----- - -// ----- Begin operating reset signal generation ----- -// ----- Reset signal is disabled always ----- -initial - begin - greset[0] = 1'b1; - end - -// ----- End operating reset signal generation ----- -// ----- Begin operating set signal generation: always disabled ----- -initial - begin - gset[0] = 1'b0; - end - -// ----- End operating set signal generation: always disabled ----- - -// ----- Begin connecting global ports of FPGA fabric to stimuli ----- - assign clk[0] = op_clock[0]; - assign prog_clk[0] = prog_clock[0]; - assign Test_en[0] = 1'b0; - assign sc_head[0] = 1'b0; - assign IO_ISOL_N[0] = 1'b0; -// ----- End connecting global ports of FPGA fabric to stimuli ----- -// ----- FPGA top-level module to be capsulated ----- - fpga_core FPGA_DUT ( - .prog_clk(prog_clk[0]), - .Test_en(Test_en[0]), - .clk(clk[0]), - .gfpga_pad_EMBEDDED_IO_HD_SOC_IN(gfpga_pad_EMBEDDED_IO_SOC_IN[0:`FPGA_IO_SIZE - 1]), - .gfpga_pad_EMBEDDED_IO_HD_SOC_OUT(gfpga_pad_EMBEDDED_IO_SOC_OUT[0:`FPGA_IO_SIZE - 1]), - .gfpga_pad_EMBEDDED_IO_HD_SOC_DIR(gfpga_pad_EMBEDDED_IO_SOC_DIR[0:`FPGA_IO_SIZE - 1]), - .ccff_head(ccff_head[0]), - .ccff_tail(ccff_tail[0]), - .sc_head(sc_head[0]), - .sc_tail(sc_tail[0]), - .IO_ISOL_N(IO_ISOL_N) - ); - -// ----- Force constant '0' to FPGA I/O as this testbench only check -// programming phase ----- - assign gfpga_pad_EMBEDDED_IO_SOC_IN[0:`FPGA_IO_SIZE - 1] = {`FPGA_IO_SIZE {1'b0}}; - assign gfpga_pad_EMBEDDED_IO_SOC_OUT[0:`FPGA_IO_SIZE - 1] = {`FPGA_IO_SIZE {1'b0}}; - -// Generate a pulse after programming reset is disabled (in the 2nd clock -// cycle). Then the head of configuration chain should be always zero - always @(negedge prog_clock[0]) begin - ccff_head = 1'b1; - if (0 != num_prog_cycles) begin - ccff_head = 1'b0; - end - end - -// ----- Count the number of programming cycles ------- - always @(posedge prog_clock[0]) begin - num_prog_cycles = num_prog_cycles + 1; - // Indicate when configuration is suppose to end - if (`FPGA_BITSTREAM_SIZE + 1 == num_prog_cycles) begin - config_done = 1'b1; - end - - // Check the ccff_tail when configuration is done - if (1'b1 == config_done) begin - // The tail should spit a pulse after configuration is done - // So it should be at logic '1' and then pulled down to logic '0' - if (0 == num_checked_points) begin - if (ccff_tail !== 1'b1) begin - $display("Error: ccff_tail = %b", sc_tail); - num_errors = num_errors + 1; - end - end - if (1 <= num_checked_points) begin - if (ccff_tail !== 1'b0) begin - $display("Error: ccff_tail = %b", sc_tail); - num_errors = num_errors + 1; - end - end - num_checked_points = num_checked_points + 1; - end - - if (2 < num_checked_points) begin - $display("Simulation finish with %d errors", num_errors); - - // End simulation - $finish; - end - end - -endmodule diff --git a/TESTBENCH/common/post_pnr_fpga_cells.v b/TESTBENCH/common/post_pnr_fpga_cells.v index 0c7cda0..cebd223 100644 --- a/TESTBENCH/common/post_pnr_fpga_cells.v +++ b/TESTBENCH/common/post_pnr_fpga_cells.v @@ -1,48 +1,3 @@ -// Include Skywater cell netlists that are used in post PnRed FPGA netlists -// Cells already used pre-PnR -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_2.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_4.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_2.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/or2/sky130_fd_sc_hd__or2_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2/sky130_fd_sc_hd__mux2_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/sdfxtp/sky130_fd_sc_hd__sdfxtp_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dfxtp/sky130_fd_sc_hd__dfxtp_1.v" - -// Cells added due to their use in PnR -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/or2/sky130_fd_sc_hd__or2_0.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2/sky130_fd_sc_hd__mux2_2.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2/sky130_fd_sc_hd__mux2_4.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2/sky130_fd_sc_hd__mux2_8.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/conb/sky130_fd_sc_hd__conb_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dlygate4sd1/sky130_fd_sc_hd__dlygate4sd1_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dlygate4sd2/sky130_fd_sc_hd__dlygate4sd2_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dlymetal6s2s/sky130_fd_sc_hd__dlymetal6s2s_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dlymetal6s6s/sky130_fd_sc_hd__dlymetal6s6s_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_6.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dlygate4sd3/sky130_fd_sc_hd__dlygate4sd3_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_6.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_8.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_12.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_16.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinv/sky130_fd_sc_hd__clkinv_16.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/bufinv/sky130_fd_sc_hd__bufinv_8.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinvlp/sky130_fd_sc_hd__clkinvlp_2.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinv/sky130_fd_sc_hd__clkinv_2.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinv/sky130_fd_sc_hd__clkinv_8.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinvlp/sky130_fd_sc_hd__clkinvlp_4.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinv/sky130_fd_sc_hd__clkinv_4.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_4.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkbuf/sky130_fd_sc_hd__clkbuf_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkbuf/sky130_fd_sc_hd__clkbuf_4.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_8.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkdlybuf4s50/sky130_fd_sc_hd__clkdlybuf4s50_2.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_12.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_16.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/bufbuf/sky130_fd_sc_hd__bufbuf_16.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/bufbuf/sky130_fd_sc_hd__bufbuf_8.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/nor2b/sky130_fd_sc_hd__nor2b_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/and2/sky130_fd_sc_hd__and2_0.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/nand2b/sky130_fd_sc_hd__nand2b_1.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/ebufn/sky130_fd_sc_hd__ebufn_4.v" +version https://git-lfs.github.com/spec/v1 +oid sha256:4ae0fb278944fcfc542a395b998e06e1c5d473df8d7d192ff9a386f1ba596ee4 +size 7630 diff --git a/TESTBENCH/common/post_pnr_scff_test.v b/TESTBENCH/common/post_pnr_scff_test.v deleted file mode 100644 index c049745..0000000 --- a/TESTBENCH/common/post_pnr_scff_test.v +++ /dev/null @@ -1,193 +0,0 @@ -//------------------------------------------- -// Verilog Testbench for Verifying -// Scan Chain of a FPGA -// Description: This test is applicable to FPGAs which have a built-in scan -// chain. It will feed a pulse to the head of the scan chain and -// check if the pulse is outputted by the tail of the can chain -// in a given time period -// -// Note: This test bench is tuned for the pre PnR netlists -// Author: Xifan TANG -// Organization: University of Utah -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// Design parameter for FPGA I/O sizes -//`define FPGA_IO_SIZE 144 -// -// Design parameter for FPGA scan-chain sizes -//`define FPGA_SCANCHAIN_SIZE 2304 - -module post_pnr_scff_test; -// ----- Local wires for global ports of FPGA fabric ----- -wire [0:0] prog_clk; -wire [0:0] Test_en; -wire [0:0] clk; - -// ----- Local wires for I/Os of FPGA fabric ----- - -wire [0:`FPGA_IO_SIZE - 1] gfpga_pad_EMBEDDED_IO_HD_SOC_IN; -wire [0:`FPGA_IO_SIZE - 1] gfpga_pad_EMBEDDED_IO_HD_SOC_OUT; -wire [0:`FPGA_IO_SIZE - 1] gfpga_pad_EMBEDDED_IO_HD_SOC_DIR; - -reg [0:0] prog_clock_reg; -wire [0:0] prog_clock; -wire [0:0] op_clock; -reg [0:0] op_clock_reg; -reg [0:0] prog_reset; -reg [0:0] prog_set; -reg [0:0] greset; -reg [0:0] gset; -// ---- Configuration-chain head ----- -wire [0:0] ccff_head; -// ---- Configuration-chain tail ----- -wire [0:0] ccff_tail; - -// ---- Scan-chain head ----- -reg [0:0] sc_head; -// ---- Scan-chain tail ----- -wire [0:0] sc_tail; - -wire [0:0] IO_ISOL_N; - -// ----- Counters for error checking ----- -integer num_clock_cycles = 0; -integer num_errors = 0; -integer num_checked_points = 0; - -// Indicate when configuration should be finished -reg scan_done = 0; - -initial - begin - scan_done = 1'b0; - end - -// ----- Begin raw programming clock signal generation ----- -initial - begin - prog_clock_reg[0] = 1'b0; - end -// ----- End raw programming clock signal generation ----- - -// ----- Begin raw operating clock signal generation ----- -initial - begin - op_clock_reg[0] = 1'b0; - end -always - begin - #5 op_clock_reg[0] = ~op_clock_reg[0]; - end - -// ----- End raw operating clock signal generation ----- -// ----- Actual operating clock is triggered only when scan_done is enabled ----- - assign prog_clock[0] = prog_clock_reg[0] & ~greset; - assign op_clock[0] = op_clock_reg[0] & ~greset; - -// ----- Begin programming reset signal generation ----- -initial - begin - prog_reset[0] = 1'b0; - end - -// ----- End programming reset signal generation ----- - -// ----- Begin programming set signal generation ----- -initial - begin - prog_set[0] = 1'b0; - end - -// ----- End programming set signal generation ----- - -// ----- Begin operating reset signal generation ----- -// ----- Reset signal is disabled always ----- -initial - begin - greset[0] = 1'b1; - #10 greset[0] = 1'b0; - end - -// ----- End operating reset signal generation ----- -// ----- Begin operating set signal generation: always disabled ----- -initial - begin - gset[0] = 1'b0; - end - -// ----- End operating set signal generation: always disabled ----- - -// ----- Begin connecting global ports of FPGA fabric to stimuli ----- - assign clk[0] = op_clock[0]; - assign prog_clk[0] = prog_clock[0]; - assign Test_en[0] = ~greset; - assign ccff_head[0] = 1'b0; - assign IO_ISOL_N[0] = 1'b0; -// ----- End connecting global ports of FPGA fabric to stimuli ----- -// ----- FPGA top-level module to be capsulated ----- - fpga_core FPGA_DUT ( - .prog_clk(prog_clk[0]), - .Test_en(Test_en[0]), - .clk(clk[0]), - .gfpga_pad_EMBEDDED_IO_HD_SOC_IN(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[0:`FPGA_IO_SIZE - 1]), - .gfpga_pad_EMBEDDED_IO_HD_SOC_OUT(gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[0:`FPGA_IO_SIZE - 1]), - .gfpga_pad_EMBEDDED_IO_HD_SOC_DIR(gfpga_pad_EMBEDDED_IO_HD_SOC_DIR[0:`FPGA_IO_SIZE - 1]), - .ccff_head(ccff_head[0]), - .ccff_tail(ccff_tail[0]), - .sc_head(sc_head[0]), - .sc_tail(sc_tail[0]), - .IO_ISOL_N(IO_ISOL_N) - ); - -// ----- Force constant '0' to FPGA I/O as this testbench only check -// programming phase ----- - assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[0:`FPGA_IO_SIZE - 1] = {`FPGA_IO_SIZE {1'b0}}; - assign gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[0:`FPGA_IO_SIZE - 1] = {`FPGA_IO_SIZE {1'b0}}; - -// Generate a pulse after operating reset is disabled (in the 2nd clock -// cycle). Then the head of scan chain should be always zero - always @(negedge op_clock[0]) begin - sc_head = 1'b1; - if (0 != num_clock_cycles) begin - sc_head = 1'b0; - end - end - -// ----- Count the number of programming cycles ------- - always @(posedge op_clock[0]) begin - num_clock_cycles = num_clock_cycles + 1; - // Indicate when scan chain loading is suppose to end - if (`FPGA_SCANCHAIN_SIZE + 1 == num_clock_cycles) begin - scan_done = 1'b1; - end - - // Check the tail of scan-chain when configuration is done - if (1'b1 == scan_done) begin - // The tail should spit a pulse after configuration is done - // So it should be at logic '1' and then pulled down to logic '0' - if (0 == num_checked_points) begin - if (sc_tail !== 1'b1) begin - $display("Error: sc_tail = %b", sc_tail); - num_errors = num_errors + 1; - end - end - if (1 <= num_checked_points) begin - if (sc_tail !== 1'b0) begin - $display("Error: sc_tail = %b", sc_tail); - num_errors = num_errors + 1; - end - end - num_checked_points = num_checked_points + 1; - end - - if (2 < num_checked_points) begin - $display("Simulation finish with %d errors", num_errors); - - // End simulation - $finish; - end - end - -endmodule diff --git a/TESTBENCH/common/post_pnr_testbench_converter.py b/TESTBENCH/common/post_pnr_testbench_converter.py index 9cd2d54..d838d95 100644 --- a/TESTBENCH/common/post_pnr_testbench_converter.py +++ b/TESTBENCH/common/post_pnr_testbench_converter.py @@ -61,6 +61,11 @@ with open(args.pre_pnr_testbench, "r") as wp: # Other lines can be directly copied to post-PnR Verilog testbenches line2output = curr_line \ # Condition A: + # Add post_pnr to top-level module name + if (curr_line.startswith("module")): + line2output = re.sub("autocheck_top_tb;$", "post_pnr_autocheck_top_tb;", curr_line) + # Add sc_head and sc_tail wire definition after ccff tail definition + # Condition B: # Add sc_head and sc_tail wire definition after ccff tail definition if (curr_line == "wire [0:0] ccff_tail;\n"): line2output = line2output \ @@ -68,16 +73,16 @@ with open(args.pre_pnr_testbench, "r") as wp: + "wire [0:0] sc_head;\n" \ + "// ---- Scan-chain tail ----\n" \ + "wire [0:0] sc_tail;\n" - # Condition B: + # Condition C: # Assign an initial value to sc_head after other ports elif (curr_line == "\tassign IO_ISOL_N[0] = 1'b1;\n"): line2output = line2output \ + "\tassign sc_head[0] = 1'b0;\n" - # Condition C: + # Condition D: # Replace fpga_top with fpga_core in DUT instanciation elif (curr_line == "\tfpga_top FPGA_DUT (\n"): line2output = "\tfpga_core FPGA_DUT (\n" - # Condition D: + # Condition E: # Add sc_head and sc_tail to the port mapping of FPGA core instance elif (curr_line == "\t\t.ccff_tail(ccff_tail[0]));\n"): line2output = "\t\t.ccff_tail(ccff_tail[0]),\n" \ diff --git a/TESTBENCH/common/post_pnr_wrapper_testbench_converter.py b/TESTBENCH/common/post_pnr_wrapper_testbench_converter.py new file mode 100644 index 0000000..3102d5c --- /dev/null +++ b/TESTBENCH/common/post_pnr_wrapper_testbench_converter.py @@ -0,0 +1,300 @@ +##################################################################### +# Python script to convert a post-PnR Verilog testbench +# to a post-PnR Verilog testbench based on Caravel Wrapper +# This script will +# - Replace the FPGA instance with a Caravel wrapper instance +# - Generate wrapper input ports based on a pin assignment json file +##################################################################### + +import os +from os.path import dirname, abspath, isfile +import shutil +import re +import argparse +import logging +import json + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) + +##################################################################### +# Parse the options +##################################################################### +parser = argparse.ArgumentParser(description='Converter for post-PnR wrapper Verilog testbench') +parser.add_argument('--post_pnr_testbench', required=True, + help='Specify the file path for the post-PnR Verilog testbench as input') +parser.add_argument('--pin_assignment_file', required=True, + help='Specify the file path to the pin assignment JSON description as input') +parser.add_argument('--wrapper_testbench', required=True, + help='Specify the file path for the post-PnR wrapper Verilog testbench to be outputted') +args = parser.parse_args() + +##################################################################### +# Check options: +# - Input file must be valid +# Otherwise, error out +# - Remove any output file if already exist +# TODO: give a warning when remove files +##################################################################### +if not isfile(args.post_pnr_testbench): + logging.error("Invalid pre-PnR testbench: " + args.post_pnr_testbench + "\nFile does not exist!\n") + exit(1) +if not isfile(args.pin_assignment_file): + logging.error("Invalid pin assignment file: " + args.pin_assignment_file + "\nFile does not exist!\n") + exit(1) +if isfile(args.wrapper_testbench): + logging.warn("Remove existing post-PnR testbench: " + args.wrapper_testbench + "!\n") + os.remove(args.wrapper_testbench) + +##################################################################### +# Parse the json file +##################################################################### +json_file = open(args.pin_assignment_file, "r") +pin_data = json.load(json_file) + +##################################################################### +# TODO: This is a duplicated function from the wrapper_lines_generator.py +# Should merge them and make it shareable between scripts + +# A function to parse pin range from json data +# JSON pin range format is LSB:MSB +# Return pin range format is [LSB, MSB] as a list +##################################################################### +def parse_json_pin_range(json_range) : + pin_range_str = json_range.split(':') + assert(2 == len(pin_range_str)) + # If the range is in decend order, we will decrease the MSB by 1 + if (int(pin_range_str[0]) > int(pin_range_str[1])) : + return range(int(pin_range_str[0]), int(pin_range_str[1]) - 1, -1) + # If the range is in acend order, we will increase the MSB by 1 + return range(int(pin_range_str[0]), int(pin_range_str[1]) + 1) + +##################################################################### +# Write the connections between wrapper ports and existing stimuli +# to the testbench file +##################################################################### +def write_testbench_wrapper_connection(tb_file, pin_data, mode_switch_io_index): + # Switch to the logic analyzer mode for io[25] which is reserved for mode-switch purpose + mode_switch_line = "assign " + pin_data['caravel_gpio_input_name'] + "[" + str(mode_switch_io_index) + "] = " \ + + "1'b0;"; + tb_file.write(" " + mode_switch_line + "\n") + + for pin_info in pin_data['pins']: + ####################################################### + # For FPGA INPUTs, + # wrapper inputs should be driven these existing wires + # For instance: + # assign wrapper_input = FPGA_INPUT; + # + # For FPGA OUTPUTs, + # wrapper outputs should drive these existing wires + # For instance: + # assign FPGA_OUTPUT = wrapper_output; + + # - FPGA I/O ports to Caravel GPIO + if (("io" == pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("gpio" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + # FPGA input <- Caravel input + curr_line = "assign " + pin_data['caravel_gpio_input_name'] + "[" + str(indices[1]) + "] = " \ + + pin_data['fpga_gpio_input_name'] + "[" + str(indices[0]) + "];"; + tb_file.write(" " + curr_line + "\n") + # FPGA output -> Caravel output + curr_line = "assign " + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_gpio_output_name'] + "[" + str(indices[1]) + "];"; + tb_file.write(" " + curr_line + "\n") + # FPGA direction -> Caravel direction + curr_line = "assign " + pin_data['fpga_gpio_direction_name'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_gpio_direction_name'] + "[" + str(indices[1]) + "];"; + tb_file.write(" " + curr_line + "\n") + + # - FPGA control input ports to Caravel GPIO + if (("io" != pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("input" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + # Connect the FPGA input port to the Caravel input + curr_line = "assign " + pin_data['caravel_gpio_input_name'] + "[" + str(indices[1]) + "] = " \ + + pin_info['fpga_pin_type'] + "[" + str(indices[0]) + "];"; + tb_file.write(" " + curr_line + "\n") + + # - FPGA control output ports to Caravel GPIO + if (("io" != pin_info['fpga_pin_type']) \ + and (1 == len(pin_info['caravel_pin_type'])) \ + and ("output" == pin_info['caravel_pin_type'][0])): + # Should have only 1 port in caravel + assert(1 == len(pin_info['caravel_pin_type'])) + assert(1 == len(pin_info['caravel_pin_index'])) + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + # Tie the Caravel input to logic '0' + curr_line = "assign " + pin_data['caravel_gpio_input_name'] + "[" + str(indices[1]) + "] = 1'b0;" + tb_file.write(" " + curr_line + "\n") + # Connect Caravel output port to FPGA control output + curr_line = "assign " + pin_info['fpga_pin_type'] + "[" + str(indices[0]) + "] = " \ + + pin_data['caravel_gpio_output_name'] + "[" + str(indices[1]) + "];"; + tb_file.write(" " + curr_line + "\n") + + # - We always try to use the logic analyzer to connect FPGA I/O ports + if (("io" == pin_info['fpga_pin_type']) \ + and ("logic_analyzer_io" == pin_info['caravel_pin_type'][0])): + # Get pin range + fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index']) + caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0]) + assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range))) + for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) : + ############################################################## + # SOC INPUT will be directly driven by logic analyzer + # since this I/O is going to interface logic analyzer input only + curr_line = "assign " + pin_data['caravel_logic_analyzer_input_name'] + "[" + str(indices[1]) + "] = " \ + + pin_data['fpga_gpio_input_name'] + "[" + str(indices[0]) + "]" + ";" + tb_file.write(" " + curr_line + "\n") + ############################################################## + # SOC OUTPUT will directly drive logic analyzer + # since this I/O is going to interface logic analyzer output only + curr_line = "assign " + pin_data['fpga_gpio_output_name'] + "[" + str(indices[0]) + "]" \ + + " = " + pin_data['caravel_logic_analyzer_output_name'] + "[" + str(indices[1]) + "];" + tb_file.write(" " + curr_line + "\n") + +##################################################################### +# Open the post-pnr Verilog testbench and start modification +##################################################################### +logging.info("Converting post-PnR testbench:"+ args.post_pnr_testbench) +logging.info("To post-PnR wrapper testbench:"+ args.wrapper_testbench) +# Create output file handler +tb_file = open(args.wrapper_testbench, "w") + +################################# +# Control signals to output lines +# Skip current line: when raised, current line will not be outputted +skip_current_line = False +fpga_instance_lines = False + +# Read line by line from pre-PnR testbench +with open(args.post_pnr_testbench, "r") as wp: + template_netlist = wp.readlines() + for line_num, curr_line in enumerate(template_netlist): + # If the current line satisfy the following conditions + # It should be modified and outputted to post-PnR Verilog testbenches + # Other lines can be directly copied to post-PnR Verilog testbenches + line2output = curr_line + # + # Add post_pnr to top-level module name + if (curr_line.startswith("module")): + line2output = re.sub("autocheck_top_tb;$", "wrapper_autocheck_top_tb;", curr_line) + # Add the wires required by the wrapper + if (curr_line == "wire [0:0] sc_tail;\n"): + line2output = line2output \ + + "// ---- Wrapper I/O wires ----\n" \ + + "// ---- Power pins ----\n" \ + + "wire [0:0] vdda1;\n" \ + + "wire [0:0] vdda2;\n" \ + + "wire [0:0] vssa1;\n" \ + + "wire [0:0] vssa2;\n" \ + + "wire [0:0] vccd1;\n" \ + + "wire [0:0] vccd2;\n" \ + + "wire [0:0] vssd1;\n" \ + + "wire [0:0] vssd2;\n" \ + + "// ---- Wishbone pins ----\n" \ + + "wire [0:0] wb_clk_i;\n" \ + + "wire [0:0] wb_rst_i;\n" \ + + "wire [0:0] wbs_stb_i;\n" \ + + "wire [0:0] wbs_cyc_i;\n" \ + + "wire [0:0] wbs_we_i;\n" \ + + "wire [3:0] wbs_sel_i;\n" \ + + "wire [31:0] wbs_dat_i;\n" \ + + "wire [31:0] wbs_adr_i;\n" \ + + "wire [0:0] wbs_ack_o;\n" \ + + "wire [31:0] wbs_dat_o;\n" \ + + "// ---- Logic analyzer pins ----\n" \ + + "wire [127:0] la_data_in;\n" \ + + "wire [127:0] la_data_out;\n" \ + + "wire [127:0] la_oen;\n" \ + + "// ---- GPIO pins ----\n" \ + + "wire [`MPRJ_IO_PADS-1:0] io_in;\n" \ + + "wire [`MPRJ_IO_PADS-1:0] io_out;\n" \ + + "wire [`MPRJ_IO_PADS-1:0] io_oeb;\n" \ + + "// ---- Analog I/O pins ----\n" \ + + "wire [`MPRJ_IO_PADS-8:0] analog_io;\n" \ + + "// ---- User clock pin ----\n" \ + + "wire [0:0] user_clock2;\n" + # TODO: This is a temporary fix for the flattened analog io port + # SHOULD BE REMOVED ABOUT UPDATED WRAPPER + for ipin in range(31): + line2output += "wire [0:0] analog_io_" + str(ipin) + "_;\n" + + # Skip all the lines about FPGA instanciation + if (curr_line == "\tfpga_core FPGA_DUT (\n"): + skip_current_line = True + fpga_instance_lines = True + + # When FPGA instance are skipped, add the wrapper instance + if ((True == fpga_instance_lines) and (curr_line.endswith(");\n"))): + skip_current_line = False + fpga_instance_lines = False + line2output = "\tfpga_top FPGA_DUT(\n" \ + + "\t\t\t.vdda1(vdda1),\n" \ + + "\t\t\t.vdda2(vdda2),\n" \ + + "\t\t\t.vssa1(vssa1),\n" \ + + "\t\t\t.vssa2(vssa2),\n" \ + + "\t\t\t.vccd1(vccd1),\n" \ + + "\t\t\t.vccd2(vccd2),\n" \ + + "\t\t\t.vssd1(vssd1),\n" \ + + "\t\t\t.vssd2(vssd2),\n" \ + + "\t\t\t.wb_clk_i(wb_clk_i),\n" \ + + "\t\t\t.wb_rst_i(wb_rst_i),\n" \ + + "\t\t\t.wbs_stb_i(wbs_stb_i),\n" \ + + "\t\t\t.wbs_we_i(wbs_we_i),\n" \ + + "\t\t\t.wbs_cyc_i(wbs_cyc_i),\n" \ + + "\t\t\t.wbs_sel_i(wbs_sel_i),\n" \ + + "\t\t\t.wbs_dat_i(wbs_dat_i),\n" \ + + "\t\t\t.wbs_adr_i(wbs_adr_i),\n" \ + + "\t\t\t.wbs_ack_o(wbs_ack_o),\n" \ + + "\t\t\t.wbs_dat_o(wbs_dat_o),\n" \ + + "\t\t\t.la_data_in(la_data_in),\n" \ + + "\t\t\t.la_data_out(la_data_out),\n" \ + + "\t\t\t.la_oen(la_oen),\n" \ + + "\t\t\t.io_in(io_in),\n" \ + + "\t\t\t.io_out(io_out),\n" \ + + "\t\t\t.io_oeb(io_oeb),\n" \ + #+ "\t\t\t.analog_io(analog_io),\n" \ + #+ "\t\t\t);\n"; + # TODO: This is a temporary fix for the flattened analog io port + # SHOULD BE REMOVED ABOUT UPDATED WRAPPER + for ipin in range(31): + line2output += ".analog_io_" + str(ipin) + "_(analog_io_" + str(ipin) + "_),\n" + + line2output += "\t\t\t.user_clock2(user_clock2)\n" + line2output += "\t\t\t);\n"; + # Wire the stimuli according to pin assignment + write_testbench_wrapper_connection(tb_file, pin_data, 25) + + # Correct the path in signal initialization + if (re.search(r'\$deposit\(FPGA_DUT', curr_line)): + line2output = re.sub(r'\$deposit\(FPGA_DUT', '$deposit(FPGA_DUT.fpga_core_uut', curr_line) + + if (False == skip_current_line): + tb_file.write(line2output) + +tb_file.close() +logging.info("Done") diff --git a/TESTBENCH/common/scff_test_post_pnr.v b/TESTBENCH/common/scff_test_post_pnr.v new file mode 100644 index 0000000..d63f540 --- /dev/null +++ b/TESTBENCH/common/scff_test_post_pnr.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d495eab2f304a576307954790e58356ff64b02576b9999c5613389f273561af4 +size 5726 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_latch_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_latch_post_pnr_autocheck_top_tb.v deleted file mode 100644 index b0d670b..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_latch_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:487515514b26136b79d18040d9912ce50fb10c507c4bfe5c5edeca87bf4cb71e -size 89574416 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_latch_post_pnr_wrapper_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_latch_post_pnr_wrapper_include_netlists.v new file mode 100644 index 0000000..8851916 --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_latch_post_pnr_wrapper_include_netlists.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92f909b526ee576979b1a02b23171c242ff03e62d862f06413b6a5236e5377cb +size 1478 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_or2_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_or2_post_pnr_autocheck_top_tb.v deleted file mode 100644 index fa1561a..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_or2_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fc1a77ea699c240030e9e3f3f98c416bbcd49334fc0f11904a607e879fda80f8 -size 89574293 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_or2_post_pnr_wrapper_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_or2_post_pnr_wrapper_include_netlists.v new file mode 100644 index 0000000..7354521 --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_or2_post_pnr_wrapper_include_netlists.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:825a6a406d866bda71202b39eb897b967484f3dc7c3cf7a62aa18791e54df573 +size 1474 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_post_pnr_autocheck_top_tb.v deleted file mode 100644 index 42fa791..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5f536d036dce7c630886ff7270cdcf1ac9569db162cff170224985418661a364 -size 89573720 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_post_pnr_wrapper_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_post_pnr_wrapper_include_netlists.v new file mode 100644 index 0000000..40df803 --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/and2_post_pnr_wrapper_include_netlists.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f6df360605df5a436036afc2ccf3b950ce42b3c9ea396350cd4ebbb4d705b9d +size 1466 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_autocheck_top_tb.v deleted file mode 100644 index 9130b58..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f62830d683e8f6ba5eee8d563b5de76962d19f82e210041c42cd0af1e2b05f8f -size 89581954 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_include_netlists.v deleted file mode 100644 index fd539a5..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_include_netlists.v +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------- -// FPGA Synthesizable Verilog Netlist -// Description: Netlist Summary -// Author: Xifan TANG -// Organization: University of Utah -// Date: Fri Nov 20 15:48:46 2020 -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// ------ Include simulation defines ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/prepnr/verilog_testbench/define_simulation.v" - -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/HDL/common/skywater_function_verification.v" - -// ------ Include Skywater cell netlists ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_fpga_cells.v" - -// ------ Include fabric top-level netlists ----- -//`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/FPGA1212_FC_HD_SKY_PNR/fpga_core/fpga_core_icv_in_design.pt.v" -`include "/research/ece/lnis/USERS/DARPA_ERI/Tapeout/Nov2020_Skywater/FPGA1212_FLAT_HD_SKY_PNR/fpga_top/fpga_top_icv_in_design.pt.v" - -`ifdef AUTOCHECKED_SIMULATION - `include "bin2bcd_output_verilog.v" -`endif - -`ifdef AUTOCHECKED_SIMULATION - `include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/bin2bcd_post_pnr_autocheck_top_tb.v" -`endif - diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_include_netlists.v index ad70cd7..0f03de9 100644 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_include_netlists.v +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_include_netlists.v @@ -1,29 +1,3 @@ -//------------------------------------------- -// FPGA Synthesizable Verilog Netlist -// Description: Netlist Summary -// Author: Xifan TANG -// Organization: University of Utah -// Date: Wed Nov 11 16:01:30 2020 -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// Design parameter for FPGA I/O sizes -`define FPGA_IO_SIZE 144 - -// Design parameter for FPGA bitstream sizes -`define FPGA_BITSTREAM_SIZE 65656 - -// ------ Include simulation defines ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/prepnr/verilog_testbench/define_simulation.v" - -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/HDL/common/skywater_function_verification.v" - -// ------ Include Skywater cell netlists ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_fpga_cells.v" - -// ------ Include fabric top-level netlists ----- -//`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/FPGA1212_FC_HD_SKY_PNR/fpga_core/fpga_core_icv_in_design.pt.v" -`include "/research/ece/lnis/USERS/DARPA_ERI/Tapeout/Nov2020_Skywater/FPGA1212_FLAT_HD_SKY_PNR/fpga_top/fpga_top_icv_in_design.pt.v" - -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_ccff_test.v" +version https://git-lfs.github.com/spec/v1 +oid sha256:f3da10525b0dff707611379ed6ae1348c294eae1a8cd31499ce2e35dde3beaab +size 1329 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_wrapper.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_wrapper.v new file mode 100644 index 0000000..195e68f --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_wrapper.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a48432026dba12e9c3a98dbbaa9f9166e975b92617e1718d338d4d28dd809179 +size 29505 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_wrapper_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_wrapper_include_netlists.v new file mode 100644 index 0000000..838b868 --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/ccff_test_post_pnr_wrapper_include_netlists.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06bb3d6a1ee52298d3ac59ad73f16132b268c013b3cb411d0dfe6f033f6aed36 +size 1488 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_autocheck_top_tb.v deleted file mode 100644 index 5f794a1..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:29a19b92ea6be7d4404a7c0b1120700953496a7d28eb3961e94cd48290519f08 -size 89577937 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_include_netlists.v deleted file mode 100644 index 971d9d6..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_include_netlists.v +++ /dev/null @@ -1,29 +0,0 @@ -//------------------------------------------- -// FPGA Synthesizable Verilog Netlist -// Description: Netlist Summary -// Author: Xifan TANG -// Organization: University of Utah -// Date: Fri Nov 20 15:48:45 2020 -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// ------ Include simulation defines ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/prepnr/verilog_testbench/define_simulation.v" -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/HDL/common/skywater_function_verification.v" - -// ------ Include Skywater cell netlists ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_fpga_cells.v" - -// ------ Include fabric top-level netlists ----- -//`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/FPGA1212_FC_HD_SKY_PNR/fpga_core/fpga_core_icv_in_design.pt.v" -`include "/research/ece/lnis/USERS/DARPA_ERI/Tapeout/Nov2020_Skywater/FPGA1212_FLAT_HD_SKY_PNR/fpga_top/fpga_top_icv_in_design.pt.v" - -`ifdef AUTOCHECKED_SIMULATION - `include "counter_output_verilog.v" -`endif - -`ifdef AUTOCHECKED_SIMULATION - `include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/counter_post_pnr_autocheck_top_tb.v" -`endif - diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/routing_test_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/routing_test_post_pnr_autocheck_top_tb.v deleted file mode 100644 index 4bd6ad4..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/routing_test_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58193f2fe4c2198c7701e1915a2d46999df531ddee21eccb3a78b1e8b6e2fe1e -size 89575314 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/routing_test_post_pnr_wrapper_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/routing_test_post_pnr_wrapper_include_netlists.v new file mode 100644 index 0000000..7139452 --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/routing_test_post_pnr_wrapper_include_netlists.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3adff4e62fe53b8cef99dc752bab3ebc6890445d6263b3aad5fdec154f53fbcf +size 1482 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_include_netlists.v index 7d8c45b..ae327f8 100644 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_include_netlists.v +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_include_netlists.v @@ -1,29 +1,3 @@ -//------------------------------------------- -// FPGA Synthesizable Verilog Netlist -// Description: Netlist Summary -// Author: Xifan TANG -// Organization: University of Utah -// Date: Wed Nov 11 16:01:30 2020 -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// Design parameter for FPGA I/O sizes -`define FPGA_IO_SIZE 144 - -// Design parameter for FPGA bitstream sizes -`define FPGA_SCANCHAIN_SIZE 2304 - -// ------ Include simulation defines ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/prepnr/verilog_testbench/define_simulation.v" - -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/HDL/common/skywater_function_verification.v" - -// ------ Include Skywater cell netlists ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_fpga_cells.v" - -// ------ Include fabric top-level netlists ----- -//`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/FPGA1212_FC_HD_SKY_PNR/fpga_core/fpga_core_icv_in_design.pt.v" -`include "/research/ece/lnis/USERS/DARPA_ERI/Tapeout/Nov2020_Skywater/FPGA1212_FLAT_HD_SKY_PNR/fpga_top/fpga_top_icv_in_design.pt.v" - -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_scff_test.v" +version https://git-lfs.github.com/spec/v1 +oid sha256:f25455fe75150d87bcfb386c5c953172a1712655ec1e38017d22aeb062314a6d +size 1328 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_wrapper.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_wrapper.v new file mode 100644 index 0000000..fd0453d --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_wrapper.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc555c2a0ddb8412c57c88ab89a2a5c7d6cb9c525484113f9ac219c763daf4d2 +size 29326 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_wrapper_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_wrapper_include_netlists.v new file mode 100644 index 0000000..5694280 --- /dev/null +++ b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/scff_test_post_pnr_wrapper_include_netlists.v @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3b64adf49892e8d7e7263273e76b566cb1f0922d404c224d550136d43b49178 +size 1487 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_autocheck_top_tb.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_autocheck_top_tb.v deleted file mode 100644 index 787d0d4..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_autocheck_top_tb.v +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:45e4cc69e796a4bcea004817e25ba9c314b5e160f8bf5cae8d9d8d8522642a5d -size 89574344 diff --git a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_include_netlists.v b/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_include_netlists.v deleted file mode 100644 index 1790f36..0000000 --- a/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_include_netlists.v +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------- -// FPGA Synthesizable Verilog Netlist -// Description: Netlist Summary -// Author: Xifan TANG -// Organization: University of Utah -// Date: Fri Nov 20 15:49:05 2020 -//------------------------------------------- -//----- Time scale ----- -`timescale 1ns / 1ps - -// ------ Include simulation defines ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/prepnr/verilog_testbench/define_simulation.v" - -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/HDL/common/skywater_function_verification.v" - -// ------ Include Skywater cell netlists ----- -`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/common/post_pnr_fpga_cells.v" - -// ------ Include fabric top-level netlists ----- -//`include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/FPGA1212_FC_HD_SKY_PNR/fpga_core/fpga_core_icv_in_design.pt.v" -`include "/research/ece/lnis/USERS/DARPA_ERI/Tapeout/Nov2020_Skywater/FPGA1212_FLAT_HD_SKY_PNR/fpga_top/fpga_top_icv_in_design.pt.v" - -`ifdef AUTOCHECKED_SIMULATION - `include "top_module_output_verilog.v" -`endif - -`ifdef AUTOCHECKED_SIMULATION - `include "/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/k4_N8_caravel_io_FPGA_12x12_fdhd_cc/postpnr/verilog_testbench/top_module_post_pnr_autocheck_top_tb.v" -`endif -