diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0cd7bc71..2e8a8246c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,9 +76,6 @@ jobs: fail-fast: false matrix: config: - - name: "Build Compatibility: GCC-7 (Ubuntu 20.04)" - cc: gcc-7 - cxx: g++-7 - name: "Build Compatibility: GCC-8 (Ubuntu 20.04)" cc: gcc-8 cxx: g++-8 @@ -137,7 +134,7 @@ jobs: run: ccache -s - name: Upload artifact uses: actions/upload-artifact@v2 - if: ${{ matrix.config.cc == 'gcc-8'}} + if: ${{ matrix.config.cc == 'gcc-9'}} with: name: openfpga path: | @@ -441,7 +438,7 @@ jobs: chmod +x build/yosys/bin/yosys-config chmod +x build/yosys/bin/yosys-filterlib chmod +x build/yosys/bin/yosys-smtbmc - - name: ${{matrix.config.name}}_GCC-8_(Ubuntu 20.04) + - name: ${{matrix.config.name}}_GCC-9_(Ubuntu 20.04) shell: bash run: source openfpga.sh && source openfpga_flow/regression_test_scripts/${{matrix.config.name}}.sh --debug --show_thread_logs - name: Upload artifact @@ -485,7 +482,7 @@ jobs: - name: Checkout OpenFPGA repo uses: actions/checkout@v3 - - name: ${{matrix.config.name}}_GCC-8_(Ubuntu 20.04) + - name: ${{matrix.config.name}}_GCC-9_(Ubuntu 20.04) shell: bash run: | bash .github/workflows/install_dependencies_run.sh diff --git a/Makefile b/Makefile index e3d23b82a..23c2cdab6 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ help: checkout: # Update all the submodules git submodule init - git submodule update --init --depth 1 + git submodule update --init --recursive prebuild: # Run cmake to generate Makefile under the build directory, before compilation diff --git a/VERSION.md b/VERSION.md index a9e3c4814..1983ccf3d 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -1.2.1529 +1.2.1769 diff --git a/docs/requirements.txt b/docs/requirements.txt index 359b7099b..732f30a96 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,14 +2,21 @@ # used by Read The Docs to install python required # modules with pip. +# Workaround to fix the bug: https://github.com/readthedocs/readthedocs.org/issues/9038 +Jinja2<3.1 + # Support Markdown #recommonmark +# Theme +sphinx-rtd-theme + #Handle references in bibtex format sphinxcontrib-bibtex # Package required to embed youtube video -sphinxcontrib-youtube +# See issues in release v1.3.0 and later on tue sphinx.util.display +sphinxcontrib-youtube <= 1.2.0 # Package required to convert SVG for latex building sphinxcontrib-svg2pdfconverter diff --git a/docs/source/manual/arch_lang/addon_vpr_syntax.rst b/docs/source/manual/arch_lang/addon_vpr_syntax.rst index ef93be938..b2c88992c 100644 --- a/docs/source/manual/arch_lang/addon_vpr_syntax.rst +++ b/docs/source/manual/arch_lang/addon_vpr_syntax.rst @@ -88,11 +88,58 @@ Layout .. warning:: Do NOT enable ``shrink_boundary`` if you are not using the tileable routing resource graph generator! +.. option:: opin2all_sides="" + + Allow each output pin of a programmable block to drive the routing tracks on all the sides of its adjacent switch block (see an illustrative example in :numref:`fig_opin2all_sides`). This can improve the routability of an FPGA fabric with an increase in the sizes of routing multiplexers in each switch block. + By default, it is ``false``. + + .. _fig_opin2all_sides: + + .. figure:: ./figures/opin2all_sides.svg + :width: 100% + :alt: Impact of opin2all_sides + + Impact on routing architecture when the opin-to-all-sides: (a) disabled; (b) enabled. + + .. warning:: Do NOT enable ``opin2all_sides`` if you are not using the tileable routing resource graph generator! + +.. option:: concat_wire="" + + In each switch block, allow each routing track which ends to drive another routing track on the opposite side, as such a wire can be continued in the same direction (see an illustrative example in :numref:`fig_concat_wire`). In other words, routing wires can be concatenated in the same direction across an FPGA fabric. This can improve the routability of an FPGA fabric with an increase in the sizes of routing multiplexers in each switch block. + By default, it is ``false``. + + .. _fig_concat_wire: + + .. figure:: ./figures/concat_wire.svg + :width: 100% + :alt: Impact of concat_wire + + Impact on routing architecture when the wire concatenation: (a) disabled; (b) enabled. + + .. warning:: Do NOT enable ``concat_wire`` if you are not using the tileable routing resource graph generator! + +.. option:: concat_pass_wire="" + + In each switch block, allow each routing track which passes to drive another routing track on the opposite side, as such a pass wire can be continued in the same direction (see an illustrative example in :numref:`fig_concat_pass_wire`). This can improve the routability of an FPGA fabric with an increase in the sizes of routing multiplexers in each switch block. + By default, it is ``false``. + + .. warning:: Please enable this option if you are looking for device support which is created by any release which is before v1.1.541!!! + + .. _fig_concat_wire: + + .. figure:: ./figures/concat_pass_wire.svg + :width: 100% + :alt: Impact of concat_pass_wire + + Impact on routing architecture when the pass wire concatenation: (a) disabled; (b) enabled. + + .. warning:: Do NOT enable ``concat_pass_wire`` if you are not using the tileable routing resource graph generator! + A quick example to show tileable routing is enabled, other options, e.g., through channels are disabled: .. code-block:: xml - + Switch Block diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index a23b4f0c6..9fd1024a7 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -62,12 +62,37 @@ Here is an example: .. code-block:: xml + ... +For subtile port merge support (see an illustrative example in :numref:`fig_subtile_port_merge`): + +- ``tile=""`` is the name of tile, that is defined in VPR architecture + +- ``port=""`` is the name of a port of the tile, that is defined in VPR architecture + +.. warning:: This is an option for power users. Suggest to enable for those global input ports, such as clock and reset, whose ``Fc`` is set to 0 in VPR architecture!!! + +.. note:: When defined, the given port of all the subtiles of a tile will be merged into one port. For example, a tile consists of 8 subtile ``A`` and 6 subtile ``B`` and all the subtiles have a port ``clk``, in the FPGA fabric, all the ``clk`` of the subtiles ``A`` and ``B`` will be wired to a common port ``clk`` at tile level. + + +.. note:: When merged, the port will have a default side of ``TOP`` and index of ``0`` on all the attributes, such as width, height etc. + +.. _fig_subtile_port_merge: + +.. figure:: ./figures/subtile_port_merge.png + :width: 100% + :alt: Difference in netlists with and without subtile port merging + + Difference in netlists with and without subtile port merging + + +For global port support: + - ``name=""`` is the port name to appear in the top-level FPGA fabric. - ``is_clock=""`` define if the global port is a clock port at the top-level FPGA fabric. An operating clock port will be driven by proper signals in auto-generated testbenches. @@ -111,7 +136,7 @@ A more illustrative example: .. _fig_global_tile_ports: .. figure:: ./figures/global_tile_ports.png - :scale: 100% + :width: 100% :alt: Difference between global port definition through circuit model and tile annotation Difference between global port definition through circuit model and tile annotation diff --git a/docs/source/manual/arch_lang/figures/concat_pass_wire.svg b/docs/source/manual/arch_lang/figures/concat_pass_wire.svg new file mode 100644 index 000000000..ccebac06b --- /dev/null +++ b/docs/source/manual/arch_lang/figures/concat_pass_wire.svg @@ -0,0 +1,574 @@ + + + + + + + + + + + + + + + + + concat_pass_wire + + base + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wires + + + + + + + + + + + + + + + legend + + + (a) + + + + + + + + + + + + + Starting routing tracks + + + + + + + + + Ending routing tracks + + + + + + + + + Passing routing tracks + + + + + + + + + Output pin of blocks + + + + + (b) + + + + + diff --git a/docs/source/manual/arch_lang/figures/concat_wire.svg b/docs/source/manual/arch_lang/figures/concat_wire.svg new file mode 100644 index 000000000..bb01dd6d5 --- /dev/null +++ b/docs/source/manual/arch_lang/figures/concat_wire.svg @@ -0,0 +1,580 @@ + + + + + + + + + + + + + + + + + concat_wire + + base + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wires + + + + + + + + + + + + + + + + + + + + + legend + + + (a) + + + + + + + + + + + + + Starting routing tracks + + + + + + + + + Ending routing tracks + + + + + + + + + Passing routing tracks + + + + + + + + + Output pin of blocks + + + + + (b) + + + + + diff --git a/docs/source/manual/arch_lang/figures/opin2all_sides.svg b/docs/source/manual/arch_lang/figures/opin2all_sides.svg new file mode 100644 index 000000000..dff4b1222 --- /dev/null +++ b/docs/source/manual/arch_lang/figures/opin2all_sides.svg @@ -0,0 +1,592 @@ + + + + + + + + + + + + + + + + + opin2all_sides + + base + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wires + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + legend + + + (a) + + + + + + + + + + + + + Starting routing tracks + + + + + + + + + Ending routing tracks + + + + + + + + + Passing routing tracks + + + + + + + + + Output pin of blocks + + + + + (b) + + + + + diff --git a/docs/source/manual/arch_lang/figures/subtile_port_merge.png b/docs/source/manual/arch_lang/figures/subtile_port_merge.png new file mode 100644 index 000000000..16f7c6021 Binary files /dev/null and b/docs/source/manual/arch_lang/figures/subtile_port_merge.png differ diff --git a/docs/source/manual/file_formats/index.rst b/docs/source/manual/file_formats/index.rst index 6a30c2b8b..6ec94c3b9 100644 --- a/docs/source/manual/file_formats/index.rst +++ b/docs/source/manual/file_formats/index.rst @@ -38,4 +38,6 @@ OpenFPGA widely uses XML format for interchangeable files io_naming_file + module_naming_file + tile_config_file diff --git a/docs/source/manual/file_formats/module_naming_file.rst b/docs/source/manual/file_formats/module_naming_file.rst new file mode 100644 index 000000000..6f4853bae --- /dev/null +++ b/docs/source/manual/file_formats/module_naming_file.rst @@ -0,0 +1,42 @@ +.. _file_formats_module_naming_file: + +Fabric Module Naming (.xml) +--------------------------- + +The XML-based description language is used to describe module names for an FPGA fabric, including: + +- the built-in name or default name for each module when building an FPGA fabric +- the customized name which is given by users for each module, in place of the built-in names + +Using the description language, users can customize the name for each module in an FPGA fabric, excluding testbenches. + +Under the root node ````, naming rules can be defined line-by-line through syntax ````. + +.. code-block:: xml + + + + + +.. note:: If you do not need to rename a module of an FPGA fabric, there is no need to define it explicitly in the naming rules. OpenFPGA can infer it. + +Syntax +`````` + +Detailed syntax are presented as follows. + +.. option:: default="" + + Define the default or built-in name of a module. This follows fixed naming rules of OpenFPGA. Suggest to run command :ref:`openfpga_setup_commands_write_module_naming_rules` to obtain an initial version for your fabric. For example, + + .. code-block:: xml + + default="cbx_1__2_" + +.. option:: given="" + + Define the customized name of a module, this is the final name will appear in netlists. For example, + + .. code-block:: xml + + given="cbx_corner_left_bottom" diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst index 56032a5e0..ffd6d8087 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst @@ -81,6 +81,40 @@ write_fabric_bitstream Specify the file format [``plain_text`` | ``xml``]. By default is ``plain_text``. See file formats in :ref:`file_formats_fabric_bitstream_xml` and :ref:`file_formats_fabric_bitstream_plain_text`. + .. option:: --filter_value + + .. warning:: Value filter is only applicable to XML file format! + + Specify the value to be keep in the bitstream file. Can be [``0`` | ``1`` ]. By default is ``none``, which means no filter is applied. + When specified, only the bit with the filter value is written to the file. + See file formats in :ref:`file_formats_fabric_bitstream_xml`. + + .. option:: --path_only + + .. warning:: This is only applicable to XML file format! + + Specify that only the ``path`` attribute is kept in the bitstream file. By default is ``off``. + When specified, only the ``path`` attribute is written to the file. + Regarding the ``path`` attribute, See file formats in :ref:`file_formats_fabric_bitstream_xml`. + + .. option:: --value_only + + .. warning:: This is only applicable to XML file format! + + Specify that only the ``value`` attribute is kept in the bitstream file. By default is ``off``. + When specified, only the ``value`` attribute is written to the file. + Regarding the ``value`` attribute, see file formats in :ref:`file_formats_fabric_bitstream_xml`. + + .. option:: --trim_path + + .. warning:: This is only applicable to XML file format! + + .. warning:: This is an option for power user! Suggest only to use when you enable the ``--group_config_block`` option when building a fabric (See details in :ref:`cmd_build_fabric`). + + Specify that the ``path`` will be trimed by 1 level in resulting bitstream file. By default is ``off``. + When specified, the hierarchy of ``path`` will be reduced by 1. For example, the original path is ``fpga_top.tile_1__1_.config_block.sub_mem.mem_out[0]``, the path after trimming is ``fpga_top.tile_1__1_.config_block.mem_out[0]``. + Regarding the ``path`` attribute, see file formats in :ref:`file_formats_fabric_bitstream_xml`. + .. option:: --fast_configuration Reduce the bitstream size when outputing by skipping dummy configuration bits. It is applicable to configuration chain, memory bank and frame-based configuration protocols. For configuration chain, when enabled, the zeros at the head of the bitstream will be skipped. For memory bank and frame-based, when enabled, all the zero configuration bits will be skipped. So ensure that your memory cells can be correctly reset to zero with a reset signal. diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst index a21c4dbfe..d3497cd98 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst @@ -55,6 +55,8 @@ write_full_testbench Specify the name of *Design Under Test* (DUT) module to be considered in the testbench. Can be either ``fpga_top`` or ``fpga_core. By default, it is ``fpga_top``. + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + .. option:: --bitstream The bitstream file to be loaded to the full testbench, which should be in the same file format that OpenFPGA can outputs (See detailes in :ref:`file_formats_fabric_bitstream_plain_text`). For example, ``--bitstream and2.bit`` @@ -130,6 +132,8 @@ write_preconfigured_fabric_wrapper Specify the name of *Design Under Test* (DUT) module to be considered in the testbench. Can be either ``fpga_top`` or ``fpga_core. By default, it is ``fpga_top``. + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + .. option:: --pin_constraints_file or -pcf Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml`` @@ -176,6 +180,83 @@ __ iverilog_website_ Show verbose log + +.. _cmd_write_testbench_template: + +write_testbench_template +~~~~~~~~~~~~~~~~~~~~~~~~ + + Write a template of testbench for a preconfigured FPGA fabric. See details in :ref:`fpga_verilog_testbench`. + + .. warning:: The template testbench only contains an instance of FPGA fabric. Please do **NOT** directly use it in design verification without a proper modification!!! + + .. option:: --file or -f + + The file path to output the testbench file. For example, ``--file /temp/testbench_template.v`` + + .. option:: --top_module + + Specify the name of top-level module to be considered in the testbench. Please avoid reserved words, i.e., ``fpga_top`` or ``fpga_core. By default, it is ``top_tb``. + + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + + .. option:: --dut_module + + Specify the name of *Design Under Test* (DUT) module to be considered in the testbench. Can be either ``fpga_top`` or ``fpga_core. By default, it is ``fpga_top``. + + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + + .. option:: --explicit_port_mapping + + Use explicit port mapping when writing the Verilog netlists + + .. option:: --default_net_type + + Specify the default net type for the Verilog netlists. Currently, supported types are ``none`` and ``wire``. Default value: ``none``. + + .. option:: --no_time_stamp + + Do not print time stamp in Verilog netlists + + .. option:: --verbose + + Show verbose log + +write_testbench_io_connection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Write the I/O connection statements in Verilog for a preconfigured FPGA fabric mapped to a given design. See details in :ref:`fpga_verilog_testbench`. + + .. warning:: The netlist may be included by the template testbench (see details in :ref:`cmd_write_testbench_template`). Please do **NOT** directly use it in design verification without a proper modification!!! + + .. option:: --file or -f + + The file path to output the netlist file. For example, ``--file /temp/testbench_io_conkt.v`` + + .. option:: --dut_module + + Specify the name of *Design Under Test* (DUT) module to be considered in the testbench. Can be either ``fpga_top`` or ``fpga_core. By default, it is ``fpga_top``. + + .. note:: Please use the reserved words ``fpga_top`` or ``fpga_core`` even when renaming is applied to the modules (See details in :ref:`openfpga_setup_commands_rename_modules`). Renaming will be applied automatically. + + .. option:: --pin_constraints_file or -pcf + + Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml`` + Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. + + .. option:: --bus_group_file or -bgf + + Specify the *Bus Group File* (BGF) if you want to group pins to buses. For example, ``-bgf bus_group.xml`` + Strongly recommend when input HDL contains bus ports. See detailed file format about :ref:`file_format_bus_group_file`. + + .. option:: --no_time_stamp + + Do not print time stamp in Verilog netlists + + .. option:: --verbose + + Show verbose log + write_mock_fpga_wrapper ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst index 62ec61e21..9ea4b2145 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst @@ -279,6 +279,9 @@ build_fabric Netlist hierarchy on grouped configuable blocks + .. option:: --name_module_using_index + + Use index in module names, e.g., ``cbx_2_``. This is applied to routing modules, as well as tile modules when option ``--group_tile`` is enabled. If disabled, the module name consist of coordinates, e.g., ``cbx_1__2_``. .. option:: --duplicate_grid_pin @@ -435,3 +438,37 @@ pcf2place .. option:: --verbose Show verbose log + +.. _openfpga_setup_commands_rename_modules: + +rename_modules +~~~~~~~~~~~~~~ + + Rename modules of an FPGA fabric with a given set of naming rules + + .. option:: --file + + Specify the file path which contain the naming rules. See details in :ref:`file_formats_module_naming_file`. + + .. option:: --verbose + + Show verbose log + +.. _openfpga_setup_commands_write_module_naming_rules: + +write_module_naming_rules +~~~~~~~~~~~~~~~~~~~~~~~~~ + + Output the naming rules for each module of an FPGA fabric to a given file + + .. option:: --file + + Specify the file path to be written to + + .. option:: --no_time_stamp + + Do not print time stamp in bitstream files + + .. option:: --verbose + + Show verbose log diff --git a/docs/source/manual/utilities/fabric_key_assistant.rst b/docs/source/manual/utilities/fabric_key_assistant.rst index 4625366d2..c607d84d1 100644 --- a/docs/source/manual/utilities/fabric_key_assistant.rst +++ b/docs/source/manual/utilities/fabric_key_assistant.rst @@ -8,7 +8,7 @@ Note that crafting a fabric key is not an easy task for engineers, as its comple This tool is developed to assist engineers when finalizing fabric key files. It can apply sanity checks on hand-crafted fabric key files, helping engineers to correct and debug. -The tool can be found at ``/build/libs/libfabrickey/test/fabric_key_assistant`` +The tool can be found at ``/build/libs/libfabrickey/fabric_key_assistant`` The tool includes the following options: diff --git a/docs/source/manual/utilities/index.rst b/docs/source/manual/utilities/index.rst index a51774314..378e733fe 100644 --- a/docs/source/manual/utilities/index.rst +++ b/docs/source/manual/utilities/index.rst @@ -11,3 +11,5 @@ OpenFPGA contains a number of utility tools to help users to craft files. :maxdepth: 2 fabric_key_assistant + + module_rename_assistant diff --git a/docs/source/manual/utilities/module_rename_assistant.rst b/docs/source/manual/utilities/module_rename_assistant.rst new file mode 100644 index 000000000..c84a81549 --- /dev/null +++ b/docs/source/manual/utilities/module_rename_assistant.rst @@ -0,0 +1,58 @@ +.. _utility_module_rename_assistant: + +Module Rename Assistant +----------------------- + +Module Rename Assistant is a tool to help users to craft module name files (see details in :ref:`file_formats_module_naming_files`). +This tool is useful to adapt module naming from a fabric to another, considering the two fabrics share the same building blocks, i.e., tile, routing blocks *etc.* +For example, when engineers craft a module naming file for a fabric ``A``, and would like to migrate the module naming rules for anthor fabric ``B``, module naming rules have to be adapted due to the changes on default names of building blocks. + +The tool can be found at ``/build/libs/libnamemanager/module_rename_assistant`` + +The tool includes the following options: + +.. option:: --reference_fabricA_names + + Specifiy a reference module name file for fabric A. This is typically generated by OpenFPGA through the commmand :ref:`openfpga_setup_commands_write_module_naming_rules`. The reference fabric key file is treated as the baseline, on which the renamed module file will be compared to. + +.. option:: --renamed_fabricA_names + + Specify the hand-crafted module name file for fabric A, which is typically hand-crafted by users. + +.. option:: --reference_fabricB_names + + Specifiy a reference module name file for fabric B. This is typically generated by OpenFPGA through the commmand :ref:`openfpga_setup_commands_write_module_naming_rules`. The reference fabric key file is treated as the baseline, on which the renamed module file will be compared to. + +.. option:: --output + + Specify the renamed module name file for fabric B to be outputted. For example, the fabric A contains reference names: + +.. code-block:: xml + + + +while the renamed module for fabric A includes: + +.. code-block:: xml + + + +the fabric B shares the same given name ``tile_4_`` but in a different default name. + +.. code-block:: xml + + + +the resulting output renamed module file includes: + +.. code-block:: xml + + + +.. option:: --verbose + + To enable verbose output + +.. option:: --help + + Show help desk diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index ab8e6dbd8..537a46357 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -8,5 +8,5 @@ add_subdirectory(libfabrickey) add_subdirectory(libfpgabitstream) add_subdirectory(libpcf) add_subdirectory(libbusgroup) -add_subdirectory(libionamemap) +add_subdirectory(libnamemanager) add_subdirectory(libtileconfig) diff --git a/libs/libarchopenfpga/CMakeLists.txt b/libs/libarchopenfpga/CMakeLists.txt index 93c20710d..13b4431f1 100644 --- a/libs/libarchopenfpga/CMakeLists.txt +++ b/libs/libarchopenfpga/CMakeLists.txt @@ -20,6 +20,7 @@ set_target_properties(libarchopenfpga PROPERTIES PREFIX "") #Avoid extra 'lib' p #Specify link-time dependancies target_link_libraries(libarchopenfpga libopenfpgautil + libopenfpgashell libvtrutil libarchfpga libpugiutil) diff --git a/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp b/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp index 6b27d0017..135e38361 100644 --- a/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp +++ b/libs/libarchopenfpga/src/read_xml_tile_annotation.cpp @@ -125,6 +125,22 @@ static void read_xml_tile_global_port_annotation( } } +/******************************************************************** + * Parse XML description for an interconnection annotation + * under a XML node + *******************************************************************/ +static void read_xml_tile_merge_port_annotation( + pugi::xml_node& xml_tile, const pugiutil::loc_data& loc_data, + openfpga::TileAnnotation& tile_annotation) { + const std::string& tile_attr = + get_attribute(xml_tile, "tile", loc_data).as_string(); + + const std::string& port_attr = + get_attribute(xml_tile, "port", loc_data).as_string(); + + tile_annotation.add_merge_subtile_ports(tile_attr, port_attr); +} + /******************************************************************** * Top function to parse XML description about tile annotation *******************************************************************/ @@ -146,11 +162,17 @@ openfpga::TileAnnotation read_xml_tile_annotations( */ for (pugi::xml_node xml_tile_global_port : xml_annotations.children()) { /* Error out if the XML child has an invalid name! */ - if (xml_tile_global_port.name() != std::string("global_port")) { - bad_tag(xml_tile_global_port, loc_data, xml_annotations, {"global_port"}); + if (xml_tile_global_port.name() == std::string("global_port")) { + read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data, + tile_annotations); + } else if (xml_tile_global_port.name() == + std::string("merge_subtile_ports")) { + read_xml_tile_merge_port_annotation(xml_tile_global_port, loc_data, + tile_annotations); + } else { + bad_tag(xml_tile_global_port, loc_data, xml_annotations, + {"global_port or merge_subtile_ports"}); } - read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data, - tile_annotations); } return tile_annotations; diff --git a/libs/libarchopenfpga/src/tile_annotation.cpp b/libs/libarchopenfpga/src/tile_annotation.cpp index 7cf41f02e..2ffacd1d0 100644 --- a/libs/libarchopenfpga/src/tile_annotation.cpp +++ b/libs/libarchopenfpga/src/tile_annotation.cpp @@ -3,7 +3,11 @@ ***********************************************************************/ #include "tile_annotation.h" +#include + +#include "command_exit_codes.h" #include "vtr_assert.h" +#include "vtr_log.h" /* namespace openfpga begins */ namespace openfpga { @@ -20,6 +24,27 @@ TileAnnotation::global_port_range TileAnnotation::global_ports() const { return vtr::make_range(global_port_ids_.begin(), global_port_ids_.end()); } +std::vector TileAnnotation::tiles_to_merge_ports() const { + std::vector tile_names; + for (auto it = tile_ports_to_merge_.begin(); it != tile_ports_to_merge_.end(); + it++) { + tile_names.push_back(it->first); + } + return tile_names; +} + +std::vector TileAnnotation::tile_ports_to_merge( + const std::string& tile_name) const { + std::vector port_names; + const auto& result = tile_ports_to_merge_.find(tile_name); + if (result == tile_ports_to_merge_.end()) { + VTR_LOG_WARN("Tile '%s' does not contain any ports to merge!\n", + tile_name.c_str()); + return port_names; + } + return result->second; +} + /************************************************************************ * Public Accessors ***********************************************************************/ @@ -77,6 +102,16 @@ std::string TileAnnotation::global_port_clock_arch_tree_name( return global_port_clock_arch_tree_names_[global_port_id]; } +bool TileAnnotation::is_tile_port_to_merge(const std::string& tile_name, + const std::string& port_name) const { + const auto& result = tile_ports_to_merge_.find(tile_name); + if (result == tile_ports_to_merge_.end()) { + return false; + } + return result->second.end() != + std::find(result->second.begin(), result->second.end(), port_name); +} + /************************************************************************ * Public Mutators ***********************************************************************/ @@ -178,4 +213,25 @@ bool TileAnnotation::valid_global_port_attributes( return ((0 == attribute_counter) || (1 == attribute_counter)); } +int TileAnnotation::add_merge_subtile_ports(const std::string& tile_name, + const std::string& port_name) { + auto result = tile_ports_to_merge_.find(tile_name); + if (result == tile_ports_to_merge_.end()) { + /* Empty list: add a new element */ + tile_ports_to_merge_[tile_name].push_back(port_name); + } else { + /* Check if the port name is already in the list, if yes, error out */ + if (result->second.end() == + std::find(result->second.begin(), result->second.end(), port_name)) { + tile_ports_to_merge_[tile_name].push_back(port_name); + } else { + VTR_LOG_ERROR( + "Port '%s' has already been defined twice for tile '%s' to be merged!", + port_name.c_str(), tile_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } + return CMD_EXEC_SUCCESS; +} + } // namespace openfpga diff --git a/libs/libarchopenfpga/src/tile_annotation.h b/libs/libarchopenfpga/src/tile_annotation.h index ddf951109..36af8a9b4 100644 --- a/libs/libarchopenfpga/src/tile_annotation.h +++ b/libs/libarchopenfpga/src/tile_annotation.h @@ -39,6 +39,9 @@ class TileAnnotation { public: /* Public accessors: aggregators */ global_port_range global_ports() const; + std::vector tiles_to_merge_ports() const; + std::vector tile_ports_to_merge( + const std::string& tile_name) const; public: /* Public accessors */ std::string global_port_name(const TileGlobalPortId& global_port_id) const; @@ -56,6 +59,10 @@ class TileAnnotation { size_t global_port_default_value( const TileGlobalPortId& global_port_id) const; + /** @brief Check if a given tile port should be merged or not */ + bool is_tile_port_to_merge(const std::string& tile_name, + const std::string& port_name) const; + public: /* Public mutators */ /* By default, we do not set it as a clock. * Users should set it through the set_global_port_is_clock() function @@ -77,6 +84,9 @@ class TileAnnotation { void set_global_port_default_value(const TileGlobalPortId& global_port_id, const size_t& default_value); + int add_merge_subtile_ports(const std::string& tile_name, + const std::string& port_name); + public: /* Public validator */ bool valid_global_port_id(const TileGlobalPortId& global_port_id) const; /* Validate attributes of a given global port @@ -102,6 +112,10 @@ class TileAnnotation { /* A fast lookup for port names */ std::map global_port_name2ids_; + + /* Merge port information for tiles */ + std::map> + tile_ports_to_merge_; // tile_name -> port_name }; } // namespace openfpga diff --git a/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp b/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp index af6bab25a..9db2e01b7 100644 --- a/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp +++ b/libs/libarchopenfpga/src/write_xml_tile_annotation.cpp @@ -87,6 +87,24 @@ static void write_xml_tile_annotation_global_port( << ""; } +/******************************************************************** + * A writer to output a device variation in a technology library to XML format + *******************************************************************/ +static void write_xml_tile_annotation_subtile_port_to_merge( + std::fstream& fp, const char* fname, const std::string& tile_name, + const std::string& port_name) { + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + fp << "\t\t" + << ""; +} + /******************************************************************** * A writer to output tile annotations to XML format *******************************************************************/ @@ -109,6 +127,13 @@ void write_xml_tile_annotations(std::fstream& fp, const char* fname, write_xml_tile_annotation_global_port(fp, fname, tile_annotation, global_port_id); } + for (std::string tile_name : tile_annotation.tiles_to_merge_ports()) { + for (std::string port_name : + tile_annotation.tile_ports_to_merge(tile_name)) { + write_xml_tile_annotation_subtile_port_to_merge(fp, fname, tile_name, + port_name); + } + } /* Write the root node for pb_type annotations */ fp << "\t" diff --git a/libs/libfpgabitstream/src/bitstream_manager_utils.cpp b/libs/libfpgabitstream/src/bitstream_manager_utils.cpp index 9a2ef1277..13ef85bbd 100644 --- a/libs/libfpgabitstream/src/bitstream_manager_utils.cpp +++ b/libs/libfpgabitstream/src/bitstream_manager_utils.cpp @@ -81,6 +81,29 @@ size_t find_bitstream_manager_config_bit_index_in_parent_block( return curr_index; } +/******************************************************************** + * Find the index of a configuration bit in the children bits of its grandparent + *block. We count the index from the parent of current parent block + *******************************************************************/ +size_t find_bitstream_manager_config_bit_index_in_grandparent_block( + const BitstreamManager& bitstream_manager, const ConfigBitId& bit_id) { + size_t curr_index = 0; + ConfigBlockId parent_blk = bitstream_manager.bit_parent_block(bit_id); + ConfigBlockId grandparent_blk = bitstream_manager.block_parent(parent_blk); + for (const ConfigBlockId& cand_blk : + bitstream_manager.block_children(grandparent_blk)) { + if (cand_blk != parent_blk) { + curr_index += bitstream_manager.block_bits(cand_blk).size(); + } else { + curr_index += find_bitstream_manager_config_bit_index_in_parent_block( + bitstream_manager, bit_id); + break; + } + } + + return curr_index; +} + /******************************************************************** * Find the total number of configuration bits under a block * As configuration bits are stored only under the leaf blocks, diff --git a/libs/libfpgabitstream/src/bitstream_manager_utils.h b/libs/libfpgabitstream/src/bitstream_manager_utils.h index e427f834c..26d6f35b8 100644 --- a/libs/libfpgabitstream/src/bitstream_manager_utils.h +++ b/libs/libfpgabitstream/src/bitstream_manager_utils.h @@ -25,6 +25,9 @@ std::vector find_bitstream_manager_top_blocks( size_t find_bitstream_manager_config_bit_index_in_parent_block( const BitstreamManager& bitstream_manager, const ConfigBitId& bit_id); +size_t find_bitstream_manager_config_bit_index_in_grandparent_block( + const BitstreamManager& bitstream_manager, const ConfigBitId& bit_id); + size_t rec_find_bitstream_manager_block_sum_of_bits( const BitstreamManager& bitstream_manager, const ConfigBlockId& block); diff --git a/libs/libionamemap/CMakeLists.txt b/libs/libnamemanager/CMakeLists.txt similarity index 72% rename from libs/libionamemap/CMakeLists.txt rename to libs/libnamemanager/CMakeLists.txt index e99236d35..3a3420acc 100644 --- a/libs/libionamemap/CMakeLists.txt +++ b/libs/libnamemanager/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.9) -project("libionamemap") +project("libnamemanager") file(GLOB_RECURSE EXEC_SOURCES test/*.cpp) file(GLOB_RECURSE LIB_SOURCES src/*/*.cpp) @@ -11,14 +11,14 @@ files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS) list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES}) #Create the library -add_library(libionamemap STATIC +add_library(libnamemanager STATIC ${LIB_HEADERS} ${LIB_SOURCES}) -target_include_directories(libionamemap PUBLIC ${LIB_INCLUDE_DIRS}) -set_target_properties(libionamemap PROPERTIES PREFIX "") #Avoid extra 'lib' prefix +target_include_directories(libnamemanager PUBLIC ${LIB_INCLUDE_DIRS}) +set_target_properties(libnamemanager PROPERTIES PREFIX "") #Avoid extra 'lib' prefix #Specify link-time dependancies -target_link_libraries(libionamemap +target_link_libraries(libnamemanager libarchopenfpga libopenfpgautil libopenfpgashell @@ -31,7 +31,7 @@ foreach(testsourcefile ${EXEC_SOURCES}) get_filename_component(testname ${testsourcefile} NAME_WE) add_executable(${testname} ${testsourcefile}) # Make sure the library is linked to each test executable - target_link_libraries(${testname} libionamemap) + target_link_libraries(${testname} libnamemanager) endforeach(testsourcefile ${EXEC_SOURCES}) -install(TARGETS libionamemap DESTINATION bin) +install(TARGETS libnamemanager DESTINATION bin) diff --git a/libs/libionamemap/example/example.xml b/libs/libnamemanager/example/example.xml similarity index 100% rename from libs/libionamemap/example/example.xml rename to libs/libnamemanager/example/example.xml diff --git a/libs/libnamemanager/example/example_module_names.xml b/libs/libnamemanager/example/example_module_names.xml new file mode 100644 index 000000000..336eeb9c1 --- /dev/null +++ b/libs/libnamemanager/example/example_module_names.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/libs/libnamemanager/example/example_module_names_expect_errors.xml b/libs/libnamemanager/example/example_module_names_expect_errors.xml new file mode 100644 index 000000000..186ce92df --- /dev/null +++ b/libs/libnamemanager/example/example_module_names_expect_errors.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/libs/libionamemap/src/base/io_name_map.cpp b/libs/libnamemanager/src/base/io_name_map.cpp similarity index 100% rename from libs/libionamemap/src/base/io_name_map.cpp rename to libs/libnamemanager/src/base/io_name_map.cpp diff --git a/libs/libionamemap/src/base/io_name_map.h b/libs/libnamemanager/src/base/io_name_map.h similarity index 100% rename from libs/libionamemap/src/base/io_name_map.h rename to libs/libnamemanager/src/base/io_name_map.h diff --git a/libs/libnamemanager/src/base/module_name_map.cpp b/libs/libnamemanager/src/base/module_name_map.cpp new file mode 100644 index 000000000..606dcc25c --- /dev/null +++ b/libs/libnamemanager/src/base/module_name_map.cpp @@ -0,0 +1,89 @@ +/****************************************************************************** + * Memember functions for data structure ModuleNameMap + ******************************************************************************/ +/* Headers from vtrutil library */ +#include "module_name_map.h" + +#include + +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/************************************************** + * Public Accessors + *************************************************/ +std::string ModuleNameMap::name(const std::string& tag) const { + auto result = tag2names_.find(tag); + if (result == tag2names_.end()) { + VTR_LOG_ERROR("The given built-in name '%s' does not exist!\n", + tag.c_str()); + return std::string(); + } + return result->second; +} + +bool ModuleNameMap::name_exist(const std::string& tag) const { + auto result = tag2names_.find(tag); + return result != tag2names_.end(); +} + +std::string ModuleNameMap::tag(const std::string& name) const { + auto result = name2tags_.find(name); + if (result == name2tags_.end()) { + VTR_LOG_ERROR("The given customized name '%s' does not exist!\n", + name.c_str()); + return std::string(); + } + return result->second; +} + +bool ModuleNameMap::tag_exist(const std::string& name) const { + auto result = name2tags_.find(name); + return result != name2tags_.end(); +} + +std::vector ModuleNameMap::tags() const { + std::vector keys; + for (auto const& element : tag2names_) { + keys.push_back(element.first); + } + return keys; +} + +int ModuleNameMap::set_tag_to_name_pair(const std::string& tag, + const std::string& name) { + /* tagA <--x--> nameA + * | + * +----> nameB + * tagB <--x--> nameB + * Scenarios to be considered: + * - Remove the double links between tagA and nameA + * - nameB should NOT be mapped to any other tags! + */ + auto result = name2tags_.find(name); + if (result != name2tags_.end() && result->second != tag) { + VTR_LOG_ERROR( + "The customized name '%s' has already been mapped to a built-in name " + "'%s'! Fail to bind it to a new built-in name '%s'\n", + name.c_str(), result->second.c_str(), tag.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + /* Clean up */ + name2tags_.erase(name); + /* Create double link */ + name2tags_[name] = tag; + tag2names_[tag] = name; + return CMD_EXEC_SUCCESS; +} + +void ModuleNameMap::clear() { + tag2names_.clear(); + name2tags_.clear(); +} + +} /* end namespace openfpga */ diff --git a/libs/libnamemanager/src/base/module_name_map.h b/libs/libnamemanager/src/base/module_name_map.h new file mode 100644 index 000000000..f3f82d9be --- /dev/null +++ b/libs/libnamemanager/src/base/module_name_map.h @@ -0,0 +1,52 @@ +#ifndef MODULE_NAME_MAP_H +#define MODULE_NAME_MAP_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include +#include +#include + +/* Begin namespace openfpga */ +namespace openfpga { + +/** + * @brief Module name map is a data structure to show mapping between a tag + * (built-in name) and customized names (may be given by users) + */ +class ModuleNameMap { + public: /* Public accessors */ + /** @brief Get customized name with a given tag */ + std::string name(const std::string& tag) const; + /** @brief Check if a name does exist with a given tag. Return true if there + * is a tag-to-name mapping */ + bool name_exist(const std::string& tag) const; + /** @brief Check if a tag does exist with a given name. Return true if there + * is a name-to-tag mapping */ + bool tag_exist(const std::string& name) const; + /** @brief Get tag with a given name */ + std::string tag(const std::string& name) const; + + /** @brief return a list of all the current keys */ + std::vector tags() const; + + public: /* Public mutators */ + /** @brief Create the one-on-one mapping between an built-in name and a + * customized name. Return 0 for success, return 1 for fail */ + int set_tag_to_name_pair(const std::string& tag, const std::string& name); + /** @brief Reset to empty status. Clear all the storage */ + void clear(); + + private: /* Internal Data */ + /* built-in name -> customized_name + * Create a double link to check any customized name is mapped to more than 1 + * built-in name! + */ + std::map tag2names_; + std::map name2tags_; +}; + +} /* End namespace openfpga*/ + +#endif diff --git a/libs/libionamemap/src/io/io_name_map_xml_constants.h b/libs/libnamemanager/src/io/io_name_map_xml_constants.h similarity index 100% rename from libs/libionamemap/src/io/io_name_map_xml_constants.h rename to libs/libnamemanager/src/io/io_name_map_xml_constants.h diff --git a/libs/libnamemanager/src/io/module_name_map_xml_constants.h b/libs/libnamemanager/src/io/module_name_map_xml_constants.h new file mode 100644 index 000000000..ae8e02338 --- /dev/null +++ b/libs/libnamemanager/src/io/module_name_map_xml_constants.h @@ -0,0 +1,11 @@ +#ifndef MODULE_NAME_MAP_XML_CONSTANTS_H +#define MODULE_NAME_MAP_XML_CONSTANTS_H + +/* Constants required by XML parser */ + +constexpr const char* XML_MODULE_NAMES_ROOT_NAME = "module_names"; +constexpr const char* XML_MODULE_NAME_NODE_NAME = "module_name"; +constexpr const char* XML_MODULE_NAME_ATTRIBUTE_DEFAULT = "default"; +constexpr const char* XML_MODULE_NAME_ATTRIBUTE_GIVEN = "given"; + +#endif diff --git a/libs/libionamemap/src/io/read_xml_io_name_map.cpp b/libs/libnamemanager/src/io/read_xml_io_name_map.cpp similarity index 100% rename from libs/libionamemap/src/io/read_xml_io_name_map.cpp rename to libs/libnamemanager/src/io/read_xml_io_name_map.cpp diff --git a/libs/libionamemap/src/io/read_xml_io_name_map.h b/libs/libnamemanager/src/io/read_xml_io_name_map.h similarity index 100% rename from libs/libionamemap/src/io/read_xml_io_name_map.h rename to libs/libnamemanager/src/io/read_xml_io_name_map.h diff --git a/libs/libnamemanager/src/io/read_xml_module_name_map.cpp b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp new file mode 100644 index 000000000..111ce871c --- /dev/null +++ b/libs/libnamemanager/src/io/read_xml_module_name_map.cpp @@ -0,0 +1,79 @@ +/******************************************************************** + * This file includes the top-level function of this library + * which reads an XML of clock network file to the associated + * data structures + *******************************************************************/ +#include + +/* Headers from pugi XML library */ +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/* Headers from vtr util library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from libarchfpga */ +#include "arch_error.h" +#include "command_exit_codes.h" +#include "module_name_map_xml_constants.h" +#include "read_xml_module_name_map.h" +#include "read_xml_util.h" + +namespace openfpga { // Begin namespace openfpga + +/******************************************************************** + * Parse XML codes of a to an object of I/O naming + *******************************************************************/ +static int read_xml_module_name_binding(pugi::xml_node& xml_binding, + const pugiutil::loc_data& loc_data, + ModuleNameMap& module_name_map) { + std::string default_name = + get_attribute(xml_binding, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, loc_data) + .as_string(); + std::string given_name = + get_attribute(xml_binding, XML_MODULE_NAME_ATTRIBUTE_GIVEN, loc_data) + .as_string(); + + return module_name_map.set_tag_to_name_pair(default_name, given_name); +} + +/******************************************************************** + * Parse XML codes about to an object of ClockNetwork + *******************************************************************/ +int read_xml_module_name_map(const char* fname, + ModuleNameMap& module_name_map) { + vtr::ScopedStartFinishTimer timer("Read module rename rules"); + + int status = CMD_EXEC_SUCCESS; + + /* Parse the file */ + pugi::xml_document doc; + pugiutil::loc_data loc_data; + + try { + loc_data = pugiutil::load_xml(doc, fname); + + pugi::xml_node xml_root = + get_single_child(doc, XML_MODULE_NAMES_ROOT_NAME, loc_data); + + for (pugi::xml_node xml_binding : xml_root.children()) { + /* Error out if the XML child has an invalid name! */ + if (xml_binding.name() != std::string(XML_MODULE_NAME_NODE_NAME)) { + bad_tag(xml_binding, loc_data, xml_root, {XML_MODULE_NAME_NODE_NAME}); + } + status = + read_xml_module_name_binding(xml_binding, loc_data, module_name_map); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_FATAL_ERROR; + } + } + } catch (pugiutil::XmlError& e) { + archfpga_throw(fname, e.line(), "%s", e.what()); + } + + return status; +} + +} // End of namespace openfpga diff --git a/libs/libnamemanager/src/io/read_xml_module_name_map.h b/libs/libnamemanager/src/io/read_xml_module_name_map.h new file mode 100644 index 000000000..140c752dd --- /dev/null +++ b/libs/libnamemanager/src/io/read_xml_module_name_map.h @@ -0,0 +1,21 @@ +#ifndef READ_XML_MODULE_NAME_MAP_H +#define READ_XML_MODULE_NAME_MAP_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "module_name_map.h" +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +namespace openfpga { // Begin namespace openfpga + +int read_xml_module_name_map(const char* fname, ModuleNameMap& module_name_map); + +} // End of namespace openfpga + +#endif diff --git a/libs/libionamemap/src/io/write_xml_io_name_map.cpp b/libs/libnamemanager/src/io/write_xml_io_name_map.cpp similarity index 100% rename from libs/libionamemap/src/io/write_xml_io_name_map.cpp rename to libs/libnamemanager/src/io/write_xml_io_name_map.cpp diff --git a/libs/libionamemap/src/io/write_xml_io_name_map.h b/libs/libnamemanager/src/io/write_xml_io_name_map.h similarity index 100% rename from libs/libionamemap/src/io/write_xml_io_name_map.h rename to libs/libnamemanager/src/io/write_xml_io_name_map.h diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.cpp b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp new file mode 100644 index 000000000..8ccd81c5c --- /dev/null +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.cpp @@ -0,0 +1,137 @@ +/******************************************************************** + * This file includes functions that outputs a clock network object to XML + *format + *******************************************************************/ +/* Headers from system goes first */ +#include +#include +#include +#include + +/* Headers from vtr util library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpga util library */ +#include "openfpga_digest.h" + +/* Headers from arch openfpga library */ +#include "write_xml_utils.h" + +/* Headers from pin constraint library */ +#include "module_name_map_xml_constants.h" +#include "write_xml_module_name_map.h" + +namespace openfpga { // Begin namespace openfpga + +/******************************************************************** + * This function write header information to a bitstream file + *******************************************************************/ +static void write_xml_module_name_map_file_head( + std::fstream& fp, const bool& include_time_stamp) { + valid_file_stream(fp); + + fp << "" << std::endl; + fp << std::endl; +} + +/******************************************************************** + * A writer to output a I/O name mapping to XML format + * + * Return 0 if successful + * Return 1 if there are more serious bugs in the architecture + * Return 2 if fail when creating files + *******************************************************************/ +static int write_xml_module_name_binding(std::fstream& fp, + const ModuleNameMap& module_name_map, + const std::string& built_in_name) { + /* Validate the file stream */ + if (false == openfpga::valid_file_stream(fp)) { + return 2; + } + + openfpga::write_tab_to_file(fp, 1); + fp << "<" << XML_MODULE_NAME_NODE_NAME << ""; + write_xml_attribute(fp, XML_MODULE_NAME_ATTRIBUTE_DEFAULT, + built_in_name.c_str()); + + std::string given_name = module_name_map.name(built_in_name); + if (given_name.empty()) { + VTR_LOG_ERROR("Default name '%s' is not mapped to any given name!\n", + built_in_name.c_str()); + return 1; + } + write_xml_attribute(fp, XML_MODULE_NAME_ATTRIBUTE_GIVEN, given_name.c_str()); + fp << "/>" + << "\n"; + + return 0; +} + +/******************************************************************** + * A writer to output an object to XML format + * + * Return 0 if successful + * Return 1 if there are more serious bugs in the architecture + * Return 2 if fail when creating files + *******************************************************************/ +int write_xml_module_name_map(const char* fname, + const ModuleNameMap& module_name_map, + const bool& include_time_stamp, + const bool& verbose) { + vtr::ScopedStartFinishTimer timer("Write module renaming rules"); + + /* Create a file handler */ + std::fstream fp; + /* Open the file stream */ + fp.open(std::string(fname), std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + write_xml_module_name_map_file_head(fp, include_time_stamp); + + /* Write the root node */ + fp << "<" << XML_MODULE_NAMES_ROOT_NAME; + fp << ">" + << "\n"; + + int err_code = 0; + + /* Write each port */ + size_t cnt = 0; + for (std::string built_in_name : module_name_map.tags()) { + /* Write bus */ + err_code = + write_xml_module_name_binding(fp, module_name_map, built_in_name); + if (0 != err_code) { + return err_code; + } + cnt++; + } + + /* Finish writing the root node */ + fp << "" + << "\n"; + + /* Close the file stream */ + fp.close(); + + VTR_LOGV(verbose, "Outputted %lu naming rules.\n", cnt); + + return err_code; +} + +} // End of namespace openfpga diff --git a/libs/libnamemanager/src/io/write_xml_module_name_map.h b/libs/libnamemanager/src/io/write_xml_module_name_map.h new file mode 100644 index 000000000..f0725df16 --- /dev/null +++ b/libs/libnamemanager/src/io/write_xml_module_name_map.h @@ -0,0 +1,23 @@ +#ifndef WRITE_XML_MODULE_NAME_MAP_H +#define WRITE_XML_MODULE_NAME_MAP_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include + +#include "module_name_map.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ +namespace openfpga { // Begin namespace openfpga + +int write_xml_module_name_map(const char* fname, + const ModuleNameMap& module_name_map, + const bool& include_time_stamp, + const bool& verbose); + +} // End of namespace openfpga + +#endif diff --git a/libs/libnamemanager/test/module_rename_assistant.cpp b/libs/libnamemanager/test/module_rename_assistant.cpp new file mode 100644 index 000000000..49de367c3 --- /dev/null +++ b/libs/libnamemanager/test/module_rename_assistant.cpp @@ -0,0 +1,159 @@ +/******************************************************************** + * Unit test functions to validate the correctness of + * 1. parser of data structures + * 2. writer of data structures + *******************************************************************/ +/* Headers from vtrutils */ +#include "vtr_assert.h" +#include "vtr_log.h" + +/* Headers from readarchopenfpga */ +#include "command_echo.h" +#include "command_exit_codes.h" +#include "command_parser.h" +#include "read_xml_module_name_map.h" +#include "write_xml_module_name_map.h" + +/** @brief Initialize the options from command-line inputs and organize in the + * format that is ready for parsing */ +static std::vector format_argv(const std::string& cmd_name, + int argc, const char** argv) { + std::vector cmd_opts; + cmd_opts.push_back(cmd_name); + for (int iarg = 1; iarg < argc; ++iarg) { + cmd_opts.push_back(std::string(argv[iarg])); + } + return cmd_opts; +} + +/** @brief Convert module renaming rules from fabric A (ref -> renamed) to + * fabric B (given the ref only) Here is an example Fabric A reference names: + * + * Fabric A renamed: + * + * Fabric B reference names: + * + * We want a renamed version for fabric B is + * + */ +static int rename_module_names_for_fabricB_from_fabricA( + const openfpga::ModuleNameMap& refA_module_names, + const openfpga::ModuleNameMap& renamedA_module_names, + const openfpga::ModuleNameMap& refB_module_names, + openfpga::ModuleNameMap& renamedB_module_names, const bool& verbose) { + /* Ensure a clear start */ + renamedB_module_names.clear(); + for (std::string ref_tag : refA_module_names.tags()) { + std::string ref_given = refA_module_names.name(ref_tag); + if (!renamedA_module_names.name_exist(ref_tag)) { + VTR_LOG_ERROR( + "Fail to find given name for default '%s' in the hand-crafted module " + "names of fabric A!\n", + ref_tag.c_str()); + return openfpga::CMD_EXEC_FATAL_ERROR; + } + std::string renamed_given = renamedA_module_names.name(ref_tag); + /* Now find the same given name in refB */ + if (!refB_module_names.tag_exist(ref_given)) { + VTR_LOG_ERROR( + "Fail to find default name for the given name '%s' in the reference " + "module names of fabric B!\n", + ref_given.c_str()); + return openfpga::CMD_EXEC_FATAL_ERROR; + } + std::string refB_tag = refB_module_names.tag(ref_given); + /* Add the new pair to the renamed modules for fabric B */ + renamedB_module_names.set_tag_to_name_pair(refB_tag, renamed_given); + VTR_LOGV(verbose, + "Successfully pair default name '%s' to given '%s' for fabric B\n", + refB_tag.c_str(), renamed_given.c_str()); + } + return openfpga::CMD_EXEC_FATAL_ERROR; +} + +int main(int argc, const char** argv) { + /* Create a new command and Initialize the options available in the user + * interface */ + openfpga::Command cmd("module_rename_assistant"); + openfpga::CommandOptionId opt_refA = + cmd.add_option("reference_fabricA_names", true, + "Specify the reference module name file for fabric A"); + cmd.set_option_require_value(opt_refA, openfpga::OPT_STRING); + openfpga::CommandOptionId opt_renamedA = + cmd.add_option("renamed_fabricA_names", true, + "Specify the hand-crafted module name file for fabric A"); + cmd.set_option_require_value(opt_renamedA, openfpga::OPT_STRING); + openfpga::CommandOptionId opt_refB = + cmd.add_option("reference_fabricB_names", true, + "Specify the reference module name file for fabric B"); + cmd.set_option_require_value(opt_refB, openfpga::OPT_STRING); + openfpga::CommandOptionId opt_renamedB = cmd.add_option( + "output", true, + "Specify the renamed module name file for fabric B to be outputted"); + cmd.set_option_require_value(opt_renamedB, openfpga::OPT_STRING); + openfpga::CommandOptionId opt_no_time_stamp = cmd.add_option( + "no_time_stamp", false, "Include time stamps in output file"); + openfpga::CommandOptionId opt_verbose = + cmd.add_option("verbose", false, "Show verbose outputs"); + openfpga::CommandOptionId opt_help = + cmd.add_option("help", false, "Show help desk"); + + /* Parse the option, to avoid issues, we use the command name to replace the + * argv[0] */ + std::vector cmd_opts = format_argv(cmd.name(), argc, argv); + + openfpga::CommandContext cmd_ctx(cmd); + if (false == parse_command(cmd_opts, cmd, cmd_ctx) || + cmd_ctx.option_enable(cmd, opt_help)) { + /* Echo the command */ + print_command_options(cmd); + return openfpga::CMD_EXEC_FATAL_ERROR; + } else { + /* Let user to confirm selected options */ + print_command_context(cmd, cmd_ctx); + } + + int status = 0; + + VTR_LOG( + "Read the reference module names for fabric A from an XML file: %s.\n", + cmd_ctx.option_value(cmd, opt_refA).c_str()); + openfpga::ModuleNameMap refA_module_names; + status = openfpga::read_xml_module_name_map( + cmd_ctx.option_value(cmd, opt_refA).c_str(), refA_module_names); + if (status != openfpga::CMD_EXEC_SUCCESS) { + return status; + } + + VTR_LOG( + "Read the reference module names for fabric B from an XML file: %s.\n", + cmd_ctx.option_value(cmd, opt_refB).c_str()); + openfpga::ModuleNameMap refB_module_names; + status = openfpga::read_xml_module_name_map( + cmd_ctx.option_value(cmd, opt_refB).c_str(), refB_module_names); + if (status != openfpga::CMD_EXEC_SUCCESS) { + return status; + } + + VTR_LOG("Read the renamed module names for fabric A from an XML file: %s.\n", + cmd_ctx.option_value(cmd, opt_renamedA).c_str()); + openfpga::ModuleNameMap renamedA_module_names; + status = openfpga::read_xml_module_name_map( + cmd_ctx.option_value(cmd, opt_renamedA).c_str(), renamedA_module_names); + if (status != openfpga::CMD_EXEC_SUCCESS) { + return status; + } + + /* Now apply name mapping from fabric A to fabric B */ + openfpga::ModuleNameMap renamedB_module_names; + status = rename_module_names_for_fabricB_from_fabricA( + refA_module_names, renamedA_module_names, refB_module_names, + renamedB_module_names, cmd_ctx.option_enable(cmd, opt_verbose)); + + VTR_LOG("Write the renamed module names for fabric B to an XML file: %s.\n", + cmd_ctx.option_value(cmd, opt_renamedB).c_str()); + return openfpga::write_xml_module_name_map( + cmd_ctx.option_value(cmd, opt_renamedB).c_str(), renamedB_module_names, + !cmd_ctx.option_enable(cmd, opt_no_time_stamp), + cmd_ctx.option_enable(cmd, opt_verbose)); +} diff --git a/libs/libionamemap/test/xml_io_io_name_map.cpp b/libs/libnamemanager/test/xml_io_io_name_map.cpp similarity index 100% rename from libs/libionamemap/test/xml_io_io_name_map.cpp rename to libs/libnamemanager/test/xml_io_io_name_map.cpp diff --git a/libs/libnamemanager/test/xml_io_module_name_map.cpp b/libs/libnamemanager/test/xml_io_module_name_map.cpp new file mode 100644 index 000000000..570842f3a --- /dev/null +++ b/libs/libnamemanager/test/xml_io_module_name_map.cpp @@ -0,0 +1,39 @@ +/******************************************************************** + * Unit test functions to validate the correctness of + * 1. parser of data structures + * 2. writer of data structures + *******************************************************************/ +/* Headers from vtrutils */ +#include "vtr_assert.h" +#include "vtr_log.h" + +/* Headers from readarchopenfpga */ +#include "read_xml_module_name_map.h" +#include "write_xml_module_name_map.h" + +int main(int argc, const char** argv) { + /* Ensure we have only one or two argument */ + VTR_ASSERT((2 == argc) || (3 == argc)); + + int status = 0; + + /* Parse the circuit library from an XML file */ + openfpga::ModuleNameMap module_name_map; + status = openfpga::read_xml_module_name_map(argv[1], module_name_map); + if (status != 0) { + return status; + } + VTR_LOG("Parsed %lu default names from XML.\n", + module_name_map.tags().size()); + + /* Output the bus group to an XML file + * This is optional only used when there is a second argument + */ + if (3 <= argc) { + status = + openfpga::write_xml_module_name_map(argv[2], module_name_map, true, true); + VTR_LOG("Write the module name mapping to an XML file: %s.\n", argv[2]); + } + + return status; +} diff --git a/openfpga/CMakeLists.txt b/openfpga/CMakeLists.txt index bea2fa94d..96c450876 100644 --- a/openfpga/CMakeLists.txt +++ b/openfpga/CMakeLists.txt @@ -41,7 +41,7 @@ target_link_libraries(libopenfpga libpcf libvtrutil libbusgroup - libionamemap + libnamemanager libtileconfig libpugixml libvpr) diff --git a/openfpga/src/base/openfpga_bitstream_command_template.h b/openfpga/src/base/openfpga_bitstream_command_template.h index bc781dcdc..f80176514 100644 --- a/openfpga/src/base/openfpga_bitstream_command_template.h +++ b/openfpga/src/base/openfpga_bitstream_command_template.h @@ -190,6 +190,27 @@ ShellCommandId add_write_fabric_bitstream_command_template( "file format of fabric bitstream [plain_text|xml]. Default: plain_text"); shell_cmd.set_option_require_value(opt_file_format, openfpga::OPT_STRING); + CommandOptionId opt_filter_value = shell_cmd.add_option( + "filter_value", false, + "Specify what values should be written out in the resulting fabric " + "bitstream [0|1|none]. Only applicable to XML file format. Default: none"); + shell_cmd.set_option_require_value(opt_filter_value, openfpga::OPT_STRING); + + shell_cmd.add_option( + "path_only", false, + "Only paths will be written out in the resulting fabric bitstream. Only " + "applicable to XML file format. Default: off"); + + shell_cmd.add_option( + "value_only", false, + "Only values will be written out in the resulting fabric bitstream. Only " + "applicable to XML file format. Default: off"); + + shell_cmd.add_option( + "trim_path", false, + "Trim the path by a level of 1 in the resulting fabric bitstream. Only " + "applicable to XML file format. Default: off"); + /* Add an option '--fast_configuration' */ shell_cmd.add_option("fast_configuration", false, "Reduce the size of bitstream to be downloaded"); diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h index 196d9ef30..8821c8392 100644 --- a/openfpga/src/base/openfpga_bitstream_template.h +++ b/openfpga/src/base/openfpga_bitstream_template.h @@ -4,6 +4,7 @@ /******************************************************************** * This file includes functions to build bitstream database *******************************************************************/ +#include "bitstream_writer_options.h" #include "build_device_bitstream.h" #include "build_fabric_bitstream.h" #include "build_io_mapping_info.h" @@ -73,7 +74,8 @@ int build_fabric_bitstream_template(T& openfpga_ctx, const Command& cmd, /* Build fabric bitstream here */ openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream( openfpga_ctx.bitstream_manager(), openfpga_ctx.module_graph(), - openfpga_ctx.arch().circuit_lib, openfpga_ctx.arch().config_protocol, + openfpga_ctx.module_name_map(), openfpga_ctx.arch().circuit_lib, + openfpga_ctx.arch().config_protocol, cmd_context.option_enable(cmd, opt_verbose)); /* TODO: should identify the error code from internal function execution */ @@ -93,6 +95,10 @@ int write_fabric_bitstream_template(const T& openfpga_ctx, const Command& cmd, CommandOptionId opt_keep_dont_care_bits = cmd.option("keep_dont_care_bits"); CommandOptionId opt_wl_decremental_order = cmd.option("wl_decremental_order"); CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + CommandOptionId opt_filter_value = cmd.option("filter_value"); + CommandOptionId opt_path_only = cmd.option("path_only"); + CommandOptionId opt_value_only = cmd.option("value_only"); + CommandOptionId opt_trim_path = cmd.option("trim_path"); /* Write fabric bitstream if required */ int status = CMD_EXEC_SUCCESS; @@ -111,26 +117,50 @@ int write_fabric_bitstream_template(const T& openfpga_ctx, const Command& cmd, file_format = cmd_context.option_value(cmd, opt_file_format); } - if (std::string("xml") == file_format) { + /* Validate options */ + BitstreamWriterOption bitfile_writer_opt; + bitfile_writer_opt.set_output_file_type(file_format); + bitfile_writer_opt.set_output_file_name( + cmd_context.option_value(cmd, opt_file)); + bitfile_writer_opt.set_time_stamp( + !cmd_context.option_enable(cmd, opt_no_time_stamp)); + bitfile_writer_opt.set_verbose_output( + cmd_context.option_enable(cmd, opt_verbose)); + bitfile_writer_opt.set_trim_path( + cmd_context.option_enable(cmd, opt_trim_path)); + bitfile_writer_opt.set_path_only( + cmd_context.option_enable(cmd, opt_path_only)); + bitfile_writer_opt.set_value_only( + cmd_context.option_enable(cmd, opt_value_only)); + bitfile_writer_opt.set_fast_configuration( + cmd_context.option_enable(cmd, opt_fast_config)); + bitfile_writer_opt.set_keep_dont_care_bits( + cmd_context.option_enable(cmd, opt_keep_dont_care_bits)); + bitfile_writer_opt.set_wl_decremental_order( + cmd_context.option_enable(cmd, opt_wl_decremental_order)); + if (cmd_context.option_enable(cmd, opt_filter_value)) { + bitfile_writer_opt.set_filter_value( + cmd_context.option_value(cmd, opt_filter_value)); + } + if (!bitfile_writer_opt.validate(true)) { + VTR_LOG_ERROR("Conflicts detected in options for bitstream writer!\n"); + return CMD_EXEC_FATAL_ERROR; + } + + if (bitfile_writer_opt.output_file_type() == + BitstreamWriterOption::e_bitfile_type::XML) { status = write_fabric_bitstream_to_xml_file( openfpga_ctx.bitstream_manager(), openfpga_ctx.fabric_bitstream(), - openfpga_ctx.arch().config_protocol, - cmd_context.option_value(cmd, opt_file), - !cmd_context.option_enable(cmd, opt_no_time_stamp), - cmd_context.option_enable(cmd, opt_verbose)); + openfpga_ctx.arch().config_protocol, bitfile_writer_opt); } else { + VTR_ASSERT_SAFE(bitfile_writer_opt.output_file_type() == + BitstreamWriterOption::e_bitfile_type::TEXT); /* By default, output in plain text format */ status = write_fabric_bitstream_to_text_file( openfpga_ctx.bitstream_manager(), openfpga_ctx.fabric_bitstream(), openfpga_ctx.blwl_shift_register_banks(), openfpga_ctx.arch().config_protocol, - openfpga_ctx.fabric_global_port_info(), - cmd_context.option_value(cmd, opt_file), - cmd_context.option_enable(cmd, opt_fast_config), - cmd_context.option_enable(cmd, opt_keep_dont_care_bits), - !cmd_context.option_enable(cmd, opt_wl_decremental_order), - !cmd_context.option_enable(cmd, opt_no_time_stamp), - cmd_context.option_enable(cmd, opt_verbose)); + openfpga_ctx.fabric_global_port_info(), bitfile_writer_opt); } return status; diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index 39e181b6d..63e623398 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -18,9 +18,12 @@ #include "openfpga_naming.h" #include "read_xml_fabric_key.h" #include "read_xml_io_name_map.h" +#include "read_xml_module_name_map.h" #include "read_xml_tile_config.h" +#include "rename_modules.h" #include "vtr_log.h" #include "vtr_time.h" +#include "write_xml_module_name_map.h" /* begin namespace openfpga */ namespace openfpga { @@ -103,6 +106,8 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, CommandOptionId opt_load_fabric_key = cmd.option("load_fabric_key"); CommandOptionId opt_group_tile = cmd.option("group_tile"); CommandOptionId opt_group_config_block = cmd.option("group_config_block"); + CommandOptionId opt_name_module_using_index = + cmd.option("name_module_using_index"); CommandOptionId opt_verbose = cmd.option("verbose"); /* Report conflicts with options: @@ -125,6 +130,16 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, return CMD_EXEC_FATAL_ERROR; } } + /* Conflicts: duplicate_grid_pin does not support any port merge */ + if (cmd_context.option_enable(cmd, opt_duplicate_grid_pin)) { + if (openfpga_ctx.arch().tile_annotations.tiles_to_merge_ports().size() > + 0) { + VTR_LOG_ERROR( + "Option '%s' requires no tile ports to be merged due to a conflict!\n", + cmd.option_name(opt_duplicate_grid_pin).c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } if (true == cmd_context.option_enable(cmd, opt_compress_routing)) { compress_routing_hierarchy_template( @@ -173,12 +188,14 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd, curr_status = build_device_module_graph( openfpga_ctx.mutable_module_graph(), openfpga_ctx.mutable_decoder_lib(), openfpga_ctx.mutable_blwl_shift_register_banks(), - openfpga_ctx.mutable_fabric_tile(), const_cast(openfpga_ctx), - g_vpr_ctx.device(), cmd_context.option_enable(cmd, opt_frame_view), + openfpga_ctx.mutable_fabric_tile(), openfpga_ctx.mutable_module_name_map(), + const_cast(openfpga_ctx), g_vpr_ctx.device(), + cmd_context.option_enable(cmd, opt_frame_view), cmd_context.option_enable(cmd, opt_compress_routing), cmd_context.option_enable(cmd, opt_duplicate_grid_pin), predefined_fabric_key, tile_config, cmd_context.option_enable(cmd, opt_group_config_block), + cmd_context.option_enable(cmd, opt_name_module_using_index), cmd_context.option_enable(cmd, opt_gen_random_fabric_key), cmd_context.option_enable(cmd, opt_verbose)); @@ -278,8 +295,8 @@ int write_fabric_hierarchy_template(const T& openfpga_ctx, const Command& cmd, /* Write hierarchy to a file */ return write_fabric_hierarchy_to_text_file( - openfpga_ctx.module_graph(), hie_file_name, size_t(depth), - cmd_context.option_enable(cmd, opt_verbose)); + openfpga_ctx.module_graph(), openfpga_ctx.module_name_map(), hie_file_name, + size_t(depth), cmd_context.option_enable(cmd, opt_verbose)); } /******************************************************************** @@ -332,8 +349,74 @@ int add_fpga_core_to_fabric_template(T& openfpga_ctx, const Command& cmd, } return add_fpga_core_to_device_module_graph( - openfpga_ctx.mutable_module_graph(), openfpga_ctx.io_name_map(), - core_inst_name, frame_view, verbose_output); + openfpga_ctx.mutable_module_graph(), openfpga_ctx.mutable_module_name_map(), + openfpga_ctx.io_name_map(), core_inst_name, frame_view, verbose_output); +} + +/******************************************************************** + * Rename modules in module graph with a set of given rules + *******************************************************************/ +template +int rename_modules_template(T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* Check the option '--file' is enabled or not + * Actually, it must be enabled as the shell interface will check + * before reaching this fuction + */ + CommandOptionId opt_file = cmd.option("file"); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + + std::string file_name = cmd_context.option_value(cmd, opt_file); + + int status = CMD_EXEC_SUCCESS; + ModuleNameMap user_module_name_map; + status = read_xml_module_name_map(file_name.c_str(), user_module_name_map); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_FATAL_ERROR; + } + + /* Apply renaming on the user version */ + status = partial_rename_fabric_modules( + openfpga_ctx.mutable_module_graph(), user_module_name_map, + cmd_context.option_enable(cmd, opt_verbose)); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_FATAL_ERROR; + } + + /* Update the internal version of module name map based on users' version */ + return update_module_name_map_with_user_version( + openfpga_ctx.mutable_module_name_map(), user_module_name_map, + cmd_context.option_enable(cmd, opt_verbose)); +} + +/******************************************************************** + * Write module naming rules to a file + *******************************************************************/ +template +int write_module_naming_rules_template(const T& openfpga_ctx, + const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_verbose = cmd.option("verbose"); + CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + + /* Check the option '--file' is enabled or not + * Actually, it must be enabled as the shell interface will check + * before reaching this fuction + */ + CommandOptionId opt_file = cmd.option("file"); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + + std::string file_name = cmd_context.option_value(cmd, opt_file); + + /* Write hierarchy to a file */ + return write_xml_module_name_map( + file_name.c_str(), openfpga_ctx.module_name_map(), + !cmd_context.option_enable(cmd, opt_no_time_stamp), + cmd_context.option_enable(cmd, opt_verbose)); } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index 9473ecc65..a334b183e 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -15,6 +15,7 @@ #include "io_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" #include "openfpga_arch.h" @@ -107,6 +108,9 @@ class OpenfpgaContext : public Context { return io_location_map_; } const openfpga::IoNameMap& io_name_map() const { return io_name_map_; } + const openfpga::ModuleNameMap& module_name_map() const { + return module_name_map_; + } const openfpga::FabricTile& fabric_tile() const { return fabric_tile_; } const openfpga::FabricGlobalPortInfo& fabric_global_port_info() const { return fabric_global_port_info_; @@ -167,6 +171,9 @@ class OpenfpgaContext : public Context { return io_location_map_; } openfpga::IoNameMap& mutable_io_name_map() { return io_name_map_; } + openfpga::ModuleNameMap& mutable_module_name_map() { + return module_name_map_; + } openfpga::FabricTile& mutable_fabric_tile() { return fabric_tile_; } openfpga::FabricGlobalPortInfo& mutable_fabric_global_port_info() { return fabric_global_port_info_; @@ -223,6 +230,7 @@ class OpenfpgaContext : public Context { openfpga::ModuleManager module_graph_; openfpga::IoLocationMap io_location_map_; openfpga::IoNameMap io_name_map_; + openfpga::ModuleNameMap module_name_map_; openfpga::FabricTile fabric_tile_; openfpga::FabricGlobalPortInfo fabric_global_port_info_; diff --git a/openfpga/src/base/openfpga_naming.cpp b/openfpga/src/base/openfpga_naming.cpp index 1623df96f..b80c3ba36 100644 --- a/openfpga/src/base/openfpga_naming.cpp +++ b/openfpga/src/base/openfpga_naming.cpp @@ -503,6 +503,13 @@ std::string generate_switch_block_module_name( std::string("_")); } +/********************************************************************* + * Generate the module name for a switch block with a given index + *********************************************************************/ +std::string generate_switch_block_module_name_using_index(const size_t& index) { + return std::string("sb_" + std::to_string(index) + std::string("_")); +} + /********************************************************************* * Generate the module name for a tile module with a given coordinate *********************************************************************/ @@ -511,6 +518,13 @@ std::string generate_tile_module_name(const vtr::Point& tile_coord) { std::to_string(tile_coord.y()) + "_"); } +/********************************************************************* + * Generate the module name for a tile module with a given index + *********************************************************************/ +std::string generate_tile_module_name_using_index(const size_t& index) { + return std::string("tile_" + std::to_string(index) + "_"); +} + /********************************************************************* * Generate the port name for a tile. Note that use the index to make the tile *port name unique! @@ -560,6 +574,27 @@ std::string generate_connection_block_module_name( std::string("_")); } +/********************************************************************* + * Generate the module name for a connection block with a given index + *********************************************************************/ +std::string generate_connection_block_module_name_using_index( + const t_rr_type& cb_type, const size_t& index) { + std::string prefix("cb"); + switch (cb_type) { + case CHANX: + prefix += std::string("x_"); + break; + case CHANY: + prefix += std::string("y_"); + break; + default: + VTR_LOG_ERROR("Invalid type of connection block!\n"); + exit(1); + } + + return std::string(prefix + std::to_string(index) + std::string("_")); +} + /********************************************************************* * Generate the port name for a grid in top-level netlists, i.e., full FPGA *fabric This function will generate a full port name including coordinates so diff --git a/openfpga/src/base/openfpga_naming.h b/openfpga/src/base/openfpga_naming.h index 4a1d35e8e..378a2836a 100644 --- a/openfpga/src/base/openfpga_naming.h +++ b/openfpga/src/base/openfpga_naming.h @@ -108,11 +108,18 @@ std::string generate_routing_track_middle_output_port_name( std::string generate_switch_block_module_name( const vtr::Point& coordinate); +std::string generate_switch_block_module_name_using_index(const size_t& index); + std::string generate_connection_block_module_name( const t_rr_type& cb_type, const vtr::Point& coordinate); +std::string generate_connection_block_module_name_using_index( + const t_rr_type& cb_type, const size_t& index); + std::string generate_tile_module_name(const vtr::Point& tile_coord); +std::string generate_tile_module_name_using_index(const size_t& index); + std::string generate_tile_module_port_name(const std::string& prefix, const std::string& port_name); diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index 55b0ae52f..96d8e3e3b 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -395,6 +395,11 @@ ShellCommandId add_build_fabric_command_template( shell_cmd.add_option("duplicate_grid_pin", false, "Duplicate the pins on the same side of a grid"); + /* Add an option '--name_module_using_index' */ + shell_cmd.add_option("name_module_using_index", false, + "Use index to name modules, such as cbx_0_, rather than " + "coordinates, such as cbx_1__0_"); + /* Add an option '--load_fabric_key' */ CommandOptionId opt_load_fkey = shell_cmd.add_option( "load_fabric_key", false, "load the fabric key from the given file"); @@ -786,6 +791,73 @@ ShellCommandId add_write_fabric_key_command_template( return shell_cmd_id; } +/******************************************************************** + * - Add a command to Shell environment: rename_modules + * - Add associated options + * - Add command dependency + *******************************************************************/ +template +ShellCommandId add_rename_modules_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("rename_modules"); + /* Add an option '--file' in short '-f'*/ + CommandOptionId opt_file = shell_cmd.add_option( + "file", true, "file path to the XML file that contains renaming rules"); + shell_cmd.set_option_short_name(opt_file, "f"); + shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING); + + shell_cmd.add_option("verbose", false, "Show verbose outputs"); + + /* Add command to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "Rename modules with a set of given rules", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function(shell_cmd_id, rename_modules_template); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + +/******************************************************************** + * - Add a command to Shell environment: write_module_naming_rules + * - Add associated options + * - Add command dependency + *******************************************************************/ +template +ShellCommandId add_write_module_naming_rules_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_module_naming_rules"); + /* Add an option '--file' in short '-f'*/ + CommandOptionId opt_file = shell_cmd.add_option( + "file", true, "file path to the XML file that contains renaming rules"); + shell_cmd.set_option_short_name(opt_file, "f"); + shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING); + + /* Add an option '--no_time_stamp' */ + shell_cmd.add_option("no_time_stamp", false, + "Do not print time stamp in output files"); + + shell_cmd.add_option("verbose", false, "Show verbose outputs"); + + /* Add command to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, + "Output the naming rules for each module of an FPGA fabric to a given file", + hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_const_execute_function( + shell_cmd_id, write_module_naming_rules_template); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + template void add_setup_command_templates(openfpga::Shell& shell, const bool& hidden = false) { @@ -1005,6 +1077,27 @@ void add_setup_command_templates(openfpga::Shell& shell, add_write_fabric_io_info_command_template( shell, openfpga_setup_cmd_class, cmd_dependency_write_fabric_io_info, hidden); + + /******************************** + * Command 'rename_modules' + */ + /* The 'rename_modules' command should NOT be executed before + * 'build_fabric' */ + std::vector cmd_dependency_rename_modules; + cmd_dependency_rename_modules.push_back(build_fabric_cmd_id); + add_rename_modules_command_template(shell, openfpga_setup_cmd_class, + cmd_dependency_rename_modules, hidden); + + /******************************** + * Command 'write_module_naming_rules' + */ + /* The 'write_module_naming_rules' command should NOT be executed before + * 'build_fabric' */ + std::vector cmd_dependency_write_module_naming_rules; + cmd_dependency_write_module_naming_rules.push_back(build_fabric_cmd_id); + add_write_module_naming_rules_command_template( + shell, openfpga_setup_cmd_class, cmd_dependency_write_module_naming_rules, + hidden); } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_verilog_command_template.h b/openfpga/src/base/openfpga_verilog_command_template.h index fa40faff9..6b27dd5e1 100644 --- a/openfpga/src/base/openfpga_verilog_command_template.h +++ b/openfpga/src/base/openfpga_verilog_command_template.h @@ -265,6 +265,131 @@ ShellCommandId add_write_preconfigured_fabric_wrapper_command_template( return shell_cmd_id; } +/******************************************************************** + * - add a command to shell environment: write a template of testbench + * - add associated options + * - add command dependency + *******************************************************************/ +template +ShellCommandId add_write_testbench_template_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_testbench_template"); + + /* add an option '--file' in short '-f'*/ + CommandOptionId output_opt = shell_cmd.add_option( + "file", true, "specify the file path to output the content"); + shell_cmd.set_option_short_name(output_opt, "f"); + shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); + + /* add an option '--top_module'*/ + CommandOptionId top_module_opt = + shell_cmd.add_option("top_module", false, + "specify the top-level module name to be used in the " + "testbench. Please avoid reserved words, i.e., " + "fpga_top or fpga_core. By default, it is top_tb."); + shell_cmd.set_option_require_value(top_module_opt, openfpga::OPT_STRING); + + /* add an option '--dut_module'*/ + CommandOptionId dut_module_opt = shell_cmd.add_option( + "dut_module", false, + "specify the module name of DUT to be used in the testbench. Can be either " + "fpga_top or fpga_core. By default, it is fpga_top."); + shell_cmd.set_option_require_value(dut_module_opt, openfpga::OPT_STRING); + + /* add an option '--explicit_port_mapping' */ + shell_cmd.add_option("explicit_port_mapping", false, + "use explicit port mapping in verilog netlists"); + + /* Add an option '--default_net_type' */ + CommandOptionId default_net_type_opt = shell_cmd.add_option( + "default_net_type", false, + "Set the default net type for Verilog netlists. Default value is 'none'"); + shell_cmd.set_option_require_value(default_net_type_opt, + openfpga::OPT_STRING); + + /* Add an option '--no_time_stamp' */ + shell_cmd.add_option("no_time_stamp", false, + "Do not print a time stamp in the output files"); + + /* add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "enable verbose output"); + + /* add command to the shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, + "generate a template of testbench for a pre-configured fpga fabric", + hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function(shell_cmd_id, + write_testbench_template_template); + + /* add command dependency to the shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + +/******************************************************************** + * - add a command to shell environment: write testbench io connection + * - add associated options + * - add command dependency + *******************************************************************/ +template +ShellCommandId add_write_testbench_io_connection_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_testbench_io_connection"); + + /* add an option '--file' in short '-f'*/ + CommandOptionId output_opt = shell_cmd.add_option( + "file", true, "specify the file path to output the content"); + shell_cmd.set_option_short_name(output_opt, "f"); + shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); + + /* add an option '--dut_module'*/ + CommandOptionId dut_module_opt = shell_cmd.add_option( + "dut_module", false, + "specify the module name of DUT to be used in the testbench. Can be either " + "fpga_top or fpga_core. By default, it is fpga_top."); + shell_cmd.set_option_require_value(dut_module_opt, openfpga::OPT_STRING); + + /* add an option '--pin_constraints_file in short '-pcf' */ + CommandOptionId pcf_opt = + shell_cmd.add_option("pin_constraints_file", false, + "specify the file path to the pin constraints"); + shell_cmd.set_option_short_name(pcf_opt, "pcf"); + shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); + + /* add an option '--bus_group_file in short '-bgf' */ + CommandOptionId bgf_opt = shell_cmd.add_option( + "bus_group_file", false, "specify the file path to the group pins to bus"); + shell_cmd.set_option_short_name(bgf_opt, "bgf"); + shell_cmd.set_option_require_value(bgf_opt, openfpga::OPT_STRING); + + /* Add an option '--no_time_stamp' */ + shell_cmd.add_option("no_time_stamp", false, + "Do not print a time stamp in the output files"); + + /* add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "enable verbose output"); + + /* add command to the shell */ + ShellCommandId shell_cmd_id = + shell.add_command(shell_cmd, + "generate a file to describe the connection to I/Os of a " + "pre-configured fpga fabric", + hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function(shell_cmd_id, + write_testbench_io_connection_template); + + /* add command dependency to the shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + /******************************************************************** * - add a command to shell environment: write mock fpga wrapper * - add associated options @@ -525,6 +650,28 @@ void add_verilog_command_templates(openfpga::Shell& shell, shell, openfpga_verilog_cmd_class, preconfig_wrapper_dependent_cmds, hidden); + /******************************** + * Command 'write_testbench_template' + */ + /* The command 'write_testbench_template' should NOT be executed + * before 'build_fabric' */ + std::vector testbench_template_dependent_cmds; + testbench_template_dependent_cmds.push_back(build_fabric_cmd_id); + add_write_testbench_template_command_template( + shell, openfpga_verilog_cmd_class, testbench_template_dependent_cmds, + hidden); + + /******************************** + * Command 'write_testbench_io_connection' + */ + /* The command 'write_testbench_io_connection' should NOT be executed + * before 'build_fabric' */ + std::vector testbench_io_conkt_dependent_cmds; + testbench_io_conkt_dependent_cmds.push_back(build_fabric_cmd_id); + add_write_testbench_io_connection_command_template( + shell, openfpga_verilog_cmd_class, testbench_io_conkt_dependent_cmds, + hidden); + /******************************** * Command 'write_mock_fpga_wrapper' */ diff --git a/openfpga/src/base/openfpga_verilog_template.h b/openfpga/src/base/openfpga_verilog_template.h index 32cb09ee0..66070a777 100644 --- a/openfpga/src/base/openfpga_verilog_template.h +++ b/openfpga/src/base/openfpga_verilog_template.h @@ -63,7 +63,7 @@ int write_fabric_verilog_template(T& openfpga_ctx, const Command& cmd, openfpga_ctx.blwl_shift_register_banks(), openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), openfpga_ctx.decoder_lib(), g_vpr_ctx.device(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(), - openfpga_ctx.fabric_tile(), options); + openfpga_ctx.fabric_tile(), openfpga_ctx.module_name_map(), options); } /******************************************************************** @@ -138,7 +138,7 @@ int write_full_testbench_template(const T& openfpga_ctx, const Command& cmd, g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, cmd_context.option_value(cmd, opt_bitstream), openfpga_ctx.io_location_map(), openfpga_ctx.io_name_map(), - openfpga_ctx.fabric_global_port_info(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, openfpga_ctx.simulation_setting(), openfpga_ctx.arch().config_protocol, options); @@ -212,11 +212,103 @@ int write_preconfigured_fabric_wrapper_template( openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, openfpga_ctx.io_location_map(), openfpga_ctx.io_name_map(), - openfpga_ctx.fabric_global_port_info(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, openfpga_ctx.arch().config_protocol, options); } +/******************************************************************** + * A wrapper function to call the testbench template generator of + *FPGA-Verilog + *******************************************************************/ +template +int write_testbench_template_template(const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_output_dir = cmd.option("file"); + CommandOptionId opt_top_module = cmd.option("top_module"); + CommandOptionId opt_dut_module = cmd.option("dut_module"); + CommandOptionId opt_explicit_port_mapping = + cmd.option("explicit_port_mapping"); + CommandOptionId opt_default_net_type = cmd.option("default_net_type"); + CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* This is an intermediate data structure which is designed to modularize the + * FPGA-Verilog Keep it independent from any other outside data structures + */ + VerilogTestbenchOption options; + options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir)); + options.set_explicit_port_mapping( + cmd_context.option_enable(cmd, opt_explicit_port_mapping)); + options.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); + options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + + if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { + options.set_default_net_type( + cmd_context.option_value(cmd, opt_default_net_type)); + } + + if (true == cmd_context.option_enable(cmd, opt_dut_module)) { + options.set_dut_module(cmd_context.option_value(cmd, opt_dut_module)); + } + + if (true == cmd_context.option_enable(cmd, opt_top_module)) { + options.set_top_module(cmd_context.option_value(cmd, opt_top_module)); + } + + return fpga_verilog_template_testbench( + openfpga_ctx.module_graph(), openfpga_ctx.io_name_map(), + openfpga_ctx.module_name_map(), options); +} + +/******************************************************************** + * A wrapper function to call the testbench I/O connection generator of + *FPGA-Verilog + *******************************************************************/ +template +int write_testbench_io_connection_template(const T& openfpga_ctx, + const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_output_dir = cmd.option("file"); + CommandOptionId opt_dut_module = cmd.option("dut_module"); + CommandOptionId opt_pcf = cmd.option("pin_constraints_file"); + CommandOptionId opt_bgf = cmd.option("bus_group_file"); + CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp"); + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* This is an intermediate data structure which is designed to modularize the + * FPGA-Verilog Keep it independent from any other outside data structures + */ + VerilogTestbenchOption options; + options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir)); + options.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp)); + options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + + if (true == cmd_context.option_enable(cmd, opt_dut_module)) { + options.set_dut_module(cmd_context.option_value(cmd, opt_dut_module)); + } + + /* If pin constraints are enabled by command options, read the file */ + PinConstraints pin_constraints; + if (true == cmd_context.option_enable(cmd, opt_pcf)) { + pin_constraints = + read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); + } + + /* If bug group file are enabled by command options, read the file */ + BusGroup bus_group; + if (true == cmd_context.option_enable(cmd, opt_bgf)) { + bus_group = + read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str()); + } + + return fpga_verilog_testbench_io_connection( + openfpga_ctx.module_graph(), g_vpr_ctx.atom(), g_vpr_ctx.placement(), + pin_constraints, bus_group, openfpga_ctx.io_location_map(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_global_port_info(), + openfpga_ctx.vpr_netlist_annotation(), options); +} + /******************************************************************** * A wrapper function to call the mock fpga wrapper generator of *FPGA-Verilog @@ -273,7 +365,8 @@ int write_mock_fpga_wrapper_template(const T& openfpga_ctx, const Command& cmd, return fpga_verilog_mock_fpga_wrapper( openfpga_ctx.module_graph(), g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, bus_group, openfpga_ctx.io_location_map(), - openfpga_ctx.io_name_map(), openfpga_ctx.fabric_global_port_info(), + openfpga_ctx.io_name_map(), openfpga_ctx.module_name_map(), + openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), options); } @@ -334,7 +427,8 @@ int write_preconfigured_testbench_template(const T& openfpga_ctx, } return fpga_verilog_preconfigured_testbench( - openfpga_ctx.module_graph(), g_vpr_ctx.atom(), pin_constraints, bus_group, + openfpga_ctx.module_graph(), openfpga_ctx.module_name_map(), + g_vpr_ctx.atom(), pin_constraints, bus_group, openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.simulation_setting(), options); diff --git a/openfpga/src/fabric/build_device_module.cpp b/openfpga/src/fabric/build_device_module.cpp index 5279c9fc7..012e3a529 100644 --- a/openfpga/src/fabric/build_device_module.cpp +++ b/openfpga/src/fabric/build_device_module.cpp @@ -23,6 +23,7 @@ #include "build_wire_modules.h" #include "command_exit_codes.h" #include "openfpga_naming.h" +#include "rename_modules.h" /* begin namespace openfpga */ namespace openfpga { @@ -34,10 +35,11 @@ namespace openfpga { int build_device_module_graph( ModuleManager& module_manager, DecoderLibrary& decoder_lib, MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile, - const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, - const bool& frame_view, const bool& compress_routing, - const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const TileConfig& tile_config, const bool& group_config_block, + ModuleNameMap& module_name_map, const OpenfpgaContext& openfpga_ctx, + const DeviceContext& vpr_device_ctx, const bool& frame_view, + const bool& compress_routing, const bool& duplicate_grid_pin, + const FabricKey& fabric_key, const TileConfig& tile_config, + const bool& group_config_block, const bool& name_module_using_index, const bool& generate_random_fabric_key, const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build fabric module graph"); @@ -85,8 +87,9 @@ int build_device_module_graph( status = build_grid_modules( module_manager, decoder_lib, vpr_device_ctx, openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib, - openfpga_ctx.mux_lib(), openfpga_ctx.arch().config_protocol.type(), - sram_model, duplicate_grid_pin, group_config_block, verbose); + openfpga_ctx.mux_lib(), openfpga_ctx.arch().tile_annotations, + openfpga_ctx.arch().config_protocol.type(), sram_model, duplicate_grid_pin, + group_config_block, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; } @@ -122,8 +125,9 @@ int build_device_module_graph( module_manager, decoder_lib, openfpga_ctx.fabric_tile(), vpr_device_ctx.grid, openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph, - openfpga_ctx.arch().circuit_lib, sram_model, - openfpga_ctx.arch().config_protocol.type(), frame_view, verbose); + openfpga_ctx.arch().tile_annotations, openfpga_ctx.arch().circuit_lib, + sram_model, openfpga_ctx.arch().config_protocol.type(), + name_module_using_index, frame_view, verbose); } /* Build FPGA fabric top-level module */ @@ -134,8 +138,9 @@ int build_device_module_graph( openfpga_ctx.arch().tile_annotations, vpr_device_ctx.rr_graph, openfpga_ctx.device_rr_gsb(), openfpga_ctx.tile_direct(), openfpga_ctx.arch().arch_direct, openfpga_ctx.arch().config_protocol, - sram_model, fabric_tile, frame_view, compress_routing, duplicate_grid_pin, - fabric_key, generate_random_fabric_key, group_config_block, verbose); + sram_model, fabric_tile, name_module_using_index, frame_view, + compress_routing, duplicate_grid_pin, fabric_key, + generate_random_fabric_key, group_config_block, verbose); if (CMD_EXEC_FATAL_ERROR == status) { return status; @@ -151,6 +156,26 @@ int build_device_module_graph( rename_primitive_module_port_names(module_manager, openfpga_ctx.arch().circuit_lib); + /* Collect module names and initialize module name mapping */ + status = + init_fabric_module_name_map(module_name_map, module_manager, verbose); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + if (name_module_using_index) { + /* Update module name data */ + status = update_module_map_name_with_indexing_names( + module_name_map, openfpga_ctx.device_rr_gsb(), fabric_tile, verbose); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + /* Apply module naming */ + status = rename_fabric_modules(module_manager, module_name_map, verbose); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + } + return status; } diff --git a/openfpga/src/fabric/build_device_module.h b/openfpga/src/fabric/build_device_module.h index fb4178cc8..7221d202c 100644 --- a/openfpga/src/fabric/build_device_module.h +++ b/openfpga/src/fabric/build_device_module.h @@ -7,6 +7,7 @@ #include "fabric_key.h" #include "fabric_tile.h" #include "io_name_map.h" +#include "module_name_map.h" #include "openfpga_context.h" #include "tile_config.h" #include "vpr_context.h" @@ -21,10 +22,11 @@ namespace openfpga { int build_device_module_graph( ModuleManager& module_manager, DecoderLibrary& decoder_lib, MemoryBankShiftRegisterBanks& blwl_sr_banks, FabricTile& fabric_tile, - const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx, - const bool& frame_view, const bool& compress_routing, - const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const TileConfig& tile_config, const bool& group_config_block, + ModuleNameMap& module_name_map, const OpenfpgaContext& openfpga_ctx, + const DeviceContext& vpr_device_ctx, const bool& frame_view, + const bool& compress_routing, const bool& duplicate_grid_pin, + const FabricKey& fabric_key, const TileConfig& tile_config, + const bool& group_config_block, const bool& name_module_using_index, const bool& generate_random_fabric_key, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_fpga_core_wrapper_module.cpp b/openfpga/src/fabric/build_fpga_core_wrapper_module.cpp index d8af89dc5..a118dbe83 100644 --- a/openfpga/src/fabric/build_fpga_core_wrapper_module.cpp +++ b/openfpga/src/fabric/build_fpga_core_wrapper_module.cpp @@ -333,6 +333,7 @@ static int create_fpga_top_module_using_naming_rules( * - Create a wrapper module 'fpga_top' on the fpga_core *******************************************************************/ int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, + ModuleNameMap& module_name_map, const IoNameMap& io_naming, const std::string& core_inst_name, const bool& frame_view, @@ -340,7 +341,8 @@ int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, int status = CMD_EXEC_SUCCESS; /* Execute the module graph api */ - std::string top_module_name = generate_fpga_top_module_name(); + std::string top_module_name = + module_name_map.name(generate_fpga_top_module_name()); ModuleId top_module = module_manager.find_module(top_module_name); if (!module_manager.valid_module_id(top_module)) { return CMD_EXEC_FATAL_ERROR; @@ -379,6 +381,17 @@ int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, VTR_LOGV(verbose, "Created a wrapper module '%s' on top of '%s'\n", top_module_name.c_str(), core_module_name.c_str()); + /* Update module name map */ + status = + module_name_map.set_tag_to_name_pair(core_module_name, core_module_name); + if (CMD_EXEC_SUCCESS != status) { + VTR_LOG_ERROR( + "Failed to register fpga core module '%s' in module name map!\n", + core_module_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + VTR_LOGV(verbose, "Updated module name map\n"); + /* Now fpga_core should be the only configurable child under the top-level * module */ module_manager.add_configurable_child( diff --git a/openfpga/src/fabric/build_fpga_core_wrapper_module.h b/openfpga/src/fabric/build_fpga_core_wrapper_module.h index 3520f6d8b..3c068db56 100644 --- a/openfpga/src/fabric/build_fpga_core_wrapper_module.h +++ b/openfpga/src/fabric/build_fpga_core_wrapper_module.h @@ -8,6 +8,7 @@ #include "io_name_map.h" #include "module_manager.h" +#include "module_name_map.h" /******************************************************************** * Function declaration @@ -17,6 +18,7 @@ namespace openfpga { int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, + ModuleNameMap& module_name_map, const IoNameMap& io_naming, const std::string& core_inst_name, const bool& frame_view, diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp index 77f4024db..cae215259 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp @@ -54,7 +54,8 @@ namespace openfpga { void add_grid_module_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(false == is_empty_type(grid_type_descriptor)); @@ -109,6 +110,17 @@ void add_grid_module_duplicated_pb_type_ports( (0. == find_physical_tile_pin_Fc(grid_type_descriptor, ipin)))) { std::string port_name = generate_grid_port_name( iwidth, iheight, subtile_index, side, pin_info); + /* If the port is required to be merged, we deposit zero as subtile + * index */ + if (tile_annotation.is_tile_port_to_merge( + std::string(grid_type_descriptor->name), + pin_info.get_name())) { + if (subtile_index == 0) { + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } else { + continue; + } + } BasicPort grid_port(port_name, 0, 0); /* Add the port to the module */ module_manager.add_port(grid_module, grid_port, @@ -297,7 +309,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const ModuleId& child_module, const size_t& child_instance, const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(false == is_empty_type(grid_type_descriptor)); @@ -314,8 +327,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->input_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } @@ -336,8 +349,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->clock_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } } diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.h b/openfpga/src/fabric/build_grid_module_duplicated_pins.h index 66e1a5634..4f2eafee2 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.h +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.h @@ -7,6 +7,7 @@ #include "module_manager.h" #include "openfpga_side_manager.h" #include "physical_types.h" +#include "tile_annotation.h" #include "vpr_device_annotation.h" /******************************************************************** @@ -19,13 +20,15 @@ namespace openfpga { void add_grid_module_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side); + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side); void add_grid_module_nets_connect_duplicated_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const ModuleId& child_module, const size_t& child_instance, const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side); + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_grid_module_utils.cpp b/openfpga/src/fabric/build_grid_module_utils.cpp index c79262805..3b3f14203 100644 --- a/openfpga/src/fabric/build_grid_module_utils.cpp +++ b/openfpga/src/fabric/build_grid_module_utils.cpp @@ -45,7 +45,8 @@ void add_grid_module_net_connect_pb_graph_pin( const ModuleId& child_module, const size_t& child_instance, const size_t& child_inst_subtile_index, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, t_pb_graph_pin* pb_graph_pin, + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, t_pb_graph_pin* pb_graph_pin, const e_side& border_side, const e_pin2pin_interc_type& pin2pin_interc_type) { /* Find the pin side for I/O grids*/ std::vector grid_pin_sides; @@ -91,6 +92,13 @@ void add_grid_module_net_connect_pb_graph_pin( subtile_index < grid_type_descriptor->capacity); std::string grid_port_name = generate_grid_port_name( pin_width, pin_height, subtile_index, side, pin_info); + /* If the port is required to be merged, we only consider the source port to + * be the subtile index of 0 */ + if (tile_annotation.is_tile_port_to_merge( + std::string(grid_type_descriptor->name), pin_info.get_name())) { + /* Exception: use top side for these merged ports */ + grid_port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } ModulePortId grid_module_port_id = module_manager.find_module_port(grid_module, grid_port_name); VTR_ASSERT(true == module_manager.valid_module_port_id( diff --git a/openfpga/src/fabric/build_grid_module_utils.h b/openfpga/src/fabric/build_grid_module_utils.h index c1f0549dd..a8d5f9d12 100644 --- a/openfpga/src/fabric/build_grid_module_utils.h +++ b/openfpga/src/fabric/build_grid_module_utils.h @@ -8,6 +8,7 @@ #include "module_manager.h" #include "openfpga_interconnect_types.h" #include "physical_types.h" +#include "tile_annotation.h" #include "vpr_device_annotation.h" /******************************************************************** @@ -25,7 +26,8 @@ void add_grid_module_net_connect_pb_graph_pin( const ModuleId& child_module, const size_t& child_instance, const size_t& child_inst_subtile_index, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, t_pb_graph_pin* pb_graph_pin, + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, t_pb_graph_pin* pb_graph_pin, const e_side& border_side, const enum e_pin2pin_interc_type& pin2pin_interc_type); diff --git a/openfpga/src/fabric/build_grid_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index bf8ca86ac..94b9d884c 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -41,7 +41,8 @@ namespace openfpga { static void add_grid_module_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(nullptr != grid_type_descriptor); @@ -90,6 +91,16 @@ static void add_grid_module_pb_type_ports( subtile_index < grid_type_descriptor->capacity); std::string port_name = generate_grid_port_name( iwidth, iheight, subtile_index, side, pin_info); + /* If the port is required to be merged, we use a special index + * index */ + if (tile_annotation.is_tile_port_to_merge( + std::string(grid_type_descriptor->name), pin_info.get_name())) { + if (subtile_index == 0) { + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } else { + continue; + } + } BasicPort grid_port(port_name, 0, 0); /* Add the port to the module */ module_manager.add_port(grid_module, grid_port, @@ -111,7 +122,8 @@ static void add_grid_module_nets_connect_pb_type_ports( ModuleManager& module_manager, const ModuleId& grid_module, const ModuleId& child_module, const size_t& child_instance, const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation, - t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) { + t_physical_tile_type_ptr grid_type_descriptor, + const TileAnnotation& tile_annotation, const e_side& border_side) { /* Ensure that we have a valid grid_type_descriptor */ VTR_ASSERT(nullptr != grid_type_descriptor); @@ -129,8 +141,8 @@ static void add_grid_module_nets_connect_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->input_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } @@ -140,8 +152,8 @@ static void add_grid_module_nets_connect_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->output_pins[iport][ipin]), border_side, - OUTPUT2OUTPUT_INTERC); + tile_annotation, &(top_pb_graph_node->output_pins[iport][ipin]), + border_side, OUTPUT2OUTPUT_INTERC); } } @@ -151,8 +163,8 @@ static void add_grid_module_nets_connect_pb_type_ports( add_grid_module_net_connect_pb_graph_pin( module_manager, grid_module, child_module, child_instance, child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor, - &(top_pb_graph_node->clock_pins[iport][ipin]), border_side, - INPUT2INPUT_INTERC); + tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]), + border_side, INPUT2INPUT_INTERC); } } } @@ -1151,8 +1163,9 @@ static int build_physical_tile_module( const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type, - const e_side& border_side, const bool& duplicate_grid_pin, - const bool& group_config_block, const bool& verbose) { + const TileAnnotation& tile_annotation, const e_side& border_side, + const bool& duplicate_grid_pin, const bool& group_config_block, + const bool& verbose) { int status = CMD_EXEC_SUCCESS; /* Create a Module for the top-level physical block, and add to module manager */ @@ -1219,7 +1232,7 @@ static int build_physical_tile_module( /* TODO: Add a physical memory block */ if (group_config_block) { status = add_physical_memory_module(module_manager, decoder_lib, - grid_module, circuit_lib, + grid_module, std::string(), circuit_lib, sram_orgz_type, sram_model, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; @@ -1231,7 +1244,7 @@ static int build_physical_tile_module( /* Default way to add these ports by following the definition in pb_types */ add_grid_module_pb_type_ports(module_manager, grid_module, vpr_device_annotation, phy_block_type, - border_side); + tile_annotation, border_side); /* Add module nets to connect the pb_type ports to sub modules */ for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) { VTR_ASSERT(sub_tile.equivalent_sites.size() == 1); @@ -1248,15 +1261,15 @@ static int build_physical_tile_module( module_manager.child_module_instances(grid_module, pb_module)) { add_grid_module_nets_connect_pb_type_ports( module_manager, grid_module, pb_module, child_instance, sub_tile, - vpr_device_annotation, phy_block_type, border_side); + vpr_device_annotation, phy_block_type, tile_annotation, border_side); } } } else { VTR_ASSERT_SAFE(true == duplicate_grid_pin); /* Add these ports with duplication */ - add_grid_module_duplicated_pb_type_ports(module_manager, grid_module, - vpr_device_annotation, - phy_block_type, border_side); + add_grid_module_duplicated_pb_type_ports( + module_manager, grid_module, vpr_device_annotation, phy_block_type, + tile_annotation, border_side); /* Add module nets to connect the duplicated pb_type ports to sub modules */ for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) { @@ -1274,7 +1287,7 @@ static int build_physical_tile_module( module_manager.child_module_instances(grid_module, pb_module)) { add_grid_module_nets_connect_duplicated_pb_type_ports( module_manager, grid_module, pb_module, child_instance, sub_tile, - vpr_device_annotation, phy_block_type, border_side); + vpr_device_annotation, phy_block_type, tile_annotation, border_side); } } } @@ -1357,6 +1370,7 @@ int build_grid_modules( ModuleManager& module_manager, DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const TileAnnotation& tile_annotation, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, const bool& duplicate_grid_pin, const bool& group_config_block, const bool& verbose) { @@ -1414,8 +1428,8 @@ int build_grid_modules( for (const e_side& io_type_side : io_type_sides) { status = build_physical_tile_module( module_manager, decoder_lib, device_annotation, circuit_lib, - sram_orgz_type, sram_model, &physical_tile, io_type_side, - duplicate_grid_pin, group_config_block, verbose); + sram_orgz_type, sram_model, &physical_tile, tile_annotation, + io_type_side, duplicate_grid_pin, group_config_block, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1424,7 +1438,7 @@ int build_grid_modules( /* For CLB and heterogenenous blocks */ status = build_physical_tile_module( module_manager, decoder_lib, device_annotation, circuit_lib, - sram_orgz_type, sram_model, &physical_tile, NUM_SIDES, + sram_orgz_type, sram_model, &physical_tile, tile_annotation, NUM_SIDES, duplicate_grid_pin, group_config_block, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; diff --git a/openfpga/src/fabric/build_grid_modules.h b/openfpga/src/fabric/build_grid_modules.h index d83cc3ac3..996b9bda2 100644 --- a/openfpga/src/fabric/build_grid_modules.h +++ b/openfpga/src/fabric/build_grid_modules.h @@ -7,6 +7,7 @@ #include "decoder_library.h" #include "module_manager.h" #include "mux_library.h" +#include "tile_annotation.h" #include "vpr_context.h" #include "vpr_device_annotation.h" @@ -21,6 +22,7 @@ int build_grid_modules( ModuleManager& module_manager, DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const TileAnnotation& tile_annotation, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, const bool& duplicate_grid_pin, const bool& group_config_block, const bool& verbose); diff --git a/openfpga/src/fabric/build_memory_modules.cpp b/openfpga/src/fabric/build_memory_modules.cpp index 80899a04c..6ac58ba21 100644 --- a/openfpga/src/fabric/build_memory_modules.cpp +++ b/openfpga/src/fabric/build_memory_modules.cpp @@ -1486,6 +1486,7 @@ int build_memory_group_module( int add_physical_memory_module(ModuleManager& module_manager, DecoderLibrary& decoder_lib, const ModuleId& curr_module, + const std::string& suggested_module_name_prefix, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, @@ -1509,8 +1510,12 @@ int add_physical_memory_module(ModuleManager& module_manager, if (module_num_config_bits == 0) { return CMD_EXEC_SUCCESS; } + std::string module_name_prefix = module_manager.module_name(curr_module); + if (!suggested_module_name_prefix.empty()) { + module_name_prefix = suggested_module_name_prefix; + } std::string phy_mem_module_name = generate_physical_memory_module_name( - module_manager.module_name(curr_module), module_num_config_bits); + module_name_prefix, module_num_config_bits); VTR_LOGV(verbose, "Adding memory group module '%s' as a child to '%s'...\n", phy_mem_module_name.c_str(), module_manager.module_name(curr_module).c_str()); diff --git a/openfpga/src/fabric/build_memory_modules.h b/openfpga/src/fabric/build_memory_modules.h index b79fd4b90..e66a70656 100644 --- a/openfpga/src/fabric/build_memory_modules.h +++ b/openfpga/src/fabric/build_memory_modules.h @@ -41,6 +41,7 @@ int build_memory_group_module( int add_physical_memory_module(ModuleManager& module_manager, DecoderLibrary& decoder_lib, const ModuleId& curr_module, + const std::string& suggested_module_name_prefix, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, const CircuitModelId& sram_model, diff --git a/openfpga/src/fabric/build_routing_modules.cpp b/openfpga/src/fabric/build_routing_modules.cpp index 1f12774c5..d552a611c 100644 --- a/openfpga/src/fabric/build_routing_modules.cpp +++ b/openfpga/src/fabric/build_routing_modules.cpp @@ -384,8 +384,8 @@ static void build_switch_block_module( const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids, const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, - const CircuitModelId& sram_model, const RRGSB& rr_gsb, - const bool& group_config_block, const bool& verbose) { + const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, + const RRGSB& rr_gsb, const bool& group_config_block, const bool& verbose) { /* Create a Module of Switch Block and add to module manager */ vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); ModuleId sb_module = module_manager.add_module( @@ -494,9 +494,12 @@ static void build_switch_block_module( /* Build a physical memory block */ if (group_config_block) { + std::string mem_module_name_prefix = + generate_switch_block_module_name_using_index( + device_rr_gsb.get_sb_unique_module_index(gsb_coordinate)); add_physical_memory_module(module_manager, decoder_lib, sb_module, - circuit_lib, sram_orgz_type, sram_model, - verbose); + mem_module_name_prefix, circuit_lib, + sram_orgz_type, sram_model, verbose); } /* Add global ports to the pb_module: @@ -891,8 +894,8 @@ static void build_connection_block_module( const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids, const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib, const e_config_protocol_type& sram_orgz_type, - const CircuitModelId& sram_model, const RRGSB& rr_gsb, - const t_rr_type& cb_type, const bool& group_config_block, + const CircuitModelId& sram_model, const DeviceRRGSB& device_rr_gsb, + const RRGSB& rr_gsb, const t_rr_type& cb_type, const bool& group_config_block, const bool& verbose) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), @@ -1022,9 +1025,13 @@ static void build_connection_block_module( /* Build a physical memory block */ if (group_config_block) { + std::string mem_module_name_prefix = + generate_connection_block_module_name_using_index( + cb_type, + device_rr_gsb.get_cb_unique_module_index(cb_type, gsb_coordinate)); add_physical_memory_module(module_manager, decoder_lib, cb_module, - circuit_lib, sram_orgz_type, sram_model, - verbose); + mem_module_name_prefix, circuit_lib, + sram_orgz_type, sram_model, verbose); } /* Add global ports to the pb_module: @@ -1105,8 +1112,8 @@ static void build_flatten_connection_block_modules( } build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, - device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, rr_gsb, - cb_type, group_config_block, verbose); + device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, + device_rr_gsb, rr_gsb, cb_type, group_config_block, verbose); } } } @@ -1138,10 +1145,10 @@ void build_flatten_routing_modules( if (false == rr_gsb.is_sb_exist(device_ctx.rr_graph)) { continue; } - build_switch_block_module(module_manager, decoder_lib, device_annotation, - device_ctx.grid, device_ctx.rr_graph, - circuit_lib, sram_orgz_type, sram_model, rr_gsb, - group_config_block, verbose); + build_switch_block_module( + module_manager, decoder_lib, device_annotation, device_ctx.grid, + device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, + device_rr_gsb, rr_gsb, group_config_block, verbose); } } @@ -1181,8 +1188,8 @@ void build_unique_routing_modules( const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); build_switch_block_module(module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, - sram_orgz_type, sram_model, unique_mirror, - group_config_block, verbose); + sram_orgz_type, sram_model, device_rr_gsb, + unique_mirror, group_config_block, verbose); } /* Build unique X-direction connection block modules */ @@ -1193,7 +1200,7 @@ void build_unique_routing_modules( build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, - unique_mirror, CHANX, group_config_block, verbose); + device_rr_gsb, unique_mirror, CHANX, group_config_block, verbose); } /* Build unique X-direction connection block modules */ @@ -1204,7 +1211,7 @@ void build_unique_routing_modules( build_connection_block_module( module_manager, decoder_lib, device_annotation, device_ctx.grid, device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, - unique_mirror, CHANY, group_config_block, verbose); + device_rr_gsb, unique_mirror, CHANY, group_config_block, verbose); } } diff --git a/openfpga/src/fabric/build_tile_modules.cpp b/openfpga/src/fabric/build_tile_modules.cpp index f20215f71..caf82f075 100644 --- a/openfpga/src/fabric/build_tile_modules.cpp +++ b/openfpga/src/fabric/build_tile_modules.cpp @@ -66,8 +66,8 @@ static int build_tile_module_port_and_nets_between_sb_and_pb( const RRGSB& rr_gsb, const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, const std::vector& pb_instances, const std::vector& sb_instances, const size_t& isb, - const bool& compact_routing_hierarchy, const bool& frame_view, - const bool& verbose) { + const bool& compact_routing_hierarchy, const bool& name_module_using_index, + const bool& frame_view, const bool& verbose) { /* Skip those Switch blocks that do not exist */ if (false == rr_gsb.is_sb_exist(rr_graph)) { return CMD_EXEC_SUCCESS; @@ -200,10 +200,14 @@ static int build_tile_module_port_and_nets_between_sb_and_pb( } else { /* Create a port on the tile module and create the net if required. * Create a proper name to avoid naming conflicts */ + std::string temp_sb_module_name = generate_switch_block_module_name( + fabric_tile.sb_coordinates(fabric_tile_id)[isb]); + if (name_module_using_index) { + temp_sb_module_name = + generate_switch_block_module_name_using_index(isb); + } src_grid_port.set_name(generate_tile_module_port_name( - generate_switch_block_module_name( - fabric_tile.sb_coordinates(fabric_tile_id)[isb]), - sink_sb_port.get_name())); + temp_sb_module_name, sink_sb_port.get_name())); ModulePortId src_tile_port_id = module_manager.add_port( tile_module, src_grid_port, ModuleManager::e_module_port_type::MODULE_INPUT_PORT); @@ -296,7 +300,8 @@ static int build_tile_module_port_and_nets_between_cb_and_pb( const std::vector& pb_instances, const std::map>& cb_instances, const size_t& icb, const bool& compact_routing_hierarchy, - const bool& frame_view, const bool& verbose) { + const bool& name_module_using_index, const bool& frame_view, + const bool& verbose) { size_t cb_instance = cb_instances.at(cb_type)[icb]; /* We could have two different coordinators, one is the instance, the other is * the module */ @@ -422,13 +427,16 @@ static int build_tile_module_port_and_nets_between_cb_and_pb( } } } else { - /* Create a port on the tile module and create the net if required. - * FIXME: Create a proper name to avoid naming conflicts */ + /* Create a port on the tile module and create the net if required. */ const RRGSB& cb_inst_rr_gsb = device_rr_gsb.get_gsb( fabric_tile.cb_coordinates(fabric_tile_id, cb_type)[icb]); std::string cb_instance_name_in_tile = generate_connection_block_module_name( cb_type, cb_inst_rr_gsb.get_cb_coordinate(cb_type)); + if (name_module_using_index) { + cb_instance_name_in_tile = + generate_connection_block_module_name_using_index(cb_type, icb); + } src_cb_port.set_name(generate_tile_module_port_name( cb_instance_name_in_tile, src_cb_port.get_name())); ModulePortId sink_tile_port_id = module_manager.add_port( @@ -504,8 +512,8 @@ static int build_tile_module_port_and_nets_between_sb_and_cb( const FabricTileId& fabric_tile_id, const std::map>& cb_instances, const std::vector& sb_instances, const size_t& isb, - const bool& compact_routing_hierarchy, const bool& frame_view, - const bool& verbose) { + const bool& compact_routing_hierarchy, const bool& name_module_using_index, + const bool& frame_view, const bool& verbose) { size_t sb_instance = sb_instances[isb]; /* We could have two different coordinators, one is the instance, the other is * the module */ @@ -684,16 +692,19 @@ static int build_tile_module_port_and_nets_between_sb_and_cb( /* Create input and output ports */ std::string chan_input_port_name = generate_sb_module_track_port_name( cb_type, side_manager.get_side(), IN_PORT); - /* Create a port on the tile module and create the net if required. FIXME: - * Create a proper name to avoid naming conflicts */ + /* Create a port on the tile module and create the net if required. */ ModulePortId sb_chan_input_port_id = module_manager.find_module_port(sb_module_id, chan_input_port_name); BasicPort chan_input_port = module_manager.module_port(sb_module_id, sb_chan_input_port_id); + std::string temp_sb_module_name = generate_switch_block_module_name( + fabric_tile.sb_coordinates(fabric_tile_id)[isb]); + if (name_module_using_index) { + temp_sb_module_name = + generate_switch_block_module_name_using_index(isb); + } chan_input_port.set_name(generate_tile_module_port_name( - generate_switch_block_module_name( - fabric_tile.sb_coordinates(fabric_tile_id)[isb]), - chan_input_port.get_name())); + temp_sb_module_name, chan_input_port.get_name())); ModulePortId tile_chan_input_port_id = module_manager.add_port( tile_module, chan_input_port, ModuleManager::e_module_port_type::MODULE_INPUT_PORT); @@ -724,9 +735,7 @@ static int build_tile_module_port_and_nets_between_sb_and_cb( BasicPort chan_output_port = module_manager.module_port(sb_module_id, sb_chan_output_port_id); chan_output_port.set_name(generate_tile_module_port_name( - generate_switch_block_module_name( - fabric_tile.sb_coordinates(fabric_tile_id)[isb]), - chan_output_port.get_name())); + temp_sb_module_name, chan_output_port.get_name())); ModulePortId tile_chan_output_port_id = module_manager.add_port( tile_module, chan_output_port, ModuleManager::e_module_port_type::MODULE_OUTPUT_PORT); @@ -866,7 +875,8 @@ static int build_tile_module_ports_from_cb( const t_rr_type& cb_type, const std::map>& cb_instances, const size_t& icb, const bool& compact_routing_hierarchy, - const bool& frame_view, const bool& verbose) { + const bool& name_module_using_index, const bool& frame_view, + const bool& verbose) { int status = CMD_EXEC_SUCCESS; size_t cb_instance = cb_instances.at(cb_type)[icb]; @@ -909,6 +919,10 @@ static int build_tile_module_ports_from_cb( const RRGSB& unique_rr_gsb = device_rr_gsb.get_gsb(cb_coord_in_unique_tile); std::string cb_instance_name_in_tile = generate_connection_block_module_name( cb_type, unique_rr_gsb.get_cb_coordinate(cb_type)); + if (name_module_using_index) { + cb_instance_name_in_tile = + generate_connection_block_module_name_using_index(cb_type, icb); + } vtr::Point tile_coord = fabric_tile.tile_coordinate(curr_fabric_tile_id); @@ -990,9 +1004,10 @@ static int build_tile_port_and_nets_from_pb( ModuleManager& module_manager, const ModuleId& tile_module, const DeviceGrid& grids, const size_t& layer, const VprDeviceAnnotation& vpr_device_annotation, const RRGraphView& rr_graph, - const vtr::Point& pb_coord, const std::vector& pb_instances, - const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id, - const size_t& ipb, const bool& frame_view, const bool& verbose) { + const TileAnnotation& tile_annotation, const vtr::Point& pb_coord, + const std::vector& pb_instances, const FabricTile& fabric_tile, + const FabricTileId& curr_fabric_tile_id, const size_t& ipb, + const bool& frame_view, const bool& verbose) { size_t pb_instance = pb_instances[ipb]; t_physical_tile_type_ptr phy_tile = grids.get_physical_type( t_physical_tile_loc(pb_coord.x(), pb_coord.y(), layer)); @@ -1051,6 +1066,14 @@ static int build_tile_port_and_nets_from_pb( subtile_index < phy_tile->capacity); std::string port_name = generate_grid_port_name( iwidth, iheight, subtile_index, side, pin_info); + if (tile_annotation.is_tile_port_to_merge(std::string(phy_tile->name), + pin_info.get_name())) { + if (subtile_index == 0) { + port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info); + } else { + continue; + } + } BasicPort pb_port(port_name, 0, 0); ModulePortId pb_module_port_id = module_manager.find_module_port(pb_module, port_name); @@ -1179,11 +1202,11 @@ static int build_tile_module_ports_and_nets( const DeviceGrid& grids, const size_t& layer, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, - const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, - const std::vector& pb_instances, + const TileAnnotation& tile_annotation, const FabricTile& fabric_tile, + const FabricTileId& fabric_tile_id, const std::vector& pb_instances, const std::map>& cb_instances, - const std::vector& sb_instances, const bool& frame_view, - const bool& verbose) { + const std::vector& sb_instances, const bool& name_module_using_index, + const bool& frame_view, const bool& verbose) { int status_code = CMD_EXEC_SUCCESS; /* Get the submodule of Switch blocks one by one, build connections between sb @@ -1196,7 +1219,8 @@ static int build_tile_module_ports_and_nets( status_code = build_tile_module_port_and_nets_between_sb_and_pb( module_manager, tile_module, grids, layer, vpr_device_annotation, device_rr_gsb, rr_graph_view, rr_gsb, fabric_tile, fabric_tile_id, - pb_instances, sb_instances, isb, true, frame_view, verbose); + pb_instances, sb_instances, isb, true, name_module_using_index, + frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1213,7 +1237,8 @@ static int build_tile_module_ports_and_nets( status_code = build_tile_module_port_and_nets_between_cb_and_pb( module_manager, tile_module, grids, layer, vpr_device_annotation, device_rr_gsb, rr_graph_view, rr_gsb, fabric_tile, fabric_tile_id, - cb_type, pb_instances, cb_instances, icb, true, frame_view, verbose); + cb_type, pb_instances, cb_instances, icb, true, name_module_using_index, + frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1230,7 +1255,7 @@ static int build_tile_module_ports_and_nets( status_code = build_tile_module_port_and_nets_between_sb_and_cb( module_manager, tile_module, device_rr_gsb, rr_graph_view, rr_gsb, fabric_tile, fabric_tile_id, cb_instances, sb_instances, isb, true, - frame_view, verbose); + name_module_using_index, frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1243,8 +1268,8 @@ static int build_tile_module_ports_and_nets( fabric_tile.pb_coordinates(fabric_tile_id)[ipb]; status_code = build_tile_port_and_nets_from_pb( module_manager, tile_module, grids, layer, vpr_device_annotation, - rr_graph_view, pb_coord, pb_instances, fabric_tile, fabric_tile_id, ipb, - frame_view, verbose); + rr_graph_view, tile_annotation, pb_coord, pb_instances, fabric_tile, + fabric_tile_id, ipb, frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1262,7 +1287,8 @@ static int build_tile_module_ports_and_nets( /* Build any ports missing from connection blocks */ status_code = build_tile_module_ports_from_cb( module_manager, tile_module, device_rr_gsb, rr_gsb, fabric_tile, - fabric_tile_id, cb_type, cb_instances, icb, true, frame_view, verbose); + fabric_tile_id, cb_type, cb_instances, icb, true, + name_module_using_index, frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1286,8 +1312,10 @@ static int build_tile_module( const DeviceGrid& grids, const size_t& layer, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, - const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, - const e_config_protocol_type& sram_orgz_type, const bool& frame_view, + const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib, + const CircuitModelId& sram_model, + const e_config_protocol_type& sram_orgz_type, + const bool& name_module_using_index, const bool& frame_view, const bool& verbose) { int status_code = CMD_EXEC_SUCCESS; @@ -1433,8 +1461,9 @@ static int build_tile_module( /* Add module nets and ports */ status_code = build_tile_module_ports_and_nets( module_manager, tile_module, grids, layer, vpr_device_annotation, - device_rr_gsb, rr_graph_view, fabric_tile, fabric_tile_id, pb_instances, - cb_instances, sb_instances, frame_view, verbose); + device_rr_gsb, rr_graph_view, tile_annotation, fabric_tile, fabric_tile_id, + pb_instances, cb_instances, sb_instances, name_module_using_index, + frame_view, verbose); /* Add global ports to the pb_module: * This is a much easier job after adding sub modules (instances), @@ -1503,9 +1532,11 @@ int build_tile_modules(ModuleManager& module_manager, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, + const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, const e_config_protocol_type& sram_orgz_type, + const bool& name_module_using_index, const bool& frame_view, const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build tile modules for the FPGA fabric"); @@ -1517,8 +1548,9 @@ int build_tile_modules(ModuleManager& module_manager, for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) { status_code = build_tile_module( module_manager, decoder_lib, fabric_tile, fabric_tile_id, grids, layer, - vpr_device_annotation, device_rr_gsb, rr_graph_view, circuit_lib, - sram_model, sram_orgz_type, frame_view, verbose); + vpr_device_annotation, device_rr_gsb, rr_graph_view, tile_annotation, + circuit_lib, sram_model, sram_orgz_type, name_module_using_index, + frame_view, verbose); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } diff --git a/openfpga/src/fabric/build_tile_modules.h b/openfpga/src/fabric/build_tile_modules.h index 0513d9850..83f219610 100644 --- a/openfpga/src/fabric/build_tile_modules.h +++ b/openfpga/src/fabric/build_tile_modules.h @@ -15,6 +15,7 @@ #include "fabric_tile.h" #include "module_manager.h" #include "rr_graph_view.h" +#include "tile_annotation.h" #include "vpr_device_annotation.h" /******************************************************************** @@ -30,9 +31,11 @@ int build_tile_modules(ModuleManager& module_manager, const VprDeviceAnnotation& vpr_device_annotation, const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view, + const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, const e_config_protocol_type& sram_orgz_type, + const bool& name_module_using_index, const bool& frame_view, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp index 5d668f2f2..238004e4d 100644 --- a/openfpga/src/fabric/build_top_module.cpp +++ b/openfpga/src/fabric/build_top_module.cpp @@ -55,10 +55,10 @@ int build_top_module( const DeviceRRGSB& device_rr_gsb, const TileDirect& tile_direct, const ArchDirect& arch_direct, const ConfigProtocol& config_protocol, const CircuitModelId& sram_model, const FabricTile& fabric_tile, - const bool& frame_view, const bool& compact_routing_hierarchy, - const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const bool& generate_random_fabric_key, const bool& group_config_block, - const bool& verbose) { + const bool& name_module_using_index, const bool& frame_view, + const bool& compact_routing_hierarchy, const bool& duplicate_grid_pin, + const FabricKey& fabric_key, const bool& generate_random_fabric_key, + const bool& group_config_block, const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build FPGA fabric module"); int status = CMD_EXEC_SUCCESS; @@ -81,13 +81,13 @@ int build_top_module( sram_model, frame_view, compact_routing_hierarchy, duplicate_grid_pin, fabric_key, group_config_block); } else { - /* TODO: Build the tile instances under the top module */ + /* Build the tile instances under the top module */ status = build_top_module_tile_child_instances( module_manager, top_module, blwl_sr_banks, circuit_lib, clk_ntwk, rr_clock_lookup, vpr_device_annotation, grids, layer, tile_annotation, rr_graph, device_rr_gsb, tile_direct, arch_direct, fabric_tile, - config_protocol, sram_model, fabric_key, group_config_block, frame_view, - verbose); + config_protocol, sram_model, fabric_key, group_config_block, + name_module_using_index, frame_view, verbose); } if (status != CMD_EXEC_SUCCESS) { diff --git a/openfpga/src/fabric/build_top_module.h b/openfpga/src/fabric/build_top_module.h index d62ac4993..ee9d346d2 100644 --- a/openfpga/src/fabric/build_top_module.h +++ b/openfpga/src/fabric/build_top_module.h @@ -42,10 +42,10 @@ int build_top_module( const DeviceRRGSB& device_rr_gsb, const TileDirect& tile_direct, const ArchDirect& arch_direct, const ConfigProtocol& config_protocol, const CircuitModelId& sram_model, const FabricTile& fabric_tile, - const bool& frame_view, const bool& compact_routing_hierarchy, - const bool& duplicate_grid_pin, const FabricKey& fabric_key, - const bool& generate_random_fabric_key, const bool& group_config_block, - const bool& verbose); + const bool& name_module_using_index, const bool& frame_view, + const bool& compact_routing_hierarchy, const bool& duplicate_grid_pin, + const FabricKey& fabric_key, const bool& generate_random_fabric_key, + const bool& group_config_block, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp index ff2bae0aa..3c1c86c1c 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.cpp +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.cpp @@ -290,7 +290,8 @@ static int build_top_module_tile_nets_between_sb_and_pb( const RRGSB& rr_gsb, const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id, const size_t& sb_idx_in_curr_fabric_tile, - const bool& compact_routing_hierarchy, const bool& verbose) { + const bool& compact_routing_hierarchy, const bool& name_module_using_index, + const bool& verbose) { /* Skip those Switch blocks that do not exist */ if (false == rr_gsb.is_sb_exist(rr_graph)) { return CMD_EXEC_SUCCESS; @@ -303,6 +304,10 @@ static int build_top_module_tile_nets_between_sb_and_pb( fabric_tile.sb_coordinates(sink_unique_tile)[sb_idx_in_curr_fabric_tile]; std::string sink_sb_instance_name_in_unique_tile = generate_switch_block_module_name(sink_sb_coord_in_unique_tile); + if (name_module_using_index) { + sink_sb_instance_name_in_unique_tile = + generate_switch_block_module_name_using_index(sb_idx_in_curr_fabric_tile); + } /* We could have two different coordinators, one is the instance, the other is * the module */ @@ -526,7 +531,8 @@ static int build_top_module_tile_nets_between_cb_and_pb( const RRGSB& rr_gsb, const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id, const t_rr_type& cb_type, const size_t& cb_idx_in_curr_fabric_tile, - const bool& compact_routing_hierarchy, const bool& verbose) { + const bool& compact_routing_hierarchy, const bool& name_module_using_index, + const bool& verbose) { vtr::Point src_tile_coord = fabric_tile.tile_coordinate(curr_fabric_tile_id); FabricTileId src_unique_tile = fabric_tile.unique_tile(src_tile_coord); @@ -537,6 +543,11 @@ static int build_top_module_tile_nets_between_cb_and_pb( std::string src_cb_instance_name_in_unique_tile = generate_connection_block_module_name( cb_type, src_cb_inst_rr_gsb.get_cb_coordinate(cb_type)); + if (name_module_using_index) { + src_cb_instance_name_in_unique_tile = + generate_connection_block_module_name_using_index( + cb_type, cb_idx_in_curr_fabric_tile); + } /* We could have two different coordinators, one is the instance, the other is * the module */ @@ -720,7 +731,8 @@ static int build_top_module_tile_nets_between_sb_and_cb( const RRGraphView& rr_graph, const RRGSB& rr_gsb, const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id, const size_t& sb_idx_in_curr_fabric_tile, - const bool& compact_routing_hierarchy, const bool& verbose) { + const bool& compact_routing_hierarchy, const bool& name_module_using_index, + const bool& verbose) { /* We could have two different coordinators, one is the instance, the other is * the module */ vtr::Point instance_sb_coordinate(rr_gsb.get_sb_x(), @@ -734,6 +746,10 @@ static int build_top_module_tile_nets_between_sb_and_cb( fabric_tile.sb_coordinates(sb_unique_tile)[sb_idx_in_curr_fabric_tile]; std::string sb_instance_name_in_unique_tile = generate_switch_block_module_name(sb_coord_in_unique_tile); + if (name_module_using_index) { + sb_instance_name_in_unique_tile = + generate_switch_block_module_name_using_index(sb_idx_in_curr_fabric_tile); + } /* Skip those Switch blocks that do not exist */ if (false == rr_gsb.is_sb_exist(rr_graph)) { @@ -835,6 +851,11 @@ static int build_top_module_tile_nets_between_sb_and_cb( std::string cb_instance_name_in_unique_tile = generate_connection_block_module_name( cb_type, unique_cb_rr_gsb.get_cb_coordinate(cb_type)); + if (name_module_using_index) { + cb_instance_name_in_unique_tile = + generate_connection_block_module_name_using_index(cb_type, + cb_idx_in_cb_tile); + } std::string cb_tile_module_name = generate_tile_module_name(cb_unique_tile_coord); ModuleId cb_tile_module = module_manager.find_module(cb_tile_module_name); @@ -955,7 +976,7 @@ static int add_top_module_nets_around_one_tile( const vtr::Matrix& tile_instance_ids, const RRGraphView& rr_graph_view, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id, - const bool& verbose) { + const bool& name_module_using_index, const bool& verbose) { int status = CMD_EXEC_SUCCESS; /* Find the module name for this type of tile */ @@ -983,7 +1004,7 @@ static int add_top_module_nets_around_one_tile( module_manager, top_module, tile_module, tile_instance_ids, tile_instance_id, grids, vpr_device_annotation, device_rr_gsb, rr_graph_view, rr_gsb, fabric_tile, curr_fabric_tile_id, isb, true, - verbose); + name_module_using_index, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1001,7 +1022,7 @@ static int add_top_module_nets_around_one_tile( module_manager, top_module, tile_module, tile_instance_ids, tile_instance_id, grids, vpr_device_annotation, device_rr_gsb, rr_graph_view, rr_gsb, fabric_tile, curr_fabric_tile_id, cb_type, icb, - true, verbose); + true, name_module_using_index, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1017,7 +1038,7 @@ static int add_top_module_nets_around_one_tile( status = build_top_module_tile_nets_between_sb_and_cb( module_manager, top_module, tile_module, tile_instance_ids, tile_instance_id, device_rr_gsb, rr_graph_view, rr_gsb, fabric_tile, - curr_fabric_tile_id, isb, true, verbose); + curr_fabric_tile_id, isb, true, name_module_using_index, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1035,7 +1056,7 @@ static int add_top_module_nets_connect_tiles( const VprDeviceAnnotation& vpr_device_annotation, const DeviceGrid& grids, const vtr::Matrix& tile_instance_ids, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, - const bool& verbose) { + const bool& name_module_using_index, const bool& verbose) { vtr::ScopedStartFinishTimer timer("Add module nets between tiles"); int status = CMD_EXEC_SUCCESS; @@ -1049,7 +1070,7 @@ static int add_top_module_nets_connect_tiles( status = add_top_module_nets_around_one_tile( module_manager, top_module, vpr_device_annotation, grids, tile_instance_ids, rr_graph, device_rr_gsb, fabric_tile, - curr_fabric_tile_id, verbose); + curr_fabric_tile_id, name_module_using_index, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -1383,6 +1404,15 @@ static int build_top_module_global_net_for_given_tile_module( std::string grid_port_name = generate_grid_port_name(grid_pin_width, grid_pin_height, subtile_index, pin_side, grid_pin_info); + if (tile_annotation.is_tile_port_to_merge( + std::string(physical_tile->name), grid_pin_info.get_name())) { + if (subtile_index == 0) { + grid_port_name = + generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); + } else { + continue; + } + } std::string tile_grid_port_name = generate_tile_module_port_name(grid_instance_name, grid_port_name); ModulePortId tile_grid_port_id = @@ -1874,7 +1904,8 @@ int build_top_module_tile_child_instances( const TileDirect& tile_direct, const ArchDirect& arch_direct, const FabricTile& fabric_tile, const ConfigProtocol& config_protocol, const CircuitModelId& sram_model, const FabricKey& fabric_key, - const bool& group_config_block, const bool& frame_view, const bool& verbose) { + const bool& group_config_block, const bool& name_module_using_index, + const bool& frame_view, const bool& verbose) { int status = CMD_EXEC_SUCCESS; vtr::Matrix tile_instance_ids; status = add_top_module_tile_instances(module_manager, top_module, @@ -1894,7 +1925,8 @@ int build_top_module_tile_child_instances( /* Regular nets between tiles */ status = add_top_module_nets_connect_tiles( module_manager, top_module, vpr_device_annotation, grids, - tile_instance_ids, rr_graph, device_rr_gsb, fabric_tile, verbose); + tile_instance_ids, rr_graph, device_rr_gsb, fabric_tile, + name_module_using_index, verbose); if (status != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } diff --git a/openfpga/src/fabric/build_top_module_child_tile_instance.h b/openfpga/src/fabric/build_top_module_child_tile_instance.h index 57d3604e4..bec2a9fa1 100644 --- a/openfpga/src/fabric/build_top_module_child_tile_instance.h +++ b/openfpga/src/fabric/build_top_module_child_tile_instance.h @@ -43,7 +43,8 @@ int build_top_module_tile_child_instances( const TileDirect& tile_direct, const ArchDirect& arch_direct, const FabricTile& fabric_tile, const ConfigProtocol& config_protocol, const CircuitModelId& sram_model, const FabricKey& fabric_key, - const bool& group_config_block, const bool& frame_view, const bool& verbose); + const bool& group_config_block, const bool& name_module_using_index, + const bool& frame_view, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index d49a6f1cf..98b256fe0 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -950,6 +950,16 @@ static int build_top_module_global_net_for_given_grid_module( std::string grid_port_name = generate_grid_port_name(grid_pin_width, grid_pin_height, subtile_index, pin_side, grid_pin_info); + if (tile_annotation.is_tile_port_to_merge( + std::string(physical_tile->name), grid_pin_info.get_name())) { + if (subtile_index == 0) { + grid_port_name = + generate_grid_port_name(0, 0, 0, TOP, grid_pin_info); + } else { + continue; + } + } + ModulePortId grid_port_id = module_manager.find_module_port(grid_module, grid_port_name); VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module, diff --git a/openfpga/src/fabric/fabric_hierarchy_writer.cpp b/openfpga/src/fabric/fabric_hierarchy_writer.cpp index 546f0ebc1..46daae954 100644 --- a/openfpga/src/fabric/fabric_hierarchy_writer.cpp +++ b/openfpga/src/fabric/fabric_hierarchy_writer.cpp @@ -84,6 +84,7 @@ static int rec_output_module_hierarchy_to_text_file( * Return 2 if fail when creating files ***************************************************************************************/ int write_fabric_hierarchy_to_text_file(const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& fname, const size_t& hie_depth_to_stop, const bool& verbose) { @@ -111,7 +112,8 @@ int write_fabric_hierarchy_to_text_file(const ModuleManager& module_manager, check_file_stream(fname.c_str(), fp); /* Find top-level module */ - std::string top_module_name = generate_fpga_top_module_name(); + std::string top_module_name = + module_name_map.name(generate_fpga_top_module_name()); ModuleId top_module = module_manager.find_module(top_module_name); if (true != module_manager.valid_module_id(top_module)) { VTR_LOGV_ERROR(verbose, "Unable to find the top-level module '%s'!\n", diff --git a/openfpga/src/fabric/fabric_hierarchy_writer.h b/openfpga/src/fabric/fabric_hierarchy_writer.h index ccba3f99d..71fbea25b 100644 --- a/openfpga/src/fabric/fabric_hierarchy_writer.h +++ b/openfpga/src/fabric/fabric_hierarchy_writer.h @@ -15,6 +15,7 @@ namespace openfpga { int write_fabric_hierarchy_to_text_file(const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& fname, const size_t& hie_depth_to_stop, const bool& verbose); diff --git a/openfpga/src/fabric/rename_modules.cpp b/openfpga/src/fabric/rename_modules.cpp new file mode 100644 index 000000000..a939932e2 --- /dev/null +++ b/openfpga/src/fabric/rename_modules.cpp @@ -0,0 +1,189 @@ +/* Headers from vtrutil library */ +#include "rename_modules.h" + +#include "command_exit_codes.h" +#include "openfpga_naming.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/** @brief Initialize a module name map with the existing module names from a + * module manager. In this case, all the built-in names are the same as + * customized names */ +int init_fabric_module_name_map(ModuleNameMap& module_name_map, + const ModuleManager& module_manager, + const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + /* the module name map should be empty! */ + module_name_map.clear(); + size_t cnt = 0; + for (ModuleId curr_module : module_manager.modules()) { + status = module_name_map.set_tag_to_name_pair( + module_manager.module_name(curr_module), + module_manager.module_name(curr_module)); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + cnt++; + } + VTR_LOGV(verbose, "Initialized module name map for '%lu' modules\n", cnt); + return CMD_EXEC_SUCCESS; +} + +int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, + const DeviceRRGSB& device_rr_gsb, + const FabricTile& fabric_tile, + const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + /* Walk through the device rr gsb on the unique routing modules */ + for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { + const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); + vtr::Point gsb_coordinate(unique_mirror.get_sb_x(), + unique_mirror.get_sb_y()); + std::string name_using_coord = + generate_switch_block_module_name(gsb_coordinate); + std::string name_using_index = + generate_switch_block_module_name_using_index(isb); + status = + module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", + name_using_index.c_str(), name_using_coord.c_str()); + } + for (t_rr_type cb_type : {CHANX, CHANY}) { + for (size_t icb = 0; icb < device_rr_gsb.get_num_cb_unique_module(cb_type); + ++icb) { + const RRGSB& unique_mirror = + device_rr_gsb.get_cb_unique_module(cb_type, icb); + vtr::Point gsb_coordinate(unique_mirror.get_cb_x(cb_type), + unique_mirror.get_cb_y(cb_type)); + std::string name_using_coord = + generate_connection_block_module_name(cb_type, gsb_coordinate); + std::string name_using_index = + generate_connection_block_module_name_using_index(cb_type, icb); + status = module_name_map.set_tag_to_name_pair(name_using_coord, + name_using_index); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", + name_using_index.c_str(), name_using_coord.c_str()); + } + } + /* Walk through the fabric tile on the unique routing modules */ + for (size_t itile = 0; itile < fabric_tile.unique_tiles().size(); ++itile) { + FabricTileId fabric_tile_id = fabric_tile.unique_tiles()[itile]; + vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); + std::string name_using_coord = generate_tile_module_name(tile_coord); + std::string name_using_index = generate_tile_module_name_using_index(itile); + status = + module_name_map.set_tag_to_name_pair(name_using_coord, name_using_index); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_SUCCESS; + } + VTR_LOGV(verbose, "Now use indexing name for module '%s' (was '%s')\n", + name_using_index.c_str(), name_using_coord.c_str()); + } + return CMD_EXEC_SUCCESS; +} + +/** @brief Apply module renaming for all the modules. Require the module name + * map cover all the modules */ +int rename_fabric_modules(ModuleManager& module_manager, + const ModuleNameMap& module_name_map, + const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + size_t cnt = 0; + for (ModuleId curr_module : module_manager.modules()) { + std::string curr_module_name = module_manager.module_name(curr_module); + /* Error out if the new name does not exist ! */ + if (!module_name_map.name_exist(curr_module_name)) { + VTR_LOG_ERROR( + "The built-in module name '%s' does not exist! Abort renaming...\n", + curr_module_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + std::string new_name = module_name_map.name(curr_module_name); + if (new_name != curr_module_name) { + VTR_LOGV(verbose, "Rename module '%s' to its new name '%s'\n", + curr_module_name.c_str(), new_name.c_str()); + module_manager.set_module_name(curr_module, new_name); + } + cnt++; + } + VTR_LOG("Renamed %lu modules\n", cnt); + return status; +} + +/** @brief Apply module renaming based on the pairs given by module name map + * only. So not all the modules are renamed. So the module name map just cover a + * subset of modules */ +int partial_rename_fabric_modules(ModuleManager& module_manager, + const ModuleNameMap& module_name_map, + const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + size_t cnt = 0; + for (std::string built_in_name : module_name_map.tags()) { + ModuleId curr_module = module_manager.find_module(built_in_name); + if (!module_manager.valid_module_id(curr_module)) { + VTR_LOG_ERROR( + "The built-in module name '%s' does not exist! Abort renaming...\n", + built_in_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + std::string new_name = module_name_map.name(built_in_name); + if (new_name != built_in_name) { + VTR_LOGV(verbose, "Rename module '%s' to its new name '%s'\n", + built_in_name.c_str(), new_name.c_str()); + module_manager.set_module_name(curr_module, new_name); + } + cnt++; + } + VTR_LOG("Renamed %lu modules\n", cnt); + return status; +} + +/** @brief The module name map kept in openfpga context always has a built-in + * name with coordinates. while users apply renaming or other internal renaming + * is applied, e.g., through option '--name_module_using_index', the module name + * in the module graph can be changed. So in the user's version, the built-in + * name may become index or anything else. We have to keep the built-in name + * consistent (use coordinates, otherwise other engines may not work, which rely + * on this convention) while the given name should follow the users' definition. + * So we need an update here For example: the current module name map is + * 'tile_1__1_' -> 'tile_4_' the user's module name map is 'tile_4_' -> + * 'tile_big' The resulting module name map is 'tile_1__1_' -> 'tile_big' + */ +int update_module_name_map_with_user_version( + ModuleNameMap& curr_module_name_map, + const ModuleNameMap& user_module_name_map, const bool& verbose) { + int status = CMD_EXEC_SUCCESS; + size_t cnt = 0; + for (std::string user_tag : user_module_name_map.tags()) { + if (!curr_module_name_map.tag_exist(user_tag)) { + VTR_LOG_ERROR( + "The built-in module name '%s' given by user does not exist in current " + "module name map! Abort updating...\n", + user_tag.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + std::string built_in_tag = curr_module_name_map.tag(user_tag); + curr_module_name_map.set_tag_to_name_pair( + built_in_tag, user_module_name_map.name(user_tag)); + VTR_LOGV(verbose, + "Now module built-in name '%s' is pointed to its new name '%s' " + "(old name '%s' is deleted)\n", + built_in_tag.c_str(), user_module_name_map.name(user_tag).c_str(), + user_tag.c_str()); + cnt++; + } + VTR_LOGV(verbose, "Update %lu built-in-to-name pairs\n", cnt); + return status; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fabric/rename_modules.h b/openfpga/src/fabric/rename_modules.h new file mode 100644 index 000000000..46ef1351f --- /dev/null +++ b/openfpga/src/fabric/rename_modules.h @@ -0,0 +1,42 @@ +#ifndef RENAME_MODULES_H +#define RENAME_MODULES_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "device_rr_gsb.h" +#include "fabric_tile.h" +#include "module_manager.h" +#include "module_name_map.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int init_fabric_module_name_map(ModuleNameMap& module_name_map, + const ModuleManager& module_manager, + const bool& verbose); + +int update_module_map_name_with_indexing_names(ModuleNameMap& module_name_map, + const DeviceRRGSB& device_rr_gsb, + const FabricTile& fabric_tile, + const bool& verbose); + +int rename_fabric_modules(ModuleManager& module_manager, + const ModuleNameMap& module_name_map, + const bool& verbose); + +int partial_rename_fabric_modules(ModuleManager& module_manager, + const ModuleNameMap& module_name_map, + const bool& verbose); + +int update_module_name_map_with_user_version( + ModuleNameMap& curr_module_name_map, + const ModuleNameMap& user_module_name_map, const bool& verbose); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp new file mode 100644 index 000000000..28f94a6ed --- /dev/null +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.cpp @@ -0,0 +1,197 @@ +/****************************************************************************** + * Memember functions for data structure BitstreamWriterOption + ******************************************************************************/ +#include "bitstream_writer_options.h" + +#include "vtr_assert.h" +#include "vtr_log.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/************************************************** + * Public Constructors + *************************************************/ +BitstreamWriterOption::BitstreamWriterOption() { + file_type_ = BitstreamWriterOption::e_bitfile_type::NUM_TYPES; + BITFILE_TYPE_STRING_ = {"plain_text", "xml"}; + output_file_.clear(); + time_stamp_ = true; + verbose_output_ = false; + + filter_value_ = ""; + trim_path_ = false; + path_only_ = false; + value_only_ = false; + + fast_config_ = false; + keep_dont_care_bits_ = false; + wl_decremental_order_ = false; +} + +/************************************************** + * Public Accessors + *************************************************/ +BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::output_file_type() + const { + return file_type_; +} + +std::string BitstreamWriterOption::output_file_name() const { + return output_file_; +} + +bool BitstreamWriterOption::time_stamp() const { return time_stamp_; } + +bool BitstreamWriterOption::verbose_output() const { return verbose_output_; } + +bool BitstreamWriterOption::filter_value() const { + return !filter_value_.empty(); +} + +bool BitstreamWriterOption::value_to_skip(const size_t& val) const { + return std::to_string(val) == filter_value_; +} + +bool BitstreamWriterOption::trim_path() const { return trim_path_; } +bool BitstreamWriterOption::output_path() const { + if (!path_only_ && !value_only_) { + return true; + } + return path_only_; +} +bool BitstreamWriterOption::output_value() const { + if (!path_only_ && !value_only_) { + return true; + } + return value_only_; +} + +bool BitstreamWriterOption::fast_configuration() const { return fast_config_; } +bool BitstreamWriterOption::keep_dont_care_bits() const { + return keep_dont_care_bits_; +} +bool BitstreamWriterOption::wl_decremental_order() const { + return wl_decremental_order_; +} + +/****************************************************************************** + * Private Mutators + ******************************************************************************/ +void BitstreamWriterOption::set_output_file_type(const std::string& val) { + file_type_ = str2bitfile_type(val); +} + +void BitstreamWriterOption::set_output_file_name( + const std::string& output_file) { + output_file_ = output_file; +} + +void BitstreamWriterOption::set_time_stamp(const bool& enabled) { + time_stamp_ = enabled; +} + +void BitstreamWriterOption::set_verbose_output(const bool& enabled) { + verbose_output_ = enabled; +} + +void BitstreamWriterOption::set_filter_value(const std::string& val) { + filter_value_ = val; +} + +void BitstreamWriterOption::set_trim_path(const bool& enabled) { + trim_path_ = enabled; +} + +void BitstreamWriterOption::set_path_only(const bool& enabled) { + path_only_ = enabled; +} + +void BitstreamWriterOption::set_value_only(const bool& enabled) { + value_only_ = enabled; +} + +void BitstreamWriterOption::set_fast_configuration(const bool& enabled) { + fast_config_ = enabled; +} + +void BitstreamWriterOption::set_keep_dont_care_bits(const bool& enabled) { + keep_dont_care_bits_ = enabled; +} + +void BitstreamWriterOption::set_wl_decremental_order(const bool& enabled) { + wl_decremental_order_ = enabled; +} + +bool BitstreamWriterOption::validate(bool show_err_msg) const { + /* Check file type */ + if (!valid_file_type(file_type_)) { + VTR_LOGV_ERROR(show_err_msg, "Invalid file type!\n"); + return false; + } + if (output_file_.empty()) { + VTR_LOGV_ERROR(show_err_msg, "Empty file name!\n"); + return false; + } + if (file_type_ == BitstreamWriterOption::e_bitfile_type::XML) { + /* All the options in the XML format should be off */ + if (path_only_ && value_only_) { + VTR_LOGV_ERROR(show_err_msg, + "Both path and value are specifed as only inputs! If " + "specified, please define one of them\n"); + return false; + } + if (!filter_value_.empty() && (filter_value_ != std::to_string(0) && + filter_value_ != std::to_string(1))) { + VTR_LOGV_ERROR(show_err_msg, + "Invalid value '%s' for filter values. Expect [0|1]!\n", + filter_value_.c_str()); + return false; + } + } + return true; +} + +BitstreamWriterOption::e_bitfile_type BitstreamWriterOption::str2bitfile_type( + const std::string& type_str, const bool& verbose) const { + for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); + itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); + ++itype) { + if (type_str == std::string(BITFILE_TYPE_STRING_[itype])) { + return static_cast(itype); + } + } + VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", + bitfile_type_all2str().c_str()); + return BitstreamWriterOption::e_bitfile_type::NUM_TYPES; +} + +std::string BitstreamWriterOption::bitfile_type2str( + const BitstreamWriterOption::e_bitfile_type& type, + const bool& verbose) const { + if (!valid_file_type(type)) { + VTR_LOGV_ERROR(verbose, "Invalid type for bitstream file! Expect %s\n", + bitfile_type_all2str().c_str()); + return std::string(); + } + return std::string(BITFILE_TYPE_STRING_[size_t(type)]); +} + +std::string BitstreamWriterOption::bitfile_type_all2str() const { + std::string full_types = "["; + for (int itype = size_t(BitstreamWriterOption::e_bitfile_type::TEXT); + itype != size_t(BitstreamWriterOption::e_bitfile_type::NUM_TYPES); + ++itype) { + full_types += std::string(BITFILE_TYPE_STRING_[itype]) + std::string("|"); + } + full_types.pop_back(); + full_types += "]"; + return full_types; +} + +bool BitstreamWriterOption::valid_file_type( + const BitstreamWriterOption::e_bitfile_type& bitfile_type) const { + return bitfile_type != BitstreamWriterOption::e_bitfile_type::NUM_TYPES; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/bitstream_writer_options.h b/openfpga/src/fpga_bitstream/bitstream_writer_options.h new file mode 100644 index 000000000..9a23aefbd --- /dev/null +++ b/openfpga/src/fpga_bitstream/bitstream_writer_options.h @@ -0,0 +1,104 @@ +#ifndef BITSTREAM_WRITER_OPTIONS_H +#define BITSTREAM_WRITER_OPTIONS_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include +#include + +/* Begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Options for Bitstream Writer + *******************************************************************/ +class BitstreamWriterOption { + public: /* Private data structures */ + /* A type to define the bitstream file format */ + enum class e_bitfile_type { TEXT, XML, NUM_TYPES }; + + public: /* Public constructor */ + /* Set default options */ + BitstreamWriterOption(); + + public: /* Public accessors */ + e_bitfile_type output_file_type() const; + std::string output_file_name() const; + bool time_stamp() const; + bool verbose_output() const; + + /* Check if a filter on value is applied */ + bool filter_value() const; + /* Check if a given value should be skipped */ + bool value_to_skip(const size_t& val) const; + /* Check if path trimming should be applied or not */ + bool trim_path() const; + /* Check if path should be outputted in the resulting file */ + bool output_path() const; + /* Check if value should be outputted in the resulting file */ + bool output_value() const; + + bool fast_configuration() const; + bool keep_dont_care_bits() const; + bool wl_decremental_order() const; + + public: /* Public mutators */ + void set_output_file_type(const std::string& val); + void set_output_file_name(const std::string& output_file); + void set_time_stamp(const bool& enabled); + void set_verbose_output(const bool& enabled); + void set_trim_path(const bool& enabled); + void set_path_only(const bool& enabled); + void set_value_only(const bool& enabled); + void set_fast_configuration(const bool& enabled); + void set_keep_dont_care_bits(const bool& enabled); + void set_wl_decremental_order(const bool& enabled); + + void set_filter_value(const std::string& val); + + public: /* Public validator */ + bool validate(bool show_err_msg = false) const; + + public: /* Internal utility */ + /** @brief Parse the file type from string to valid type. Parser + * error can be turned on */ + e_bitfile_type str2bitfile_type(const std::string& type_str, + const bool& verbose = false) const; + + /** @brief Output the string representing file_type */ + std::string bitfile_type2str(const e_bitfile_type& type, + const bool& verbose = false) const; + /** @brief Validate the file_type */ + bool valid_file_type(const e_bitfile_type& bitfile_type) const; + + /* Generate a string include all the valid style + * Useful for printing debugging messages */ + std::string bitfile_type_all2str() const; + + private: /* Internal Data */ + /* Universal options */ + e_bitfile_type file_type_; + std::string output_file_; + bool time_stamp_; + bool verbose_output_; + + /* XML-specific options */ + std::string filter_value_; + bool trim_path_; + bool path_only_; + bool value_only_; + + /* Plain-text options */ + bool fast_config_; + bool keep_dont_care_bits_; + bool wl_decremental_order_; + + /* Constants */ + std::array + BITFILE_TYPE_STRING_; +}; + +} /* End namespace openfpga*/ + +#endif diff --git a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp index 69e723f05..9d7b89789 100644 --- a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp @@ -161,7 +161,8 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, /* Create the top-level block for bitstream * This is related to the top-level module of fpga */ - std::string top_block_name = generate_fpga_top_module_name(); + std::string top_block_name = + openfpga_ctx.module_name_map().name(generate_fpga_top_module_name()); ConfigBlockId top_block = bitstream_manager.add_block(top_block_name); ModuleId top_module = openfpga_ctx.module_graph().find_module(top_block_name); VTR_ASSERT(true == openfpga_ctx.module_graph().valid_module_id(top_module)); @@ -169,6 +170,9 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, /* Create the core block when the fpga_core is added */ size_t num_blocks_to_reserve = 0; std::string core_block_name = generate_fpga_core_module_name(); + if (openfpga_ctx.module_name_map().name_exist(core_block_name)) { + core_block_name = openfpga_ctx.module_name_map().name(core_block_name); + } const ModuleId& core_module = openfpga_ctx.module_graph().find_module(core_block_name); if (openfpga_ctx.module_graph().valid_module_id(core_module)) { @@ -206,22 +210,23 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, /* Create bitstream from grids */ VTR_LOGV(verbose, "Building grid bitstream...\n"); - build_grid_bitstream(bitstream_manager, top_block, - openfpga_ctx.module_graph(), openfpga_ctx.fabric_tile(), - openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), - vpr_ctx.device().grid, 0, vpr_ctx.atom(), - openfpga_ctx.vpr_device_annotation(), - openfpga_ctx.vpr_clustering_annotation(), - openfpga_ctx.vpr_placement_annotation(), - openfpga_ctx.vpr_bitstream_annotation(), verbose); + build_grid_bitstream( + bitstream_manager, top_block, openfpga_ctx.module_graph(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_tile(), + openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), + vpr_ctx.device().grid, 0, vpr_ctx.atom(), + openfpga_ctx.vpr_device_annotation(), + openfpga_ctx.vpr_clustering_annotation(), + openfpga_ctx.vpr_placement_annotation(), + openfpga_ctx.vpr_bitstream_annotation(), verbose); VTR_LOGV(verbose, "Done\n"); /* Create bitstream from routing architectures */ VTR_LOGV(verbose, "Building routing bitstream...\n"); build_routing_bitstream( bitstream_manager, top_block, openfpga_ctx.module_graph(), - openfpga_ctx.fabric_tile(), openfpga_ctx.arch().circuit_lib, - openfpga_ctx.mux_lib(), vpr_ctx.atom(), + openfpga_ctx.module_name_map(), openfpga_ctx.fabric_tile(), + openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), vpr_ctx.atom(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(), vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(), openfpga_ctx.flow_manager().compress_routing(), verbose); diff --git a/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp index edf20681c..3ab2d753f 100644 --- a/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp @@ -772,14 +772,16 @@ static void build_module_fabric_dependent_bitstream( *******************************************************************/ FabricBitstream build_fabric_dependent_bitstream( const BitstreamManager& bitstream_manager, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const ConfigProtocol& config_protocol, const bool& verbose) { + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, + const bool& verbose) { FabricBitstream fabric_bitstream; vtr::ScopedStartFinishTimer timer("\nBuild fabric dependent bitstream\n"); /* Get the top module name in module manager, which is our starting point */ - std::string top_module_name = generate_fpga_top_module_name(); + std::string top_module_name = + module_name_map.name(generate_fpga_top_module_name()); ModuleId top_module = module_manager.find_module(top_module_name); VTR_ASSERT(true == module_manager.valid_module_id(top_module)); @@ -794,6 +796,9 @@ FabricBitstream build_fabric_dependent_bitstream( /* Create the core block when the fpga_core is added */ std::string core_block_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_block_name)) { + core_block_name = module_name_map.name(core_block_name); + } const ModuleId& core_module = module_manager.find_module(core_block_name); if (module_manager.valid_module_id(core_module)) { /* Now we use the core_block as the top-level block for the remaining diff --git a/openfpga/src/fpga_bitstream/build_fabric_bitstream.h b/openfpga/src/fpga_bitstream/build_fabric_bitstream.h index 5f5deb1c6..8c52742d0 100644 --- a/openfpga/src/fpga_bitstream/build_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/build_fabric_bitstream.h @@ -11,6 +11,7 @@ #include "config_protocol.h" #include "fabric_bitstream.h" #include "module_manager.h" +#include "module_name_map.h" /******************************************************************** * Function declaration @@ -21,8 +22,9 @@ namespace openfpga { FabricBitstream build_fabric_dependent_bitstream( const BitstreamManager& bitstream_manager, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const ConfigProtocol& config_protocol, const bool& verbose); + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, + const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index df3f070aa..d8e4f17fb 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -180,9 +180,9 @@ static void build_physical_block_pin_interc_bitstream( BitstreamManager& bitstream_manager, std::map& grouped_mem_inst_scoreboard, const ConfigBlockId& parent_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprBitstreamAnnotation& bitstream_annotation, const PhysicalPb& physical_pb, t_pb_graph_pin* des_pb_graph_pin, t_mode* physical_mode, const bool& verbose) { @@ -290,6 +290,7 @@ static void build_physical_block_pin_interc_bitstream( std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_MODULE_POSTFIX)); + mem_module_name = module_name_map.name(mem_module_name); ModuleId mux_mem_module = module_manager.find_module(mem_module_name); VTR_ASSERT(true == module_manager.valid_module_id(mux_mem_module)); ModulePortId mux_mem_out_port_id = module_manager.find_module_port( @@ -302,6 +303,9 @@ static void build_physical_block_pin_interc_bitstream( std::string feedthru_mem_block_name = generate_mux_subckt_name( circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX)); + if (module_name_map.name_exist(feedthru_mem_block_name)) { + feedthru_mem_block_name = module_name_map.name(feedthru_mem_block_name); + } ModuleId feedthru_mem_module = module_manager.find_module(feedthru_mem_block_name); if (module_manager.valid_module_id(feedthru_mem_module)) { @@ -375,9 +379,9 @@ static void build_physical_block_interc_port_bitstream( BitstreamManager& bitstream_manager, std::map& grouped_mem_inst_scoreboard, const ConfigBlockId& parent_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprBitstreamAnnotation& bitstream_annotation, t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb, const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode, @@ -390,8 +394,9 @@ static void build_physical_block_interc_port_bitstream( ++ipin) { build_physical_block_pin_interc_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - parent_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, physical_pb, + parent_configurable_block, module_manager, module_name_map, + circuit_lib, mux_lib, atom_ctx, device_annotation, + bitstream_annotation, physical_pb, &(physical_pb_graph_node->input_pins[iport][ipin]), physical_mode, verbose); } @@ -404,8 +409,9 @@ static void build_physical_block_interc_port_bitstream( ipin < physical_pb_graph_node->num_output_pins[iport]; ++ipin) { build_physical_block_pin_interc_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - parent_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, physical_pb, + parent_configurable_block, module_manager, module_name_map, + circuit_lib, mux_lib, atom_ctx, device_annotation, + bitstream_annotation, physical_pb, &(physical_pb_graph_node->output_pins[iport][ipin]), physical_mode, verbose); } @@ -418,8 +424,9 @@ static void build_physical_block_interc_port_bitstream( ++ipin) { build_physical_block_pin_interc_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - parent_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, physical_pb, + parent_configurable_block, module_manager, module_name_map, + circuit_lib, mux_lib, atom_ctx, device_annotation, + bitstream_annotation, physical_pb, &(physical_pb_graph_node->clock_pins[iport][ipin]), physical_mode, verbose); } @@ -439,9 +446,9 @@ static void build_physical_block_interc_bitstream( BitstreamManager& bitstream_manager, std::map& grouped_mem_inst_scoreboard, const ConfigBlockId& parent_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprBitstreamAnnotation& bitstream_annotation, t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb, t_mode* physical_mode, const bool& verbose) { @@ -463,9 +470,9 @@ static void build_physical_block_interc_bitstream( */ build_physical_block_interc_port_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, parent_configurable_block, - module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation, - bitstream_annotation, physical_pb_graph_node, physical_pb, - CIRCUIT_PB_PORT_OUTPUT, physical_mode, verbose); + module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx, + device_annotation, bitstream_annotation, physical_pb_graph_node, + physical_pb, CIRCUIT_PB_PORT_OUTPUT, physical_mode, verbose); /* We check input_pins of child_pb_graph_node and its the input_edges * Iterate over the interconnections between inputs of physical_pb_graph_node @@ -486,15 +493,17 @@ static void build_physical_block_interc_bitstream( /* For each child_pb_graph_node input pins*/ build_physical_block_interc_port_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - parent_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, child_pb_graph_node, - physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode, verbose); + parent_configurable_block, module_manager, module_name_map, circuit_lib, + mux_lib, atom_ctx, device_annotation, bitstream_annotation, + child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode, + verbose); /* For clock pins, we should do the same work */ build_physical_block_interc_port_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - parent_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, child_pb_graph_node, - physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode, verbose); + parent_configurable_block, module_manager, module_name_map, circuit_lib, + mux_lib, atom_ctx, device_annotation, bitstream_annotation, + child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode, + verbose); } } } @@ -697,9 +706,9 @@ static void rec_build_physical_block_bitstream( BitstreamManager& bitstream_manager, std::map& grouped_mem_inst_scoreboard, const ConfigBlockId& parent_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprBitstreamAnnotation& bitstream_annotation, const e_side& border_side, const PhysicalPb& physical_pb, const PhysicalPbId& pb_id, t_pb_graph_node* physical_pb_graph_node, const size_t& pb_graph_node_index, @@ -713,6 +722,7 @@ static void rec_build_physical_block_bitstream( /* Early exit if this parent module has no configurable child modules */ std::string pb_module_name = generate_physical_block_module_name(physical_pb_type); + pb_module_name = module_name_map.name(pb_module_name); ModuleId pb_module = module_manager.find_module(pb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(pb_module)); @@ -758,8 +768,9 @@ static void rec_build_physical_block_bitstream( /* Go recursively */ rec_build_physical_block_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block, - module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation, - bitstream_annotation, border_side, physical_pb, child_pb, + module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx, + device_annotation, bitstream_annotation, border_side, physical_pb, + child_pb, &(physical_pb_graph_node ->child_pb_graph_nodes[physical_mode->index][ipb][jpb]), jpb, verbose); @@ -804,9 +815,9 @@ static void rec_build_physical_block_bitstream( /* Generate the bitstream for the interconnection in this physical block */ build_physical_block_interc_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block, - module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation, - bitstream_annotation, physical_pb_graph_node, physical_pb, physical_mode, - verbose); + module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx, + device_annotation, bitstream_annotation, physical_pb_graph_node, + physical_pb, physical_mode, verbose); } /******************************************************************** @@ -817,10 +828,10 @@ static void rec_build_physical_block_bitstream( *******************************************************************/ static void build_physical_block_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, - const FabricTileId& curr_tile, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const FabricTileId& curr_tile, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprClusteringAnnotation& cluster_annotation, const VprPlacementAnnotation& place_annotation, const VprBitstreamAnnotation& bitstream_annotation, const DeviceGrid& grids, @@ -835,6 +846,7 @@ static void build_physical_block_bitstream( std::string grid_module_name = generate_grid_block_module_name( grid_module_name_prefix, std::string(grid_type->name), is_io_type(grid_type), border_side); + grid_module_name = module_name_map.name(grid_module_name); ModuleId grid_module = module_manager.find_module(grid_module_name); VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); @@ -916,10 +928,10 @@ static void build_physical_block_bitstream( /* Recursively traverse the pb_graph and generate bitstream */ rec_build_physical_block_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - grid_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, border_side, - PhysicalPb(), PhysicalPbId::INVALID(), lb_type->pb_graph_head, z, - verbose); + grid_configurable_block, module_manager, module_name_map, circuit_lib, + mux_lib, atom_ctx, device_annotation, bitstream_annotation, + border_side, PhysicalPb(), PhysicalPbId::INVALID(), + lb_type->pb_graph_head, z, verbose); } else { const PhysicalPb& phy_pb = cluster_annotation.physical_pb( place_annotation.grid_blocks(grid_coord)[z]); @@ -932,9 +944,9 @@ static void build_physical_block_bitstream( /* Recursively traverse the pb_graph and generate bitstream */ rec_build_physical_block_bitstream( bitstream_manager, grouped_mem_inst_scoreboard, - grid_configurable_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, bitstream_annotation, border_side, - phy_pb, top_pb_id, pb_graph_head, z, verbose); + grid_configurable_block, module_manager, module_name_map, circuit_lib, + mux_lib, atom_ctx, device_annotation, bitstream_annotation, + border_side, phy_pb, top_pb_id, pb_graph_head, z, verbose); } } } @@ -948,10 +960,10 @@ static void build_physical_block_bitstream( *******************************************************************/ void build_grid_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const DeviceGrid& grids, const size_t& layer, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const DeviceGrid& grids, const size_t& layer, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprClusteringAnnotation& cluster_annotation, const VprPlacementAnnotation& place_annotation, const VprBitstreamAnnotation& bitstream_annotation, const bool& verbose) { @@ -992,10 +1004,10 @@ void build_grid_bitstream( } build_physical_block_bitstream( - bitstream_manager, parent_block, module_manager, fabric_tile, curr_tile, - circuit_lib, mux_lib, atom_ctx, device_annotation, cluster_annotation, - place_annotation, bitstream_annotation, grids, layer, grid_coord, - NUM_SIDES, verbose); + bitstream_manager, parent_block, module_manager, module_name_map, + fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx, + device_annotation, cluster_annotation, place_annotation, + bitstream_annotation, grids, layer, grid_coord, NUM_SIDES, verbose); } } VTR_LOGV(verbose, "Done\n"); @@ -1040,10 +1052,10 @@ void build_grid_bitstream( } build_physical_block_bitstream( - bitstream_manager, parent_block, module_manager, fabric_tile, curr_tile, - circuit_lib, mux_lib, atom_ctx, device_annotation, cluster_annotation, - place_annotation, bitstream_annotation, grids, layer, io_coordinate, - io_side, verbose); + bitstream_manager, parent_block, module_manager, module_name_map, + fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx, + device_annotation, cluster_annotation, place_annotation, + bitstream_annotation, grids, layer, io_coordinate, io_side, verbose); } } VTR_LOGV(verbose, "Done\n"); diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.h b/openfpga/src/fpga_bitstream/build_grid_bitstream.h index a3f4f2603..36b297c98 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.h +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.h @@ -11,6 +11,7 @@ #include "device_grid.h" #include "fabric_tile.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "vpr_bitstream_annotation.h" #include "vpr_clustering_annotation.h" @@ -27,10 +28,10 @@ namespace openfpga { void build_grid_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const DeviceGrid& grids, const size_t& layer, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const DeviceGrid& grids, const size_t& layer, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprClusteringAnnotation& cluster_annotation, const VprPlacementAnnotation& place_annotation, const VprBitstreamAnnotation& bitstream_annotation, const bool& verbose); diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp index 0c1d7c31e..d299c635e 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp @@ -33,10 +33,11 @@ namespace openfpga { *******************************************************************/ static void build_switch_block_mux_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& mux_mem_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const RRGraphView& rr_graph, - const RRNodeId& cur_rr_node, const std::vector& drive_rr_nodes, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const RRGraphView& rr_graph, const RRNodeId& cur_rr_node, + const std::vector& drive_rr_nodes, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const bool& verbose) { /* Check current rr_node is CHANX or CHANY*/ VTR_ASSERT((CHANX == rr_graph.node_type(cur_rr_node)) || @@ -94,6 +95,7 @@ static void build_switch_block_mux_bitstream( std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_MODULE_POSTFIX)); + mem_module_name = module_name_map.name(mem_module_name); ModuleId mux_mem_module = module_manager.find_module(mem_module_name); VTR_ASSERT(true == module_manager.valid_module_id(mux_mem_module)); ModulePortId mux_mem_out_port_id = module_manager.find_module_port( @@ -152,9 +154,10 @@ static void build_switch_block_mux_bitstream( static void build_switch_block_interc_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& sb_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const RRGraphView& rr_graph, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const RRGraphView& rr_graph, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGSB& rr_gsb, const e_side& chan_side, const size_t& chan_node_id, const bool& verbose) { std::vector driver_rr_nodes; @@ -190,9 +193,9 @@ static void build_switch_block_interc_bitstream( bitstream_manager.block_name(sb_configurable_block).c_str()); /* This is a routing multiplexer! Generate bitstream */ build_switch_block_mux_bitstream( - bitstream_manager, mux_mem_block, module_manager, circuit_lib, mux_lib, - rr_graph, cur_rr_node, driver_rr_nodes, atom_ctx, device_annotation, - routing_annotation, verbose); + bitstream_manager, mux_mem_block, module_manager, module_name_map, + circuit_lib, mux_lib, rr_graph, cur_rr_node, driver_rr_nodes, atom_ctx, + device_annotation, routing_annotation, verbose); } /*Nothing should be done else*/ } @@ -209,9 +212,9 @@ static void build_switch_block_interc_bitstream( *******************************************************************/ static void build_switch_block_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& sb_config_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const RRGSB& rr_gsb, const bool& verbose) { /* Iterate over all the multiplexers */ @@ -229,9 +232,9 @@ static void build_switch_block_bitstream( continue; } build_switch_block_interc_bitstream( - bitstream_manager, sb_config_block, module_manager, circuit_lib, - mux_lib, rr_graph, atom_ctx, device_annotation, routing_annotation, - rr_gsb, side_manager.get_side(), itrack, verbose); + bitstream_manager, sb_config_block, module_manager, module_name_map, + circuit_lib, mux_lib, rr_graph, atom_ctx, device_annotation, + routing_annotation, rr_gsb, side_manager.get_side(), itrack, verbose); } } } @@ -245,9 +248,9 @@ static void build_switch_block_bitstream( *******************************************************************/ static void build_connection_block_mux_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& mux_mem_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const RRGSB& rr_gsb, const e_side& cb_ipin_side, const size_t& ipin_index, const bool& verbose) { @@ -310,6 +313,7 @@ static void build_connection_block_mux_bitstream( std::string mem_module_name = generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size, std::string(MEMORY_MODULE_POSTFIX)); + mem_module_name = module_name_map.name(mem_module_name); ModuleId mux_mem_module = module_manager.find_module(mem_module_name); VTR_ASSERT(true == module_manager.valid_module_id(mux_mem_module)); ModulePortId mux_mem_out_port_id = module_manager.find_module_port( @@ -368,9 +372,9 @@ static void build_connection_block_mux_bitstream( static void build_connection_block_interc_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& cb_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const RRGSB& rr_gsb, const e_side& cb_ipin_side, const size_t& ipin_index, const bool& verbose) { @@ -402,9 +406,9 @@ static void build_connection_block_interc_bitstream( bitstream_manager.block_name(cb_configurable_block).c_str()); /* This is a routing multiplexer! Generate bitstream */ build_connection_block_mux_bitstream( - bitstream_manager, mux_mem_block, module_manager, circuit_lib, mux_lib, - atom_ctx, device_annotation, routing_annotation, rr_graph, rr_gsb, - cb_ipin_side, ipin_index, verbose); + bitstream_manager, mux_mem_block, module_manager, module_name_map, + circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, + rr_graph, rr_gsb, cb_ipin_side, ipin_index, verbose); } /*Nothing should be done else*/ } @@ -422,9 +426,9 @@ static void build_connection_block_interc_bitstream( static void build_connection_block_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& cb_configurable_block, - const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const MuxLibrary& mux_lib, const AtomContext& atom_ctx, - const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, + const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const RRGSB& rr_gsb, const t_rr_type& cb_type, const bool& verbose) { /* Find routing multiplexers on the sides of a Connection block where IPIN @@ -439,9 +443,9 @@ static void build_connection_block_bitstream( VTR_LOGV(verbose, "\tGenerating bitstream for IPIN at '%s' side\n", side_manager.to_string().c_str()); build_connection_block_interc_bitstream( - bitstream_manager, cb_configurable_block, module_manager, circuit_lib, - mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, - rr_gsb, cb_ipin_side, inode, verbose); + bitstream_manager, cb_configurable_block, module_manager, + module_name_map, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, rr_gsb, cb_ipin_side, inode, verbose); } } } @@ -452,9 +456,10 @@ static void build_connection_block_bitstream( static void build_connection_block_bitstreams( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy, const t_rr_type& cb_type, const bool& verbose) { @@ -501,7 +506,8 @@ static void build_connection_block_bitstreams( cb_module_name = generate_connection_block_module_name(cb_type, unique_cb_coord); } - ModuleId cb_module = module_manager.find_module(cb_module_name); + ModuleId cb_module = + module_manager.find_module(module_name_map.name(cb_module_name)); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); /* Bypass empty blocks which have none configurable children */ @@ -578,9 +584,9 @@ static void build_connection_block_bitstreams( } build_connection_block_bitstream( - bitstream_manager, cb_configurable_block, module_manager, circuit_lib, - mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, - rr_gsb, cb_type, verbose); + bitstream_manager, cb_configurable_block, module_manager, + module_name_map, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, rr_gsb, cb_type, verbose); VTR_LOGV(verbose, "\tDone\n"); } @@ -596,9 +602,10 @@ static void build_connection_block_bitstreams( void build_routing_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy, const bool& verbose) { @@ -636,7 +643,8 @@ void build_routing_bitstream( unique_sb_coord.set_y(unique_mirror.get_sb_y()); sb_module_name = generate_switch_block_module_name(unique_sb_coord); } - ModuleId sb_module = module_manager.find_module(sb_module_name); + ModuleId sb_module = + module_manager.find_module(module_name_map.name(sb_module_name)); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Bypass empty blocks which have none configurable children */ @@ -708,9 +716,9 @@ void build_routing_bitstream( } build_switch_block_bitstream( - bitstream_manager, sb_configurable_block, module_manager, circuit_lib, - mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, - rr_gsb, verbose); + bitstream_manager, sb_configurable_block, module_manager, + module_name_map, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, rr_gsb, verbose); VTR_LOGV(verbose, "\tDone\n"); } @@ -725,17 +733,19 @@ void build_routing_bitstream( VTR_LOG("Generating bitstream for X-direction Connection blocks ..."); build_connection_block_bitstreams( - bitstream_manager, top_configurable_block, module_manager, fabric_tile, - circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, - rr_graph, device_rr_gsb, compact_routing_hierarchy, CHANX, verbose); + bitstream_manager, top_configurable_block, module_manager, module_name_map, + fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy, + CHANX, verbose); VTR_LOG("Done\n"); VTR_LOG("Generating bitstream for Y-direction Connection blocks ..."); build_connection_block_bitstreams( - bitstream_manager, top_configurable_block, module_manager, fabric_tile, - circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, - rr_graph, device_rr_gsb, compact_routing_hierarchy, CHANY, verbose); + bitstream_manager, top_configurable_block, module_manager, module_name_map, + fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation, + routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy, + CHANY, verbose); VTR_LOG("Done\n"); } diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.h b/openfpga/src/fpga_bitstream/build_routing_bitstream.h index b268acd79..c3af671bd 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.h +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.h @@ -14,6 +14,7 @@ #include "device_rr_gsb.h" #include "fabric_tile.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "vpr_context.h" #include "vpr_device_annotation.h" @@ -29,9 +30,10 @@ namespace openfpga { void build_routing_bitstream( BitstreamManager& bitstream_manager, const ConfigBlockId& top_configurable_block, - const ModuleManager& module_manager, const FabricTile& fabric_tile, - const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib, - const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricTile& fabric_tile, const CircuitLibrary& circuit_lib, + const MuxLibrary& mux_lib, const AtomContext& atom_ctx, + const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph, const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy, const bool& verbose); diff --git a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp index 4cde144d5..1f83f7a57 100644 --- a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.cpp @@ -579,10 +579,11 @@ int write_fabric_bitstream_to_text_file( const FabricBitstream& fabric_bitstream, const MemoryBankShiftRegisterBanks& blwl_sr_banks, const ConfigProtocol& config_protocol, - const FabricGlobalPortInfo& global_ports, const std::string& fname, - const bool& fast_configuration, const bool& keep_dont_care_bits, - const bool& wl_incremental_order, const bool& include_time_stamp, - const bool& verbose) { + const FabricGlobalPortInfo& global_ports, + const BitstreamWriterOption& options) { + VTR_ASSERT(options.output_file_type() == + BitstreamWriterOption::e_bitfile_type::TEXT); + std::string fname = options.output_file_name(); /* Ensure that we have a valid file name */ if (true == fname.empty()) { VTR_LOG_ERROR( @@ -603,8 +604,10 @@ int write_fabric_bitstream_to_text_file( check_file_stream(fname.c_str(), fp); bool apply_fast_configuration = - is_fast_configuration_applicable(global_ports) && fast_configuration; - if (fast_configuration && apply_fast_configuration != fast_configuration) { + is_fast_configuration_applicable(global_ports) && + options.fast_configuration(); + if (options.fast_configuration() && + apply_fast_configuration != options.fast_configuration()) { VTR_LOG_WARN("Disable fast configuration even it is enabled by user\n"); } @@ -616,7 +619,7 @@ int write_fabric_bitstream_to_text_file( } /* Write file head */ - write_fabric_bitstream_text_file_head(fp, include_time_stamp); + write_fabric_bitstream_text_file_head(fp, options.time_stamp()); /* Output fabric bitstream to the file */ int status = 0; @@ -649,19 +652,18 @@ int write_fabric_bitstream_to_text_file( // bitstream status = fast_write_memory_bank_flatten_fabric_bitstream_to_text_file( fp, apply_fast_configuration, bit_value_to_skip, fabric_bitstream, - keep_dont_care_bits, wl_incremental_order); + options.keep_dont_care_bits(), options.wl_decremental_order()); } else if (BLWL_PROTOCOL_FLATTEN == config_protocol.bl_protocol_type()) { status = write_memory_bank_flatten_fabric_bitstream_to_text_file( fp, apply_fast_configuration, bit_value_to_skip, fabric_bitstream, - keep_dont_care_bits); + options.keep_dont_care_bits()); } else { VTR_ASSERT(BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.bl_protocol_type()); status = write_memory_bank_shift_register_fabric_bitstream_to_text_file( - fp, apply_fast_configuration, bit_value_to_skip, - - fabric_bitstream, blwl_sr_banks, keep_dont_care_bits); + fp, apply_fast_configuration, bit_value_to_skip, fabric_bitstream, + blwl_sr_banks, options.keep_dont_care_bits()); } break; } @@ -685,7 +687,8 @@ int write_fabric_bitstream_to_text_file( /* Close file handler */ fp.close(); - VTR_LOGV(verbose, "Outputted %lu configuration bits to plain text file: %s\n", + VTR_LOGV(options.verbose_output(), + "Outputted %lu configuration bits to plain text file: %s\n", fabric_bitstream.bits().size(), fname.c_str()); return status; diff --git a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h index 59f4774de..48d542ddf 100644 --- a/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/write_text_fabric_bitstream.h @@ -8,6 +8,7 @@ #include #include "bitstream_manager.h" +#include "bitstream_writer_options.h" #include "config_protocol.h" #include "fabric_bitstream.h" #include "fabric_global_port_info.h" @@ -25,10 +26,8 @@ int write_fabric_bitstream_to_text_file( const FabricBitstream& fabric_bitstream, const MemoryBankShiftRegisterBanks& blwl_sr_banks, const ConfigProtocol& config_protocol, - const FabricGlobalPortInfo& global_ports, const std::string& fname, - const bool& fast_configuration, const bool& keep_dont_care_bits, - const bool& wl_incremental_order, const bool& include_time_stamp, - const bool& verbose); + const FabricGlobalPortInfo& global_ports, + const BitstreamWriterOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp index 06f0c079e..9bd3287e1 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.cpp @@ -72,36 +72,57 @@ static int write_fabric_config_bit_to_xml_file( std::fstream& fp, const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, const FabricBitId& fabric_bit, const e_config_protocol_type& config_type, bool fast_xml, - const int& xml_hierarchy_depth, std::string& bl_addr, std::string& wl_addr) { + const int& xml_hierarchy_depth, std::string& bl_addr, std::string& wl_addr, + const BitstreamWriterOption& options) { if (false == valid_file_stream(fp)) { return 1; } + if (options.value_to_skip( + bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit)))) { + return 0; + } write_tab_to_file(fp, xml_hierarchy_depth); fp << " block_hierarchy = - find_bitstream_manager_block_hierarchy(bitstream_manager, config_block); - std::string hie_path; - for (const ConfigBlockId& temp_block : block_hierarchy) { - hie_path += bitstream_manager.block_name(temp_block); - hie_path += std::string("."); - } - hie_path += generate_configurable_memory_data_out_name(); - hie_path += std::string("["); - hie_path += - std::to_string(find_bitstream_manager_config_bit_index_in_parent_block( - bitstream_manager, config_bit)); - hie_path += std::string("]"); - fp << " path=\"" << hie_path << "\">\n"; + if (options.output_path()) { + std::vector block_hierarchy = + find_bitstream_manager_block_hierarchy(bitstream_manager, config_block); + std::string hie_path; + for (size_t iblk = 0; iblk < block_hierarchy.size(); ++iblk) { + /* If enabled, pop the last block name */ + if (options.trim_path() && iblk == block_hierarchy.size() - 1) { + break; + } + hie_path += bitstream_manager.block_name(block_hierarchy[iblk]); + hie_path += std::string("."); + } + hie_path += generate_configurable_memory_data_out_name(); + hie_path += std::string("["); + size_t bit_idx_in_parent_block = + find_bitstream_manager_config_bit_index_in_parent_block(bitstream_manager, + config_bit); + if (options.trim_path()) { + bit_idx_in_parent_block = + find_bitstream_manager_config_bit_index_in_grandparent_block( + bitstream_manager, config_bit); + } + hie_path += std::to_string(bit_idx_in_parent_block); + hie_path += std::string("]"); + + fp << " path=\"" << hie_path << "\""; + } + fp << ">\n"; switch (config_type) { case CONFIG_MEM_STANDALONE: @@ -196,7 +217,7 @@ static int write_fabric_regional_config_bit_to_xml_file( const FabricBitstream& fabric_bitstream, const FabricBitRegionId& fabric_region, const e_config_protocol_type& config_type, bool fast_xml, - const int& xml_hierarchy_depth) { + const int& xml_hierarchy_depth, const BitstreamWriterOption& options) { if (false == valid_file_stream(fp)) { return 1; } @@ -228,7 +249,7 @@ static int write_fabric_regional_config_bit_to_xml_file( fabric_bitstream.region_bits(fabric_region)) { status = write_fabric_config_bit_to_xml_file( fp, bitstream_manager, fabric_bitstream, fabric_bit, config_type, - fast_xml, xml_hierarchy_depth + 1, bl_addr, wl_addr); + fast_xml, xml_hierarchy_depth + 1, bl_addr, wl_addr, options); if (1 == status) { return status; } @@ -261,9 +282,11 @@ static int write_fabric_regional_config_bit_to_xml_file( int write_fabric_bitstream_to_xml_file( const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, - const ConfigProtocol& config_protocol, const std::string& fname, - const bool& include_time_stamp, const bool& verbose) { + const ConfigProtocol& config_protocol, const BitstreamWriterOption& options) { + VTR_ASSERT(options.output_file_type() == + BitstreamWriterOption::e_bitfile_type::XML); /* Ensure that we have a valid file name */ + std::string fname = options.output_file_name(); if (true == fname.empty()) { VTR_LOG_ERROR( "Received empty file name to output bitstream!\n\tPlease specify a valid " @@ -282,7 +305,7 @@ int write_fabric_bitstream_to_xml_file( check_file_stream(fname.c_str(), fp); /* Write XML head */ - write_fabric_bitstream_xml_file_head(fp, include_time_stamp); + write_fabric_bitstream_xml_file_head(fp, options.time_stamp()); int xml_hierarchy_depth = 0; fp << "\n"; @@ -294,7 +317,7 @@ int write_fabric_bitstream_to_xml_file( fp, bitstream_manager, fabric_bitstream, region, config_protocol.type(), BLWL_PROTOCOL_FLATTEN == config_protocol.bl_protocol_type() && BLWL_PROTOCOL_FLATTEN == config_protocol.wl_protocol_type(), - xml_hierarchy_depth + 1); + xml_hierarchy_depth + 1, options); if (1 == status) { break; } @@ -306,7 +329,8 @@ int write_fabric_bitstream_to_xml_file( /* Close file handler */ fp.close(); - VTR_LOGV(verbose, "Outputted %lu configuration bits to XML file: %s\n", + VTR_LOGV(options.verbose_output(), + "Outputted %lu configuration bits to XML file: %s\n", fabric_bitstream.bits().size(), fname.c_str()); return status; diff --git a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h index ce5b3a384..8e40a8d36 100644 --- a/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/write_xml_fabric_bitstream.h @@ -8,6 +8,7 @@ #include #include "bitstream_manager.h" +#include "bitstream_writer_options.h" #include "config_protocol.h" #include "fabric_bitstream.h" @@ -21,8 +22,7 @@ namespace openfpga { int write_fabric_bitstream_to_xml_file( const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, - const ConfigProtocol& config_protocol, const std::string& fname, - const bool& include_time_stamp, const bool& verbose); + const ConfigProtocol& config_protocol, const BitstreamWriterOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 1dbf64dc9..a8d2f78b2 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -23,6 +23,8 @@ #include "verilog_routing.h" #include "verilog_simulation_info_writer.h" #include "verilog_submodule.h" +#include "verilog_template_testbench.h" +#include "verilog_testbench_io_connection.h" #include "verilog_tile.h" #include "verilog_top_module.h" #include "verilog_top_testbench.h" @@ -61,7 +63,7 @@ int fpga_fabric_verilog( const DecoderLibrary &decoder_lib, const DeviceContext &device_ctx, const VprDeviceAnnotation &device_annotation, const DeviceRRGSB &device_rr_gsb, const FabricTile &fabric_tile, - const FabricVerilogOption &options) { + const ModuleNameMap &module_name_map, const FabricVerilogOption &options) { vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n"); int status_code = CMD_EXEC_SUCCESS; @@ -105,33 +107,36 @@ int fpga_fabric_verilog( * logic generation is not possible!!! */ print_verilog_submodule(module_manager, netlist_manager, blwl_sr_banks, - mux_lib, decoder_lib, circuit_lib, submodule_dir_path, + mux_lib, decoder_lib, circuit_lib, module_name_map, + submodule_dir_path, std::string(DEFAULT_SUBMODULE_DIR_NAME), options); /* Generate routing blocks */ if (true == options.compress_routing()) { print_verilog_unique_routing_modules( netlist_manager, const_cast(module_manager), - device_rr_gsb, rr_dir_path, std::string(DEFAULT_RR_DIR_NAME), options); + module_name_map, device_rr_gsb, rr_dir_path, + std::string(DEFAULT_RR_DIR_NAME), options); } else { VTR_ASSERT(false == options.compress_routing()); print_verilog_flatten_routing_modules( netlist_manager, const_cast(module_manager), - device_rr_gsb, device_ctx.rr_graph, rr_dir_path, + module_name_map, device_rr_gsb, device_ctx.rr_graph, rr_dir_path, std::string(DEFAULT_RR_DIR_NAME), options); } /* Generate grids */ print_verilog_grids( netlist_manager, const_cast(module_manager), - device_ctx, device_annotation, lb_dir_path, + module_name_map, device_ctx, device_annotation, lb_dir_path, std::string(DEFAULT_LB_DIR_NAME), options, options.verbose_output()); /* Generate tiles */ if (!fabric_tile.empty()) { status_code = print_verilog_tiles( netlist_manager, const_cast(module_manager), - tile_dir_path, fabric_tile, std::string(DEFAULT_TILE_DIR_NAME), options); + module_name_map, tile_dir_path, fabric_tile, + std::string(DEFAULT_TILE_DIR_NAME), options); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } @@ -140,10 +145,10 @@ int fpga_fabric_verilog( /* Generate FPGA fabric */ print_verilog_core_module(netlist_manager, const_cast(module_manager), - src_dir_path, options); + module_name_map, src_dir_path, options); print_verilog_top_module(netlist_manager, const_cast(module_manager), - src_dir_path, options); + module_name_map, src_dir_path, options); /* Generate an netlist including all the fabric-related netlists */ print_verilog_fabric_include_netlist( @@ -172,7 +177,7 @@ int fpga_verilog_full_testbench( const AtomContext &atom_ctx, const PlacementContext &place_ctx, const PinConstraints &pin_constraints, const BusGroup &bus_group, const std::string &bitstream_file, const IoLocationMap &io_location_map, - const IoNameMap &io_name_map, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const CircuitLibrary &circuit_lib, @@ -200,7 +205,7 @@ int fpga_verilog_full_testbench( module_manager, bitstream_manager, fabric_bitstream, blwl_sr_banks, circuit_lib, config_protocol, fabric_global_port_info, atom_ctx, place_ctx, pin_constraints, bus_group, bitstream_file, io_location_map, io_name_map, - netlist_annotation, netlist_name, top_testbench_file_path, + module_name_map, netlist_annotation, netlist_name, top_testbench_file_path, simulation_setting, options); /* Generate a Verilog file including all the netlists that have been generated @@ -222,7 +227,7 @@ int fpga_verilog_preconfigured_fabric_wrapper( const BitstreamManager &bitstream_manager, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const PinConstraints &pin_constraints, const BusGroup &bus_group, const IoLocationMap &io_location_map, - const IoNameMap &io_name_map, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const CircuitLibrary &circuit_lib, const ConfigProtocol &config_protocol, @@ -247,8 +252,74 @@ int fpga_verilog_preconfigured_fabric_wrapper( status = print_verilog_preconfig_top_module( module_manager, bitstream_manager, config_protocol, circuit_lib, fabric_global_port_info, atom_ctx, place_ctx, pin_constraints, bus_group, - io_location_map, io_name_map, netlist_annotation, netlist_name, - formal_verification_top_netlist_file_path, options); + io_location_map, io_name_map, module_name_map, netlist_annotation, + netlist_name, formal_verification_top_netlist_file_path, options); + + return status; +} + +/******************************************************************** + * A top-level function of FPGA-Verilog which focuses on template testbench + *generation This function will generate + * - A wrapper module, which encapsulate the FPGA module in a Verilog module + *which have the same port as the input benchmark + ********************************************************************/ +int fpga_verilog_template_testbench(const ModuleManager &module_manager, + const IoNameMap &io_name_map, + const ModuleNameMap &module_name_map, + const VerilogTestbenchOption &options) { + vtr::ScopedStartFinishTimer timer( + "Write a template testbench for a preconfigured FPGA fabric\n"); + + std::string src_dir_path = + format_dir_path(find_path_dir_name(options.output_directory())); + std::string testbench_file_path = options.output_directory(); + + int status = CMD_EXEC_SUCCESS; + + /* Create directories */ + create_directory(src_dir_path); + + /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and + * pre-configured testbench for verification */ + status = print_verilog_template_testbench( + module_manager, io_name_map, module_name_map, testbench_file_path, options); + + return status; +} + +/******************************************************************** + * A top-level function of FPGA-Verilog which focuses on generating I/O + *connection part of testbenches + ********************************************************************/ +int fpga_verilog_testbench_io_connection( + const ModuleManager &module_manager, const AtomContext &atom_ctx, + const PlacementContext &place_ctx, const PinConstraints &pin_constraints, + const BusGroup &bus_group, const IoLocationMap &io_location_map, + const ModuleNameMap &module_name_map, + const FabricGlobalPortInfo &fabric_global_port_info, + const VprNetlistAnnotation &netlist_annotation, + const VerilogTestbenchOption &options) { + vtr::ScopedStartFinishTimer timer( + "Write a template testbench for a preconfigured FPGA fabric\n"); + + std::string src_dir_path = + format_dir_path(find_path_dir_name(options.output_directory())); + std::string testbench_file_path = options.output_directory(); + + std::string netlist_name = atom_ctx.nlist.netlist_name(); + + int status = CMD_EXEC_SUCCESS; + + /* Create directories */ + create_directory(src_dir_path); + + /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and + * pre-configured testbench for verification */ + status = print_verilog_testbench_io_connection( + module_manager, fabric_global_port_info, atom_ctx, place_ctx, + pin_constraints, bus_group, io_location_map, module_name_map, + netlist_annotation, netlist_name, testbench_file_path, options); return status; } @@ -261,7 +332,7 @@ int fpga_verilog_mock_fpga_wrapper( const ModuleManager &module_manager, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const PinConstraints &pin_constraints, const BusGroup &bus_group, const IoLocationMap &io_location_map, - const IoNameMap &io_name_map, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const VerilogTestbenchOption &options) { @@ -286,7 +357,7 @@ int fpga_verilog_mock_fpga_wrapper( std::string netlist_file_path = src_dir_path + netlist_file_name; status = print_verilog_mock_fpga_wrapper( module_manager, fabric_global_port_info, atom_ctx, place_ctx, - pin_constraints, bus_group, io_location_map, io_name_map, + pin_constraints, bus_group, io_location_map, io_name_map, module_name_map, netlist_annotation, netlist_name, netlist_file_path, options); /* Add fname to the netlist name list */ @@ -316,8 +387,9 @@ int fpga_verilog_mock_fpga_wrapper( *verification and formal verification purpose. ********************************************************************/ int fpga_verilog_preconfigured_testbench( - const ModuleManager &module_manager, const AtomContext &atom_ctx, - const PinConstraints &pin_constraints, const BusGroup &bus_group, + const ModuleManager &module_manager, const ModuleNameMap &module_name_map, + const AtomContext &atom_ctx, const PinConstraints &pin_constraints, + const BusGroup &bus_group, const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const SimulationSetting &simulation_setting, @@ -340,8 +412,8 @@ int fpga_verilog_preconfigured_testbench( std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); print_verilog_random_top_testbench( netlist_name, random_top_testbench_file_path, atom_ctx, netlist_annotation, - module_manager, fabric_global_port_info, pin_constraints, bus_group, - simulation_setting, options); + module_manager, module_name_map, fabric_global_port_info, pin_constraints, + bus_group, simulation_setting, options); /* Generate a Verilog file including all the netlists that have been generated */ diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index bea3ba4d7..5030288d0 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -22,6 +22,7 @@ #include "io_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" #include "pin_constraints.h" @@ -45,7 +46,7 @@ int fpga_fabric_verilog( const DecoderLibrary& decoder_lib, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const DeviceRRGSB& device_rr_gsb, const FabricTile& fabric_tile, - const FabricVerilogOption& options); + const ModuleNameMap& module_name_map, const FabricVerilogOption& options); int fpga_verilog_full_testbench( const ModuleManager& module_manager, @@ -55,7 +56,7 @@ int fpga_verilog_full_testbench( const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const std::string& bitstream_file, const IoLocationMap& io_location_map, - const IoNameMap& io_name_map, + const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& fabric_global_port_info, const VprNetlistAnnotation& netlist_annotation, const CircuitLibrary& circuit_lib, @@ -67,24 +68,39 @@ int fpga_verilog_preconfigured_fabric_wrapper( const BitstreamManager& bitstream_manager, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const IoLocationMap& io_location_map, - const IoNameMap& io_name_map, + const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& fabric_global_port_info, const VprNetlistAnnotation& netlist_annotation, const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, const VerilogTestbenchOption& options); +int fpga_verilog_template_testbench(const ModuleManager& module_manager, + const IoNameMap& io_name_map, + const ModuleNameMap& module_name_map, + const VerilogTestbenchOption& options); + +int fpga_verilog_testbench_io_connection( + const ModuleManager& module_manager, const AtomContext& atom_ctx, + const PlacementContext& place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const IoLocationMap& io_location_map, + const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& fabric_global_port_info, + const VprNetlistAnnotation& netlist_annotation, + const VerilogTestbenchOption& options); + int fpga_verilog_mock_fpga_wrapper( const ModuleManager& module_manager, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const IoLocationMap& io_location_map, - const IoNameMap& io_name_map, + const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& fabric_global_port_info, const VprNetlistAnnotation& netlist_annotation, const VerilogTestbenchOption& options); int fpga_verilog_preconfigured_testbench( - const ModuleManager& module_manager, const AtomContext& atom_ctx, - const PinConstraints& pin_constraints, const BusGroup& bus_group, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const AtomContext& atom_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const FabricGlobalPortInfo& fabric_global_port_info, const VprNetlistAnnotation& netlist_annotation, const SimulationSetting& simulation_setting, diff --git a/openfpga/src/fpga_verilog/verilog_decoders.cpp b/openfpga/src/fpga_verilog/verilog_decoders.cpp index 693384e39..be75439ec 100644 --- a/openfpga/src/fpga_verilog/verilog_decoders.cpp +++ b/openfpga/src/fpga_verilog/verilog_decoders.cpp @@ -42,6 +42,7 @@ namespace openfpga { static void print_verilog_mux_local_decoder_module( std::fstream& fp, const ModuleManager& module_manager, const DecoderLibrary& decoder_lib, const DecoderId& decoder, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Get the number of inputs */ size_t addr_size = decoder_lib.addr_size(decoder); @@ -51,8 +52,8 @@ static void print_verilog_mux_local_decoder_module( VTR_ASSERT(true == valid_file_stream(fp)); /* TODO: create a name for the local encoder */ - std::string module_name = - generate_mux_local_decoder_subckt_name(addr_size, data_size); + std::string module_name = module_name_map.name( + generate_mux_local_decoder_subckt_name(addr_size, data_size)); /* Create a Verilog Module based on the circuit model, and add to module * manager */ @@ -180,8 +181,8 @@ static void print_verilog_mux_local_decoder_module( void print_verilog_submodule_mux_local_decoders( const ModuleManager& module_manager, NetlistManager& netlist_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, const std::string& submodule_dir_name, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options) { std::string verilog_fname(LOCAL_ENCODER_VERILOG_FILE_NAME); std::string verilog_fpath(submodule_dir + verilog_fname); @@ -235,7 +236,8 @@ void print_verilog_submodule_mux_local_decoders( /* Generate Verilog modules for the found unique local encoders */ for (const auto& decoder : decoder_lib.decoders()) { print_verilog_mux_local_decoder_module(fp, module_manager, decoder_lib, - decoder, options.default_net_type()); + decoder, module_name_map, + options.default_net_type()); } /* Close the file stream */ @@ -280,6 +282,7 @@ void print_verilog_submodule_mux_local_decoders( static void print_verilog_arch_decoder_module( std::fstream& fp, const ModuleManager& module_manager, const DecoderLibrary& decoder_lib, const DecoderId& decoder, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Get the number of inputs */ size_t addr_size = decoder_lib.addr_size(decoder); @@ -289,8 +292,8 @@ static void print_verilog_arch_decoder_module( VTR_ASSERT(true == valid_file_stream(fp)); /* Create a name for the decoder */ - std::string module_name = - generate_memory_decoder_subckt_name(addr_size, data_size); + std::string module_name = module_name_map.name( + generate_memory_decoder_subckt_name(addr_size, data_size)); /* Create a Verilog Module based on the circuit model, and add to module * manager */ @@ -603,6 +606,7 @@ static void print_verilog_arch_decoder_module( static void print_verilog_arch_decoder_with_data_in_module( std::fstream& fp, const ModuleManager& module_manager, const DecoderLibrary& decoder_lib, const DecoderId& decoder, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Get the number of inputs */ size_t addr_size = decoder_lib.addr_size(decoder); @@ -613,8 +617,8 @@ static void print_verilog_arch_decoder_with_data_in_module( VTR_ASSERT(true == valid_file_stream(fp)); /* Create a name for the decoder */ - std::string module_name = - generate_memory_decoder_with_data_in_subckt_name(addr_size, data_size); + std::string module_name = module_name_map.name( + generate_memory_decoder_with_data_in_subckt_name(addr_size, data_size)); /* Create a Verilog Module based on the circuit model, and add to module * manager */ @@ -778,8 +782,9 @@ static void print_verilog_arch_decoder_with_data_in_module( ***************************************************************************************/ void print_verilog_submodule_arch_decoders( const ModuleManager& module_manager, NetlistManager& netlist_manager, - const DecoderLibrary& decoder_lib, const std::string& submodule_dir, - const std::string& submodule_dir_name, const FabricVerilogOption& options) { + const DecoderLibrary& decoder_lib, const ModuleNameMap& module_name_map, + const std::string& submodule_dir, const std::string& submodule_dir_name, + const FabricVerilogOption& options) { std::string verilog_fname(ARCH_ENCODER_VERILOG_FILE_NAME); std::string verilog_fpath(submodule_dir + verilog_fname); @@ -801,10 +806,12 @@ void print_verilog_submodule_arch_decoders( for (const auto& decoder : decoder_lib.decoders()) { if (true == decoder_lib.use_data_in(decoder)) { print_verilog_arch_decoder_with_data_in_module( - fp, module_manager, decoder_lib, decoder, options.default_net_type()); + fp, module_manager, decoder_lib, decoder, module_name_map, + options.default_net_type()); } else { print_verilog_arch_decoder_module(fp, module_manager, decoder_lib, - decoder, options.default_net_type()); + decoder, module_name_map, + options.default_net_type()); } } diff --git a/openfpga/src/fpga_verilog/verilog_decoders.h b/openfpga/src/fpga_verilog/verilog_decoders.h index b94edda10..1f730bcc6 100644 --- a/openfpga/src/fpga_verilog/verilog_decoders.h +++ b/openfpga/src/fpga_verilog/verilog_decoders.h @@ -12,6 +12,7 @@ #include "decoder_library.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_graph.h" #include "mux_library.h" #include "netlist_manager.h" @@ -27,13 +28,14 @@ namespace openfpga { void print_verilog_submodule_mux_local_decoders( const ModuleManager& module_manager, NetlistManager& netlist_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, const std::string& submodule_dir_name, - const FabricVerilogOption& options); + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options); void print_verilog_submodule_arch_decoders( const ModuleManager& module_manager, NetlistManager& netlist_manager, - const DecoderLibrary& decoder_lib, const std::string& submodule_dir, - const std::string& submodule_dir_name, const FabricVerilogOption& options); + const DecoderLibrary& decoder_lib, const ModuleNameMap& module_name_map, + const std::string& submodule_dir, const std::string& submodule_dir_name, + const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_essential_gates.cpp b/openfpga/src/fpga_verilog/verilog_essential_gates.cpp index 84d2e7d6c..2930721dc 100644 --- a/openfpga/src/fpga_verilog/verilog_essential_gates.cpp +++ b/openfpga/src/fpga_verilog/verilog_essential_gates.cpp @@ -151,6 +151,7 @@ static void print_verilog_invbuf_body(std::fstream& fp, static void print_verilog_invbuf_module( const ModuleManager& module_manager, std::fstream& fp, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -175,8 +176,8 @@ static void print_verilog_invbuf_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId module_id = - module_manager.find_module(circuit_lib.model_name(circuit_model)); + ModuleId module_id = module_manager.find_module( + module_name_map.name(circuit_lib.model_name(circuit_model))); VTR_ASSERT(true == module_manager.valid_module_id(module_id)); /* dump module definition + ports */ @@ -220,6 +221,7 @@ static void print_verilog_invbuf_module( static void print_verilog_passgate_module( const ModuleManager& module_manager, std::fstream& fp, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -270,8 +272,8 @@ static void print_verilog_passgate_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId module_id = - module_manager.find_module(circuit_lib.model_name(circuit_model)); + ModuleId module_id = module_manager.find_module( + module_name_map.name(circuit_lib.model_name(circuit_model))); VTR_ASSERT(true == module_manager.valid_module_id(module_id)); /* dump module definition + ports */ @@ -443,6 +445,7 @@ static void print_verilog_mux2_gate_body( static void print_verilog_gate_module( const ModuleManager& module_manager, std::fstream& fp, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -465,8 +468,8 @@ static void print_verilog_gate_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId module_id = - module_manager.find_module(circuit_lib.model_name(circuit_model)); + ModuleId module_id = module_manager.find_module( + module_name_map.name(circuit_lib.model_name(circuit_model))); VTR_ASSERT(true == module_manager.valid_module_id(module_id)); /* dump module definition + ports */ @@ -506,11 +509,12 @@ static void print_verilog_gate_module( ***********************************************/ static void print_verilog_constant_generator_module( const ModuleManager& module_manager, std::fstream& fp, - const size_t& const_value, + const size_t& const_value, const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Find the module in module manager */ std::string module_name = generate_const_value_module_name(const_value); - ModuleId const_val_module = module_manager.find_module(module_name); + ModuleId const_val_module = + module_manager.find_module(module_name_map.name(module_name)); VTR_ASSERT(true == module_manager.valid_module_id(const_val_module)); /* Ensure a valid file handler*/ @@ -544,6 +548,7 @@ void print_verilog_submodule_essentials(const ModuleManager& module_manager, const std::string& submodule_dir, const std::string& submodule_dir_name, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const FabricVerilogOption& options) { std::string verilog_fname(ESSENTIALS_VERILOG_FILE_NAME); std::string verilog_fpath = submodule_dir + verilog_fname; @@ -563,11 +568,11 @@ void print_verilog_submodule_essentials(const ModuleManager& module_manager, /* Print constant generators */ /* VDD */ - print_verilog_constant_generator_module(module_manager, fp, 0, - options.default_net_type()); + print_verilog_constant_generator_module( + module_manager, fp, 0, module_name_map, options.default_net_type()); /* GND */ - print_verilog_constant_generator_module(module_manager, fp, 1, - options.default_net_type()); + print_verilog_constant_generator_module( + module_manager, fp, 1, module_name_map, options.default_net_type()); for (const auto& circuit_model : circuit_lib.models()) { /* By pass user-defined modules */ @@ -576,17 +581,19 @@ void print_verilog_submodule_essentials(const ModuleManager& module_manager, } if (CIRCUIT_MODEL_INVBUF == circuit_lib.model_type(circuit_model)) { print_verilog_invbuf_module(module_manager, fp, circuit_lib, - circuit_model, options.default_net_type()); + circuit_model, module_name_map, + options.default_net_type()); continue; } if (CIRCUIT_MODEL_PASSGATE == circuit_lib.model_type(circuit_model)) { print_verilog_passgate_module(module_manager, fp, circuit_lib, - circuit_model, options.default_net_type()); + circuit_model, module_name_map, + options.default_net_type()); continue; } if (CIRCUIT_MODEL_GATE == circuit_lib.model_type(circuit_model)) { print_verilog_gate_module(module_manager, fp, circuit_lib, circuit_model, - options.default_net_type()); + module_name_map, options.default_net_type()); continue; } } diff --git a/openfpga/src/fpga_verilog/verilog_essential_gates.h b/openfpga/src/fpga_verilog/verilog_essential_gates.h index 6921c110d..f34624f3a 100644 --- a/openfpga/src/fpga_verilog/verilog_essential_gates.h +++ b/openfpga/src/fpga_verilog/verilog_essential_gates.h @@ -9,6 +9,7 @@ #include "circuit_library.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" #include "verilog_port_types.h" @@ -24,6 +25,7 @@ void print_verilog_submodule_essentials(const ModuleManager& module_manager, const std::string& submodule_dir, const std::string& submodule_dir_name, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp index 045a69024..8cc1e69de 100644 --- a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp @@ -52,7 +52,7 @@ constexpr const char* FORMAL_TB_SIM_START_PORT_NAME = "sim_start"; *******************************************************************/ static void print_verilog_top_random_testbench_ports( std::fstream& fp, const ModuleManager& module_manager, - const std::string& circuit_name, + const ModuleNameMap& module_name_map, const std::string& circuit_name, const std::vector& clock_port_names, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const VerilogTestbenchOption& options) { @@ -82,10 +82,11 @@ static void print_verilog_top_random_testbench_ports( fp << std::endl; print_verilog_testbench_shared_ports( - fp, module_manager, FabricGlobalPortInfo(), PinConstraints(), atom_ctx, - netlist_annotation, clock_port_names, std::string(), - std::string(BENCHMARK_PORT_POSTFIX), std::string(FPGA_PORT_POSTFIX), - std::string(CHECKFLAG_PORT_POSTFIX), options.no_self_checking()); + fp, module_manager, module_name_map, FabricGlobalPortInfo(), + PinConstraints(), atom_ctx, netlist_annotation, clock_port_names, + std::string(), std::string(BENCHMARK_PORT_POSTFIX), + std::string(FPGA_PORT_POSTFIX), std::string(CHECKFLAG_PORT_POSTFIX), + options.no_self_checking()); /* Instantiate an integer to count the number of error * and determine if the simulation succeed or failed @@ -168,7 +169,8 @@ static void print_verilog_random_testbench_fpga_instance( static void print_verilog_random_testbench_reset_stimuli( std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const std::vector& clock_port_names, const BasicPort& clock_port) { @@ -199,18 +201,18 @@ static void print_verilog_random_testbench_reset_stimuli( /* Bypass any constained net that are mapped to a global port of the FPGA * fabric because their stimulus cannot be random */ - if (false == - port_is_fabric_global_reset_port(global_ports, module_manager, - pin_constraints.net_pin(block_name))) { + if (false == port_is_fabric_global_reset_port( + global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name))) { continue; } /* Generete stimuli for this net which is how reset signal works */ BasicPort reset_port(block_name, 1); size_t initial_value = 1; - if (1 == - global_ports.global_port_default_value(find_fabric_global_port( - global_ports, module_manager, pin_constraints.net_pin(block_name)))) { + if (1 == global_ports.global_port_default_value(find_fabric_global_port( + global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name)))) { initial_value = 0; } @@ -270,7 +272,8 @@ static void print_verilog_random_testbench_reset_stimuli( void print_verilog_random_top_testbench( const std::string& circuit_name, const std::string& verilog_fname, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const BusGroup& bus_group, const SimulationSetting& simulation_parameters, const VerilogTestbenchOption& options) { @@ -301,9 +304,9 @@ void print_verilog_random_top_testbench( find_atom_netlist_clock_port_names(atom_ctx.nlist, netlist_annotation); /* Start of testbench */ - print_verilog_top_random_testbench_ports(fp, module_manager, circuit_name, - clock_port_names, atom_ctx, - netlist_annotation, options); + print_verilog_top_random_testbench_ports( + fp, module_manager, module_name_map, circuit_name, clock_port_names, + atom_ctx, netlist_annotation, options); /* Call defined top-level module */ print_verilog_random_testbench_fpga_instance( @@ -329,12 +332,12 @@ void print_verilog_random_top_testbench( * limitation should be removed! */ print_verilog_random_testbench_reset_stimuli( - fp, atom_ctx, netlist_annotation, module_manager, global_ports, - pin_constraints, clock_port_names, clock_ports[0]); + fp, atom_ctx, netlist_annotation, module_manager, module_name_map, + global_ports, pin_constraints, clock_port_names, clock_ports[0]); print_verilog_testbench_random_stimuli( - fp, atom_ctx, netlist_annotation, module_manager, global_ports, - pin_constraints, clock_port_names, std::string(), + fp, atom_ctx, netlist_annotation, module_manager, module_name_map, + global_ports, pin_constraints, clock_port_names, std::string(), std::string(CHECKFLAG_PORT_POSTFIX), clock_ports, options.no_self_checking()); diff --git a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h index 0e26165e6..4079e27b1 100644 --- a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h @@ -9,6 +9,7 @@ #include "bus_group.h" #include "fabric_global_port_info.h" #include "module_manager.h" +#include "module_name_map.h" #include "pin_constraints.h" #include "simulation_setting.h" #include "verilog_testbench_options.h" @@ -25,7 +26,8 @@ namespace openfpga { void print_verilog_random_top_testbench( const std::string& circuit_name, const std::string& verilog_fname, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const BusGroup& bus_group, const SimulationSetting& simulation_parameters, const VerilogTestbenchOption& options); diff --git a/openfpga/src/fpga_verilog/verilog_grid.cpp b/openfpga/src/fpga_verilog/verilog_grid.cpp index 44036a727..7d79f3a4d 100644 --- a/openfpga/src/fpga_verilog/verilog_grid.cpp +++ b/openfpga/src/fpga_verilog/verilog_grid.cpp @@ -66,9 +66,9 @@ namespace openfpga { *******************************************************************/ static void print_verilog_primitive_block( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const std::string& subckt_dir, const std::string& subckt_dir_name, - t_pb_graph_node* primitive_pb_graph_node, const FabricVerilogOption& options, - const bool& verbose) { + const ModuleNameMap& module_name_map, const std::string& subckt_dir, + const std::string& subckt_dir_name, t_pb_graph_node* primitive_pb_graph_node, + const FabricVerilogOption& options, const bool& verbose) { /* Ensure a valid pb_graph_node */ if (nullptr == primitive_pb_graph_node) { VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid primitive_pb_graph_node!\n"); @@ -101,6 +101,7 @@ static void print_verilog_primitive_block( /* Generate the module name for this primitive pb_graph_node*/ std::string primitive_module_name = generate_physical_block_module_name(primitive_pb_graph_node->pb_type); + primitive_module_name = module_name_map.name(primitive_module_name); /* Create a module of the primitive LUT and register it to module manager */ ModuleId primitive_module = module_manager.find_module(primitive_module_name); @@ -150,6 +151,7 @@ static void print_verilog_primitive_block( *******************************************************************/ static void rec_print_verilog_logical_tile( NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, const std::string& subckt_dir_name, t_pb_graph_node* physical_pb_graph_node, const FabricVerilogOption& options, const bool& verbose) { @@ -172,8 +174,8 @@ static void rec_print_verilog_logical_tile( for (int ipb = 0; ipb < physical_mode->num_pb_type_children; ++ipb) { /* Go recursive to visit the children */ rec_print_verilog_logical_tile( - netlist_manager, module_manager, device_annotation, subckt_dir, - subckt_dir_name, + netlist_manager, module_manager, module_name_map, device_annotation, + subckt_dir, subckt_dir_name, &(physical_pb_graph_node ->child_pb_graph_nodes[physical_mode->index][ipb][0]), options, verbose); @@ -182,9 +184,9 @@ static void rec_print_verilog_logical_tile( /* For leaf node, a primitive Verilog module will be generated. */ if (true == is_primitive_pb_type(physical_pb_type)) { - print_verilog_primitive_block(netlist_manager, module_manager, subckt_dir, - subckt_dir_name, physical_pb_graph_node, - options, verbose); + print_verilog_primitive_block(netlist_manager, module_manager, + module_name_map, subckt_dir, subckt_dir_name, + physical_pb_graph_node, options, verbose); /* Finish for primitive node, return */ return; } @@ -214,6 +216,7 @@ static void rec_print_verilog_logical_tile( /* Generate the name of the Verilog module for this pb_type */ std::string pb_module_name = generate_physical_block_module_name(physical_pb_type); + pb_module_name = module_name_map.name(pb_module_name); /* Register the Verilog module in module manager */ ModuleId pb_module = module_manager.find_module(pb_module_name); @@ -261,6 +264,7 @@ static void rec_print_verilog_logical_tile( *****************************************************************************/ static void print_verilog_logical_tile_netlist( NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, const std::string& subckt_dir_name, t_pb_graph_node* pb_graph_head, const FabricVerilogOption& options, const bool& verbose) { @@ -276,9 +280,9 @@ static void print_verilog_logical_tile_netlist( */ /* Print Verilog modules starting from the top-level pb_type/pb_graph_node, * and traverse the graph in a recursive way */ - rec_print_verilog_logical_tile(netlist_manager, module_manager, - device_annotation, subckt_dir, subckt_dir_name, - pb_graph_head, options, verbose); + rec_print_verilog_logical_tile( + netlist_manager, module_manager, module_name_map, device_annotation, + subckt_dir, subckt_dir_name, pb_graph_head, options, verbose); VTR_LOG("Done\n"); VTR_LOG("\n"); @@ -294,9 +298,9 @@ static void print_verilog_logical_tile_netlist( *****************************************************************************/ static void print_verilog_physical_tile_netlist( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const std::string& subckt_dir, const std::string& subckt_dir_name, - t_physical_tile_type_ptr phy_block_type, const e_side& border_side, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& subckt_dir, + const std::string& subckt_dir_name, t_physical_tile_type_ptr phy_block_type, + const e_side& border_side, const FabricVerilogOption& options) { /* Give a name to the Verilog netlist */ std::string verilog_fname(generate_grid_block_netlist_name( std::string(GRID_MODULE_NAME_PREFIX) + std::string(phy_block_type->name), @@ -334,6 +338,7 @@ static void print_verilog_physical_tile_netlist( std::string grid_module_name = generate_grid_block_module_name( std::string(GRID_VERILOG_FILE_NAME_PREFIX), std::string(phy_block_type->name), is_io_type(phy_block_type), border_side); + grid_module_name = module_name_map.name(grid_module_name); ModuleId grid_module = module_manager.find_module(grid_module_name); VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); @@ -377,9 +382,10 @@ static void print_verilog_physical_tile_netlist( ****************************************************************************/ void print_verilog_grids( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, - const std::string& subckt_dir, const std::string& subckt_dir_name, - const FabricVerilogOption& options, const bool& verbose) { + const ModuleNameMap& module_name_map, const DeviceContext& device_ctx, + const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, + const std::string& subckt_dir_name, const FabricVerilogOption& options, + const bool& verbose) { /* Create a vector to contain all the Verilog netlist names that have been * generated in this function */ std::vector netlist_names; @@ -400,8 +406,9 @@ void print_verilog_grids( continue; } print_verilog_logical_tile_netlist( - netlist_manager, module_manager, device_annotation, subckt_dir, - subckt_dir_name, logical_tile.pb_graph_head, options, verbose); + netlist_manager, module_manager, module_name_map, device_annotation, + subckt_dir, subckt_dir_name, logical_tile.pb_graph_head, options, + verbose); } VTR_LOG("Writing logical tiles..."); VTR_LOG("Done\n"); @@ -432,15 +439,15 @@ void print_verilog_grids( find_physical_io_tile_located_sides(device_ctx.grid, &physical_tile); for (const e_side& io_type_side : io_type_sides) { print_verilog_physical_tile_netlist( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, - &physical_tile, io_type_side, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, &physical_tile, io_type_side, options); } continue; } else { /* For CLB and heterogenenous blocks */ - print_verilog_physical_tile_netlist(netlist_manager, module_manager, - subckt_dir, subckt_dir_name, - &physical_tile, NUM_SIDES, options); + print_verilog_physical_tile_netlist( + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, &physical_tile, NUM_SIDES, options); } } VTR_LOG("Building physical tiles..."); diff --git a/openfpga/src/fpga_verilog/verilog_grid.h b/openfpga/src/fpga_verilog/verilog_grid.h index 565c4cc83..ca975424f 100644 --- a/openfpga/src/fpga_verilog/verilog_grid.h +++ b/openfpga/src/fpga_verilog/verilog_grid.h @@ -8,6 +8,7 @@ #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" #include "vpr_context.h" #include "vpr_device_annotation.h" @@ -21,9 +22,10 @@ namespace openfpga { void print_verilog_grids( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, - const std::string& subckt_dir, const std::string& subckt_dir_name, - const FabricVerilogOption& options, const bool& verbose); + const ModuleNameMap& module_name_map, const DeviceContext& device_ctx, + const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, + const std::string& subckt_dir_name, const FabricVerilogOption& options, + const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_lut.cpp b/openfpga/src/fpga_verilog/verilog_lut.cpp index 856c4e7ef..fab9205e4 100644 --- a/openfpga/src/fpga_verilog/verilog_lut.cpp +++ b/openfpga/src/fpga_verilog/verilog_lut.cpp @@ -29,6 +29,7 @@ namespace openfpga { void print_verilog_submodule_luts(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, const std::string& submodule_dir_name, const FabricVerilogOption& options) { @@ -55,8 +56,8 @@ void print_verilog_submodule_luts(const ModuleManager& module_manager, continue; } /* Find the module id */ - ModuleId lut_module = - module_manager.find_module(circuit_lib.model_name(lut_model)); + ModuleId lut_module = module_manager.find_module( + module_name_map.name(circuit_lib.model_name(lut_model))); VTR_ASSERT(true == module_manager.valid_module_id(lut_module)); write_verilog_module_to_file( fp, module_manager, lut_module, diff --git a/openfpga/src/fpga_verilog/verilog_lut.h b/openfpga/src/fpga_verilog/verilog_lut.h index 2505f21e9..f4dd8da8c 100644 --- a/openfpga/src/fpga_verilog/verilog_lut.h +++ b/openfpga/src/fpga_verilog/verilog_lut.h @@ -10,6 +10,7 @@ #include "circuit_library.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" /******************************************************************** @@ -22,6 +23,7 @@ namespace openfpga { void print_verilog_submodule_luts(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, const std::string& submodule_dir_name, const FabricVerilogOption& options); diff --git a/openfpga/src/fpga_verilog/verilog_memory.cpp b/openfpga/src/fpga_verilog/verilog_memory.cpp index 365ace6a5..8c56e5e8e 100644 --- a/openfpga/src/fpga_verilog/verilog_memory.cpp +++ b/openfpga/src/fpga_verilog/verilog_memory.cpp @@ -42,7 +42,7 @@ namespace openfpga { static void print_verilog_mux_memory_module( const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, std::fstream& fp, const CircuitModelId& mux_model, const MuxGraph& mux_graph, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const FabricVerilogOption& options) { /* Multiplexers built with different technology is in different organization */ switch (circuit_lib.design_tech_type(mux_model)) { @@ -53,6 +53,7 @@ static void print_verilog_mux_memory_module( find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), std::string(MEMORY_MODULE_POSTFIX)); + module_name = module_name_map.name(module_name); ModuleId mem_module = module_manager.find_module(module_name); VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); /* Write the module content in Verilog format */ @@ -71,6 +72,9 @@ static void print_verilog_mux_memory_module( find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX)); + if (module_name_map.name_exist(feedthru_module_name)) { + feedthru_module_name = module_name_map.name(feedthru_module_name); + } ModuleId feedthru_mem_module = module_manager.find_module(feedthru_module_name); if (module_manager.valid_module_id(feedthru_mem_module)) { @@ -118,13 +122,11 @@ static void print_verilog_mux_memory_module( * Take another example, the memory circuit can implement the scan-chain or * memory-bank organization for the memories. ********************************************************************/ -void print_verilog_submodule_memories(const ModuleManager& module_manager, - NetlistManager& netlist_manager, - const MuxLibrary& mux_lib, - const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, - const std::string& submodule_dir_name, - const FabricVerilogOption& options) { +void print_verilog_submodule_memories( + const ModuleManager& module_manager, NetlistManager& netlist_manager, + const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options) { /* Plug in with the mux subckt */ std::string verilog_fname(MEMORIES_VERILOG_FILE_NAME); std::string verilog_fpath(submodule_dir + verilog_fname); @@ -155,7 +157,7 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, } /* Create a Verilog module for the memories used by the multiplexer */ print_verilog_mux_memory_module(module_manager, circuit_lib, fp, mux_model, - mux_graph, options); + mux_graph, module_name_map, options); } /* Create the memory circuits for non-MUX circuit models. @@ -198,6 +200,7 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, /* Create the module name for the memory block */ std::string module_name = generate_memory_module_name( circuit_lib, model, sram_models[0], std::string(MEMORY_MODULE_POSTFIX)); + module_name = module_name_map.name(module_name); ModuleId mem_module = module_manager.find_module(module_name); VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); @@ -214,6 +217,9 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, std::string feedthru_module_name = generate_memory_module_name(circuit_lib, model, sram_models[0], std::string(MEMORY_MODULE_POSTFIX), true); + if (module_name_map.name_exist(feedthru_module_name)) { + feedthru_module_name = module_name_map.name(feedthru_module_name); + } ModuleId feedthru_mem_module = module_manager.find_module(feedthru_module_name); diff --git a/openfpga/src/fpga_verilog/verilog_memory.h b/openfpga/src/fpga_verilog/verilog_memory.h index 1c3702eff..e2b5aa308 100644 --- a/openfpga/src/fpga_verilog/verilog_memory.h +++ b/openfpga/src/fpga_verilog/verilog_memory.h @@ -9,6 +9,7 @@ #include "circuit_library.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_graph.h" #include "mux_library.h" #include "netlist_manager.h" @@ -20,13 +21,11 @@ /* begin namespace openfpga */ namespace openfpga { -void print_verilog_submodule_memories(const ModuleManager& module_manager, - NetlistManager& netlist_manager, - const MuxLibrary& mux_lib, - const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, - const std::string& submodule_dir_name, - const FabricVerilogOption& options); +void print_verilog_submodule_memories( + const ModuleManager& module_manager, NetlistManager& netlist_manager, + const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp b/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp index e20f02e96..ad238dbf2 100644 --- a/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp +++ b/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp @@ -44,7 +44,8 @@ static void print_verilog_mock_fpga_wrapper_connect_ios( std::fstream& fp, const ModuleManager& module_manager, const ModuleId& top_module, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, - const IoNameMap& io_name_map, const PinConstraints& pin_constraints, + const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, + const PinConstraints& pin_constraints, const FabricGlobalPortInfo& global_ports, const VprNetlistAnnotation& netlist_annotation, const std::string& net_name_postfix, @@ -189,7 +190,7 @@ static void print_verilog_mock_fpga_wrapper_connect_ios( } /* For global ports, use wires; otherwise, use registers*/ if (true == port_is_fabric_global_reset_port( - global_ports, module_manager, + global_ports, module_manager, module_name_map, pin_constraints.net_pin(block_name))) { continue; } @@ -446,6 +447,7 @@ int print_verilog_mock_fpga_wrapper( const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const IoLocationMap& io_location_map, const IoNameMap& io_name_map, + const ModuleNameMap& module_name_map, const VprNetlistAnnotation& netlist_annotation, const std::string& circuit_name, const std::string& verilog_fname, const VerilogTestbenchOption& options) { @@ -472,7 +474,8 @@ int print_verilog_mock_fpga_wrapper( print_verilog_file_header(fp, title, options.time_stamp()); /* Find the top_module */ - ModuleId top_module = module_manager.find_module(options.dut_module()); + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); if (!module_manager.valid_module_id(top_module)) { VTR_LOG_ERROR( "Unable to find the DUT module '%s'. Please check if you create " @@ -483,8 +486,11 @@ int print_verilog_mock_fpga_wrapper( /* Note that we always need the core module as it contains the original port * names before possible renaming at top-level module. If there is no core * module, it means that the current top module is the core module */ - ModuleId core_module = - module_manager.find_module(generate_fpga_core_module_name()); + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); if (!module_manager.valid_module_id(core_module)) { core_module = top_module; } @@ -514,8 +520,8 @@ int print_verilog_mock_fpga_wrapper( /* Print local wires */ print_verilog_testbench_shared_input_ports( - fp, module_manager, global_ports, pin_constraints, atom_ctx, - netlist_annotation, benchmark_clock_port_names, true, + fp, module_manager, module_name_map, global_ports, pin_constraints, + atom_ctx, netlist_annotation, benchmark_clock_port_names, true, std::string(APPINST_PORT_POSTFIX), false); print_verilog_testbench_shared_benchmark_output_ports( @@ -541,8 +547,8 @@ int print_verilog_mock_fpga_wrapper( /* Connect I/Os to benchmark I/Os or constant driver */ print_verilog_mock_fpga_wrapper_connect_ios( fp, module_manager, core_module, atom_ctx, place_ctx, io_location_map, - require_io_naming ? io_name_map : IoNameMap(), pin_constraints, - global_ports, netlist_annotation, std::string(), + require_io_naming ? io_name_map : IoNameMap(), module_name_map, + pin_constraints, global_ports, netlist_annotation, std::string(), std::string(APPINST_PORT_POSTFIX), std::string(APPINST_PORT_POSTFIX), benchmark_clock_port_names, (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); diff --git a/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.h b/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.h index 4632811a6..3088db369 100644 --- a/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.h +++ b/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.h @@ -15,6 +15,7 @@ #include "io_location_map.h" #include "io_name_map.h" #include "module_manager.h" +#include "module_name_map.h" #include "pin_constraints.h" #include "verilog_testbench_options.h" #include "vpr_context.h" @@ -32,6 +33,7 @@ int print_verilog_mock_fpga_wrapper( const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const IoLocationMap& io_location_map, const IoNameMap& io_name_map, + const ModuleNameMap& module_name_map, const VprNetlistAnnotation& netlist_annotation, const std::string& circuit_name, const std::string& verilog_fname, const VerilogTestbenchOption& options); diff --git a/openfpga/src/fpga_verilog/verilog_mux.cpp b/openfpga/src/fpga_verilog/verilog_mux.cpp index 40df031e0..6fd2b2df4 100644 --- a/openfpga/src/fpga_verilog/verilog_mux.cpp +++ b/openfpga/src/fpga_verilog/verilog_mux.cpp @@ -643,12 +643,13 @@ static void generate_verilog_rram_mux_branch_module( static void generate_verilog_mux_branch_module( ModuleManager& module_manager, const CircuitLibrary& circuit_lib, std::fstream& fp, const CircuitModelId& mux_model, const MuxGraph& mux_graph, - const bool& use_explicit_port_map, + const ModuleNameMap& module_name_map, const bool& use_explicit_port_map, const e_verilog_default_net_type& default_net_type, std::map& branch_mux_module_is_outputted) { std::string module_name = generate_mux_branch_subckt_name( circuit_lib, mux_model, mux_graph.num_inputs(), mux_graph.num_memory_bits(), VERILOG_MUX_BASIS_POSTFIX); + module_name = module_name_map.name(module_name); /* Skip outputting if the module has already been outputted */ auto result = branch_mux_module_is_outputted.find(module_name); @@ -1400,13 +1401,14 @@ static void generate_verilog_rram_mux_module( static void generate_verilog_mux_module( ModuleManager& module_manager, const CircuitLibrary& circuit_lib, std::fstream& fp, const CircuitModelId& mux_model, const MuxGraph& mux_graph, - const bool& use_explicit_port_map, + const ModuleNameMap& module_name_map, const bool& use_explicit_port_map, const e_verilog_default_net_type& default_net_type) { std::string module_name = generate_mux_subckt_name(circuit_lib, mux_model, find_mux_num_datapath_inputs( circuit_lib, mux_model, mux_graph.num_inputs()), std::string("")); + module_name = module_name_map.name(module_name); /* Multiplexers built with different technology is in different organization */ @@ -1447,8 +1449,8 @@ static void generate_verilog_mux_module( static void print_verilog_submodule_mux_primitives( ModuleManager& module_manager, NetlistManager& netlist_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, const std::string& submodule_dir_name, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options) { /* Output primitive cells for MUX modules */ std::string verilog_fname(MUX_PRIMITIVES_VERILOG_FILE_NAME); std::string verilog_fpath(submodule_dir + verilog_fname); @@ -1484,8 +1486,8 @@ static void print_verilog_submodule_mux_primitives( for (auto branch_mux_graph : branch_mux_graphs) { generate_verilog_mux_branch_module( module_manager, circuit_lib, fp, mux_circuit_model, branch_mux_graph, - options.explicit_port_mapping(), options.default_net_type(), - branch_mux_module_is_outputted); + module_name_map, options.explicit_port_mapping(), + options.default_net_type(), branch_mux_module_is_outputted); } } @@ -1512,8 +1514,8 @@ static void print_verilog_submodule_mux_primitives( static void print_verilog_submodule_mux_top_modules( ModuleManager& module_manager, NetlistManager& netlist_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, const std::string& submodule_dir_name, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options) { /* Output top-level MUX modules */ std::string verilog_fname(MUXES_VERILOG_FILE_NAME); std::string verilog_fpath(submodule_dir + verilog_fname); @@ -1536,9 +1538,10 @@ static void print_verilog_submodule_mux_top_modules( const MuxGraph& mux_graph = mux_lib.mux_graph(mux); CircuitModelId mux_circuit_model = mux_lib.mux_circuit_model(mux); /* Create MUX circuits */ - generate_verilog_mux_module( - module_manager, circuit_lib, fp, mux_circuit_model, mux_graph, - options.explicit_port_mapping(), options.default_net_type()); + generate_verilog_mux_module(module_manager, circuit_lib, fp, + mux_circuit_model, mux_graph, module_name_map, + options.explicit_port_mapping(), + options.default_net_type()); } /* Close the file stream */ @@ -1566,20 +1569,18 @@ static void print_verilog_submodule_mux_top_modules( * - A Verilog netlist contains all the top-level * module for routing multiplexers **********************************************/ -void print_verilog_submodule_muxes(ModuleManager& module_manager, - NetlistManager& netlist_manager, - const MuxLibrary& mux_lib, - const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, - const std::string& submodule_dir_name, - const FabricVerilogOption& options) { - print_verilog_submodule_mux_primitives(module_manager, netlist_manager, - mux_lib, circuit_lib, submodule_dir, - submodule_dir_name, options); +void print_verilog_submodule_muxes( + ModuleManager& module_manager, NetlistManager& netlist_manager, + const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options) { + print_verilog_submodule_mux_primitives( + module_manager, netlist_manager, mux_lib, circuit_lib, module_name_map, + submodule_dir, submodule_dir_name, options); - print_verilog_submodule_mux_top_modules(module_manager, netlist_manager, - mux_lib, circuit_lib, submodule_dir, - submodule_dir_name, options); + print_verilog_submodule_mux_top_modules( + module_manager, netlist_manager, mux_lib, circuit_lib, module_name_map, + submodule_dir, submodule_dir_name, options); } } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_mux.h b/openfpga/src/fpga_verilog/verilog_mux.h index f21c99f5a..3657ff09f 100644 --- a/openfpga/src/fpga_verilog/verilog_mux.h +++ b/openfpga/src/fpga_verilog/verilog_mux.h @@ -10,6 +10,7 @@ #include "circuit_library.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_graph.h" #include "mux_library.h" #include "netlist_manager.h" @@ -21,13 +22,11 @@ /* begin namespace openfpga */ namespace openfpga { -void print_verilog_submodule_muxes(ModuleManager& module_manager, - NetlistManager& netlist_manager, - const MuxLibrary& mux_lib, - const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, - const std::string& submodule_dir_name, - const FabricVerilogOption& options); +void print_verilog_submodule_muxes( + ModuleManager& module_manager, NetlistManager& netlist_manager, + const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 0fa26c73f..e278ff9fa 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -19,6 +19,7 @@ #include "openfpga_reserved_words.h" #include "verilog_constants.h" #include "verilog_preconfig_top_module.h" +#include "verilog_preconfig_top_module_utils.h" #include "verilog_testbench_utils.h" #include "verilog_writer_utils.h" @@ -130,176 +131,6 @@ static void print_verilog_preconfig_top_module_ports( fp << std::endl; } -/******************************************************************** - * Print internal wires for the pre-configured FPGA top module - * The internal wires are tailored for the ports of FPGA top module - * which will be different in various configuration protocols - *******************************************************************/ -static void print_verilog_preconfig_top_module_internal_wires( - std::fstream &fp, const ModuleManager &module_manager, - const ModuleId &top_module) { - /* Validate the file stream */ - valid_file_stream(fp); - - /* Global ports of top-level module */ - print_verilog_comment(fp, - std::string("----- Local wires for FPGA fabric -----")); - for (const ModulePortId &module_port_id : - module_manager.module_ports(top_module)) { - BasicPort module_port = - module_manager.module_port(top_module, module_port_id); - /* Add a postfix to the internal wires to be different from other reserved - * ports */ - module_port.set_name( - module_port.get_name() + - std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); - fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" - << std::endl; - } - /* Add an empty line as a splitter */ - fp << std::endl; -} - -/******************************************************************** - * Connect global ports of FPGA top module to constants except: - * 1. operating clock, which should be wired to the clock port of - * this pre-configured FPGA top module - *******************************************************************/ -static int print_verilog_preconfig_top_module_connect_global_ports( - std::fstream &fp, const ModuleManager &module_manager, - const ModuleId &top_module, const PinConstraints &pin_constraints, - const FabricGlobalPortInfo &fabric_global_ports, - const std::vector &benchmark_clock_port_names) { - /* Validate the file stream */ - valid_file_stream(fp); - - print_verilog_comment( - fp, - std::string("----- Begin Connect Global ports of FPGA top module -----")); - - for (const FabricGlobalPortId &global_port_id : - fabric_global_ports.global_ports()) { - ModulePortId module_global_port_id = - fabric_global_ports.global_module_port(global_port_id); - VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT == - module_manager.port_type(top_module, module_global_port_id)); - BasicPort module_global_port = - module_manager.module_port(top_module, module_global_port_id); - /* Now, for operating clock port, we should wire it to the clock of - * benchmark! */ - if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) && - (false == fabric_global_ports.global_port_is_prog(global_port_id))) { - /* Wiring to each pin of the global port: benchmark clock is always 1-bit - */ - for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); - ++pin_id) { - BasicPort module_clock_pin( - module_global_port.get_name() + - std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), - module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]); - - /* If the clock port name is in the pin constraints, we should wire it - * to the constrained pin */ - std::string constrained_net_name = pin_constraints.pin_net(BasicPort( - module_global_port.get_name(), module_global_port.pins()[pin_id], - module_global_port.pins()[pin_id])); - - /* If constrained to an open net or there is no clock in the benchmark, - * we assign it to a default value */ - if ((true == pin_constraints.unmapped_net(constrained_net_name)) || - (true == benchmark_clock_port_names.empty())) { - std::vector default_values( - 1, fabric_global_ports.global_port_default_value(global_port_id)); - print_verilog_wire_constant_values(fp, module_clock_pin, - default_values); - continue; - } - - std::string clock_name_to_connect; - if (!pin_constraints.unconstrained_net(constrained_net_name)) { - clock_name_to_connect = constrained_net_name; - } else { - /* Otherwise, we must have a clear one-to-one clock net - * corresponding!!! */ - if (benchmark_clock_port_names.size() != - module_global_port.get_width()) { - VTR_LOG_ERROR( - "Unable to map %lu benchmark clocks to %lu clock pins of " - "FPGA!\nRequire clear pin constraints!\n", - benchmark_clock_port_names.size(), - module_global_port.get_width()); - return CMD_EXEC_FATAL_ERROR; - } - clock_name_to_connect = benchmark_clock_port_names[pin_id]; - } - - BasicPort benchmark_clock_pin(clock_name_to_connect, 1); - print_verilog_wire_connection(fp, module_clock_pin, benchmark_clock_pin, - false); - } - /* Finish, go to the next */ - continue; - } - - /* For other ports, give an default value */ - for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); - ++pin_id) { - BasicPort module_global_pin(module_global_port.get_name(), - module_global_port.pins()[pin_id], - module_global_port.pins()[pin_id]); - - /* If the global port name is in the pin constraints, we should wire it to - * the constrained pin */ - std::string constrained_net_name = - pin_constraints.pin_net(module_global_pin); - - module_global_pin.set_name( - module_global_port.get_name() + - std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); - - /* - If constrained to a given net in the benchmark, we connect the global - * pin to the net - * - If constrained to an open net in the benchmark, we assign it to a - * default value - */ - if ((false == pin_constraints.unconstrained_net(constrained_net_name)) && - (false == pin_constraints.unmapped_net(constrained_net_name))) { - BasicPort benchmark_pin(constrained_net_name, 1); - print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, - false); - } else { - VTR_ASSERT_SAFE(std::string(PIN_CONSTRAINT_OPEN_NET) == - constrained_net_name); - std::vector default_values( - module_global_pin.get_width(), - fabric_global_ports.global_port_default_value(global_port_id)); - /* For configuration done signals, we should enable them in - * preconfigured wrapper */ - if (fabric_global_ports.global_port_is_config_enable(global_port_id)) { - VTR_LOG( - "Config-enable port '%s' is detected with default value '%ld'", - module_global_pin.get_name().c_str(), - fabric_global_ports.global_port_default_value(global_port_id)); - default_values.clear(); - default_values.resize( - module_global_pin.get_width(), - 1 - fabric_global_ports.global_port_default_value(global_port_id)); - } - print_verilog_wire_constant_values(fp, module_global_pin, - default_values); - } - } - } - - print_verilog_comment( - fp, std::string("----- End Connect Global ports of FPGA top module -----")); - - /* Add an empty line as a splitter */ - fp << std::endl; - - return CMD_EXEC_SUCCESS; -} - /******************************************************************** * Impose the bitstream on the configuration memories * This function uses 'assign' syntax to impost the bitstream at mem port @@ -540,7 +371,8 @@ int print_verilog_preconfig_top_module( const FabricGlobalPortInfo &global_ports, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const PinConstraints &pin_constraints, const BusGroup &bus_group, const IoLocationMap &io_location_map, - const IoNameMap &io_name_map, const VprNetlistAnnotation &netlist_annotation, + const IoNameMap &io_name_map, const ModuleNameMap &module_name_map, + const VprNetlistAnnotation &netlist_annotation, const std::string &circuit_name, const std::string &verilog_fname, const VerilogTestbenchOption &options) { std::string timer_message = @@ -573,7 +405,8 @@ int print_verilog_preconfig_top_module( netlist_annotation, bus_group); /* Spot the dut module */ - ModuleId top_module = module_manager.find_module(options.dut_module()); + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); if (!module_manager.valid_module_id(top_module)) { VTR_LOG_ERROR( "Unable to find the DUT module '%s'. Please check if you create " @@ -584,15 +417,19 @@ int print_verilog_preconfig_top_module( /* Note that we always need the core module as it contains the original port * names before possible renaming at top-level module. If there is no core * module, it means that the current top module is the core module */ - ModuleId core_module = - module_manager.find_module(generate_fpga_core_module_name()); + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); if (!module_manager.valid_module_id(core_module)) { core_module = top_module; } /* Print internal wires */ - print_verilog_preconfig_top_module_internal_wires(fp, module_manager, - core_module); + print_verilog_preconfig_top_module_internal_wires( + fp, module_manager, core_module, + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); /* Instanciate FPGA top-level module */ print_verilog_testbench_fpga_instance( @@ -609,7 +446,8 @@ int print_verilog_preconfig_top_module( * signals! */ status = print_verilog_preconfig_top_module_connect_global_ports( fp, module_manager, core_module, pin_constraints, global_ports, - benchmark_clock_port_names); + benchmark_clock_port_names, + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX)); if (CMD_EXEC_FATAL_ERROR == status) { return status; } @@ -629,10 +467,10 @@ int print_verilog_preconfig_top_module( /* If we do have the core module, and the dut is specified as core module, the * hierarchy path when adding should be the instance name of the core module */ - std::string inst_name = generate_fpga_top_module_name(); + std::string inst_name = module_name_map.name(generate_fpga_top_module_name()); if (options.dut_module() == generate_fpga_core_module_name()) { - ModuleId parent_module = - module_manager.find_module(generate_fpga_top_module_name()); + ModuleId parent_module = module_manager.find_module( + module_name_map.name(generate_fpga_top_module_name())); inst_name = module_manager.instance_name(parent_module, core_module, 0); } diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h index 59501a15f..0d7f3edac 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h @@ -15,6 +15,7 @@ #include "io_location_map.h" #include "io_name_map.h" #include "module_manager.h" +#include "module_name_map.h" #include "pin_constraints.h" #include "verilog_testbench_options.h" #include "vpr_context.h" @@ -34,7 +35,8 @@ int print_verilog_preconfig_top_module( const FabricGlobalPortInfo& global_ports, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const IoLocationMap& io_location_map, - const IoNameMap& io_name_map, const VprNetlistAnnotation& netlist_annotation, + const IoNameMap& io_name_map, const ModuleNameMap& module_name_map, + const VprNetlistAnnotation& netlist_annotation, const std::string& circuit_name, const std::string& verilog_fname, const VerilogTestbenchOption& options); diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp new file mode 100644 index 000000000..944506c89 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.cpp @@ -0,0 +1,190 @@ +/******************************************************************** + * This file includes functions that are used to generate + * a Verilog module of a pre-configured FPGA fabric + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "openfpga_atom_netlist_utils.h" +#include "openfpga_digest.h" +#include "openfpga_naming.h" +#include "openfpga_port.h" +#include "verilog_preconfig_top_module_utils.h" +#include "verilog_writer_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Print internal wires for the pre-configured FPGA top module + * The internal wires are tailored for the ports of FPGA top module + * which will be different in various configuration protocols + *******************************************************************/ +void print_verilog_preconfig_top_module_internal_wires( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const std::string &port_postfix) { + /* Validate the file stream */ + valid_file_stream(fp); + + /* Global ports of top-level module */ + print_verilog_comment(fp, + std::string("----- Local wires for FPGA fabric -----")); + for (const ModulePortId &module_port_id : + module_manager.module_ports(top_module)) { + BasicPort module_port = + module_manager.module_port(top_module, module_port_id); + /* Add a postfix to the internal wires to be different from other reserved + * ports */ + module_port.set_name(module_port.get_name() + port_postfix); + fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" + << std::endl; + } + /* Add an empty line as a splitter */ + fp << std::endl; +} + +/******************************************************************** + * Connect global ports of FPGA top module to constants except: + * 1. operating clock, which should be wired to the clock port of + * this pre-configured FPGA top module + *******************************************************************/ +int print_verilog_preconfig_top_module_connect_global_ports( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const PinConstraints &pin_constraints, + const FabricGlobalPortInfo &fabric_global_ports, + const std::vector &benchmark_clock_port_names, + const std::string &port_postfix) { + /* Validate the file stream */ + valid_file_stream(fp); + + print_verilog_comment( + fp, + std::string("----- Begin Connect Global ports of FPGA top module -----")); + + for (const FabricGlobalPortId &global_port_id : + fabric_global_ports.global_ports()) { + ModulePortId module_global_port_id = + fabric_global_ports.global_module_port(global_port_id); + VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT == + module_manager.port_type(top_module, module_global_port_id)); + BasicPort module_global_port = + module_manager.module_port(top_module, module_global_port_id); + /* Now, for operating clock port, we should wire it to the clock of + * benchmark! */ + if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) && + (false == fabric_global_ports.global_port_is_prog(global_port_id))) { + /* Wiring to each pin of the global port: benchmark clock is always 1-bit + */ + for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); + ++pin_id) { + BasicPort module_clock_pin(module_global_port.get_name() + port_postfix, + module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id]); + + /* If the clock port name is in the pin constraints, we should wire it + * to the constrained pin */ + std::string constrained_net_name = pin_constraints.pin_net(BasicPort( + module_global_port.get_name(), module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id])); + + /* If constrained to an open net or there is no clock in the benchmark, + * we assign it to a default value */ + if ((true == pin_constraints.unmapped_net(constrained_net_name)) || + (true == benchmark_clock_port_names.empty())) { + std::vector default_values( + 1, fabric_global_ports.global_port_default_value(global_port_id)); + print_verilog_wire_constant_values(fp, module_clock_pin, + default_values); + continue; + } + + std::string clock_name_to_connect; + if (!pin_constraints.unconstrained_net(constrained_net_name)) { + clock_name_to_connect = constrained_net_name; + } else { + /* Otherwise, we must have a clear one-to-one clock net + * corresponding!!! */ + if (benchmark_clock_port_names.size() != + module_global_port.get_width()) { + VTR_LOG_ERROR( + "Unable to map %lu benchmark clocks to %lu clock pins of " + "FPGA!\nRequire clear pin constraints!\n", + benchmark_clock_port_names.size(), + module_global_port.get_width()); + return CMD_EXEC_FATAL_ERROR; + } + clock_name_to_connect = benchmark_clock_port_names[pin_id]; + } + + BasicPort benchmark_clock_pin(clock_name_to_connect, 1); + print_verilog_wire_connection(fp, module_clock_pin, benchmark_clock_pin, + false); + } + /* Finish, go to the next */ + continue; + } + + /* For other ports, give an default value */ + for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); + ++pin_id) { + BasicPort module_global_pin(module_global_port.get_name(), + module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id]); + + /* If the global port name is in the pin constraints, we should wire it to + * the constrained pin */ + std::string constrained_net_name = + pin_constraints.pin_net(module_global_pin); + + module_global_pin.set_name(module_global_port.get_name() + port_postfix); + + /* - If constrained to a given net in the benchmark, we connect the global + * pin to the net + * - If constrained to an open net in the benchmark, we assign it to a + * default value + */ + if ((false == pin_constraints.unconstrained_net(constrained_net_name)) && + (false == pin_constraints.unmapped_net(constrained_net_name))) { + BasicPort benchmark_pin(constrained_net_name, 1); + print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, + false); + } else { + VTR_ASSERT_SAFE(std::string(PIN_CONSTRAINT_OPEN_NET) == + constrained_net_name); + std::vector default_values( + module_global_pin.get_width(), + fabric_global_ports.global_port_default_value(global_port_id)); + /* For configuration done signals, we should enable them in + * preconfigured wrapper */ + if (fabric_global_ports.global_port_is_config_enable(global_port_id)) { + VTR_LOG( + "Config-enable port '%s' is detected with default value '%ld'", + module_global_pin.get_name().c_str(), + fabric_global_ports.global_port_default_value(global_port_id)); + default_values.clear(); + default_values.resize( + module_global_pin.get_width(), + 1 - fabric_global_ports.global_port_default_value(global_port_id)); + } + print_verilog_wire_constant_values(fp, module_global_pin, + default_values); + } + } + } + + print_verilog_comment( + fp, std::string("----- End Connect Global ports of FPGA top module -----")); + + /* Add an empty line as a splitter */ + fp << std::endl; + + return CMD_EXEC_SUCCESS; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h new file mode 100644 index 000000000..55c85eadd --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module_utils.h @@ -0,0 +1,44 @@ +#ifndef VERILOG_PRECONFIG_TOP_MODULE_UTILS_H +#define VERILOG_PRECONFIG_TOP_MODULE_UTILS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "bitstream_manager.h" +#include "bus_group.h" +#include "circuit_library.h" +#include "config_protocol.h" +#include "fabric_global_port_info.h" +#include "io_location_map.h" +#include "io_name_map.h" +#include "module_manager.h" +#include "module_name_map.h" +#include "pin_constraints.h" +#include "verilog_testbench_options.h" +#include "vpr_context.h" +#include "vpr_netlist_annotation.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void print_verilog_preconfig_top_module_internal_wires( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const std::string &port_postfix); + +int print_verilog_preconfig_top_module_connect_global_ports( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const PinConstraints &pin_constraints, + const FabricGlobalPortInfo &fabric_global_ports, + const std::vector &benchmark_clock_port_names, + const std::string &port_postfix); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index 1cf57dabb..dbe59e935 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -77,14 +77,22 @@ namespace openfpga { ********************************************************************/ static void print_verilog_routing_connection_box_unique_module( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const std::string& subckt_dir, const std::string& subckt_dir_name, - const RRGSB& rr_gsb, const t_rr_type& cb_type, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& subckt_dir, + const std::string& subckt_dir_name, const RRGSB& rr_gsb, + const t_rr_type& cb_type, const FabricVerilogOption& options) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)); std::string verilog_fname(generate_connection_block_netlist_name( cb_type, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); + std::string orig_module_name = + generate_connection_block_module_name(cb_type, gsb_coordinate); + if (module_name_map.name_exist(orig_module_name)) { + verilog_fname = generate_tile_module_netlist_name( + module_name_map.name(orig_module_name), + std::string(VERILOG_NETLIST_FILE_POSTFIX)); + } + std::string verilog_fpath(subckt_dir + verilog_fname); /* Create the file stream */ @@ -102,8 +110,8 @@ static void print_verilog_routing_connection_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId cb_module = module_manager.find_module( - generate_connection_block_module_name(cb_type, gsb_coordinate)); + std::string cb_module_name = module_name_map.name(orig_module_name); + ModuleId cb_module = module_manager.find_module(cb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); /* Write the verilog module */ @@ -191,13 +199,21 @@ static void print_verilog_routing_connection_box_unique_module( ********************************************************************/ static void print_verilog_routing_switch_box_unique_module( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const std::string& subckt_dir, const std::string& subckt_dir_name, - const RRGSB& rr_gsb, const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& subckt_dir, + const std::string& subckt_dir_name, const RRGSB& rr_gsb, + const FabricVerilogOption& options) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); std::string verilog_fname(generate_routing_block_netlist_name( SB_VERILOG_FILE_NAME_PREFIX, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); + std::string orig_module_name = + generate_switch_block_module_name(gsb_coordinate); + if (module_name_map.name_exist(orig_module_name)) { + verilog_fname = generate_tile_module_netlist_name( + module_name_map.name(orig_module_name), + std::string(VERILOG_NETLIST_FILE_POSTFIX)); + } std::string verilog_fpath(subckt_dir + verilog_fname); /* Create the file stream */ @@ -215,8 +231,8 @@ static void print_verilog_routing_switch_box_unique_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId sb_module = module_manager.find_module( - generate_switch_block_module_name(gsb_coordinate)); + std::string sb_module_name = module_name_map.name(orig_module_name); + ModuleId sb_module = module_manager.find_module(sb_module_name); VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Write the verilog module */ @@ -245,9 +261,9 @@ static void print_verilog_routing_switch_box_unique_module( *******************************************************************/ static void print_verilog_flatten_connection_block_modules( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, - const std::string& subckt_dir_name, const t_rr_type& cb_type, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, + const std::string& subckt_dir, const std::string& subckt_dir_name, + const t_rr_type& cb_type, const FabricVerilogOption& options) { /* Build unique X-direction connection block modules */ vtr::Point cb_range = device_rr_gsb.get_gsb_range(); @@ -262,8 +278,8 @@ static void print_verilog_flatten_connection_block_modules( continue; } print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, rr_gsb, - cb_type, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, rr_gsb, cb_type, options); } } } @@ -277,13 +293,11 @@ static void print_verilog_flatten_connection_block_modules( * 1. Connection blocks * 2. Switch blocks *******************************************************************/ -void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, - const ModuleManager& module_manager, - const DeviceRRGSB& device_rr_gsb, - const RRGraphView& rr_graph, - const std::string& subckt_dir, - const std::string& subckt_dir_name, - const FabricVerilogOption& options) { +void print_verilog_flatten_routing_modules( + NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, + const RRGraphView& rr_graph, const std::string& subckt_dir, + const std::string& subckt_dir_name, const FabricVerilogOption& options) { /* Create a vector to contain all the Verilog netlist names that have been * generated in this function */ std::vector netlist_names; @@ -298,18 +312,18 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, continue; } print_verilog_routing_switch_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, rr_gsb, - options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, rr_gsb, options); } } print_verilog_flatten_connection_block_modules( - netlist_manager, module_manager, device_rr_gsb, subckt_dir, subckt_dir_name, - CHANX, options); + netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, + subckt_dir_name, CHANX, options); print_verilog_flatten_connection_block_modules( - netlist_manager, module_manager, device_rr_gsb, subckt_dir, subckt_dir_name, - CHANY, options); + netlist_manager, module_manager, module_name_map, device_rr_gsb, subckt_dir, + subckt_dir_name, CHANY, options); } /******************************************************************** @@ -324,6 +338,7 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, *******************************************************************/ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, const std::string& subckt_dir_name, @@ -336,8 +351,8 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); print_verilog_routing_switch_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, - unique_mirror, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, unique_mirror, options); } /* Build unique X-direction connection block modules */ @@ -346,8 +361,8 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(CHANX, icb); print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, - unique_mirror, CHANX, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, unique_mirror, CHANX, options); } /* Build unique X-direction connection block modules */ @@ -356,8 +371,8 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(CHANY, icb); print_verilog_routing_connection_box_unique_module( - netlist_manager, module_manager, subckt_dir, subckt_dir_name, - unique_mirror, CHANY, options); + netlist_manager, module_manager, module_name_map, subckt_dir, + subckt_dir_name, unique_mirror, CHANY, options); } VTR_LOG("\n"); diff --git a/openfpga/src/fpga_verilog/verilog_routing.h b/openfpga/src/fpga_verilog/verilog_routing.h index 2766c1b2a..2450db35e 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.h +++ b/openfpga/src/fpga_verilog/verilog_routing.h @@ -8,6 +8,7 @@ #include "device_rr_gsb.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" #include "rr_graph_view.h" @@ -19,16 +20,15 @@ /* begin namespace openfpga */ namespace openfpga { -void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, - const ModuleManager& module_manager, - const DeviceRRGSB& device_rr_gsb, - const RRGraphView& rr_graph, - const std::string& subckt_dir, - const std::string& subckt_dir_name, - const FabricVerilogOption& options); +void print_verilog_flatten_routing_modules( + NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, + const RRGraphView& rr_graph, const std::string& subckt_dir, + const std::string& subckt_dir_name, const FabricVerilogOption& options); void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, const std::string& subckt_dir_name, diff --git a/openfpga/src/fpga_verilog/verilog_submodule.cpp b/openfpga/src/fpga_verilog/verilog_submodule.cpp index c73da4304..242e2402f 100644 --- a/openfpga/src/fpga_verilog/verilog_submodule.cpp +++ b/openfpga/src/fpga_verilog/verilog_submodule.cpp @@ -36,16 +36,19 @@ void print_verilog_submodule( ModuleManager& module_manager, NetlistManager& netlist_manager, const MemoryBankShiftRegisterBanks& blwl_sr_banks, const MuxLibrary& mux_lib, const DecoderLibrary& decoder_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, const std::string& submodule_dir_name, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& fpga_verilog_opts) { print_verilog_submodule_essentials( const_cast(module_manager), netlist_manager, - submodule_dir, submodule_dir_name, circuit_lib, fpga_verilog_opts); + submodule_dir, submodule_dir_name, circuit_lib, module_name_map, + fpga_verilog_opts); /* Decoders for architecture */ print_verilog_submodule_arch_decoders( const_cast(module_manager), netlist_manager, - decoder_lib, submodule_dir, submodule_dir_name, fpga_verilog_opts); + decoder_lib, module_name_map, submodule_dir, submodule_dir_name, + fpga_verilog_opts); /* Routing multiplexers */ /* NOTE: local decoders generation must go before the MUX generation!!! @@ -54,25 +57,29 @@ void print_verilog_submodule( */ print_verilog_submodule_mux_local_decoders( const_cast(module_manager), netlist_manager, mux_lib, - circuit_lib, submodule_dir, submodule_dir_name, fpga_verilog_opts); + circuit_lib, module_name_map, submodule_dir, submodule_dir_name, + fpga_verilog_opts); print_verilog_submodule_muxes(module_manager, netlist_manager, mux_lib, - circuit_lib, submodule_dir, submodule_dir_name, - fpga_verilog_opts); + circuit_lib, module_name_map, submodule_dir, + submodule_dir_name, fpga_verilog_opts); /* LUTes */ print_verilog_submodule_luts(const_cast(module_manager), - netlist_manager, circuit_lib, submodule_dir, - submodule_dir_name, fpga_verilog_opts); + netlist_manager, circuit_lib, module_name_map, + submodule_dir, submodule_dir_name, + fpga_verilog_opts); /* Hard wires */ print_verilog_submodule_wires( const_cast(module_manager), netlist_manager, - circuit_lib, submodule_dir, submodule_dir_name, fpga_verilog_opts); + circuit_lib, module_name_map, submodule_dir, submodule_dir_name, + fpga_verilog_opts); /* Memories */ print_verilog_submodule_memories( const_cast(module_manager), netlist_manager, mux_lib, - circuit_lib, submodule_dir, submodule_dir_name, fpga_verilog_opts); + circuit_lib, module_name_map, submodule_dir, submodule_dir_name, + fpga_verilog_opts); /* Shift register banks */ print_verilog_submodule_shift_register_banks( diff --git a/openfpga/src/fpga_verilog/verilog_submodule.h b/openfpga/src/fpga_verilog/verilog_submodule.h index 13f50d73a..894608601 100644 --- a/openfpga/src/fpga_verilog/verilog_submodule.h +++ b/openfpga/src/fpga_verilog/verilog_submodule.h @@ -8,6 +8,7 @@ #include "fabric_verilog_options.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" +#include "module_name_map.h" #include "mux_library.h" #include "netlist_manager.h" @@ -22,7 +23,8 @@ void print_verilog_submodule( ModuleManager& module_manager, NetlistManager& netlist_manager, const MemoryBankShiftRegisterBanks& blwl_sr_banks, const MuxLibrary& mux_lib, const DecoderLibrary& decoder_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir, const std::string& submodule_dir_name, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, + const std::string& submodule_dir_name, const FabricVerilogOption& fpga_verilog_opts); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.cpp b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp new file mode 100644 index 000000000..3f48d2a6c --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.cpp @@ -0,0 +1,132 @@ +/******************************************************************** + * This file includes functions that are used to generate + * a Verilog module of a pre-configured FPGA fabric + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "bitstream_manager_utils.h" +#include "openfpga_atom_netlist_utils.h" +#include "openfpga_digest.h" +#include "openfpga_naming.h" +#include "openfpga_port.h" +#include "openfpga_reserved_words.h" +#include "verilog_constants.h" +#include "verilog_preconfig_top_module_utils.h" +#include "verilog_template_testbench.h" +#include "verilog_testbench_utils.h" +#include "verilog_writer_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Top-level function to generate a template testbench for a FPGA fabric. + * + * Testbench + * +-------------------------------------------- + * | + * | FPGA fabric + * | +-------------------------------+ + * | | | + * | 0/1---->|FPGA global ports | + * | | | + * |--------->|FPGA_clock | + * | | | + * |--------->|FPGA mapped I/Os | + * | | | + * |<---------|FPGA mapped I/Os | + * | | | + * | 0/1---->|FPGA unmapped I/Os | + * | | | + * |--------->|Internal_configuration_ports | + * | +-------------------------------+ + * | + * +------------------------------------------- + *******************************************************************/ +int print_verilog_template_testbench(const ModuleManager &module_manager, + const IoNameMap &io_name_map, + const ModuleNameMap &module_name_map, + const std::string &verilog_fname, + const VerilogTestbenchOption &options) { + std::string timer_message = std::string( + "Write a template Verilog testbench for pre-configured FPGA top-level " + "netlist"); + + int status = CMD_EXEC_SUCCESS; + + /* Start time count */ + vtr::ScopedStartFinishTimer timer(timer_message); + + /* Create the file stream */ + std::fstream fp; + fp.open(verilog_fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(verilog_fname.c_str(), fp); + + /* Generate a brief description on the Verilog file*/ + std::string title = + std::string("A template Verilog testbench for pre-configured FPGA fabric"); + print_verilog_file_header(fp, title, options.time_stamp()); + + print_verilog_comment(fp, + std::string("Require an adaption to your needs before " + "used for design verification!!!")); + + print_verilog_default_net_type_declaration(fp, options.default_net_type()); + + /* Module declaration */ + fp << "module " << options.top_module(); + fp << ";" << std::endl; + + /* Spot the dut module */ + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); + if (!module_manager.valid_module_id(top_module)) { + VTR_LOG_ERROR( + "Unable to find the DUT module '%s'. Please check if you create " + "dedicated module when building the fabric!\n", + options.dut_module().c_str()); + return CMD_EXEC_FATAL_ERROR; + } + /* Note that we always need the core module as it contains the original port + * names before possible renaming at top-level module. If there is no core + * module, it means that the current top module is the core module */ + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); + if (!module_manager.valid_module_id(core_module)) { + core_module = top_module; + } + + /* Print internal wires */ + print_verilog_preconfig_top_module_internal_wires(fp, module_manager, + core_module, std::string()); + + /* Instanciate FPGA top-level module */ + print_verilog_testbench_fpga_instance( + fp, module_manager, top_module, core_module, + std::string(FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME), + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), io_name_map, + options.explicit_port_mapping()); + + /* Testbench ends*/ + print_verilog_module_end(fp, options.top_module(), + options.default_net_type()); + + /* Close the file stream */ + fp.close(); + + return status; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_template_testbench.h b/openfpga/src/fpga_verilog/verilog_template_testbench.h new file mode 100644 index 000000000..baa07cbc7 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_template_testbench.h @@ -0,0 +1,30 @@ +#ifndef VERILOG_TEMPLATE_TESTBENCH_H +#define VERILOG_TEMPLATE_TESTBENCH_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "io_name_map.h" +#include "module_manager.h" +#include "module_name_map.h" +#include "verilog_testbench_options.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int print_verilog_template_testbench(const ModuleManager &module_manager, + const IoNameMap &io_name_map, + const ModuleNameMap &module_name_map, + const std::string &verilog_fname, + const VerilogTestbenchOption &options); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp new file mode 100644 index 000000000..30018e400 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.cpp @@ -0,0 +1,111 @@ +/******************************************************************** + * This file includes functions that are used to generate + * a Verilog module of a pre-configured FPGA fabric + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "command_exit_codes.h" +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "openfpga_atom_netlist_utils.h" +#include "openfpga_digest.h" +#include "openfpga_naming.h" +#include "openfpga_port.h" +#include "openfpga_reserved_words.h" +#include "verilog_constants.h" +#include "verilog_preconfig_top_module_utils.h" +#include "verilog_testbench_io_connection.h" +#include "verilog_testbench_utils.h" +#include "verilog_writer_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Top-level function to generate the I/O connections for a pre-configured FPGA + *fabric. + *******************************************************************/ +int print_verilog_testbench_io_connection( + const ModuleManager &module_manager, const FabricGlobalPortInfo &global_ports, + const AtomContext &atom_ctx, const PlacementContext &place_ctx, + const PinConstraints &pin_constraints, const BusGroup &bus_group, + const IoLocationMap &io_location_map, const ModuleNameMap &module_name_map, + const VprNetlistAnnotation &netlist_annotation, + const std::string &circuit_name, const std::string &verilog_fname, + const VerilogTestbenchOption &options) { + std::string timer_message = std::string( + "Write I/O connections for pre-configured FPGA " + "fabric mapped to design '") + + circuit_name + std::string("'"); + + int status = CMD_EXEC_SUCCESS; + + /* Start time count */ + vtr::ScopedStartFinishTimer timer(timer_message); + + /* Create the file stream */ + std::fstream fp; + fp.open(verilog_fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(verilog_fname.c_str(), fp); + + /* Generate a brief description on the Verilog file*/ + std::string title = + std::string( + "I/O connections for a pre-configured FPGA fabric mapped to design: ") + + circuit_name; + print_verilog_file_header(fp, title, options.time_stamp()); + + /* Spot the dut module */ + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); + if (!module_manager.valid_module_id(top_module)) { + VTR_LOG_ERROR( + "Unable to find the DUT module '%s'. Please check if you create " + "dedicated module when building the fabric!\n", + options.dut_module().c_str()); + return CMD_EXEC_FATAL_ERROR; + } + /* Note that we always need the core module as it contains the original port + * names before possible renaming at top-level module. If there is no core + * module, it means that the current top module is the core module */ + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); + if (!module_manager.valid_module_id(core_module)) { + core_module = top_module; + } + + /* Find clock ports in benchmark */ + std::vector benchmark_clock_port_names = + find_atom_netlist_clock_port_names(atom_ctx.nlist, netlist_annotation); + + /* Connect FPGA top module global ports to constant or benchmark global + * signals! */ + status = print_verilog_preconfig_top_module_connect_global_ports( + fp, module_manager, core_module, pin_constraints, global_ports, + benchmark_clock_port_names, std::string()); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + + /* Connect I/Os to benchmark I/Os or constant driver */ + print_verilog_testbench_connect_fpga_ios( + fp, module_manager, core_module, atom_ctx, place_ctx, io_location_map, + netlist_annotation, bus_group, std::string(), std::string(), std::string(), + std::vector(), (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); + + /* Close the file stream */ + fp.close(); + + return status; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_testbench_io_connection.h b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.h new file mode 100644 index 000000000..9875c4d61 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_testbench_io_connection.h @@ -0,0 +1,38 @@ +#ifndef VERILOG_TESTBENCH_IO_CONNECTION_H +#define VERILOG_TESTBENCH_IO_CONNECTION_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "bus_group.h" +#include "fabric_global_port_info.h" +#include "io_location_map.h" +#include "module_manager.h" +#include "module_name_map.h" +#include "pin_constraints.h" +#include "verilog_testbench_options.h" +#include "vpr_context.h" +#include "vpr_netlist_annotation.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +int print_verilog_testbench_io_connection( + const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const AtomContext& atom_ctx, const PlacementContext& place_ctx, + const PinConstraints& pin_constraints, const BusGroup& bus_group, + const IoLocationMap& io_location_map, const ModuleNameMap& module_name_map, + const VprNetlistAnnotation& netlist_annotation, + const std::string& circuit_name, const std::string& verilog_fname, + const VerilogTestbenchOption& options); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp index 5e4709419..a6db0353b 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp @@ -15,6 +15,7 @@ namespace openfpga { *************************************************/ VerilogTestbenchOption::VerilogTestbenchOption() { output_directory_.clear(); + top_module_ = "top_tb"; dut_module_ = "fpga_top"; fabric_netlist_file_path_.clear(); reference_benchmark_file_path_.clear(); @@ -41,6 +42,8 @@ std::string VerilogTestbenchOption::output_directory() const { std::string VerilogTestbenchOption::dut_module() const { return dut_module_; } +std::string VerilogTestbenchOption::top_module() const { return top_module_; } + std::string VerilogTestbenchOption::fabric_netlist_file_path() const { return fabric_netlist_file_path_; } @@ -112,6 +115,19 @@ void VerilogTestbenchOption::set_output_directory( output_directory_ = output_dir; } +void VerilogTestbenchOption::set_top_module(const std::string& top_module) { + /* Precheck: avoid naming conflicts */ + if (top_module == generate_fpga_top_module_name() || + top_module == generate_fpga_core_module_name()) { + VTR_LOG_ERROR( + "Conflicted module name '%s' as top-levle module! Please avoid [%s|%s]\n", + top_module.c_str(), generate_fpga_top_module_name().c_str(), + generate_fpga_core_module_name().c_str()); + exit(1); + } + top_module_ = top_module; +} + void VerilogTestbenchOption::set_dut_module(const std::string& dut_module) { /* Precheck: only accept two legal names */ if (dut_module != generate_fpga_top_module_name() && diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.h b/openfpga/src/fpga_verilog/verilog_testbench_options.h index aafa15d71..97d2e27fd 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.h @@ -37,6 +37,7 @@ class VerilogTestbenchOption { public: /* Public accessors */ std::string output_directory() const; + std::string top_module() const; std::string dut_module() const; std::string fabric_netlist_file_path() const; std::string reference_benchmark_file_path() const; @@ -61,6 +62,7 @@ class VerilogTestbenchOption { public: /* Public mutators */ void set_output_directory(const std::string& output_dir); + void set_top_module(const std::string& top_module); void set_dut_module(const std::string& dut_module); /* The reference verilog file path is the key parameters that will have an * impact on other options: @@ -95,6 +97,7 @@ class VerilogTestbenchOption { private: /* Internal Data */ std::string output_directory_; + std::string top_module_; std::string dut_module_; std::string fabric_netlist_file_path_; std::string reference_benchmark_file_path_; diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index e3895c28d..4dbb879c9 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -818,7 +818,8 @@ void print_verilog_testbench_clock_stimuli( void print_verilog_testbench_random_stimuli( std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const std::vector& clock_port_names, const std::string& input_port_postfix, @@ -858,9 +859,9 @@ void print_verilog_testbench_random_stimuli( /* Bypass any constained net that are mapped to a global port of the FPGA * fabric because their stimulus cannot be random */ - if (true == - port_is_fabric_global_reset_port(global_ports, module_manager, - pin_constraints.net_pin(block_name))) { + if (true == port_is_fabric_global_reset_port( + global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name))) { continue; } @@ -942,9 +943,9 @@ void print_verilog_testbench_random_stimuli( /* Bypass any constained net that are mapped to a global port of the FPGA * fabric because their stimulus cannot be random */ - if (true == - port_is_fabric_global_reset_port(global_ports, module_manager, - pin_constraints.net_pin(block_name))) { + if (true == port_is_fabric_global_reset_port( + global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name))) { continue; } @@ -970,6 +971,7 @@ void print_verilog_testbench_random_stimuli( *******************************************************************/ void print_verilog_testbench_shared_input_ports( std::fstream& fp, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, @@ -1006,9 +1008,9 @@ void print_verilog_testbench_shared_input_ports( /* Each logical block assumes a single-width port */ BasicPort input_port(block_name + shared_input_port_postfix, 1); /* For global ports, use wires; otherwise, use registers*/ - if (false == - port_is_fabric_global_reset_port(global_ports, module_manager, - pin_constraints.net_pin(block_name))) { + if (false == port_is_fabric_global_reset_port( + global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name))) { if (use_reg_port) { fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";" << std::endl; @@ -1159,6 +1161,7 @@ void print_verilog_testbench_shared_check_flags( *******************************************************************/ void print_verilog_testbench_shared_ports( std::fstream& fp, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, @@ -1168,9 +1171,9 @@ void print_verilog_testbench_shared_ports( const std::string& fpga_output_port_postfix, const std::string& check_flag_port_postfix, const bool& no_self_checking) { print_verilog_testbench_shared_input_ports( - fp, module_manager, global_ports, pin_constraints, atom_ctx, - netlist_annotation, clock_port_names, false, shared_input_port_postfix, - true); + fp, module_manager, module_name_map, global_ports, pin_constraints, + atom_ctx, netlist_annotation, clock_port_names, false, + shared_input_port_postfix, true); print_verilog_testbench_shared_fpga_output_ports( fp, atom_ctx, netlist_annotation, fpga_output_port_postfix); diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 87059645f..243bd9904 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -14,6 +14,7 @@ #include "io_location_map.h" #include "io_name_map.h" #include "module_manager.h" +#include "module_name_map.h" #include "pin_constraints.h" #include "simulation_setting.h" #include "vpr_context.h" @@ -84,7 +85,8 @@ void print_verilog_testbench_clock_stimuli( void print_verilog_testbench_random_stimuli( std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const std::vector& clock_port_names, const std::string& input_port_postfix, @@ -93,6 +95,7 @@ void print_verilog_testbench_random_stimuli( void print_verilog_testbench_shared_input_ports( std::fstream& fp, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, @@ -117,6 +120,7 @@ void print_verilog_testbench_shared_check_flags( void print_verilog_testbench_shared_ports( std::fstream& fp, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, diff --git a/openfpga/src/fpga_verilog/verilog_tile.cpp b/openfpga/src/fpga_verilog/verilog_tile.cpp index 400695554..da32fc58c 100644 --- a/openfpga/src/fpga_verilog/verilog_tile.cpp +++ b/openfpga/src/fpga_verilog/verilog_tile.cpp @@ -26,13 +26,14 @@ namespace openfpga { *******************************************************************/ static int print_verilog_tile_module_netlist( NetlistManager& netlist_manager, const ModuleManager& module_manager, - const std::string& verilog_dir, const FabricTile& fabric_tile, - const FabricTileId& fabric_tile_id, const std::string& subckt_dir_name, - const FabricVerilogOption& options) { + const ModuleNameMap& module_name_map, const std::string& verilog_dir, + const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id, + const std::string& subckt_dir_name, const FabricVerilogOption& options) { /* Create a module as the top-level fabric, and add it to the module manager */ vtr::Point tile_coord = fabric_tile.tile_coordinate(fabric_tile_id); - std::string tile_module_name = generate_tile_module_name(tile_coord); + std::string tile_module_name = + module_name_map.name(generate_tile_module_name(tile_coord)); ModuleId tile_module = module_manager.find_module(tile_module_name); if (!module_manager.valid_module_id(tile_module)) { return CMD_EXEC_FATAL_ERROR; @@ -89,6 +90,7 @@ static int print_verilog_tile_module_netlist( *******************************************************************/ int print_verilog_tiles(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricTile& fabric_tile, const std::string& subckt_dir_name, @@ -100,8 +102,8 @@ int print_verilog_tiles(NetlistManager& netlist_manager, /* Build a module for each unique tile */ for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) { status_code = print_verilog_tile_module_netlist( - netlist_manager, module_manager, verilog_dir, fabric_tile, fabric_tile_id, - subckt_dir_name, options); + netlist_manager, module_manager, module_name_map, verilog_dir, + fabric_tile, fabric_tile_id, subckt_dir_name, options); if (status_code != CMD_EXEC_SUCCESS) { return CMD_EXEC_FATAL_ERROR; } diff --git a/openfpga/src/fpga_verilog/verilog_tile.h b/openfpga/src/fpga_verilog/verilog_tile.h index 03dac11ae..6fb6c63ef 100644 --- a/openfpga/src/fpga_verilog/verilog_tile.h +++ b/openfpga/src/fpga_verilog/verilog_tile.h @@ -9,6 +9,7 @@ #include "fabric_tile.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" /******************************************************************** @@ -20,6 +21,7 @@ namespace openfpga { int print_verilog_tiles(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricTile& fabric_tile, const std::string& subckt_dir_name, diff --git a/openfpga/src/fpga_verilog/verilog_top_module.cpp b/openfpga/src/fpga_verilog/verilog_top_module.cpp index fc87412ca..b8c302f21 100644 --- a/openfpga/src/fpga_verilog/verilog_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_module.cpp @@ -26,11 +26,15 @@ namespace openfpga { *******************************************************************/ void print_verilog_core_module(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricVerilogOption& options) { /* Create a module as the top-level fabric, and add it to the module manager */ std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } ModuleId core_module = module_manager.find_module(core_module_name); /* It could happen that the module does not exist, just return with no errors */ @@ -94,11 +98,13 @@ void print_verilog_core_module(NetlistManager& netlist_manager, *******************************************************************/ void print_verilog_top_module(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricVerilogOption& options) { /* Create a module as the top-level fabric, and add it to the module manager */ std::string top_module_name = generate_fpga_top_module_name(); + top_module_name = module_name_map.name(top_module_name); ModuleId top_module = module_manager.find_module(top_module_name); VTR_ASSERT(true == module_manager.valid_module_id(top_module)); diff --git a/openfpga/src/fpga_verilog/verilog_top_module.h b/openfpga/src/fpga_verilog/verilog_top_module.h index c10dd5e89..6a8259195 100644 --- a/openfpga/src/fpga_verilog/verilog_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_top_module.h @@ -8,6 +8,7 @@ #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" /******************************************************************** @@ -19,11 +20,13 @@ namespace openfpga { void print_verilog_core_module(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricVerilogOption& options); void print_verilog_top_module(NetlistManager& netlist_manager, const ModuleManager& module_manager, + const ModuleNameMap& module_name_map, const std::string& verilog_dir, const FabricVerilogOption& options); diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index a0993d079..2443abf5c 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -398,7 +398,7 @@ static void print_verilog_top_testbench_global_config_done_ports_stimuli( module_global_port)); BasicPort stimuli_config_done_port( - std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1); + std::string(TOP_TB_CONFIG_ALL_DONE_PORT_NAME), 1); /* Wire the port to the input stimuli: * The wiring will be inverted if the default value of the global port is 1 * Otherwise, the wiring will not be inverted! @@ -801,8 +801,8 @@ static void print_verilog_top_testbench_benchmark_clock_ports( *******************************************************************/ static void print_verilog_top_testbench_ports( std::fstream& fp, const ModuleManager& module_manager, - const ModuleId& top_module, const AtomContext& atom_ctx, - const VprNetlistAnnotation& netlist_annotation, + const ModuleNameMap& module_name_map, const ModuleId& top_module, + const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const std::vector& clock_port_names, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, @@ -950,8 +950,8 @@ static void print_verilog_top_testbench_ports( std::vector global_port_names; print_verilog_testbench_shared_ports( - fp, module_manager, global_ports, pin_constraints, atom_ctx, - netlist_annotation, clock_port_names, + fp, module_manager, module_name_map, global_ports, pin_constraints, + atom_ctx, netlist_annotation, clock_port_names, std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX), std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), @@ -1695,8 +1695,15 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( } else { VTR_ASSERT(num_prog_clocks > 1); for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { + std::vector curr_clk_ctrl_regions = + config_protocol.prog_clock_pin_ccff_head_indices( + config_protocol.prog_clock_pins()[iclk]); + size_t curr_regional_bitstream_max_size = + find_fabric_regional_bitstream_max_size(fabric_bitstream, + curr_clk_ctrl_regions); fp << "\t"; - fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << iclk << " <= 0"; + fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << iclk << " <= " + << regional_bitstream_max_size - curr_regional_bitstream_max_size; fp << ";"; fp << std::endl; } @@ -1905,9 +1912,12 @@ static void print_verilog_full_testbench_configuration_chain_bitstream( } else { VTR_ASSERT(num_prog_clocks > 1); for (size_t iclk = 0; iclk < num_prog_clocks; ++iclk) { + BasicPort curr_prog_clock_port(std::string(TOP_TB_PROG_CLOCK_PORT_NAME), + iclk, iclk); fp << "always"; fp << " @(negedge " - << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ")"; + << generate_verilog_port(VERILOG_PORT_CONKT, curr_prog_clock_port) + << ")"; fp << " begin"; fp << std::endl; @@ -2336,7 +2346,8 @@ static void print_verilog_full_testbench_bitstream( static void print_verilog_top_testbench_reset_stimuli( std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, const std::string& port_name_postfix, const std::vector& clock_port_names) { valid_file_stream(fp); @@ -2366,15 +2377,15 @@ static void print_verilog_top_testbench_reset_stimuli( /* Bypass any constained net that are mapped to a global port of the FPGA * fabric because their stimulus cannot be random */ - if (false == - port_is_fabric_global_reset_port(global_ports, module_manager, - pin_constraints.net_pin(block_name))) { + if (false == port_is_fabric_global_reset_port( + global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name))) { continue; } - size_t initial_value = - global_ports.global_port_default_value(find_fabric_global_port( - global_ports, module_manager, pin_constraints.net_pin(block_name))); + size_t initial_value = global_ports.global_port_default_value( + find_fabric_global_port(global_ports, module_manager, module_name_map, + pin_constraints.net_pin(block_name))); /* Connect stimuli to greset with an optional inversion, depending on the * default value */ @@ -2447,6 +2458,7 @@ int print_verilog_full_testbench( const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const std::string& bitstream_file, const IoLocationMap& io_location_map, const IoNameMap& io_name_map, + const ModuleNameMap& module_name_map, const VprNetlistAnnotation& netlist_annotation, const std::string& circuit_name, const std::string& verilog_fname, const SimulationSetting& simulation_parameters, @@ -2477,7 +2489,8 @@ int print_verilog_full_testbench( print_verilog_file_header(fp, title, options.time_stamp()); /* Spot the dut module */ - ModuleId top_module = module_manager.find_module(options.dut_module()); + ModuleId top_module = + module_manager.find_module(module_name_map.name(options.dut_module())); if (!module_manager.valid_module_id(top_module)) { VTR_LOG_ERROR( "Unable to find the DUT module '%s'. Please check if you create " @@ -2488,8 +2501,11 @@ int print_verilog_full_testbench( /* Note that we always need the core module as it contains the original port * names before possible renaming at top-level module. If there is no core * module, it means that the current top module is the core module */ - ModuleId core_module = - module_manager.find_module(generate_fpga_core_module_name()); + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); if (!module_manager.valid_module_id(core_module)) { core_module = top_module; } @@ -2516,9 +2532,9 @@ int print_verilog_full_testbench( /* Start of testbench */ print_verilog_top_testbench_ports( - fp, module_manager, core_module, atom_ctx, netlist_annotation, - clock_port_names, global_ports, pin_constraints, simulation_parameters, - config_protocol, circuit_name, options); + fp, module_manager, module_name_map, core_module, atom_ctx, + netlist_annotation, clock_port_names, global_ports, pin_constraints, + simulation_parameters, config_protocol, circuit_name, options); /* Find the clock period */ float prog_clock_period = @@ -2624,12 +2640,12 @@ int print_verilog_full_testbench( /* Add stimuli for reset, set, clock and iopad signals */ print_verilog_top_testbench_reset_stimuli( - fp, atom_ctx, netlist_annotation, module_manager, global_ports, - pin_constraints, std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), - clock_port_names); + fp, atom_ctx, netlist_annotation, module_manager, module_name_map, + global_ports, pin_constraints, + std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), clock_port_names); print_verilog_testbench_random_stimuli( - fp, atom_ctx, netlist_annotation, module_manager, global_ports, - pin_constraints, clock_port_names, + fp, atom_ctx, netlist_annotation, module_manager, module_name_map, + global_ports, pin_constraints, clock_port_names, std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX), std::vector( diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.h b/openfpga/src/fpga_verilog/verilog_top_testbench.h index 0e9b4865c..27a8d8311 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.h @@ -17,6 +17,7 @@ #include "io_name_map.h" #include "memory_bank_shift_register_banks.h" #include "module_manager.h" +#include "module_name_map.h" #include "pin_constraints.h" #include "simulation_setting.h" #include "verilog_testbench_options.h" @@ -40,6 +41,7 @@ int print_verilog_full_testbench( const PlacementContext& place_ctx, const PinConstraints& pin_constraints, const BusGroup& bus_group, const std::string& bitstream_file, const IoLocationMap& io_location_map, const IoNameMap& io_name_map, + const ModuleNameMap& module_name_map, const VprNetlistAnnotation& netlist_annotation, const std::string& circuit_name, const std::string& verilog_fname, const SimulationSetting& simulation_parameters, diff --git a/openfpga/src/fpga_verilog/verilog_wire.cpp b/openfpga/src/fpga_verilog/verilog_wire.cpp index 544c3b7c9..cc34957c8 100644 --- a/openfpga/src/fpga_verilog/verilog_wire.cpp +++ b/openfpga/src/fpga_verilog/verilog_wire.cpp @@ -34,6 +34,7 @@ namespace openfpga { static void print_verilog_wire_module( const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, std::fstream& fp, const CircuitModelId& wire_model, + const ModuleNameMap& module_name_map, const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -55,8 +56,8 @@ static void print_verilog_wire_module( /* Create a Verilog Module based on the circuit model, and add to module * manager */ - ModuleId wire_module = - module_manager.find_module(circuit_lib.model_name(wire_model)); + ModuleId wire_module = module_manager.find_module( + module_name_map.name(circuit_lib.model_name(wire_model))); VTR_ASSERT(true == module_manager.valid_module_id(wire_module)); /* dump module definition + ports */ @@ -106,6 +107,7 @@ static void print_verilog_wire_module( void print_verilog_submodule_wires(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, const std::string& submodule_dir_name, const FabricVerilogOption& options) { @@ -133,7 +135,7 @@ void print_verilog_submodule_wires(const ModuleManager& module_manager, continue; } print_verilog_wire_module(module_manager, circuit_lib, fp, model, - options.default_net_type()); + module_name_map, options.default_net_type()); } print_verilog_comment( fp, std::string("----- END Verilog modules for regular wires -----")); diff --git a/openfpga/src/fpga_verilog/verilog_wire.h b/openfpga/src/fpga_verilog/verilog_wire.h index 69cbe7f24..6b61558fb 100644 --- a/openfpga/src/fpga_verilog/verilog_wire.h +++ b/openfpga/src/fpga_verilog/verilog_wire.h @@ -10,6 +10,7 @@ #include "circuit_library.h" #include "fabric_verilog_options.h" #include "module_manager.h" +#include "module_name_map.h" #include "netlist_manager.h" #include "verilog_port_types.h" @@ -23,6 +24,7 @@ namespace openfpga { void print_verilog_submodule_wires(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, + const ModuleNameMap& module_name_map, const std::string& submodule_dir, const std::string& submodule_dir_name, const FabricVerilogOption& options); diff --git a/openfpga/src/utils/fabric_bitstream_utils.cpp b/openfpga/src/utils/fabric_bitstream_utils.cpp index d26eff686..eab11cb23 100644 --- a/openfpga/src/utils/fabric_bitstream_utils.cpp +++ b/openfpga/src/utils/fabric_bitstream_utils.cpp @@ -33,7 +33,7 @@ size_t find_fabric_regional_bitstream_max_size( for (const auto& region : fabric_bitstream.regions()) { if (!region_whitelist.empty() && (std::find(region_whitelist.begin(), region_whitelist.end(), - size_t(region)) != region_whitelist.end())) { + size_t(region)) == region_whitelist.end())) { continue; } if (regional_bitstream_max_size < @@ -65,7 +65,7 @@ size_t find_configuration_chain_fabric_bitstream_size_to_be_skipped( for (const auto& region : fabric_bitstream.regions()) { if (!region_whitelist.empty() && (std::find(region_whitelist.begin(), region_whitelist.end(), - size_t(region)) != region_whitelist.end())) { + size_t(region)) == region_whitelist.end())) { continue; } size_t curr_region_num_bits_to_skip = 0; diff --git a/openfpga/src/utils/fabric_global_port_info_utils.cpp b/openfpga/src/utils/fabric_global_port_info_utils.cpp index aaba4b123..39253d0ca 100644 --- a/openfpga/src/utils/fabric_global_port_info_utils.cpp +++ b/openfpga/src/utils/fabric_global_port_info_utils.cpp @@ -72,15 +72,19 @@ std::vector find_fabric_global_programming_set_ports( *******************************************************************/ bool port_is_fabric_global_reset_port( const FabricGlobalPortInfo& fabric_global_port_info, - const ModuleManager& module_manager, const BasicPort& port) { + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const BasicPort& port) { /* Find the top_module: the fabric global ports are always part of the ports * of the top/core module. If there is a core module, we should consider core * only */ - ModuleId top_module = - module_manager.find_module(generate_fpga_top_module_name()); + ModuleId top_module = module_manager.find_module( + module_name_map.name(generate_fpga_top_module_name())); VTR_ASSERT(true == module_manager.valid_module_id(top_module)); - ModuleId core_module = - module_manager.find_module(generate_fpga_core_module_name()); + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); if (module_manager.valid_module_id(core_module)) { top_module = core_module; } @@ -111,15 +115,19 @@ bool port_is_fabric_global_reset_port( *******************************************************************/ FabricGlobalPortId find_fabric_global_port( const FabricGlobalPortInfo& fabric_global_port_info, - const ModuleManager& module_manager, const BasicPort& port) { + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const BasicPort& port) { /* Find the top_module: the fabric global ports are always part of the ports * of the top/core module. If there is a core module, we should consider core * only */ - ModuleId top_module = - module_manager.find_module(generate_fpga_top_module_name()); + ModuleId top_module = module_manager.find_module( + module_name_map.name(generate_fpga_top_module_name())); VTR_ASSERT(true == module_manager.valid_module_id(top_module)); - ModuleId core_module = - module_manager.find_module(generate_fpga_core_module_name()); + std::string core_module_name = generate_fpga_core_module_name(); + if (module_name_map.name_exist(core_module_name)) { + core_module_name = module_name_map.name(core_module_name); + } + ModuleId core_module = module_manager.find_module(core_module_name); if (module_manager.valid_module_id(core_module)) { top_module = core_module; } diff --git a/openfpga/src/utils/fabric_global_port_info_utils.h b/openfpga/src/utils/fabric_global_port_info_utils.h index 5fd300337..0c2e2320c 100644 --- a/openfpga/src/utils/fabric_global_port_info_utils.h +++ b/openfpga/src/utils/fabric_global_port_info_utils.h @@ -8,6 +8,7 @@ #include "fabric_global_port_info.h" #include "module_manager.h" +#include "module_name_map.h" /******************************************************************** * Function declaration @@ -24,11 +25,13 @@ std::vector find_fabric_global_programming_set_ports( bool port_is_fabric_global_reset_port( const FabricGlobalPortInfo& fabric_global_port_info, - const ModuleManager& module_manager, const BasicPort& port); + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const BasicPort& port); FabricGlobalPortId find_fabric_global_port( const FabricGlobalPortInfo& fabric_global_port_info, - const ModuleManager& module_manager, const BasicPort& port); + const ModuleManager& module_manager, const ModuleNameMap& module_name_map, + const BasicPort& port); } /* end namespace openfpga */ diff --git a/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml new file mode 100644 index 000000000..a7c1a8bfa --- /dev/null +++ b/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + + + + + 10e-12 5e-12 5e-12 + + + 10e-12 5e-12 5e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga new file mode 100644 index 000000000..956451380 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga @@ -0,0 +1,63 @@ +# Run VPR for the 'and' design +# When the global clock is defined as a port of a tile, clock routing in VPR should be skipped +# This is due to the Fc_in of clock port is set to 0 for global wiring +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing ${OPENFPGA_GROUP_CONFIG_BLOCK_OPTIONS} ${OPENFPGA_GROUP_TILE_CONFIG_OPTIONS} #--verbose + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga index 978feaa56..cdb981da2 100644 --- a/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga @@ -45,7 +45,7 @@ build_architecture_bitstream --verbose --write_file fabric_independent_bitstream build_fabric_bitstream --verbose # Write fabric-dependent bitstream -write_fabric_bitstream --file fabric_bitstream.bit --format plain_text +write_fabric_bitstream --file fabric_bitstream.xml --format xml ${OPENFPGA_FABRIC_BITSTREAM_OPTIONS} # Write the Verilog netlist for FPGA fabric # - Enable the use of explicit port mapping in Verilog netlist diff --git a/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga new file mode 100644 index 000000000..18a919cd2 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga @@ -0,0 +1,74 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} --clock_modeling ideal + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing --group_config_block ${OPENFPGA_GROUP_TILE_CONFIG_OPTION} ${OPENFPGA_FABRIC_MODULE_NAME_OPTIONS} #--verbose +# Add a fpga core between fpga top and the underlying modules +${OPENFPGA_ADD_FPGA_CORE_MODULE} + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit + +# Write the SDC files for PnR backend +# - Turn on every options here +# FIXME: Not supported yet. +#write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +#write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +#write_analysis_sdc --file ./SDC_analysis + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga new file mode 100644 index 000000000..d087939c5 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga @@ -0,0 +1,84 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} --clock_modeling ideal ${OPENFPGA_VPR_EXTRA_OPTIONS} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Optionally pb pin fixup +${OPENFPGA_PB_PIN_FIXUP_COMMAND} + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing ${OPENFPGA_FABRIC_MODULE_NAME_OPTIONS} ${OPENFPGA_GROUP_TILE_CONFIG_OPTION} #--verbose +# Add a fpga core between fpga top and the underlying modules +${OPENFPGA_ADD_FPGA_CORE_MODULE} +# Output module naming for debugging. Comment it if not required +write_module_naming_rules --file module_names_before_renaming.xml +# Rename modules with a given rule +rename_modules --file ${OPENFPGA_RENAME_MODULE_FILE} +# Output module naming for debugging. Comment it if not required +write_module_naming_rules --file module_names_after_renaming.xml + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC ${OPENFPGA_VERILOG_TESTBENCH_OPTIONS} +write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_TESTBENCH_OPTIONS} + +# Write the SDC files for PnR backend +# - Turn on every options here +# FIXME: Not supported yet. +#write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +#write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +#write_analysis_sdc --file ./SDC_analysis + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga new file mode 100644 index 000000000..7f0f8eeaf --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga @@ -0,0 +1,57 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing #--verbose + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --verbose + +# Write template testbenches +write_testbench_template --file ./TESTBENCH/template_testbench.v --top_module template_top_tb ${OPENFPGA_VERILOG_PORT_MAPPING} +write_testbench_io_connection --file ./TESTBENCH/io_connections.v --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} --bus_group_file ${OPENFPGA_BUS_GROUP_FILE} + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 749765a33..e240b64dd 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -99,6 +99,7 @@ run-task basic_tests/generate_fabric $@ echo -e "Testing Verilog testbench generation only"; run-task basic_tests/generate_testbench $@ +run-task basic_tests/generate_template_testbench $@ echo -e "Testing separated Verilog fabric netlists and testbench locations"; run-task basic_tests/custom_fabric_netlist_location $@ @@ -202,9 +203,17 @@ run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile $@ run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape $@ run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile $@ +echo -e "Module naming"; +run-task basic_tests/module_naming/using_index $@ +run-task basic_tests/module_naming/renaming_rules $@ +run-task basic_tests/module_naming/renaming_rules_strong $@ +run-task basic_tests/module_naming/renaming_rules_on_indexed_names $@ + echo -e "Testing global port definition from tiles"; run-task basic_tests/global_tile_ports/global_tile_clock $@ run-task basic_tests/global_tile_ports/global_tile_clock_subtile $@ +run-task basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge $@ +run-task basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config $@ run-task basic_tests/global_tile_ports/global_tile_reset $@ run-task basic_tests/global_tile_ports/global_tile_4clock $@ run-task basic_tests/global_tile_ports/global_tile_4clock_pin $@ diff --git a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh index f5bb9a78f..184eceee9 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -45,3 +45,10 @@ run-task fpga_bitstream/report_bitstream_distribution/custom_depth $@ echo -e "Testing bitstream file with don't care bits"; run-task fpga_bitstream/dont_care_bits/ql_memory_bank_flatten $@ run-task fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register $@ + +echo -e "Testing bitstream file with selective contents"; +run-task fpga_bitstream/trim_path $@ +run-task fpga_bitstream/filter_value0 $@ +run-task fpga_bitstream/filter_value1 $@ +run-task fpga_bitstream/path_only $@ +run-task fpga_bitstream/value_only $@ diff --git a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh index 3cad92b31..46bf5cba9 100755 --- a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh @@ -140,6 +140,9 @@ echo -e "Testing through channels in tileable routing"; run-task fpga_verilog/thru_channel/thru_narrow_tile $@ run-task fpga_verilog/thru_channel/thru_wide_tile $@ +echo -e "Testing wire concatation in tileable routing"; +run-task fpga_verilog/rr_concat_wire $@ + echo -e "Testing the generation of preconfigured fabric wrapper for different HDL simulators"; run-task fpga_verilog/verilog_netlist_formats/embed_bitstream_none $@ run-task fpga_verilog/verilog_netlist_formats/embed_bitstream_modelsim $@ diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml new file mode 100644 index 000000000..a0fd22f77 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/counter8_bus_group.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml new file mode 100644 index 000000000..50a42a566 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/mac4_bus_group.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml new file mode 100644 index 000000000..9d692672b --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_dummy.xml @@ -0,0 +1,5 @@ + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf new file mode 100644 index 000000000..e869ac5a1 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/generate_template_testbench/config/task.conf @@ -0,0 +1,51 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_testbench_template_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_verilog_port_mapping=--explicit_port_mapping + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v +bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v +bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt +bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys + +bench0_top = counter +bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml +bench0_openfpga_bus_group_file=${PATH:TASK_DIR}/config/counter8_bus_group.xml + +bench1_top = mac_4 +bench1_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_dummy.xml +bench1_openfpga_bus_group_file=${PATH:TASK_DIR}/config/mac4_bus_group.xml + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge/config/task.conf new file mode 100644 index 000000000..adbbaa2cb --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge/config/task.conf @@ -0,0 +1,35 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=2x2_hybrid_io + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2_pipelined + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.conf new file mode 100644 index 000000000..dc9eacdb7 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/task.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 = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_options_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_registerable_io_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=2x2_hybrid_io +openfpga_group_tile_config_options=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_group_config_block_options=--group_config_block + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2_pipelined + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf index c8f54dda0..2da309cac 100644 --- a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile/config/task.conf @@ -26,6 +26,7 @@ openfpga_vpr_route_chan_width=60 openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml openfpga_verilog_testbench_options= openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml diff --git a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf index 8967adc33..8eb945a23 100644 --- a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape/config/task.conf @@ -26,6 +26,7 @@ openfpga_vpr_route_chan_width=60 openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml openfpga_verilog_testbench_options= openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileableL_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml diff --git a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf index a04c046d9..06aaf0e87 100644 --- a/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile/config/task.conf @@ -26,6 +26,7 @@ openfpga_vpr_route_chan_width=20 openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml openfpga_verilog_testbench_options=--explicit_port_mapping openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml new file mode 100644 index 000000000..3cdf37fcb --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/module_names.xml @@ -0,0 +1,4 @@ + + + + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf new file mode 100644 index 000000000..33318738a --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/task.conf @@ -0,0 +1,51 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_module_name_options= +openfpga_rename_module_file = ${PATH:TASK_DIR}/config/module_names.xml + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/module_names.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/module_names.xml new file mode 100644 index 000000000..96a11c378 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/module_names.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/task.conf b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/task.conf new file mode 100644 index 000000000..d11e17813 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/task.conf @@ -0,0 +1,51 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module=add_fpga_core_to_fabric --instance_name fpga_core_inst +openfpga_fabric_module_name_options=--name_module_using_index +openfpga_rename_module_file = ${PATH:TASK_DIR}/config/module_names.xml + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_on_indexed_names/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/module_names.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/module_names.xml new file mode 100644 index 000000000..709463de8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/module_names.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/task.conf b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/task.conf new file mode 100644 index 000000000..5ff7370f8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/task.conf @@ -0,0 +1,51 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/module_rename_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module=add_fpga_core_to_fabric --instance_name fpga_core_inst +openfpga_fabric_module_name_options= +openfpga_rename_module_file = ${PATH:TASK_DIR}/config/module_names.xml + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/renaming_rules_strong/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf new file mode 100644 index 000000000..f327229ec --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/task.conf @@ -0,0 +1,39 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/module_rename_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_add_fpga_core_module= +openfpga_vpr_device=4x4 +openfpga_vpr_route_chan_width=20 +openfpga_fabric_module_name_options=--name_module_using_index + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_TileOrgzTl_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = or2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/module_naming/using_index/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf new file mode 100644 index 000000000..2d68176e0 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--filter_value 0 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value0/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf new file mode 100644 index 000000000..56d0f79e2 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--filter_value 1 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/filter_value1/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf new file mode 100644 index 000000000..ce8eb7c70 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/path_only/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--path_only + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/path_only/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf new file mode 100644 index 000000000..a9032b322 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--trim_path + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/trim_path/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf new file mode 100644 index 000000000..16f68f62c --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/value_only/config/task.conf @@ -0,0 +1,56 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on +openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose +openfpga_vpr_device=3x2 +openfpga_vpr_route_chan_width=60 +openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml +openfpga_verilog_testbench_options= +openfpga_add_fpga_core_module= +openfpga_fabric_bitstream_options=--value_only + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +#end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml b/openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml new file mode 100644 index 000000000..1a1f3f6e8 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/value_only/config/tile_config.xml @@ -0,0 +1 @@ + diff --git a/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf b/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf index 989f8e09a..ae5896549 100644 --- a/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/lut_design/single_mode/config/task.conf @@ -19,7 +19,7 @@ fpga_flow=vpr_blif openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_example_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_N10_40nm_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml -openfpga_vpr_device_layout=2x2 +openfpga_vpr_device_layout=auto [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py new file mode 100644 index 000000000..3303aaf0a --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/bus_group_gen.py @@ -0,0 +1,173 @@ +##################################################################### +# A script to create a bus group file based on an input verilog file +# The bug group file is an input required by OpenFPGA +##################################################################### +import os +from os.path import dirname, abspath +import argparse +import logging +import subprocess +import hashlib +import yaml +import pyverilog +from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer +from xml.dom import minidom + +##################################################################### +# Error codes +##################################################################### +error_codes = { + "SUCCESS": 0, + "MD5_ERROR": 1, + "OPTION_ERROR": 2, + "FILE_ERROR": 3 +} + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO); + +##################################################################### +# Generate the string for a Verilog port +##################################################################### +def gen_verilog_port_str(port_name, msb, lsb): + port_str = str(port_name) + "[" + str(msb) + ":" + str(lsb) + "]" + return port_str + +##################################################################### +# Generate the string for a flatten Verilog port +##################################################################### +def gen_flatten_verilog_port_str(port_name, pin_id): + port_str = str(port_name) + "_" + str(pin_id) + "_" + return port_str + +##################################################################### +# Parse a verilog file and collect bus port information +##################################################################### +def parse_verilog_file_bus_ports(verilog_files, top_module): + # Check if verilog file exists + verilog_file_list = [] + for verilog_f in verilog_files: + print(verilog_f) + verilog_f_abspath = os.path.abspath(verilog_f["name"]) + if not os.path.exists(verilog_f_abspath): + raise IOError("file not found: " + verilog_f_abspath) + + verilog_file_list.append(verilog_f_abspath) + + # Parse verilog file + analyzer = VerilogDataflowAnalyzer(verilog_file_list, top_module) + analyzer.generate() + # Get port information + terms = analyzer.getTerms() + # Create XML tree + xml = minidom.Document() + bus_group = xml.createElement("bus_group") + xml.appendChild(bus_group) + for tk, tv in sorted(terms.items(), key=lambda x: str(x[0])): + logging.debug(tv.name) + logging.debug(tv.termtype) + logging.debug("[" + str(tv.lsb) + ":" + str(tv.msb) + "]") + for tk, tv in sorted(terms.items(), key=lambda x: str(x[0])): + # Skip ports that do not belong to top module + if (top_module != str(tv.name).split(".")[-2]): + continue + port_name = str(tv.name).split(".")[-1] + + # Skip minus lsb or msb, which are in don't care set + if (("Minus" == str(tv.lsb)) or ("Minus" == str(tv.msb))): + continue + port_lsb = int(str(tv.lsb)) + port_msb = int(str(tv.msb)) + # Only care input and outports + if ((not ("Input" in tv.termtype)) and (not ("Output" in tv.termtype))): + continue + # Only care bus (msb - lsb > 0) + if (abs(port_lsb - port_msb) == 0): + continue + # Reaching here, this is a bus port we need + # Get the second part of the name, which is the port name + cur_bus = xml.createElement("bus") + cur_bus.setAttribute("name", gen_verilog_port_str(port_name, port_msb, port_lsb)) + # Get if this is little endian or not + cur_bus.setAttribute("big_endian", "false") + if (port_lsb > port_msb): + cur_bus.setAttribute("big_endian", "true") + bus_group.appendChild(cur_bus) + # Add all the pins + for ipin in range(min([port_msb, port_lsb]), max([port_msb, port_lsb]) + 1): + cur_pin = xml.createElement("pin") + cur_pin.setAttribute('id', str(ipin)) + cur_pin.setAttribute('name', gen_flatten_verilog_port_str(port_name, ipin)) + cur_bus.appendChild(cur_pin) + + return xml, bus_group + +##################################################################### +# Generate bus group files with a given task list +##################################################################### +def generate_bus_group_files(task_db): + # Iterate over all the tasks + for verilog_fname in task_db.keys(): + space_limit = 120 + log_str = "Parsing verilog file: " + top_module_name = task_db[verilog_fname]["top_module"] + logging_space = "." * (space_limit - len(log_str) - len(top_module_name)) + logging.info(log_str + top_module_name) + xml, bus_group_data = parse_verilog_file_bus_ports(task_db[verilog_fname]["source"], top_module_name) + logging.info(log_str + top_module_name + logging_space + "Done") + # Write bus ports to an XML file + bus_group_frelname = task_db[verilog_fname]["bus_group_file"] + bus_group_fname = os.path.abspath(bus_group_frelname) + log_str = "Writing bus group file:" + logging_space = "." * (space_limit - len(log_str) - len(bus_group_frelname)) + logging.info(log_str + bus_group_frelname) + xml_str = xml.toprettyxml(indent="\t") + with open(bus_group_fname, "w") as bus_group_f: + bus_group_f.write(xml_str) + logging.info(log_str + bus_group_frelname + logging_space + "Done") + +##################################################################### +# Read task list from a yaml file +##################################################################### +def read_yaml_to_task_database(yaml_filename): + task_db = {} + with open(yaml_filename, 'r') as stream: + try: + task_db = yaml.load(stream, Loader=yaml.FullLoader) + logging.info("Found " + str(len(task_db)) + " tasks to create symbolic links") + except yaml.YAMLError as exc: + logging.error(exc) + exit(error_codes["FILE_ERROR"]); + + return task_db + +##################################################################### +# Write result database to a yaml file +##################################################################### +def write_result_database_to_yaml(result_db, yaml_filename): + with open(yaml_filename, 'w') as yaml_file: + yaml.dump(result_db, yaml_file, default_flow_style=False) + +##################################################################### +# Main function +##################################################################### +if __name__ == '__main__': + # Execute when the module is not initialized from an import statement + + # Parse the options and apply sanity checks + parser = argparse.ArgumentParser(description='Create bus group files for Verilog inputs') + parser.add_argument('--task_list', + required=True, + help='Configuration file in YAML format which contains a list of input Verilog and output bus group files') + args = parser.parse_args() + + # Create a database for tasks + task_db = {} + task_db = read_yaml_to_task_database(args.task_list) + + # Generate links based on the task list in database + generate_bus_group_files(task_db) + logging.info("Created " + str(len(task_db)) + " bus group files") + exit(error_codes["SUCCESS"]) diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml new file mode 100644 index 000000000..2c0a81258 --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/counter8_bus_group_task.yaml @@ -0,0 +1,5 @@ +counter8: + source: + - name: counter_output_verilog.v + top_module: counter + bus_group_file: bus_group.xml diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf new file mode 100644 index 000000000..39335966e --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/rr_concat_wire/config/task.conf @@ -0,0 +1,48 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/auto_bus_group_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_verilog_port_mapping=--explicit_port_mapping + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v +bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v +bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt +bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v +bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v +bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36 +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys + +bench0_top = counter +bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml +bench0_openfpga_bus_group_file=bus_group.xml + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/vpr_arch/README.md b/openfpga_flow/vpr_arch/README.md index cbec4f286..65f3c3d55 100644 --- a/openfpga_flow/vpr_arch/README.md +++ b/openfpga_flow/vpr_arch/README.md @@ -5,8 +5,9 @@ Please reveal the following architecture features in the names to help quickly s * The keyword 'frac' is to specify if fracturable LUT is used or not. * The keyword 'Native' is to specify if fracturable LUT design is a native one (without mode switch) or a standard one (with mode switch). - N: Number of logic elements for a CLB. If you have multiple CLB architectures, this should be largest number. -- tileable: If the routing architecture is tileable or not. +- tileable: If the routing architecture is tileable or not. * The keyword 'IO' specifies if the I/O tile is tileable or not + * The keyword 'ConcatWire' specifies if the routing wires can be continued in the same direction or not. For example, L4 -> L1 - fracff<2edge>: Use multi-mode flip-flop model, where reset/set polarity is configurable. When 2edge is specified, clock polarity can be switched between postive edge triggered and negative edge triggered - adder\_chain: If hard adder/carry chain is used inside CLBs - register\_chain: If shift register chain is used inside CLBs diff --git a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml index 3c32dbc99..33a4f4e56 100644 --- a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml @@ -67,7 +67,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml b/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml index b3b4110a3..2946ce80a 100644 --- a/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_frac_N4_tileable_adder_chain_40nm.xml @@ -103,7 +103,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml b/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml index 4706bb30f..634dacd64 100644 --- a/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_N10_tileable_40nm.xml @@ -67,7 +67,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml new file mode 100644 index 000000000..370341554 --- /dev/null +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileableConcatWire_adder_chain_dpram8K_dsp36_fracff_40nm.xml @@ -0,0 +1,1239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + io.outpad io.inpad + io.outpad io.inpad + io.outpad io.inpad + io.outpad io.inpad + + + + + + + + + + + + + + + + + + + + + + + + + + clb.clk clb.reset clb.set + clb.cin + clb.O[9:0] clb.I[19:0] + clb.cout clb.O[19:10] clb.I[39:20] + + + + + + + + + + + + + + + + + + + + + memory.clk + + memory.waddr[4:0] memory.raddr[4:0] memory.data_in[3:0] memory.wen memory.data_out[3:0] + memory.waddr[9:5] memory.raddr[9:5] memory.data_in[7:4] memory.ren memory.data_out[7:4] + + + + + + + + + + + + + + + + mult_36.b[0:9] mult_36.b[10:35] mult_36.out[36:71] + + mult_36.a[0:9] mult_36.a[10:35] mult_36.out[0:35] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 1 1 1 1 + 1 1 1 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 235e-12 + 235e-12 + 235e-12 + 235e-12 + 235e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 195e-12 + 195e-12 + 195e-12 + 195e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 261e-12 + 261e-12 + 261e-12 + 261e-12 + 261e-12 + 261e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml index b2eea07af..d0750f9ac 100644 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm.xml @@ -234,7 +234,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml index 0ae64adda..428a0e617 100644 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml @@ -302,7 +302,7 @@ - + diff --git a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml index 1190e3624..1b6f2760b 100755 --- a/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml +++ b/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml @@ -146,7 +146,7 @@ - + diff --git a/vtr-verilog-to-routing b/vtr-verilog-to-routing index 254d38faa..eb9722851 160000 --- a/vtr-verilog-to-routing +++ b/vtr-verilog-to-routing @@ -1 +1 @@ -Subproject commit 254d38faa02884c9b48d6a82e18fd54d9b567d44 +Subproject commit eb9722851bd3de03df7fb9ace5bdfb9cb078ca83 diff --git a/yosys b/yosys index 9e004426e..c95298225 160000 --- a/yosys +++ b/yosys @@ -1 +1 @@ -Subproject commit 9e004426e0783d5bbbe846be54b8266451cd5f7f +Subproject commit c95298225ddb5d5f7e193d5ab23aa969aa9628ff