Merge branch 'repack_debug' of github.com:lnis-uofu/OpenFPGA into repack_debug

This commit is contained in:
ubuntu 2023-11-28 02:05:32 -08:00
commit f4b406ad2f
195 changed files with 8238 additions and 816 deletions

View File

@ -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

View File

@ -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

View File

@ -1 +1 @@
1.2.1529
1.2.1769

View File

@ -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

View File

@ -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="<bool>"
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="<bool>"
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="<bool>"
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
<layout tileable="true" through_channel="false" shrink_boundary="false">
<layout tileable="true" through_channel="false" shrink_boundary="false" opin2all_sides="false" concat_wire="false" concat_pass_wire="false">
</layout>
Switch Block

View File

@ -62,12 +62,37 @@ Here is an example:
.. code-block:: xml
<tile_annotations>
<merge_subtile_ports tile="<string>" port="<string>"/>
<global_port name="<string>" is_clock="<bool>" clock_arch_tree_name="<string>" is_reset="<bool>" is_set="<bool>" default_val="<int>">
<tile name="<string>" port="<string>" x="<int>" y="<int>"/>
...
</global_port>
</tile_annotations>
For subtile port merge support (see an illustrative example in :numref:`fig_subtile_port_merge`):
- ``tile="<string>"`` is the name of tile, that is defined in VPR architecture
- ``port="<string>"`` 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="<string>"`` is the port name to appear in the top-level FPGA fabric.
- ``is_clock="<bool>"`` 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

View File

@ -0,0 +1,574 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="364.54 140.62 715.76 406.36" width="715.76" height="406.36">
<defs>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
<g>
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="black">
<g>
<path d="M 4.8 0 L 0 -1.8 L 0 1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
</defs>
<g id="concat_pass_wire" fill="none" stroke-opacity="1" fill-opacity="1" stroke="none" stroke-dasharray="none">
<title>concat_pass_wire</title>
<g id="concat_pass_wire_base">
<title>base</title>
<g id="Group_1411">
<g id="Graphic_362">
<rect x="403.24" y="178.38365" width="249.84" height="256.4605" fill="white"/>
<rect x="403.24" y="178.38365" width="249.84" height="256.4605" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_513">
<g id="Graphic_363">
<rect x="648.04" y="198.68417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="648.04" y="198.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_368">
<rect x="648.04" y="344.32614" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="648.04" y="344.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_367">
<rect x="648.04" y="228.232" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="648.04" y="228.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_366">
<rect x="648.04" y="257.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="257.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_510">
<rect x="648.04" y="289.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="289.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_509">
<rect x="648.04" y="316.87548" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="648.04" y="316.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_511">
<rect x="648.04" y="371.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="371.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_512">
<rect x="648.04" y="399.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="399.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_514">
<g id="Graphic_526">
<rect x="397.04" y="199.68417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="397.04" y="199.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_523">
<rect x="397.04" y="345.32614" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="397.04" y="345.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_522">
<rect x="397.04" y="229.232" width="12.96" height="12.96" fill="#80ff80"/>
<rect x="397.04" y="229.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_521">
<rect x="397.04" y="258.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="258.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_518">
<rect x="397.04" y="290.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="290.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_517">
<rect x="397.04" y="317.87548" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="397.04" y="317.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_516">
<rect x="397.04" y="372.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="372.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_515">
<rect x="397.04" y="400.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="400.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_527">
<g id="Graphic_539">
<rect x="623.53215" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="623.53215" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_536">
<rect x="477.8902" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="477.8902" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_535">
<rect x="593.9843" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="593.9843" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_534">
<rect x="564.4365" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="564.4365" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_531">
<rect x="532.7915" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="532.7915" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_530">
<rect x="505.34085" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="505.34085" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_529">
<rect x="450.4395" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="450.4395" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_528">
<rect x="422.98886" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="422.98886" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_540">
<g id="Graphic_552">
<rect x="623.53215" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="623.53215" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_549">
<rect x="477.8902" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="477.8902" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_548">
<rect x="593.9843" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="593.9843" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_547">
<rect x="564.4365" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="564.4365" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_544">
<rect x="532.7915" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="532.7915" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_543">
<rect x="505.34085" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="505.34085" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_542">
<rect x="450.4395" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="450.4395" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_541">
<rect x="422.98886" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="422.98886" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Line_972">
<line x1="429.88" y1="171.32417" x2="430.2512" y2="151.86237" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_973">
<line x1="457.52" y1="142.80835" x2="457.52" y2="160.58" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_975">
<line x1="485.16" y1="170.48" x2="485.5312" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_974">
<line x1="512.8" y1="141.96417" x2="512.8" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_979">
<line x1="540.44" y1="172.16835" x2="540.8112" y2="152.70655" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_978">
<line x1="571.26" y1="143.65253" x2="571.26" y2="161.42417" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_977">
<line x1="602.08" y1="170.48" x2="602.4512" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_976">
<line x1="629.72" y1="141.96417" x2="629.72" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_987">
<line x1="429.3205" y1="473.7113" x2="429.6917" y2="454.24953" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_986">
<line x1="456.9605" y1="445.1955" x2="456.9605" y2="462.96715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_985">
<line x1="484.6005" y1="472.86715" x2="484.9717" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_984">
<line x1="512.2405" y1="444.35133" x2="512.2405" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_983">
<line x1="539.8805" y1="474.5555" x2="540.2517" y2="455.0937" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_982">
<line x1="570.7005" y1="446.0397" x2="570.7005" y2="463.8113" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_981">
<line x1="601.5205" y1="472.86715" x2="601.8917" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_980">
<line x1="629.1605" y1="444.35133" x2="629.1605" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_988">
<line x1="366.04" y1="205.84416" x2="387.14035" y2="206.02432" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_989">
<line x1="397.04" y1="236.12417" x2="377.93965" y2="236.28225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_991">
<line x1="366.56" y1="265.72417" x2="387.14054" y2="265.94024" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_990">
<line x1="394.04" y1="297.32417" x2="374.93965" y2="297.48225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_995">
<line x1="367.56" y1="323.70746" x2="384.1407" y2="323.90783" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_994">
<line x1="396.04" y1="350.64746" x2="374.9397" y2="350.81083" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_993">
<line x1="365.56" y1="378.69075" x2="386.14054" y2="378.9068" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_992">
<line x1="395.04" y1="407.18746" x2="375.93965" y2="407.34554" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1378">
<line x1="665.5342" y1="204.64416" x2="704.1402" y2="204.89886" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1377">
<line x1="710.3468" y1="234.92417" x2="674.1398" y2="234.69445" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1376">
<line x1="666.20714" y1="264.52417" x2="701.11745" y2="264.77348" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1375">
<line x1="710.48684" y1="296.12417" x2="674.13986" y2="296.3128" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1374">
<line x1="667.5013" y1="322.50746" x2="700.5871" y2="322.75376" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1373">
<line x1="710.48684" y1="350.63164" x2="674.1379" y2="349.88955" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1372">
<line x1="665.2438" y1="377.49074" x2="704.14" y2="377.60306" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1371">
<line x1="708.5197" y1="405.63164" x2="674.7633" y2="405.3191" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1396">
<rect x="397.04" y="419.5437" width="12.96" height="12.96" fill="yellow"/>
<rect x="397.04" y="419.5437" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1412">
<g id="Graphic_1482">
<rect x="769" y="178.38365" width="249.84" height="256.4605" fill="white"/>
<rect x="769" y="178.38365" width="249.84" height="256.4605" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_1473">
<g id="Graphic_1481">
<rect x="1013.8" y="198.68417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="1013.8" y="198.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1480">
<rect x="1013.8" y="344.32614" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="1013.8" y="344.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1479">
<rect x="1013.8" y="228.232" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="1013.8" y="228.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1478">
<rect x="1013.8" y="257.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="257.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1477">
<rect x="1013.8" y="289.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="289.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1476">
<rect x="1013.8" y="316.87548" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="1013.8" y="316.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1475">
<rect x="1013.8" y="371.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="371.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1474">
<rect x="1013.8" y="399.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="399.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1464">
<g id="Graphic_1472">
<rect x="762.8" y="199.68417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="762.8" y="199.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1471">
<rect x="762.8" y="345.32614" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="762.8" y="345.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1470">
<rect x="762.8" y="229.232" width="12.96" height="12.96" fill="#80ff80"/>
<rect x="762.8" y="229.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1469">
<rect x="762.8" y="258.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="258.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1468">
<rect x="762.8" y="290.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="290.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1467">
<rect x="762.8" y="317.87548" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="762.8" y="317.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1466">
<rect x="762.8" y="372.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="372.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1465">
<rect x="762.8" y="400.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="400.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1455">
<g id="Graphic_1463">
<rect x="989.2921" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="989.2921" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1462">
<rect x="843.6502" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="843.6502" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1461">
<rect x="959.7443" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="959.7443" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1460">
<rect x="930.1965" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="930.1965" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1459">
<rect x="898.5515" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="898.5515" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1458">
<rect x="871.1008" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="871.1008" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1457">
<rect x="816.1995" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="816.1995" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1456">
<rect x="788.7489" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="788.7489" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1446">
<g id="Graphic_1454">
<rect x="989.2921" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="989.2921" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1453">
<rect x="843.6502" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="843.6502" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1452">
<rect x="959.7443" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="959.7443" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1451">
<rect x="930.1965" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="930.1965" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1450">
<rect x="898.5515" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="898.5515" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1449">
<rect x="871.1008" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="871.1008" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1448">
<rect x="816.1995" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="816.1995" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1447">
<rect x="788.7489" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="788.7489" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Line_1445">
<line x1="795.64" y1="171.32417" x2="796.0112" y2="151.86237" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1444">
<line x1="823.28" y1="142.80835" x2="823.28" y2="160.58" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1443">
<line x1="850.92" y1="170.48" x2="851.2912" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1442">
<line x1="878.56" y1="141.96417" x2="878.56" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1441">
<line x1="906.2" y1="172.16835" x2="906.5712" y2="152.70655" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1440">
<line x1="937.02" y1="143.65253" x2="937.02" y2="161.42417" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1439">
<line x1="967.84" y1="170.48" x2="968.2112" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1438">
<line x1="995.48" y1="141.96417" x2="995.48" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1437">
<line x1="795.0805" y1="473.7113" x2="795.4517" y2="454.24953" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1436">
<line x1="822.7205" y1="445.1955" x2="822.7205" y2="462.96715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1435">
<line x1="850.3605" y1="472.86715" x2="850.7317" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1434">
<line x1="878.0005" y1="444.35133" x2="878.0005" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1433">
<line x1="905.6405" y1="474.5555" x2="906.0117" y2="455.0937" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1432">
<line x1="936.4605" y1="446.0397" x2="936.4605" y2="463.8113" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1431">
<line x1="967.2805" y1="472.86715" x2="967.6517" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1430">
<line x1="994.9205" y1="444.35133" x2="994.9205" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1429">
<line x1="731.8" y1="205.84416" x2="752.90035" y2="206.02432" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1428">
<line x1="762.8" y1="236.12417" x2="743.69964" y2="236.28225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1427">
<line x1="732.32" y1="265.72417" x2="752.9005" y2="265.94024" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1426">
<line x1="759.8" y1="297.32417" x2="740.69964" y2="297.48225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1425">
<line x1="733.32" y1="323.70746" x2="749.9007" y2="323.90783" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1424">
<line x1="761.8" y1="350.64746" x2="740.6997" y2="350.81083" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1423">
<line x1="731.32" y1="378.69075" x2="751.9005" y2="378.9068" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1422">
<line x1="760.8" y1="407.18746" x2="741.69964" y2="407.34554" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1421">
<line x1="1031.2942" y1="204.64416" x2="1069.9002" y2="204.89886" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1420">
<line x1="1076.1068" y1="234.92417" x2="1039.8998" y2="234.69445" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1419">
<line x1="1031.9671" y1="264.52417" x2="1066.8774" y2="264.77348" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1418">
<line x1="1076.2468" y1="296.12417" x2="1039.8998" y2="296.3128" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1417">
<line x1="1033.2613" y1="322.50746" x2="1066.3471" y2="322.75376" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1416">
<line x1="1076.2468" y1="350.63164" x2="1039.8979" y2="349.88955" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1415">
<line x1="1031.0038" y1="377.49074" x2="1069.9" y2="377.60306" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1414">
<line x1="1074.2797" y1="405.63164" x2="1040.5233" y2="405.3191" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1413">
<rect x="762.8" y="419.5437" width="12.96" height="12.96" fill="yellow"/>
<rect x="762.8" y="419.5437" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
</g>
<g id="concat_pass_wire_wires">
<title>wires</title>
<g id="Line_1501">
<line x1="410" y1="266" x2="562.93445" y2="420.82253" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1509">
<line x1="776.16" y1="266" x2="788.8524" y2="196.19192" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1508">
<line x1="776.16" y1="266" x2="1001.6421" y2="209.8603" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1507">
<line x1="776.16" y1="266" x2="929.0944" y2="420.82253" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</g>
<g id="concat_pass_wire_legend">
<title>legend</title>
<g id="Graphic_1490">
<text transform="translate(366.54814 145.5255)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">(a)</tspan>
</text>
</g>
<g id="Graphic_1499">
<rect x="505.44" y="488.88" width="454.32" height="57.6" fill="white"/>
<rect x="505.44" y="488.88" width="454.32" height="57.6" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1498">
<rect x="514.1" y="496.6278" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="514.1" y="496.6278" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1497">
<text transform="translate(538.1717 492.45767)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">Starting routing tracks</tspan>
</text>
</g>
<g id="Graphic_1496">
<rect x="725.2653" y="496.58" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="725.2653" y="496.58" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1495">
<text transform="translate(741.1591 492.45767)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="2.25" y="16">Ending routing tracks </tspan>
</text>
</g>
<g id="Graphic_1494">
<rect x="514.1" y="522.5078" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="514.1" y="522.5078" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1493">
<text transform="translate(532.7875 517.6055)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="2.25" y="16">Passing routing tracks </tspan>
</text>
</g>
<g id="Graphic_1492">
<rect x="725.2653" y="523.5078" width="12.96" height="12.96" fill="yellow"/>
<rect x="725.2653" y="523.5078" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1491">
<text transform="translate(753.9636 518.6055)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">Output pin of blocks</tspan>
</text>
</g>
<g id="Graphic_1500">
<text transform="translate(751.7481 145.5255)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">(b)</tspan>
</text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,580 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="364.54 140.62 715.76 406.36" width="715.76" height="406.36">
<defs>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
<g>
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="black">
<g>
<path d="M 4.8 0 L 0 -1.8 L 0 1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
</defs>
<g id="concat_wire" fill="none" stroke-opacity="1" fill-opacity="1" stroke="none" stroke-dasharray="none">
<title>concat_wire</title>
<g id="concat_wire_base">
<title>base</title>
<g id="Group_1411">
<g id="Graphic_362">
<rect x="403.24" y="178.38365" width="249.84" height="256.4605" fill="white"/>
<rect x="403.24" y="178.38365" width="249.84" height="256.4605" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_513">
<g id="Graphic_363">
<rect x="648.04" y="198.68417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="648.04" y="198.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_368">
<rect x="648.04" y="344.32614" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="648.04" y="344.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_367">
<rect x="648.04" y="228.232" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="648.04" y="228.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_366">
<rect x="648.04" y="257.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="257.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_510">
<rect x="648.04" y="289.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="289.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_509">
<rect x="648.04" y="316.87548" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="648.04" y="316.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_511">
<rect x="648.04" y="371.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="371.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_512">
<rect x="648.04" y="399.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="399.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_514">
<g id="Graphic_526">
<rect x="397.04" y="199.68417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="397.04" y="199.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_523">
<rect x="397.04" y="345.32614" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="397.04" y="345.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_522">
<rect x="397.04" y="229.232" width="12.96" height="12.96" fill="#80ff80"/>
<rect x="397.04" y="229.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_521">
<rect x="397.04" y="258.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="258.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_518">
<rect x="397.04" y="290.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="290.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_517">
<rect x="397.04" y="317.87548" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="397.04" y="317.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_516">
<rect x="397.04" y="372.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="372.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_515">
<rect x="397.04" y="400.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="400.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_527">
<g id="Graphic_539">
<rect x="623.53215" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="623.53215" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_536">
<rect x="477.8902" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="477.8902" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_535">
<rect x="593.9843" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="593.9843" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_534">
<rect x="564.4365" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="564.4365" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_531">
<rect x="532.7915" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="532.7915" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_530">
<rect x="505.34085" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="505.34085" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_529">
<rect x="450.4395" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="450.4395" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_528">
<rect x="422.98886" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="422.98886" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_540">
<g id="Graphic_552">
<rect x="623.53215" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="623.53215" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_549">
<rect x="477.8902" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="477.8902" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_548">
<rect x="593.9843" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="593.9843" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_547">
<rect x="564.4365" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="564.4365" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_544">
<rect x="532.7915" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="532.7915" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_543">
<rect x="505.34085" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="505.34085" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_542">
<rect x="450.4395" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="450.4395" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_541">
<rect x="422.98886" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="422.98886" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Line_972">
<line x1="429.88" y1="171.32417" x2="430.2512" y2="151.86237" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_973">
<line x1="457.52" y1="142.80835" x2="457.52" y2="160.58" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_975">
<line x1="485.16" y1="170.48" x2="485.5312" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_974">
<line x1="512.8" y1="141.96417" x2="512.8" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_979">
<line x1="540.44" y1="172.16835" x2="540.8112" y2="152.70655" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_978">
<line x1="571.26" y1="143.65253" x2="571.26" y2="161.42417" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_977">
<line x1="602.08" y1="170.48" x2="602.4512" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_976">
<line x1="629.72" y1="141.96417" x2="629.72" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_987">
<line x1="429.3205" y1="473.7113" x2="429.6917" y2="454.24953" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_986">
<line x1="456.9605" y1="445.1955" x2="456.9605" y2="462.96715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_985">
<line x1="484.6005" y1="472.86715" x2="484.9717" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_984">
<line x1="512.2405" y1="444.35133" x2="512.2405" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_983">
<line x1="539.8805" y1="474.5555" x2="540.2517" y2="455.0937" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_982">
<line x1="570.7005" y1="446.0397" x2="570.7005" y2="463.8113" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_981">
<line x1="601.5205" y1="472.86715" x2="601.8917" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_980">
<line x1="629.1605" y1="444.35133" x2="629.1605" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_988">
<line x1="366.04" y1="205.84416" x2="387.14035" y2="206.02432" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_989">
<line x1="397.04" y1="236.12417" x2="377.93965" y2="236.28225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_991">
<line x1="366.56" y1="265.72417" x2="387.14054" y2="265.94024" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_990">
<line x1="394.04" y1="297.32417" x2="374.93965" y2="297.48225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_995">
<line x1="367.56" y1="323.70746" x2="384.1407" y2="323.90783" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_994">
<line x1="396.04" y1="350.64746" x2="374.9397" y2="350.81083" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_993">
<line x1="365.56" y1="378.69075" x2="386.14054" y2="378.9068" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_992">
<line x1="395.04" y1="407.18746" x2="375.93965" y2="407.34554" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1378">
<line x1="665.5342" y1="204.64416" x2="704.1402" y2="204.89886" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1377">
<line x1="710.3468" y1="234.92417" x2="674.1398" y2="234.69445" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1376">
<line x1="666.20714" y1="264.52417" x2="701.11745" y2="264.77348" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1375">
<line x1="710.48684" y1="296.12417" x2="674.13986" y2="296.3128" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1374">
<line x1="667.5013" y1="322.50746" x2="700.5871" y2="322.75376" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1373">
<line x1="710.48684" y1="350.63164" x2="674.1379" y2="349.88955" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1372">
<line x1="665.2438" y1="377.49074" x2="704.14" y2="377.60306" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1371">
<line x1="708.5197" y1="405.63164" x2="674.7633" y2="405.3191" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1396">
<rect x="397.04" y="419.5437" width="12.96" height="12.96" fill="yellow"/>
<rect x="397.04" y="419.5437" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1412">
<g id="Graphic_1482">
<rect x="769" y="178.38365" width="249.84" height="256.4605" fill="white"/>
<rect x="769" y="178.38365" width="249.84" height="256.4605" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_1473">
<g id="Graphic_1481">
<rect x="1013.8" y="198.68417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="1013.8" y="198.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1480">
<rect x="1013.8" y="344.32614" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="1013.8" y="344.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1479">
<rect x="1013.8" y="228.232" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="1013.8" y="228.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1478">
<rect x="1013.8" y="257.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="257.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1477">
<rect x="1013.8" y="289.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="289.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1476">
<rect x="1013.8" y="316.87548" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="1013.8" y="316.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1475">
<rect x="1013.8" y="371.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="371.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1474">
<rect x="1013.8" y="399.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="399.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1464">
<g id="Graphic_1472">
<rect x="762.8" y="199.68417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="762.8" y="199.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1471">
<rect x="762.8" y="345.32614" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="762.8" y="345.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1470">
<rect x="762.8" y="229.232" width="12.96" height="12.96" fill="#80ff80"/>
<rect x="762.8" y="229.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1469">
<rect x="762.8" y="258.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="258.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1468">
<rect x="762.8" y="290.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="290.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1467">
<rect x="762.8" y="317.87548" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="762.8" y="317.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1466">
<rect x="762.8" y="372.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="372.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1465">
<rect x="762.8" y="400.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="400.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1455">
<g id="Graphic_1463">
<rect x="989.2921" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="989.2921" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1462">
<rect x="843.6502" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="843.6502" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1461">
<rect x="959.7443" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="959.7443" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1460">
<rect x="930.1965" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="930.1965" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1459">
<rect x="898.5515" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="898.5515" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1458">
<rect x="871.1008" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="871.1008" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1457">
<rect x="816.1995" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="816.1995" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1456">
<rect x="788.7489" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="788.7489" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1446">
<g id="Graphic_1454">
<rect x="989.2921" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="989.2921" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1453">
<rect x="843.6502" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="843.6502" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1452">
<rect x="959.7443" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="959.7443" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1451">
<rect x="930.1965" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="930.1965" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1450">
<rect x="898.5515" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="898.5515" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1449">
<rect x="871.1008" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="871.1008" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1448">
<rect x="816.1995" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="816.1995" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1447">
<rect x="788.7489" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="788.7489" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Line_1445">
<line x1="795.64" y1="171.32417" x2="796.0112" y2="151.86237" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1444">
<line x1="823.28" y1="142.80835" x2="823.28" y2="160.58" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1443">
<line x1="850.92" y1="170.48" x2="851.2912" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1442">
<line x1="878.56" y1="141.96417" x2="878.56" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1441">
<line x1="906.2" y1="172.16835" x2="906.5712" y2="152.70655" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1440">
<line x1="937.02" y1="143.65253" x2="937.02" y2="161.42417" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1439">
<line x1="967.84" y1="170.48" x2="968.2112" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1438">
<line x1="995.48" y1="141.96417" x2="995.48" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1437">
<line x1="795.0805" y1="473.7113" x2="795.4517" y2="454.24953" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1436">
<line x1="822.7205" y1="445.1955" x2="822.7205" y2="462.96715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1435">
<line x1="850.3605" y1="472.86715" x2="850.7317" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1434">
<line x1="878.0005" y1="444.35133" x2="878.0005" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1433">
<line x1="905.6405" y1="474.5555" x2="906.0117" y2="455.0937" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1432">
<line x1="936.4605" y1="446.0397" x2="936.4605" y2="463.8113" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1431">
<line x1="967.2805" y1="472.86715" x2="967.6517" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1430">
<line x1="994.9205" y1="444.35133" x2="994.9205" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1429">
<line x1="731.8" y1="205.84416" x2="752.90035" y2="206.02432" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1428">
<line x1="762.8" y1="236.12417" x2="743.69964" y2="236.28225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1427">
<line x1="732.32" y1="265.72417" x2="752.9005" y2="265.94024" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1426">
<line x1="759.8" y1="297.32417" x2="740.69964" y2="297.48225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1425">
<line x1="733.32" y1="323.70746" x2="749.9007" y2="323.90783" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1424">
<line x1="761.8" y1="350.64746" x2="740.6997" y2="350.81083" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1423">
<line x1="731.32" y1="378.69075" x2="751.9005" y2="378.9068" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1422">
<line x1="760.8" y1="407.18746" x2="741.69964" y2="407.34554" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1421">
<line x1="1031.2942" y1="204.64416" x2="1069.9002" y2="204.89886" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1420">
<line x1="1076.1068" y1="234.92417" x2="1039.8998" y2="234.69445" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1419">
<line x1="1031.9671" y1="264.52417" x2="1066.8774" y2="264.77348" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1418">
<line x1="1076.2468" y1="296.12417" x2="1039.8998" y2="296.3128" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1417">
<line x1="1033.2613" y1="322.50746" x2="1066.3471" y2="322.75376" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1416">
<line x1="1076.2468" y1="350.63164" x2="1039.8979" y2="349.88955" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1415">
<line x1="1031.0038" y1="377.49074" x2="1069.9" y2="377.60306" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1414">
<line x1="1074.2797" y1="405.63164" x2="1040.5233" y2="405.3191" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1413">
<rect x="762.8" y="419.5437" width="12.96" height="12.96" fill="yellow"/>
<rect x="762.8" y="419.5437" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
</g>
<g id="concat_wire_wires">
<title>wires</title>
<g id="Line_1503">
<line x1="410" y1="206.74365" x2="418.0052" y2="194.33896" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1502">
<line x1="410" y1="206.74365" x2="635.1" y2="206.74365" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1501">
<line x1="410" y1="206.74365" x2="564.3567" y2="416.60816" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1506">
<line x1="778.32" y1="206.74365" x2="786.3252" y2="194.33896" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1505">
<line x1="778.32" y1="206.74365" x2="1003.42" y2="206.74365" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1504">
<line x1="778.32" y1="206.74365" x2="932.6767" y2="416.60816" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</g>
<g id="concat_wire_legend">
<title>legend</title>
<g id="Graphic_1490">
<text transform="translate(366.54814 145.5255)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">(a)</tspan>
</text>
</g>
<g id="Graphic_1499">
<rect x="505.44" y="488.88" width="454.32" height="57.6" fill="white"/>
<rect x="505.44" y="488.88" width="454.32" height="57.6" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1498">
<rect x="514.1" y="496.6278" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="514.1" y="496.6278" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1497">
<text transform="translate(538.1717 492.45767)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">Starting routing tracks</tspan>
</text>
</g>
<g id="Graphic_1496">
<rect x="725.2653" y="496.58" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="725.2653" y="496.58" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1495">
<text transform="translate(741.1591 492.45767)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="2.25" y="16">Ending routing tracks </tspan>
</text>
</g>
<g id="Graphic_1494">
<rect x="514.1" y="522.5078" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="514.1" y="522.5078" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1493">
<text transform="translate(532.7875 517.6055)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="2.25" y="16">Passing routing tracks </tspan>
</text>
</g>
<g id="Graphic_1492">
<rect x="725.2653" y="523.5078" width="12.96" height="12.96" fill="yellow"/>
<rect x="725.2653" y="523.5078" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1491">
<text transform="translate(753.9636 518.6055)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">Output pin of blocks</tspan>
</text>
</g>
<g id="Graphic_1500">
<text transform="translate(751.7481 145.5255)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">(b)</tspan>
</text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,592 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="364.54 140.62 715.76 406.36" width="715.76" height="406.36">
<defs>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">
<g>
<path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
<marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="black">
<g>
<path d="M 4.8 0 L 0 -1.8 L 0 1.8 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>
</g>
</marker>
</defs>
<g id="opin2all_sides" fill="none" stroke-opacity="1" fill-opacity="1" stroke="none" stroke-dasharray="none">
<title>opin2all_sides</title>
<g id="opin2all_sides_base">
<title>base</title>
<g id="Group_1411">
<g id="Graphic_362">
<rect x="403.24" y="178.38365" width="249.84" height="256.4605" fill="white"/>
<rect x="403.24" y="178.38365" width="249.84" height="256.4605" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_513">
<g id="Graphic_363">
<rect x="648.04" y="198.68417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="648.04" y="198.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_368">
<rect x="648.04" y="344.32614" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="648.04" y="344.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_367">
<rect x="648.04" y="228.232" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="648.04" y="228.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_366">
<rect x="648.04" y="257.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="257.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_510">
<rect x="648.04" y="289.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="289.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_509">
<rect x="648.04" y="316.87548" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="648.04" y="316.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_511">
<rect x="648.04" y="371.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="371.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_512">
<rect x="648.04" y="399.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="648.04" y="399.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_514">
<g id="Graphic_526">
<rect x="397.04" y="199.68417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="397.04" y="199.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_523">
<rect x="397.04" y="345.32614" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="397.04" y="345.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_522">
<rect x="397.04" y="229.232" width="12.96" height="12.96" fill="#80ff80"/>
<rect x="397.04" y="229.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_521">
<rect x="397.04" y="258.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="258.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_518">
<rect x="397.04" y="290.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="290.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_517">
<rect x="397.04" y="317.87548" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="397.04" y="317.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_516">
<rect x="397.04" y="372.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="372.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_515">
<rect x="397.04" y="400.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="397.04" y="400.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_527">
<g id="Graphic_539">
<rect x="623.53215" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="623.53215" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_536">
<rect x="477.8902" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="477.8902" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_535">
<rect x="593.9843" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="593.9843" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_534">
<rect x="564.4365" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="564.4365" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_531">
<rect x="532.7915" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="532.7915" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_530">
<rect x="505.34085" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="505.34085" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_529">
<rect x="450.4395" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="450.4395" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_528">
<rect x="422.98886" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="422.98886" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_540">
<g id="Graphic_552">
<rect x="623.53215" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="623.53215" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_549">
<rect x="477.8902" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="477.8902" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_548">
<rect x="593.9843" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="593.9843" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_547">
<rect x="564.4365" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="564.4365" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_544">
<rect x="532.7915" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="532.7915" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_543">
<rect x="505.34085" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="505.34085" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_542">
<rect x="450.4395" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="450.4395" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_541">
<rect x="422.98886" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="422.98886" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Line_972">
<line x1="429.88" y1="171.32417" x2="430.2512" y2="151.86237" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_973">
<line x1="457.52" y1="142.80835" x2="457.52" y2="160.58" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_975">
<line x1="485.16" y1="170.48" x2="485.5312" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_974">
<line x1="512.8" y1="141.96417" x2="512.8" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_979">
<line x1="540.44" y1="172.16835" x2="540.8112" y2="152.70655" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_978">
<line x1="571.26" y1="143.65253" x2="571.26" y2="161.42417" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_977">
<line x1="602.08" y1="170.48" x2="602.4512" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_976">
<line x1="629.72" y1="141.96417" x2="629.72" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_987">
<line x1="429.3205" y1="473.7113" x2="429.6917" y2="454.24953" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_986">
<line x1="456.9605" y1="445.1955" x2="456.9605" y2="462.96715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_985">
<line x1="484.6005" y1="472.86715" x2="484.9717" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_984">
<line x1="512.2405" y1="444.35133" x2="512.2405" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_983">
<line x1="539.8805" y1="474.5555" x2="540.2517" y2="455.0937" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_982">
<line x1="570.7005" y1="446.0397" x2="570.7005" y2="463.8113" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_981">
<line x1="601.5205" y1="472.86715" x2="601.8917" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_980">
<line x1="629.1605" y1="444.35133" x2="629.1605" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_988">
<line x1="366.04" y1="205.84416" x2="387.14035" y2="206.02432" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_989">
<line x1="397.04" y1="236.12417" x2="377.93965" y2="236.28225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_991">
<line x1="366.56" y1="265.72417" x2="387.14054" y2="265.94024" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_990">
<line x1="394.04" y1="297.32417" x2="374.93965" y2="297.48225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_995">
<line x1="367.56" y1="323.70746" x2="384.1407" y2="323.90783" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_994">
<line x1="396.04" y1="350.64746" x2="374.9397" y2="350.81083" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_993">
<line x1="365.56" y1="378.69075" x2="386.14054" y2="378.9068" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_992">
<line x1="395.04" y1="407.18746" x2="375.93965" y2="407.34554" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1378">
<line x1="665.5342" y1="204.64416" x2="704.1402" y2="204.89886" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1377">
<line x1="710.3468" y1="234.92417" x2="674.1398" y2="234.69445" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1376">
<line x1="666.20714" y1="264.52417" x2="701.11745" y2="264.77348" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1375">
<line x1="710.48684" y1="296.12417" x2="674.13986" y2="296.3128" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1374">
<line x1="667.5013" y1="322.50746" x2="700.5871" y2="322.75376" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1373">
<line x1="710.48684" y1="350.63164" x2="674.1379" y2="349.88955" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1372">
<line x1="665.2438" y1="377.49074" x2="704.14" y2="377.60306" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1371">
<line x1="708.5197" y1="405.63164" x2="674.7633" y2="405.3191" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1396">
<rect x="397.04" y="419.5437" width="12.96" height="12.96" fill="yellow"/>
<rect x="397.04" y="419.5437" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1412">
<g id="Graphic_1482">
<rect x="769" y="178.38365" width="249.84" height="256.4605" fill="white"/>
<rect x="769" y="178.38365" width="249.84" height="256.4605" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_1473">
<g id="Graphic_1481">
<rect x="1013.8" y="198.68417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="1013.8" y="198.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1480">
<rect x="1013.8" y="344.32614" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="1013.8" y="344.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1479">
<rect x="1013.8" y="228.232" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="1013.8" y="228.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1478">
<rect x="1013.8" y="257.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="257.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1477">
<rect x="1013.8" y="289.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="289.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1476">
<rect x="1013.8" y="316.87548" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="1013.8" y="316.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1475">
<rect x="1013.8" y="371.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="371.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1474">
<rect x="1013.8" y="399.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="1013.8" y="399.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1464">
<g id="Graphic_1472">
<rect x="762.8" y="199.68417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="762.8" y="199.68417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1471">
<rect x="762.8" y="345.32614" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="762.8" y="345.32614" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1470">
<rect x="762.8" y="229.232" width="12.96" height="12.96" fill="#80ff80"/>
<rect x="762.8" y="229.232" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1469">
<rect x="762.8" y="258.77982" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="258.77982" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1468">
<rect x="762.8" y="290.4248" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="290.4248" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1467">
<rect x="762.8" y="317.87548" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="762.8" y="317.87548" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1466">
<rect x="762.8" y="372.7768" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="372.7768" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1465">
<rect x="762.8" y="400.22746" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="762.8" y="400.22746" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1455">
<g id="Graphic_1463">
<rect x="989.2921" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="989.2921" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1462">
<rect x="843.6502" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="843.6502" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1461">
<rect x="959.7443" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="959.7443" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1460">
<rect x="930.1965" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="930.1965" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1459">
<rect x="898.5515" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="898.5515" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1458">
<rect x="871.1008" y="171.32417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="871.1008" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1457">
<rect x="816.1995" y="171.32417" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="816.1995" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1456">
<rect x="788.7489" y="171.32417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="788.7489" y="171.32417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Group_1446">
<g id="Graphic_1454">
<rect x="989.2921" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="989.2921" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1453">
<rect x="843.6502" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="843.6502" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1452">
<rect x="959.7443" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="959.7443" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1451">
<rect x="930.1965" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="930.1965" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1450">
<rect x="898.5515" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="898.5515" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1449">
<rect x="871.1008" y="428.36417" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="871.1008" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1448">
<rect x="816.1995" y="428.36417" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="816.1995" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1447">
<rect x="788.7489" y="428.36417" width="12.96" height="12.96" fill="red"/>
<rect x="788.7489" y="428.36417" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
<g id="Line_1445">
<line x1="795.64" y1="171.32417" x2="796.0112" y2="151.86237" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1444">
<line x1="823.28" y1="142.80835" x2="823.28" y2="160.58" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1443">
<line x1="850.92" y1="170.48" x2="851.2912" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1442">
<line x1="878.56" y1="141.96417" x2="878.56" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1441">
<line x1="906.2" y1="172.16835" x2="906.5712" y2="152.70655" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1440">
<line x1="937.02" y1="143.65253" x2="937.02" y2="161.42417" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1439">
<line x1="967.84" y1="170.48" x2="968.2112" y2="151.0182" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1438">
<line x1="995.48" y1="141.96417" x2="995.48" y2="159.73582" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1437">
<line x1="795.0805" y1="473.7113" x2="795.4517" y2="454.24953" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1436">
<line x1="822.7205" y1="445.1955" x2="822.7205" y2="462.96715" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1435">
<line x1="850.3605" y1="472.86715" x2="850.7317" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1434">
<line x1="878.0005" y1="444.35133" x2="878.0005" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1433">
<line x1="905.6405" y1="474.5555" x2="906.0117" y2="455.0937" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1432">
<line x1="936.4605" y1="446.0397" x2="936.4605" y2="463.8113" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1431">
<line x1="967.2805" y1="472.86715" x2="967.6517" y2="453.40535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1430">
<line x1="994.9205" y1="444.35133" x2="994.9205" y2="462.123" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1429">
<line x1="731.8" y1="205.84416" x2="752.90035" y2="206.02432" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1428">
<line x1="762.8" y1="236.12417" x2="743.69964" y2="236.28225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1427">
<line x1="732.32" y1="265.72417" x2="752.9005" y2="265.94024" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1426">
<line x1="759.8" y1="297.32417" x2="740.69964" y2="297.48225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1425">
<line x1="733.32" y1="323.70746" x2="749.9007" y2="323.90783" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1424">
<line x1="761.8" y1="350.64746" x2="740.6997" y2="350.81083" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1423">
<line x1="731.32" y1="378.69075" x2="751.9005" y2="378.9068" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1422">
<line x1="760.8" y1="407.18746" x2="741.69964" y2="407.34554" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1421">
<line x1="1031.2942" y1="204.64416" x2="1069.9002" y2="204.89886" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1420">
<line x1="1076.1068" y1="234.92417" x2="1039.8998" y2="234.69445" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1419">
<line x1="1031.9671" y1="264.52417" x2="1066.8774" y2="264.77348" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1418">
<line x1="1076.2468" y1="296.12417" x2="1039.8998" y2="296.3128" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1417">
<line x1="1033.2613" y1="322.50746" x2="1066.3471" y2="322.75376" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1416">
<line x1="1076.2468" y1="350.63164" x2="1039.8979" y2="349.88955" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1415">
<line x1="1031.0038" y1="377.49074" x2="1069.9" y2="377.60306" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_1414">
<line x1="1074.2797" y1="405.63164" x2="1040.5233" y2="405.3191" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1413">
<rect x="762.8" y="419.5437" width="12.96" height="12.96" fill="yellow"/>
<rect x="762.8" y="419.5437" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
</g>
<g id="opin2all_sides_wires">
<title>wires</title>
<g id="Line_1406">
<path d="M 407.3898 426.1812 C 407.3898 426.1812 438.39373 412.8658 438.3898 391 C 438.3874 377.5346 426.6264 364.72587 417.59013 356.8716" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1407">
<path d="M 407.3898 426.1812 C 407.3898 426.1812 470.30214 386.4459 470.2982 332 C 470.2953 291.4208 435.344 256.89188 417.54087 241.9359" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1409">
<path d="M 776.5 427 C 776.5 427 797.6378 405.5312 796.5046 384 C 795.9039 372.5868 789.1951 364.00094 783.0226 358.4519" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1408">
<path d="M 776.5 427 C 776.5 427 820.4932 383.39456 819.36 329 C 818.5508 290.1589 795.004 258.85852 781.6044 244.1343" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1483">
<path d="M 776.5 427 C 776.5 427 796.6181 406.30017 810.5 408 C 817.1427 408.8134 820.8628 414.5728 822.9363 420.35843" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1484">
<path d="M 776.5 427 C 776.5 427 819.3213 392.30017 865.5 394 C 896.4812 395.1404 919.1997 412.3047 930.7975 423.4788" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1485">
<path d="M 776.5 427 C 776.5 427 806.6569 401.59694 875.5 371 C 927.455 347.90887 983.0061 330.05415 1007.1343 322.68376" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1486">
<path d="M 776.5 427 C 776.5 427 832.5237 381.3271 902.5 319 C 954.7636 272.44945 996.4549 232.9577 1014.2125 215.94759" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1487">
<path d="M 776.5 427 C 776.5 427 844.9537 380.8431 881.5 312 C 907.8248 262.41144 908.6778 217.8486 907.0957 196.80031" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_1488">
<path d="M 776.5 427 C 776.5 427 841.8201 370.1264 847.5 301 C 851.7266 249.56022 821.4487 209.33536 805.6783 192.119" marker-end="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</g>
<g id="opin2all_sides_legend">
<title>legend</title>
<g id="Graphic_1490">
<text transform="translate(366.54814 145.5255)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">(a)</tspan>
</text>
</g>
<g id="Graphic_1499">
<rect x="505.44" y="488.88" width="454.32" height="57.6" fill="white"/>
<rect x="505.44" y="488.88" width="454.32" height="57.6" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1498">
<rect x="514.1" y="496.6278" width="12.96" height="12.96" fill="#40ff40"/>
<rect x="514.1" y="496.6278" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1497">
<text transform="translate(538.1717 492.45767)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">Starting routing tracks</tspan>
</text>
</g>
<g id="Graphic_1496">
<rect x="725.2653" y="496.58" width="12.96" height="12.96" fill="#ff4040"/>
<rect x="725.2653" y="496.58" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1495">
<text transform="translate(741.1591 492.45767)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="2.25" y="16">Ending routing tracks </tspan>
</text>
</g>
<g id="Graphic_1494">
<rect x="514.1" y="522.5078" width="12.96" height="12.96" fill="#80ffff"/>
<rect x="514.1" y="522.5078" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1493">
<text transform="translate(532.7875 517.6055)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="2.25" y="16">Passing routing tracks </tspan>
</text>
</g>
<g id="Graphic_1492">
<rect x="725.2653" y="523.5078" width="12.96" height="12.96" fill="yellow"/>
<rect x="725.2653" y="523.5078" width="12.96" height="12.96" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_1491">
<text transform="translate(753.9636 518.6055)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">Output pin of blocks</tspan>
</text>
</g>
<g id="Graphic_1500">
<text transform="translate(751.7481 145.5255)" fill="black">
<tspan font-family="Times New Roman" font-style="italic" font-weight="bold" font-size="18" fill="black" x="0" y="16">(b)</tspan>
</text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -38,4 +38,6 @@ OpenFPGA widely uses XML format for interchangeable files
io_naming_file
module_naming_file
tile_config_file

View File

@ -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 ``<module_names>``, naming rules can be defined line-by-line through syntax ``<module_name>``.
.. code-block:: xml
<module_names>
<module_name default="<string>" given="<string>"/>
</module_names>
.. 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="<string>"
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="<string>"
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"

View File

@ -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 <int>
.. 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.

View File

@ -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 <string>
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 <string> or -pcf <string>
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 <string> or -f <string>
The file path to output the testbench file. For example, ``--file /temp/testbench_template.v``
.. option:: --top_module <string>
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 <string>
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 <string>
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 <string> or -f <string>
The file path to output the netlist file. For example, ``--file /temp/testbench_io_conkt.v``
.. option:: --dut_module <string>
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 <string> or -pcf <string>
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 <string> or -bgf <string>
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
~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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 <string>
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 <string>
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

View File

@ -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:

View File

@ -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

View File

@ -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 <string>
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 <string>
Specify the hand-crafted module name file for fabric A, which is typically hand-crafted by users.
.. option:: --reference_fabricB_names <string>
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 <string>
Specify the renamed module name file for fabric B to be outputted. For example, the fabric A contains reference names:
.. code-block:: xml
<module_name default="tile_1__1_" given="tile_4_"/>
while the renamed module for fabric A includes:
.. code-block:: xml
<module_name default="tile_1__1_" given="tile_big"/>
the fabric B shares the same given name ``tile_4_`` but in a different default name.
.. code-block:: xml
<module_name default="tile_2__2_" given="tile_4_"/>
the resulting output renamed module file includes:
.. code-block:: xml
<module_name default="tile_2__2_" given="tile_big"/>
.. option:: --verbose
To enable verbose output
.. option:: --help
Show help desk

View File

@ -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)

View File

@ -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)

View File

@ -125,6 +125,22 @@ static void read_xml_tile_global_port_annotation(
}
}
/********************************************************************
* Parse XML description for an interconnection annotation
* under a <global_port> 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;

View File

@ -3,7 +3,11 @@
***********************************************************************/
#include "tile_annotation.h"
#include <algorithm>
#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<std::string> TileAnnotation::tiles_to_merge_ports() const {
std::vector<std::string> 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<std::string> TileAnnotation::tile_ports_to_merge(
const std::string& tile_name) const {
std::vector<std::string> 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

View File

@ -39,6 +39,9 @@ class TileAnnotation {
public: /* Public accessors: aggregators */
global_port_range global_ports() const;
std::vector<std::string> tiles_to_merge_ports() const;
std::vector<std::string> 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<std::string, TileGlobalPortId> global_port_name2ids_;
/* Merge port information for tiles */
std::map<std::string, std::vector<std::string>>
tile_ports_to_merge_; // tile_name -> port_name
};
} // namespace openfpga

View File

@ -87,6 +87,24 @@ static void write_xml_tile_annotation_global_port(
<< "</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"
<< "<merge_subtile_ports ";
write_xml_attribute(fp, "tile", tile_name.c_str());
write_xml_attribute(fp, "port", port_name.c_str());
fp << "/>";
}
/********************************************************************
* 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"

View File

@ -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,

View File

@ -25,6 +25,9 @@ std::vector<ConfigBlockId> 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);

View File

@ -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)

View File

@ -0,0 +1,5 @@
<module_names>
<module_name default="tile_0__1_" given="tile_io_bottom"/>
<module_name default="tile_1__1_" given="tile_clb"/>
<module_name default="tile_1__0_" given="tile_io_left"/>
</module_names>

View File

@ -0,0 +1,6 @@
<module_names>
<module_name default="tile_0__1_" given="tile_io_bottom"/>
<module_name default="tile_1__1_" given="tile_clb"/>
<module_name default="tile_1__0_" given="tile_io_left"/>
<module_name default="tile_3__0_" given="tile_io_left"/>
</module_names>

View File

@ -0,0 +1,89 @@
/******************************************************************************
* Memember functions for data structure ModuleNameMap
******************************************************************************/
/* Headers from vtrutil library */
#include "module_name_map.h"
#include <algorithm>
#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<std::string> ModuleNameMap::tags() const {
std::vector<std::string> 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 */

View File

@ -0,0 +1,52 @@
#ifndef MODULE_NAME_MAP_H
#define MODULE_NAME_MAP_H
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
#include <map>
#include <string>
#include <vector>
/* 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<std::string> 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<std::string, std::string> tag2names_;
std::map<std::string, std::string> name2tags_;
};
} /* End namespace openfpga*/
#endif

View File

@ -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

View File

@ -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 <string>
/* 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 <port> 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 <ports> 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

View File

@ -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

View File

@ -0,0 +1,137 @@
/********************************************************************
* This file includes functions that outputs a clock network object to XML
*format
*******************************************************************/
/* Headers from system goes first */
#include <algorithm>
#include <chrono>
#include <ctime>
#include <string>
/* 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 << "\t- Module Naming rules" << std::endl;
fp << "\t- Author: Xifan TANG" << std::endl;
fp << "\t- Organization: RapidFlex" << std::endl;
if (include_time_stamp) {
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
fp << "\t- Date: " << std::ctime(&end_time);
}
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 << "</" << XML_MODULE_NAMES_ROOT_NAME << ">"
<< "\n";
/* Close the file stream */
fp.close();
VTR_LOGV(verbose, "Outputted %lu naming rules.\n", cnt);
return err_code;
}
} // End of namespace openfpga

View File

@ -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 <fstream>
#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

View File

@ -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<std::string> format_argv(const std::string& cmd_name,
int argc, const char** argv) {
std::vector<std::string> 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:
* <module_name default="tile_1__1_" given="tile_4_"/>
* Fabric A renamed:
* <module_name default="tile_1__1_" given="tile_big"/>
* Fabric B reference names:
* <module_name default="tile_2__2_" given="tile_4_"/>
* We want a renamed version for fabric B is
* <module_name default="tile_2__2_" given="tile_big"/>
*/
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<std::string> 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));
}

View File

@ -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;
}

View File

@ -41,7 +41,7 @@ target_link_libraries(libopenfpga
libpcf
libvtrutil
libbusgroup
libionamemap
libnamemanager
libtileconfig
libpugixml
libvpr)

View File

@ -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");

View File

@ -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;

View File

@ -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<T>(
@ -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<const T&>(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<const T&>(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 <class T>
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 <class T>
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 */

View File

@ -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_;

View File

@ -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<size_t>& 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

View File

@ -108,11 +108,18 @@ std::string generate_routing_track_middle_output_port_name(
std::string generate_switch_block_module_name(
const vtr::Point<size_t>& 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<size_t>& 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<size_t>& 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);

View File

@ -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 <class T>
ShellCommandId add_rename_modules_command_template(
openfpga::Shell<T>& shell, const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& 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<T>);
/* 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 <class T>
ShellCommandId add_write_module_naming_rules_command_template(
openfpga::Shell<T>& shell, const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& 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<T>);
/* Add command dependency to the Shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
return shell_cmd_id;
}
template <class T>
void add_setup_command_templates(openfpga::Shell<T>& shell,
const bool& hidden = false) {
@ -1005,6 +1077,27 @@ void add_setup_command_templates(openfpga::Shell<T>& shell,
add_write_fabric_io_info_command_template<T>(
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<ShellCommandId> cmd_dependency_rename_modules;
cmd_dependency_rename_modules.push_back(build_fabric_cmd_id);
add_rename_modules_command_template<T>(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<ShellCommandId> 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<T>(
shell, openfpga_setup_cmd_class, cmd_dependency_write_module_naming_rules,
hidden);
}
} /* end namespace openfpga */

View File

@ -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 <class T>
ShellCommandId add_write_testbench_template_command_template(
openfpga::Shell<T>& shell, const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& 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<T>);
/* 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 <class T>
ShellCommandId add_write_testbench_io_connection_command_template(
openfpga::Shell<T>& shell, const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& 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<T>);
/* 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<T>& 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<ShellCommandId> testbench_template_dependent_cmds;
testbench_template_dependent_cmds.push_back(build_fabric_cmd_id);
add_write_testbench_template_command_template<T>(
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<ShellCommandId> testbench_io_conkt_dependent_cmds;
testbench_io_conkt_dependent_cmds.push_back(build_fabric_cmd_id);
add_write_testbench_io_connection_command_template<T>(
shell, openfpga_verilog_cmd_class, testbench_io_conkt_dependent_cmds,
hidden);
/********************************
* Command 'write_mock_fpga_wrapper'
*/

View File

@ -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 <class T>
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 <class T>
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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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(

View File

@ -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,

View File

@ -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);
}
}
}

View File

@ -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 */

View File

@ -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<e_side> 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(

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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());

View File

@ -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,

View File

@ -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<size_t> 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<size_t> 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);
}
}

View File

@ -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<size_t>& pb_instances,
const std::vector<size_t>& 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<size_t>& pb_instances,
const std::map<t_rr_type, std::vector<size_t>>& 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<t_rr_type, std::vector<size_t>>& cb_instances,
const std::vector<size_t>& 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<t_rr_type, std::vector<size_t>>& 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<size_t> 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<size_t>& pb_coord, const std::vector<size_t>& 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<size_t>& pb_coord,
const std::vector<size_t>& 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<size_t>& pb_instances,
const TileAnnotation& tile_annotation, const FabricTile& fabric_tile,
const FabricTileId& fabric_tile_id, const std::vector<size_t>& pb_instances,
const std::map<t_rr_type, std::vector<size_t>>& cb_instances,
const std::vector<size_t>& sb_instances, const bool& frame_view,
const bool& verbose) {
const std::vector<size_t>& 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;
}

View File

@ -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 */

View File

@ -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) {

View File

@ -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 */

View File

@ -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<size_t> 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<size_t> 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<size_t>& 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<size_t>& 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<size_t> 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;
}

View File

@ -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 */

View File

@ -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,

View File

@ -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",

View File

@ -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);

View File

@ -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<size_t> 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<size_t> 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<size_t> 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 */

View File

@ -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

View File

@ -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<BitstreamWriterOption::e_bitfile_type>(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 */

View File

@ -0,0 +1,104 @@
#ifndef BITSTREAM_WRITER_OPTIONS_H
#define BITSTREAM_WRITER_OPTIONS_H
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
#include <array>
#include <string>
/* 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<const char*, size_t(e_bitfile_type::NUM_TYPES)>
BITFILE_TYPE_STRING_;
};
} /* End namespace openfpga*/
#endif

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -180,9 +180,9 @@ static void build_physical_block_pin_interc_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& 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<std::string, size_t>& 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<std::string, size_t>& 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<std::string, size_t>& 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");

View File

@ -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);

View File

@ -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<RRNodeId>& 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<RRNodeId>& 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<RRNodeId> 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");
}

View File

@ -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);

View File

@ -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;

View File

@ -8,6 +8,7 @@
#include <vector>
#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 */

View File

@ -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 << "<bit id=\"" << size_t(fabric_bit) << "\"";
fp << " value=\"";
fp << bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit));
fp << "\"";
if (options.output_value()) {
fp << " value=\"";
fp << bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit));
fp << "\"";
}
/* Output hierarchy of this parent*/
const ConfigBitId& config_bit = fabric_bitstream.config_bit(fabric_bit);
const ConfigBlockId& config_block =
bitstream_manager.bit_parent_block(config_bit);
std::vector<ConfigBlockId> 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<ConfigBlockId> 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 << "<fabric_bitstream>\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;

View File

@ -8,6 +8,7 @@
#include <vector>
#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 */

View File

@ -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<const ModuleManager &>(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<const ModuleManager &>(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<const ModuleManager &>(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<const ModuleManager &>(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<const ModuleManager &>(module_manager),
src_dir_path, options);
module_name_map, src_dir_path, options);
print_verilog_top_module(netlist_manager,
const_cast<const ModuleManager &>(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
*/

View File

@ -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,

View File

@ -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());
}
}

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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 */

Some files were not shown because too many files have changed in this diff Show More