Merge remote-tracking branch 'origin/master' into github-action-optimizations

This commit is contained in:
Ashton Snelgrove 2021-01-13 17:07:54 -07:00
commit afa55f1942
39 changed files with 3755 additions and 299 deletions

View File

@ -14,6 +14,7 @@ python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/config
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/configuration_chain_use_set --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/configuration_chain_use_setb --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/configuration_chain_use_set_reset --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/configuration_chain_config_enable_scff --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/multi_region_configuration_chain --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/fast_configuration_chain --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/full_testbench/fast_configuration_chain_use_set --debug --show_thread_logs
@ -108,3 +109,6 @@ python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/tile_organization/til
echo -e "Testing global port definition from tiles";
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/global_tile_ports/global_tile_clock --debug --show_thread_logs
python3 openfpga_flow/scripts/run_fpga_task.py basic_tests/global_tile_ports/global_tile_reset --debug --show_thread_logs
echo -e "Testing yosys flow using custom ys script for running quicklogic device";
python3 openfpga_flow/scripts/run_fpga_task.py quicklogic_tests/flow_test --debug --show_thread_logs

View File

@ -49,6 +49,9 @@ python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/io/embedded_io --deb
echo -e "Testing Verilog generation with SoC I/Os for an FPGA ";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/io/soc_io --debug --show_thread_logs
echo -e "Testing Verilog generation with registerable I/Os for an FPGA ";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/io/registerable_io --debug --show_thread_logs
echo -e "Testing Verilog generation with adder chain across an FPGA";
python3 openfpga_flow/scripts/run_fpga_task.py fpga_verilog/fabric_chain/adder_chain --debug --show_thread_logs

View File

@ -60,21 +60,14 @@ Here is an example:
.. code-block:: xml
<tile_annotations>
<global_port name="<string>" tile_port="<string>" is_clock="<bool>" is_reset="<bool>" is_set="<bool>" default_val="<int>"/>
<global_port name="<string>" is_clock="<bool>" is_reset="<bool>" is_set="<bool>" default_val="<int>">
<tile name="<string>" port="<string>" x="<int>" y="<int>"/>
...
</global_port>
</tile_annotations>
- ``name="<string>"`` is the port name to appear in the top-level FPGA fabric.
- ``tile_port="<string>"`` is the port name of a physical tile, e.g., ``tile_port="clb.clk"``.
.. note:: The port of physical tile must be a valid port of the physical definition in VPR architecture!
.. note:: The linked port of physical tile must meet the following requirements:
- If the ``global_port`` is set as clock through ``is_clock="true"``, the port of the physical tile must also be a clock port.
- If not a clock, the port of the physical tile must be defined as non-clock global
- The port of the physical tile should have zero connectivity (``Fc=0``) in VPR architecture
- ``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.
- ``is_reset="<bool>"`` define if the global port is a reset port at the top-level FPGA fabric. An operating reset port will be driven by proper signals in testbenches.
@ -87,6 +80,26 @@ Here is an example:
- ``default_val="<int>"`` define if the default value for the global port when initialized in testbenches. Valid values are either ``0`` or ``1``. For example, the default value of an active-high reset pin is ``0``, while an active-low reset pin is ``1``.
.. note:: A global port could be connected from different tiles by defining multiple <tile> lines under a global port!!!
.. option:: <tile name="<string>" port="<string>" x="<int>" y="<int>"/>
- ``name="<string>"`` is the name of a physical tile, e.g., ``name="clb"``.
- ``port="<string>"`` is the port name of a physical tile, e.g., ``port="clk[0:3]"``.
- ``x="<int>"`` is the x coordinate of a physical tile, e.g., ``x="1"``. If the x coordinate is set to ``-1``, it means all the valid x coordinates of the selected physical tile in the FPGA device will be considered.
- ``y="<int>"`` is the y coordinate of a physical tile, e.g., ``y="1"``. If the y coordinate is set to ``-1``, it means all the valid y coordinates of the selected physical tile in the FPGA device will be considered.
.. note:: The port of physical tile must be a valid port of the physical definition in VPR architecture! If you define a multi-bit port, it must be explicitly defined in the port, e.g., clk[0:3], which must be in the range of the port definition in physical tiles of VPR architecture files!!!
.. note:: The linked port of physical tile must meet the following requirements:
- If the ``global_port`` is set as clock through ``is_clock="true"``, the port of the physical tile must also be a clock port.
- If not a clock, the port of the physical tile must be defined as non-clock global
- The port of the physical tile should have zero connectivity (``Fc=0``) in VPR architecture
A more illustrative example:
:numref:`fig_global_tile_ports` illustrates the difference between the global ports defined through ``circuit_model`` and ``tile_annotation``.
@ -114,7 +127,9 @@ When a global port, e.g., ``clk``, is defined in ``tile_annotation`` using the f
.. code-block:: xml
<tile_annotations>
<global_port name="clk" tile_port="clb.clk" is_clock="true"/>
<global_port name="clk" is_clock="true">
<tile name="clb" port="clk"/>
</global_port>
</tile_annotations>
Clock port ``clk`` of each ``clb`` tile will be connected to a common clock port of the top module, while local clock network is customizable through VPR's architecture description language. For instance, the local clock network can be a programmable clock network.

View File

@ -979,18 +979,18 @@ This example shows:
.. _circuit_model_ccff_example:
Configuration-chain Flip-flop
`````````````````````````````
Regular Configuration-chain Flip-flop
`````````````````````````````````````
:numref:`fig_ccff` illustrates an example of scan-chain flop-flop used to build a configuration chain.
:numref:`fig_ccff_config_chain` illustrates an example of standard flip-flops used to build a configuration chain.
.. _fig_ccff:
.. _fig_ccff_config_chain:
.. figure:: ./figures/scff.png
.. figure:: ./figures/config_chain.svg
:scale: 50%
:alt: SCFF symbol
An example of a Scan-Chain Flip-Flop.
An example of a Flip-Flop organized in a chain.
The code describing this FF is:
@ -999,14 +999,94 @@ The code describing this FF is:
<circuit_model type="ccff" name="ccff" prefix="ccff" verilog_netlist="ccff.v" spice_netlist="ccff.sp">
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="CK" size="1" is_global="true"/>
<port type="output" prefix="QN" size="1"/>
<port type="clock" prefix="CK" size="1" is_global="true" is_prog="true" is_clock="true"/>
</circuit_model>
This example shows:
- A configuration-chain flip-flop which is defined in a Verilog netlist ``ccff.v`` and a SPICE netlist ``ccff.sp``
- The flip-flop has a global clock port, ``CK``, which will be wired a global programming clock
.. note::
The output ports of the configuration flip-flop must follow a fixed sequence in definition:
- The first output port **MUST** be the data output port, e.g., ``Q``.
- The second output port **MUST** be the **inverted** data output port, e.g., ``QN``.
Configuration-chain Flip-flop with Configure Enable Signals
```````````````````````````````````````````````````````````
Configuration chain could be built with flip-flops with outputs that are enabled by specific signals.
Consider the example in :numref:`fig_ccff_config_chain_config_enable`, the flip-flop has
- a configure enable signal ``CFG_EN`` to release the data output ``Q`` and ``QN``
- a pair of data outputs ``Q`` and ``QN`` which are controlled by the configure enable signal ``CFG_EN``
- a regular data output ``SCAN_Q`` which outputs registered data
.. _fig_ccff_config_chain_config_enable:
.. figure:: ./figures/config_chain_config_enable.svg
:scale: 50%
:alt: SCFF symbol
An example of a Flip-Flop with config enable feature organized in a chain.
The code describing this FF is:
.. code-block:: xml
<circuit_model type="ccff" name="ccff" prefix="ccff" verilog_netlist="ccff.v" spice_netlist="ccff.sp">
<port type="input" prefix="CFG_EN" size="1" is_global="true" is_config_enable="true"/>
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="SCAN_Q" size="1"/>
<port type="output" prefix="QN" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="CK" size="1" is_global="true" is_prog="true" is_clock="true"/>
</circuit_model>
.. note::
The output ports of the configuration flip-flop must follow a fixed sequence in definition:
- The first output port **MUST** be the regular data output port, e.g., ``SCAN_Q``.
- The second output port **MUST** be the **inverted** data output port which is activated by the configure enable signal, e.g., ``QN``.
- The second output port **MUST** be the data output port which is activated by the configure enable signal, e.g., ``Q``.
Configuration-chain Flip-flop with Scan Input
`````````````````````````````````````````````
Configuration chain could be built with flip-flops with a scan chain input .
Consider the example in :numref:`fig_ccff_config_chain_scan_capable`, the flip-flop has
- an additional input ``SI`` to enable scan-chain capabaility
- a configure enable signal ``CFG_EN`` to release the data output ``Q`` and ``QN``
- a pair of data outputs ``Q`` and ``QN`` which are controlled by the configure enable signal ``CFG_EN``
- a regular data output ``SCAN_Q`` which outputs registered data
.. _fig_ccff_config_chain_scan_capable:
.. figure:: ./figures/config_chain_scan_capable.svg
:scale: 50%
:alt: SCFF symbol
An example of a Flip-Flop with scan input organized in a chain.
The code describing this FF is:
.. code-block:: xml
<circuit_model type="ccff" name="ccff" prefix="ccff" verilog_netlist="ccff.v" spice_netlist="ccff.sp">
<port type="input" prefix="CFG_EN" size="1" is_global="true" is_config_enable="true"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="SI" size="1"/>
<port type="output" prefix="SCAN_Q" size="1"/>
<port type="output" prefix="QN" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="CK" size="1" is_global="true" is_prog="true" is_clock="true"/>
</circuit_model>
.. note::
The input ports of the configuration flip-flop must follow a fixed sequence in definition:
- The first input port **MUST** be the regular data input port, e.g., ``D``.
- The second input port **MUST** be the scan input port, e.g., ``SI``.
Hard Logics
~~~~~~~~~~~

View File

@ -0,0 +1,375 @@
<?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 version="1.1" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xl="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="85.49984 326.11534 685.6513 148.03441" width="685.6513" height="148.03441">
<defs>
<font-face font-family="Times New Roman" font-size="14" panose-1="2 2 6 3 5 4 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="0" x-height="447.2656" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPSMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="9" panose-1="2 2 6 3 5 4 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="0" x-height="447.2656" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPSMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="14" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1166.6423" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="9" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1814.777" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="12" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1361.0827" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="12" panose-1="2 2 8 3 7 5 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="95.21484" slope="0" x-height="456.54297" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="700">
<font-face-src>
<font-face-name name="TimesNewRomanPS-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<metadata> Produced by OmniGraffle 7.18.1\n2021-01-05 01:03:21 +0000</metadata>
<g id="regular" stroke-opacity="1" stroke="none" fill-opacity="1" fill="none" stroke-dasharray="none">
<title>regular</title>
<g id="regular_Layer_1">
<title>Layer 1</title>
<g id="Group_35788">
<g id="Graphic_35772">
<rect x="176.97979" y="347.32" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="176.97979" y="347.32" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(181.97979 368.86263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35775">
<text transform="translate(178.04028 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35776">
<text transform="translate(185.1764 387.8059)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35778">
<line x1="175.8488" y1="362.96" x2="164.16" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35779">
<line x1="175.8488" y1="392.49704" x2="164.16" y2="392.51084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35781">
<line x1="257.2396" y1="362.96" x2="245.5508" y2="362.97366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35780">
<line x1="257.2396" y1="385.51786" x2="245.5508" y2="385.53153" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35785">
<path d="M 176.97979 388.91704 L 184.53979 392.99704 L 176.97979 397.07704 Z" fill="#ccc"/>
<path d="M 176.97979 388.91704 L 184.53979 392.99704 L 176.97979 397.07704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35786">
<text transform="translate(235.8 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
<g id="Graphic_35787">
<text transform="translate(229.54877 380.8267)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
</g>
<g id="Group_35789">
<g id="Graphic_35799">
<rect x="295.0598" y="347.32" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="295.0598" y="347.32" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(300.0598 368.86263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35798">
<text transform="translate(296.12027 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35797">
<text transform="translate(303.2564 387.8059)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35796">
<line x1="293.9288" y1="362.96" x2="282.24" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35795">
<line x1="293.9288" y1="392.49704" x2="282.24" y2="392.51084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35794">
<line x1="375.3196" y1="362.96" x2="363.6308" y2="362.97366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35793">
<line x1="375.3196" y1="385.51786" x2="363.6308" y2="385.53153" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35792">
<path d="M 295.0598 388.91704 L 302.6198 392.99704 L 295.0598 397.07704 Z" fill="#ccc"/>
<path d="M 295.0598 388.91704 L 302.6198 392.99704 L 295.0598 397.07704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35791">
<text transform="translate(353.88 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
<g id="Graphic_35790">
<text transform="translate(347.62877 380.8267)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
</g>
<g id="Group_35800">
<g id="Graphic_35810">
<rect x="591.108" y="347.07" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="591.108" y="347.07" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(596.108 368.61263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-style="italic" font-weight="400" fill="black" x="10.830357" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35809">
<text transform="translate(592.1685 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35808">
<text transform="translate(599.799 387.5559)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35807">
<line x1="589.977" y1="362.71" x2="578.2882" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35806">
<line x1="589.977" y1="392.24704" x2="578.2882" y2="392.26084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35805">
<line x1="671.3678" y1="362.71" x2="659.679" y2="362.72366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35804">
<line x1="671.3678" y1="385.26786" x2="659.679" y2="385.28153" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35803">
<path d="M 591.108 388.66704 L 598.668 392.74704 L 591.108 396.82704 Z" fill="#ccc"/>
<path d="M 591.108 388.66704 L 598.668 392.74704 L 591.108 396.82704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35802">
<text transform="translate(649.9282 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
<g id="Graphic_35801">
<text transform="translate(643.9253 380.5767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
</g>
<g id="Line_35812">
<line x1="257.2396" y1="362.96" x2="282.24" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35813">
<line x1="123.76164" y1="420.28384" x2="578.2882" y2="419.25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35814">
<line x1="578.2882" y1="392.26084" x2="578.2882" y2="419.25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35815">
<line x1="282.24" y1="392.51084" x2="282.4856" y2="417.73015" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35816">
<line x1="164.16" y1="392.51084" x2="164.11552" y2="417.301" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35817">
<text transform="translate(96.08 413.06613)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CLK</tspan>
</text>
</g>
<g id="Graphic_35818">
<text transform="translate(90.49984 355.6251)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CCFF_HEAD</tspan>
</text>
</g>
<g id="Line_35819">
<line x1="257.2396" y1="385.51786" x2="256.6573" y2="449.64" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35820">
<line x1="268.8802" y1="365.89998" x2="269.125" y2="439" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35821">
<ellipse cx="268.8701" cy="362.88" rx="2.47010548958709" ry="2.52000397038629" fill="black"/>
<ellipse cx="268.8701" cy="362.88" rx="2.47010548958709" ry="2.52000397038629" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35822">
<ellipse cx="282.515" cy="420.75" rx="2.47010548958708" ry="2.5200039703863" fill="black"/>
<ellipse cx="282.515" cy="420.75" rx="2.47010548958708" ry="2.5200039703863" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35823">
<ellipse cx="164.1101" cy="420.321" rx="2.47010548958709" ry="2.52000397038635" fill="black"/>
<ellipse cx="164.1101" cy="420.321" rx="2.47010548958709" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_35825">
<line x1="375.3196" y1="385.51786" x2="375.0411" y2="447.48" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35824">
<line x1="389.23688" y1="362.88283" x2="389.11" y2="439" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35826">
<ellipse cx="389.3301" cy="362.88" rx="2.47010548958705" ry="2.52000397038629" fill="black"/>
<ellipse cx="389.3301" cy="362.88" rx="2.47010548958705" ry="2.52000397038629" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Group_35827">
<g id="Graphic_35837">
<rect x="430.7424" y="347.07" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="430.7424" y="347.07" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(435.7424 368.61263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-style="italic" font-weight="400" fill="black" x="10.830357" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35836">
<text transform="translate(431.8029 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35835">
<text transform="translate(439.4334 387.5559)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35834">
<line x1="429.6114" y1="362.71" x2="417.9226" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35833">
<line x1="429.6114" y1="392.24704" x2="417.9226" y2="392.26084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35832">
<line x1="511.0022" y1="362.71" x2="499.3134" y2="362.72366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35831">
<line x1="511.0022" y1="385.26786" x2="499.3134" y2="385.28153" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35830">
<path d="M 430.7424 388.66704 L 438.3024 392.74704 L 430.7424 396.82704 Z" fill="#ccc"/>
<path d="M 430.7424 388.66704 L 438.3024 392.74704 L 430.7424 396.82704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35829">
<text transform="translate(489.5626 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
<g id="Graphic_35828">
<text transform="translate(483.5597 380.5767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-style="italic" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
</g>
<g id="Line_35838">
<line x1="375.3196" y1="362.96" x2="417.9226" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35839">
<text transform="translate(560.84 352.07)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-style="italic" font-weight="400" fill="black" x="0" y="12"></tspan>
</text>
</g>
<g id="Line_35841">
<line x1="417.9226" y1="392.26084" x2="417.7868" y2="416.7892" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35840">
<ellipse cx="417.7701" cy="419.80915" rx="2.47010548958708" ry="2.52000397038635" fill="black"/>
<ellipse cx="417.7701" cy="419.80915" rx="2.47010548958708" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35842">
<text transform="translate(705.2 355.28)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CCFF_TAIL</tspan>
</text>
</g>
<g id="Line_35843">
<line x1="511.0022" y1="362.7562" x2="553.6052" y2="362.52" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35844">
<line x1="671.3678" y1="362.71" x2="700.2" y2="362.63117" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35846">
<line x1="523.2969" y1="362.16283" x2="523.17" y2="438.28" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35845">
<ellipse cx="523.3901" cy="362.16" rx="2.47010548958711" ry="2.52000397038627" fill="black"/>
<ellipse cx="523.3901" cy="362.16" rx="2.47010548958711" ry="2.52000397038627" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_35848">
<line x1="686.1907" y1="362.16283" x2="686.0638" y2="438.28" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35847">
<ellipse cx="686.2839" cy="362.16" rx="2.47010548958711" ry="2.52000397038627" fill="black"/>
<ellipse cx="686.2839" cy="362.16" rx="2.47010548958711" ry="2.52000397038627" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_35849">
<line x1="511.2522" y1="385.29786" x2="511.6981" y2="447.48" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35850">
<line x1="671.6178" y1="385.29786" x2="671.3248" y2="446.4" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35851">
<text transform="translate(266 436.64)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[0]</tspan>
</text>
</g>
<g id="Graphic_35852">
<text transform="translate(223.88 454.64)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[0]</tspan>
</text>
</g>
<g id="Graphic_35853">
<text transform="translate(388.10408 435.2)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[1]</tspan>
</text>
</g>
<g id="Graphic_35854">
<text transform="translate(342.32 452.48)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[1]</tspan>
</text>
</g>
<g id="Graphic_35856">
<text transform="translate(522.32 435.2)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[2]</tspan>
</text>
</g>
<g id="Graphic_35855">
<text transform="translate(479.12 452.48)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[2]</tspan>
</text>
</g>
<g id="Graphic_35858">
<text transform="translate(678.92 435.2)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[n]</tspan>
</text>
</g>
<g id="Graphic_35857">
<text transform="translate(638.6 451.4)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[n]</tspan>
</text>
</g>
<g id="Line_35859">
<line x1="97" y1="432.37333" x2="770.6512" y2="428.66667" stroke="#ff2600" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
</g>
<g id="Graphic_35860">
<text transform="translate(94.55704 439.64204)" fill="#ff2600">
<tspan font-family="Times New Roman" font-size="12" font-weight="700" fill="#ff2600" x="0" y="11">Configurable Circuits</tspan>
</text>
</g>
<g id="Graphic_35861">
<text transform="translate(90.49984 331.11534)" fill="#ff2600">
<tspan font-family="Times New Roman" font-size="12" font-weight="700" fill="#ff2600" x="0" y="11">Configuration Chain</tspan>
</text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,411 @@
<?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 version="1.1" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xl="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="85.49984 288 687.9915 211.40894" width="687.9915" height="211.40894">
<defs>
<font-face font-family="Times New Roman" font-size="12" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1361.0827" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="14" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1166.6423" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="14" panose-1="2 2 6 3 5 4 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="0" x-height="447.2656" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPSMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="9" panose-1="2 2 6 3 5 4 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="0" x-height="447.2656" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPSMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="12" panose-1="2 2 8 3 7 5 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="95.21484" slope="0" x-height="456.54297" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="700">
<font-face-src>
<font-face-name name="TimesNewRomanPS-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<metadata> Produced by OmniGraffle 7.18.1\n2021-01-05 01:03:21 +0000</metadata>
<g id="config_enable" stroke-opacity="1" stroke="none" fill-opacity="1" fill="none" stroke-dasharray="none">
<title>config_enable</title>
<g id="config_enable_Layer_1">
<title>Layer 1</title>
<g id="Line_35813">
<line x1="123.76164" y1="420.2495" x2="580.523" y2="418.25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35816">
<line x1="164.16" y1="392.51084" x2="164.11552" y2="417.301" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35817">
<text transform="translate(96.08 413.06613)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CLK</tspan>
</text>
</g>
<g id="Graphic_35818">
<text transform="translate(90.49984 355.6251)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CCFF_HEAD</tspan>
</text>
</g>
<g id="Graphic_35822">
<ellipse cx="294.0701" cy="419.42256" rx="2.47010548958708" ry="2.52000397038635" fill="black"/>
<ellipse cx="294.0701" cy="419.42256" rx="2.47010548958708" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35823">
<ellipse cx="164.1101" cy="420.321" rx="2.47010548958709" ry="2.52000397038635" fill="black"/>
<ellipse cx="164.1101" cy="420.321" rx="2.47010548958709" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35839">
<text transform="translate(560.84 352.07)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-style="italic" font-weight="400" fill="black" x="0" y="12"></tspan>
</text>
</g>
<g id="Graphic_35840">
<ellipse cx="417.7701" cy="419.80915" rx="2.47010548958708" ry="2.52000397038635" fill="black"/>
<ellipse cx="417.7701" cy="419.80915" rx="2.47010548958708" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35842">
<text transform="translate(680.8373 354.9051)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CCFF_TAIL</tspan>
</text>
</g>
<g id="Line_35843">
<line x1="511.0022" y1="362.7562" x2="553.6052" y2="362.52" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35849">
<line x1="580.523" y1="392.26084" x2="580.523" y2="418.25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35851">
<text transform="translate(189.32 452.48)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[0]</tspan>
</text>
</g>
<g id="Graphic_35852">
<text transform="translate(232.16 433.04)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[0]</tspan>
</text>
</g>
<g id="Graphic_35853">
<text transform="translate(318.56 449.6)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[1]</tspan>
</text>
</g>
<g id="Graphic_35854">
<text transform="translate(362.9025 430.88)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[1]</tspan>
</text>
</g>
<g id="Graphic_35856">
<text transform="translate(442.04 452.48)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[2]</tspan>
</text>
</g>
<g id="Graphic_35855">
<text transform="translate(486.68 430.88)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[2]</tspan>
</text>
</g>
<g id="Graphic_35858">
<text transform="translate(606.2 446.72)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[n]</tspan>
</text>
</g>
<g id="Graphic_35857">
<text transform="translate(650.12 429.8)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[n]</tspan>
</text>
</g>
<g id="Group_35863">
<g id="Graphic_35772">
<rect x="176.97979" y="347.32" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="176.97979" y="347.32" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(181.97979 368.86263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35775">
<text transform="translate(178.04028 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35776">
<text transform="translate(185.1764 387.8059)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35778">
<line x1="175.8488" y1="362.96" x2="164.16" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35779">
<line x1="175.8488" y1="392.49704" x2="164.16" y2="392.51084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35781">
<line x1="257.2396" y1="362.96" x2="245.5508" y2="362.97366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35785">
<path d="M 176.97979 388.91704 L 184.53979 392.99704 L 176.97979 397.07704 Z" fill="#ccc"/>
<path d="M 176.97979 388.91704 L 184.53979 392.99704 L 176.97979 397.07704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35786">
<text transform="translate(207.96647 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35859">
<text transform="translate(226.63794 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35860">
<text transform="translate(214.92 395.61767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35861">
<line x1="218.88" y1="405.90486" x2="218.96188" y2="447.48" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35862">
<line x1="235.8" y1="406" x2="235.8" y2="432.84513" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Group_35864">
<g id="Graphic_35874">
<rect x="306.9398" y="347.32" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="306.9398" y="347.32" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(311.9398 368.86263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35873">
<text transform="translate(308.00027 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35872">
<text transform="translate(315.1364 387.8059)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35871">
<line x1="305.8088" y1="362.96" x2="294.12" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35870">
<line x1="305.8088" y1="392.49704" x2="294.12" y2="392.51084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35869">
<line x1="387.1996" y1="362.96" x2="375.5108" y2="362.97366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35868">
<path d="M 306.9398 388.91704 L 314.4998 392.99704 L 306.9398 397.07704 Z" fill="#ccc"/>
<path d="M 306.9398 388.91704 L 314.4998 392.99704 L 306.9398 397.07704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35867">
<text transform="translate(337.92647 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35866">
<text transform="translate(356.59794 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35865">
<text transform="translate(344.88 395.61767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35875">
<line x1="257.2396" y1="362.96" x2="294.12" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Group_35877">
<g id="Graphic_35887">
<rect x="430.7424" y="347.07" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="430.7424" y="347.07" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(435.7424 368.61263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35886">
<text transform="translate(431.8029 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35885">
<text transform="translate(438.939 387.5559)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35884">
<line x1="429.6114" y1="362.71" x2="417.9226" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35883">
<line x1="429.6114" y1="392.24704" x2="417.9226" y2="392.26084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35882">
<line x1="511.0022" y1="362.71" x2="499.3134" y2="362.72366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35881">
<path d="M 430.7424 388.66704 L 438.3024 392.74704 L 430.7424 396.82704 Z" fill="#ccc"/>
<path d="M 430.7424 388.66704 L 438.3024 392.74704 L 430.7424 396.82704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35880">
<text transform="translate(461.7291 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35879">
<text transform="translate(480.40056 395.11767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35878">
<text transform="translate(468.6826 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35888">
<line x1="387.1996" y1="362.96" x2="417.9226" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Group_35889">
<g id="Graphic_35899">
<rect x="593.3428" y="347.07" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="593.3428" y="347.07" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(598.3428 368.61263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35898">
<text transform="translate(594.4033 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35897">
<text transform="translate(601.5394 387.5559)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35896">
<line x1="592.2118" y1="362.71" x2="580.523" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35895">
<line x1="592.2118" y1="392.24704" x2="580.523" y2="392.26084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35894">
<line x1="673.6026" y1="362.71" x2="661.9138" y2="362.72366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35893">
<path d="M 593.3428 388.66704 L 600.9028 392.74704 L 593.3428 396.82704 Z" fill="#ccc"/>
<path d="M 593.3428 388.66704 L 600.9028 392.74704 L 593.3428 396.82704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35892">
<text transform="translate(624.32946 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35891">
<text transform="translate(643.0009 395.11767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35890">
<text transform="translate(631.283 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35901">
<line x1="348.32055" y1="406.1741" x2="348.24887" y2="444.6" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35900">
<line x1="365.24055" y1="406" x2="365.24055" y2="432.84513" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35903">
<line x1="471.725" y1="405.73076" x2="471.7103" y2="447.48" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35902">
<line x1="488.645" y1="405.55665" x2="488.645" y2="432.4018" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35905">
<line x1="635.885" y1="406.47363" x2="635.8709" y2="441.72" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35904">
<line x1="652.805" y1="406.29953" x2="652.805" y2="433.14467" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35906">
<line x1="417.9226" y1="393.48" x2="417.9226" y2="419.46915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35907">
<line x1="294.12" y1="392.51084" x2="294.0757" y2="416.40256" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35909">
<text transform="translate(189 347.32)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Graphic_35910">
<text transform="translate(188.0328 309.2)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CFG_EN</tspan>
</text>
</g>
<g id="Graphic_35911">
<text transform="translate(318.24 347.07)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Line_35914">
<line x1="210.6998" y1="328.70976" x2="210.6998" y2="346.32" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35915">
<line x1="341.7405" y1="338.41742" x2="341.7405" y2="346.75" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35917">
<text transform="translate(439.644 347.07)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Line_35916">
<line x1="463.1445" y1="338.12" x2="463.1445" y2="346.75" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35919">
<text transform="translate(603.804 347.07)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Line_35918">
<line x1="627.3045" y1="334.08" x2="627.3045" y2="346.75" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35920">
<line x1="213.16987" y1="336.11768" x2="627.3045" y2="334.08" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35921">
<ellipse cx="463.1445" cy="335.1" rx="2.47010548958708" ry="2.52000397038632" fill="black"/>
<ellipse cx="463.1445" cy="335.1" rx="2.47010548958708" ry="2.52000397038632" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35922">
<ellipse cx="341.7405" cy="335.39742" rx="2.47010548958708" ry="2.52000397038629" fill="black"/>
<ellipse cx="341.7405" cy="335.39742" rx="2.47010548958708" ry="2.52000397038629" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35923">
<ellipse cx="210.6998" cy="336.12983" rx="2.47010548958711" ry="2.5200039703863" fill="black"/>
<ellipse cx="210.6998" cy="336.12983" rx="2.47010548958711" ry="2.5200039703863" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_35926">
<line x1="99.34016" y1="472.63047" x2="772.9913" y2="468.9238" stroke="#ff2600" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
</g>
<g id="Graphic_35925">
<text transform="translate(96.8972 479.89917)" fill="#ff2600">
<tspan font-family="Times New Roman" font-size="12" font-weight="700" fill="#ff2600" x="0" y="11">Configurable Circuits</tspan>
</text>
</g>
<g id="Graphic_35924">
<text transform="translate(93.2 293)" fill="#ff2600">
<tspan font-family="Times New Roman" font-size="12" font-weight="700" fill="#ff2600" x="0" y="11">Configuration Chain</tspan>
</text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,462 @@
<?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 version="1.1" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xl="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="60.48 304.2 713.0113 195.20894" width="713.0113" height="195.20894">
<defs>
<font-face font-family="Times New Roman" font-size="12" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1361.0827" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="14" panose-1="2 2 5 3 5 4 5 9 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="-1166.6423" x-height="430.1758" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-style="italic" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPS-ItalicMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="14" panose-1="2 2 6 3 5 4 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="0" x-height="447.2656" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPSMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="9" panose-1="2 2 6 3 5 4 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="48.828125" slope="0" x-height="447.2656" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="400">
<font-face-src>
<font-face-name name="TimesNewRomanPSMT"/>
</font-face-src>
</font-face>
<font-face font-family="Times New Roman" font-size="12" panose-1="2 2 8 3 7 5 5 2 3 4" units-per-em="1000" underline-position="-108.88672" underline-thickness="95.21484" slope="0" x-height="456.54297" cap-height="662.1094" ascent="891.1133" descent="-216.3086" font-weight="700">
<font-face-src>
<font-face-name name="TimesNewRomanPS-BoldMT"/>
</font-face-src>
</font-face>
</defs>
<metadata> Produced by OmniGraffle 7.18.1\n2021-01-05 01:03:21 +0000</metadata>
<g id="scan_capable" stroke-opacity="1" stroke="none" fill-opacity="1" fill="none" stroke-dasharray="none">
<title>scan_capable</title>
<g id="scan_capable_Layer_1">
<title>Layer 1</title>
<g id="Line_35813">
<line x1="123.76164" y1="420.2495" x2="580.523" y2="418.25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35816">
<line x1="164.16" y1="392.51084" x2="164.11552" y2="417.301" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35817">
<text transform="translate(96.08 413.06613)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CLK</tspan>
</text>
</g>
<g id="Graphic_35818">
<text transform="translate(65.48 355.64)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CCFF_HEAD</tspan>
</text>
</g>
<g id="Graphic_35822">
<ellipse cx="294.0701" cy="419.42256" rx="2.47010548958708" ry="2.52000397038635" fill="black"/>
<ellipse cx="294.0701" cy="419.42256" rx="2.47010548958708" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35823">
<ellipse cx="164.1101" cy="420.321" rx="2.47010548958709" ry="2.52000397038635" fill="black"/>
<ellipse cx="164.1101" cy="420.321" rx="2.47010548958709" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35839">
<text transform="translate(560.84 352.07)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-style="italic" font-weight="400" fill="black" x="0" y="12"></tspan>
</text>
</g>
<g id="Graphic_35840">
<ellipse cx="417.7701" cy="419.80915" rx="2.47010548958708" ry="2.52000397038635" fill="black"/>
<ellipse cx="417.7701" cy="419.80915" rx="2.47010548958708" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35842">
<text transform="translate(680.8373 354.9051)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CCFF_TAIL</tspan>
</text>
</g>
<g id="Line_35843">
<line x1="511.0022" y1="362.7562" x2="553.6052" y2="362.52" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35849">
<line x1="580.523" y1="392.26084" x2="580.523" y2="418.25" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35851">
<text transform="translate(189.32 452.48)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[0]</tspan>
</text>
</g>
<g id="Graphic_35852">
<text transform="translate(232.16 433.04)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[0]</tspan>
</text>
</g>
<g id="Graphic_35853">
<text transform="translate(318.56 449.6)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[1]</tspan>
</text>
</g>
<g id="Graphic_35854">
<text transform="translate(362.9025 430.88)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[1]</tspan>
</text>
</g>
<g id="Graphic_35856">
<text transform="translate(442.04 452.48)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[2]</tspan>
</text>
</g>
<g id="Graphic_35855">
<text transform="translate(486.68 430.88)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[2]</tspan>
</text>
</g>
<g id="Graphic_35858">
<text transform="translate(606.2 446.72)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_out[n]</tspan>
</text>
</g>
<g id="Graphic_35857">
<text transform="translate(650.12 429.8)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">mem_outb[n]</tspan>
</text>
</g>
<g id="Group_35863">
<g id="Graphic_35772">
<rect x="176.97979" y="347.32" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="176.97979" y="347.32" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(181.97979 368.86263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35775">
<text transform="translate(178.04028 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35776">
<text transform="translate(185.1764 387.8059)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35778">
<line x1="175.8488" y1="362.96" x2="164.16" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35779">
<line x1="175.8488" y1="392.49704" x2="164.16" y2="392.51084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35781">
<line x1="257.2396" y1="362.96" x2="245.5508" y2="362.97366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35785">
<path d="M 176.97979 388.91704 L 184.53979 392.99704 L 176.97979 397.07704 Z" fill="#ccc"/>
<path d="M 176.97979 388.91704 L 184.53979 392.99704 L 176.97979 397.07704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35786">
<text transform="translate(207.96647 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35859">
<text transform="translate(226.63794 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35860">
<text transform="translate(214.92 395.61767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35861">
<line x1="218.88" y1="405.90486" x2="218.96188" y2="447.48" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35862">
<line x1="235.8" y1="406" x2="235.8" y2="432.84513" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Group_35864">
<g id="Graphic_35874">
<rect x="306.9398" y="347.32" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="306.9398" y="347.32" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(311.9398 368.86263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35873">
<text transform="translate(308.00027 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35872">
<text transform="translate(315.1364 387.8059)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35871">
<line x1="305.8088" y1="362.96" x2="294.12" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35870">
<line x1="305.8088" y1="392.49704" x2="294.12" y2="392.51084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35869">
<line x1="387.1996" y1="362.96" x2="375.5108" y2="362.97366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35868">
<path d="M 306.9398 388.91704 L 314.4998 392.99704 L 306.9398 397.07704 Z" fill="#ccc"/>
<path d="M 306.9398 388.91704 L 314.4998 392.99704 L 306.9398 397.07704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35867">
<text transform="translate(337.92647 358.26883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35866">
<text transform="translate(356.59794 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35865">
<text transform="translate(344.88 395.61767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35875">
<line x1="257.2396" y1="362.96" x2="294.12" y2="362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Group_35877">
<g id="Graphic_35887">
<rect x="430.7424" y="347.07" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="430.7424" y="347.07" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(435.7424 368.61263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35886">
<text transform="translate(431.8029 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35885">
<text transform="translate(438.939 387.5559)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35884">
<line x1="429.6114" y1="362.71" x2="417.9226" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35883">
<line x1="429.6114" y1="392.24704" x2="417.9226" y2="392.26084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35882">
<line x1="511.0022" y1="362.71" x2="499.3134" y2="362.72366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35881">
<path d="M 430.7424 388.66704 L 438.3024 392.74704 L 430.7424 396.82704 Z" fill="#ccc"/>
<path d="M 430.7424 388.66704 L 438.3024 392.74704 L 430.7424 396.82704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35880">
<text transform="translate(461.7291 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35879">
<text transform="translate(480.40056 395.11767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35878">
<text transform="translate(468.6826 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35888">
<line x1="387.1996" y1="362.96" x2="417.9226" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Group_35889">
<g id="Graphic_35899">
<rect x="593.3428" y="347.07" width="67.44001" height="58.68" fill="#ffffc0"/>
<rect x="593.3428" y="347.07" width="67.44001" height="58.68" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<text transform="translate(598.3428 368.61263)" fill="black">
<tspan font-family="Times New Roman" font-size="14" font-weight="400" fill="black" x="11.595982" y="12">CCFF</tspan>
</text>
</g>
<g id="Graphic_35898">
<text transform="translate(594.4033 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">D</tspan>
</text>
</g>
<g id="Graphic_35897">
<text transform="translate(601.5394 387.5559)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CLK</tspan>
</text>
</g>
<g id="Line_35896">
<line x1="592.2118" y1="362.71" x2="580.523" y2="362.7238" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35895">
<line x1="592.2118" y1="392.24704" x2="580.523" y2="392.26084" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35894">
<line x1="673.6026" y1="362.71" x2="661.9138" y2="362.72366" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35893">
<path d="M 593.3428 388.66704 L 600.9028 392.74704 L 593.3428 396.82704 Z" fill="#ccc"/>
<path d="M 593.3428 388.66704 L 600.9028 392.74704 L 593.3428 396.82704 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35892">
<text transform="translate(624.32946 358.01883)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SCAN_Q</tspan>
</text>
</g>
<g id="Graphic_35891">
<text transform="translate(643.0009 395.11767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">QN</tspan>
</text>
</g>
<g id="Graphic_35890">
<text transform="translate(631.283 395.36767)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">Q</tspan>
</text>
</g>
</g>
<g id="Line_35901">
<line x1="348.32055" y1="406.1741" x2="348.24887" y2="444.6" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35900">
<line x1="365.24055" y1="406" x2="365.24055" y2="432.84513" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35903">
<line x1="471.725" y1="405.73076" x2="471.7103" y2="447.48" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35902">
<line x1="488.645" y1="405.55665" x2="488.645" y2="432.4018" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35905">
<line x1="635.885" y1="406.47363" x2="635.8709" y2="441.72" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35904">
<line x1="652.805" y1="406.29953" x2="652.805" y2="433.14467" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35906">
<line x1="417.9226" y1="393.48" x2="417.9226" y2="419.46915" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35907">
<line x1="294.12" y1="392.51084" x2="294.0757" y2="416.40256" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35909">
<text transform="translate(189 347.32)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Graphic_35910">
<text transform="translate(188.0328 309.2)" fill="black">
<tspan font-family="Times New Roman" font-size="12" font-style="italic" font-weight="400" fill="black" x="0" y="11">CFG_EN</tspan>
</text>
</g>
<g id="Graphic_35911">
<text transform="translate(318.24 347.07)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Line_35914">
<line x1="210.6998" y1="328.70976" x2="210.6998" y2="346.32" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35915">
<line x1="341.7405" y1="338.41742" x2="341.7405" y2="346.75" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35917">
<text transform="translate(439.644 347.07)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Line_35916">
<line x1="463.1445" y1="338.12" x2="463.1445" y2="346.75" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35919">
<text transform="translate(603.804 347.07)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">CONFIG_EN</tspan>
</text>
</g>
<g id="Line_35918">
<line x1="627.3045" y1="334.08" x2="627.3045" y2="346.75" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Line_35920">
<line x1="213.16987" y1="336.11768" x2="627.3045" y2="334.08" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35921">
<ellipse cx="463.1445" cy="335.1" rx="2.47010548958708" ry="2.52000397038632" fill="black"/>
<ellipse cx="463.1445" cy="335.1" rx="2.47010548958708" ry="2.52000397038632" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35922">
<ellipse cx="341.7405" cy="335.39742" rx="2.47010548958708" ry="2.52000397038629" fill="black"/>
<ellipse cx="341.7405" cy="335.39742" rx="2.47010548958708" ry="2.52000397038629" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35923">
<ellipse cx="210.6998" cy="336.12983" rx="2.47010548958711" ry="2.5200039703863" fill="black"/>
<ellipse cx="210.6998" cy="336.12983" rx="2.47010548958711" ry="2.5200039703863" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_35926">
<line x1="99.34016" y1="472.63047" x2="772.9913" y2="468.9238" stroke="#ff2600" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4.0,4.0" stroke-width="1"/>
</g>
<g id="Graphic_35925">
<text transform="translate(96.8972 479.89917)" fill="#ff2600">
<tspan font-family="Times New Roman" font-size="12" font-weight="700" fill="#ff2600" x="0" y="11">Configurable Circuits</tspan>
</text>
</g>
<g id="Graphic_35924">
<text transform="translate(71.011316 309.2)" fill="#ff2600">
<tspan font-family="Times New Roman" font-size="12" font-weight="700" fill="#ff2600" x="0" y="11">Configuration Chain</tspan>
</text>
</g>
<g id="Graphic_35927">
<text transform="translate(177.84 372.6)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SI</tspan>
</text>
</g>
<g id="Line_35928">
<path d="M 175.8488 377.29115 L 164.16 377.375 L 164.16 362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35929">
<ellipse cx="164.16" cy="363.2949" rx="2.4701054895871" ry="2.52000397038626" fill="black"/>
<ellipse cx="164.16" cy="363.2949" rx="2.4701054895871" ry="2.52000397038626" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Line_35931">
<line x1="139.14015" y1="362.6472" x2="164.07007" y2="362.49023" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35934">
<text transform="translate(307.8 372.6)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SI</tspan>
</text>
</g>
<g id="Line_35933">
<path d="M 305.8088 377.29115 L 294.12 377.375 L 294.12 362.9738" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35932">
<ellipse cx="294.12" cy="363.2949" rx="2.47010548958708" ry="2.52000397038629" fill="black"/>
<ellipse cx="294.12" cy="363.2949" rx="2.47010548958708" ry="2.52000397038629" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35937">
<text transform="translate(431.6026 372.1462)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SI</tspan>
</text>
</g>
<g id="Line_35936">
<path d="M 429.6114 376.83735 L 417.9226 376.9212 L 417.9226 362.52" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35935">
<ellipse cx="417.9226" cy="362.8411" rx="2.47010548958708" ry="2.52000397038635" fill="black"/>
<ellipse cx="417.9226" cy="362.8411" rx="2.47010548958708" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
<g id="Graphic_35940">
<text transform="translate(594.203 372.1462)" fill="black">
<tspan font-family="Times New Roman" font-size="9" font-weight="400" fill="black" x="0" y="8">SI</tspan>
</text>
</g>
<g id="Line_35939">
<path d="M 592.2118 376.83735 L 580.523 376.9212 L 580.523 362.52" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<g id="Graphic_35938">
<ellipse cx="580.523" cy="362.8411" rx="2.47010548958711" ry="2.52000397038635" fill="black"/>
<ellipse cx="580.523" cy="362.8411" rx="2.47010548958711" ry="2.52000397038635" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -290,17 +290,35 @@ size_t check_ccff_circuit_model_ports(const CircuitLibrary& circuit_lib,
VTR_ASSERT(CIRCUIT_MODEL_CCFF == circuit_lib.model_type(circuit_model));
/* Check if we have D, Set and Reset */
/* We can have either 1 input which is D or 2 inputs which are D and scan input */
size_t num_input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true).size();
if ((1 != num_input_ports) && (2 != num_input_ports)) {
VTR_LOG_ERROR("Configuration flip-flop '%s' must have either 1 or 2 %s ports!\n\tAmong which:\n\t\tthe first input is a regular input (e.g., D)\n\t\tand the other could be scan-chain input (e.g., SI)\n",
circuit_lib.model_name(circuit_model).c_str(),
CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(CIRCUIT_MODEL_PORT_INPUT)]);
num_err++;
}
num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model,
CIRCUIT_MODEL_PORT_INPUT,
1, 1, false);
num_input_ports, 1, false);
/* Check if we have a clock */
num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model,
CIRCUIT_MODEL_PORT_CLOCK,
1, 1, true);
/* Check if we have 1 or 2 outputs */
/* Check if we have 1 or 2 or 3 outputs */
size_t num_output_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, true).size();
if ((1 != num_output_ports)
&& (2 != num_output_ports)
&& (3 != num_output_ports)) {
VTR_LOG_ERROR("Configuration flip-flop '%s' must have either 1 or 2 or 3 %s ports!\n\tAmong which:\n\t\tthe first port is the manadatory regular data output (e.g., Q) and \n\t\tthe second port could be the inverted data output which can optionally be enabled by configure-enable signal (e.g., QN or cgf_en_QN) and \n\t\tthe third port could be the data output which can optionally be enabled by configure-enable signal (e.g., cgf_en_Q)\n",
circuit_lib.model_name(circuit_model).c_str(),
CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(CIRCUIT_MODEL_PORT_OUTPUT)]);
num_err++;
}
num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model,
CIRCUIT_MODEL_PORT_OUTPUT,
num_output_ports, 1, false);

View File

@ -30,25 +30,12 @@ static
void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
const pugiutil::loc_data& loc_data,
openfpga::TileAnnotation& tile_annotation) {
/* We have two mandatory XML attributes
* 1. name of the port
* 2. name of the tile and ports in the format of <tile_name>.<tile_port_name>
/* We have mandatory XML attributes:
* - name of the port
*/
const std::string& name_attr = get_attribute(xml_tile, "name", loc_data).as_string();
const std::string& tile_port_name_attr = get_attribute(xml_tile, "tile_port", loc_data).as_string();
/* Extract the tile name */
openfpga::StringToken tokenizer(tile_port_name_attr);
std::vector<std::string> tile_port_tokens = tokenizer.split('.');
if (2 != tile_port_tokens.size()) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tile),
"Invalid tile_port attribute '%s'! Valid format is <tile_name>.<port_name>\n",
tile_port_name_attr.c_str());
}
/* Extract the tile port information */
openfpga::PortParser tile_port_parser(tile_port_tokens[1]);
TileGlobalPortId tile_global_port_id = tile_annotation.create_global_port(name_attr, tile_port_tokens[0], tile_port_parser.port());
TileGlobalPortId tile_global_port_id = tile_annotation.create_global_port(name_attr);
/* Report any duplicated port names */
if (TileGlobalPortId::INVALID() == tile_global_port_id) {
@ -57,6 +44,39 @@ void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
name_attr.c_str());
}
/* Iterate over the children under this node,
* each child should be named after <pb_type>
*/
for (pugi::xml_node xml_tile_port : xml_tile.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_tile_port.name() != std::string("tile")) {
bad_tag(xml_tile_port, loc_data, xml_tile, {"tile"});
}
/* Parse the name of the tiles and ports */
const std::string& tile_name_attr = get_attribute(xml_tile_port, "name", loc_data).as_string();
const std::string& port_name_attr = get_attribute(xml_tile_port, "port", loc_data).as_string();
/* Extract the tile port information */
openfpga::PortParser tile_port_parser(port_name_attr);
/* Parse tile coordinates */
vtr::Point<size_t> tile_coord(get_attribute(xml_tile_port, "x", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1),
get_attribute(xml_tile_port, "y", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1));
/* Add tile port information */
tile_annotation.add_global_port_tile_information(tile_global_port_id,
tile_name_attr,
tile_port_parser.port(),
tile_coord);
}
/* Check: Must have at least one global port tile information */
if (true == tile_annotation.global_port_tile_names(tile_global_port_id).empty()) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tile),
"Invalid tile annotation for global port '%s'! At least 1 tile port definition is expected!\n",
name_attr.c_str());
}
/* Get is_clock attributes */
tile_annotation.set_global_port_is_clock(tile_global_port_id, get_attribute(xml_tile, "is_clock", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
@ -81,7 +101,7 @@ void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
* Top function to parse XML description about tile annotation
*******************************************************************/
openfpga::TileAnnotation read_xml_tile_annotations(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data) {
const pugiutil::loc_data& loc_data) {
openfpga::TileAnnotation tile_annotations;
/* Parse configuration protocol root node */

View File

@ -30,16 +30,21 @@ std::string TileAnnotation::global_port_name(const TileGlobalPortId& global_port
return global_port_names_[global_port_id];
}
std::string TileAnnotation::global_port_tile_name(const TileGlobalPortId& global_port_id) const {
std::vector<std::string> TileAnnotation::global_port_tile_names(const TileGlobalPortId& global_port_id) const {
VTR_ASSERT(valid_global_port_id(global_port_id));
return global_port_tile_names_[global_port_id];
}
BasicPort TileAnnotation::global_port_tile_port(const TileGlobalPortId& global_port_id) const {
std::vector<BasicPort> TileAnnotation::global_port_tile_ports(const TileGlobalPortId& global_port_id) const {
VTR_ASSERT(valid_global_port_id(global_port_id));
return global_port_tile_ports_[global_port_id];
}
std::vector<vtr::Point<size_t>> TileAnnotation::global_port_tile_coordinates(const TileGlobalPortId& global_port_id) const {
VTR_ASSERT(valid_global_port_id(global_port_id));
return global_port_tile_coordinates_[global_port_id];
}
bool TileAnnotation::global_port_is_clock(const TileGlobalPortId& global_port_id) const {
VTR_ASSERT(valid_global_port_id(global_port_id));
return global_port_is_clock_[global_port_id];
@ -63,9 +68,7 @@ size_t TileAnnotation::global_port_default_value(const TileGlobalPortId& global_
/************************************************************************
* Public Mutators
***********************************************************************/
TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name,
const std::string& tile_name,
const BasicPort& tile_port) {
TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name) {
/* Ensure that the name is unique */
std::map<std::string, TileGlobalPortId>::iterator it = global_port_name2ids_.find(port_name);
if (it != global_port_name2ids_.end()) {
@ -76,8 +79,9 @@ TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name
TileGlobalPortId port_id = TileGlobalPortId(global_port_ids_.size());
global_port_ids_.push_back(port_id);
global_port_names_.push_back(port_name);
global_port_tile_names_.push_back(tile_name);
global_port_tile_ports_.push_back(tile_port);
global_port_tile_names_.emplace_back();
global_port_tile_ports_.emplace_back();
global_port_tile_coordinates_.emplace_back();
global_port_is_clock_.push_back(false);
global_port_is_set_.push_back(false);
global_port_is_reset_.push_back(false);
@ -89,6 +93,16 @@ TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name
return port_id;
}
void TileAnnotation::add_global_port_tile_information(const TileGlobalPortId& global_port_id,
const std::string& tile_name,
const BasicPort& tile_port,
const vtr::Point<size_t>& tile_coord) {
VTR_ASSERT(valid_global_port_id(global_port_id));
global_port_tile_names_[global_port_id].push_back(tile_name);
global_port_tile_ports_[global_port_id].push_back(tile_port);
global_port_tile_coordinates_[global_port_id].push_back(tile_coord);
}
void TileAnnotation::set_global_port_is_clock(const TileGlobalPortId& global_port_id,
const bool& is_clock) {
VTR_ASSERT(valid_global_port_id(global_port_id));

View File

@ -9,6 +9,7 @@
#include <array>
#include "vtr_vector.h"
#include "vtr_geometry.h"
#include "openfpga_port.h"
@ -39,8 +40,9 @@ class TileAnnotation {
global_port_range global_ports() const;
public: /* Public accessors */
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
std::string global_port_tile_name(const TileGlobalPortId& global_port_id) const;
BasicPort global_port_tile_port(const TileGlobalPortId& global_port_id) const;
std::vector<std::string> global_port_tile_names(const TileGlobalPortId& global_port_id) const;
std::vector<BasicPort> global_port_tile_ports(const TileGlobalPortId& global_port_id) const;
std::vector<vtr::Point<size_t>> global_port_tile_coordinates(const TileGlobalPortId& global_port_id) const;
bool global_port_is_clock(const TileGlobalPortId& global_port_id) const;
bool global_port_is_set(const TileGlobalPortId& global_port_id) const;
bool global_port_is_reset(const TileGlobalPortId& global_port_id) const;
@ -49,9 +51,12 @@ class TileAnnotation {
/* By default, we do not set it as a clock.
* Users should set it through the set_global_port_is_clock() function
*/
TileGlobalPortId create_global_port(const std::string& port_name,
const std::string& tile_name,
const BasicPort& tile_port);
TileGlobalPortId create_global_port(const std::string& port_name);
/* Add tile port information */
void add_global_port_tile_information(const TileGlobalPortId& global_port_id,
const std::string& tile_name,
const BasicPort& tile_port,
const vtr::Point<size_t>& tile_coord);
void set_global_port_is_clock(const TileGlobalPortId& global_port_id,
const bool& is_clock);
void set_global_port_is_set(const TileGlobalPortId& global_port_id,
@ -70,8 +75,9 @@ class TileAnnotation {
/* Global port information for tiles */
vtr::vector<TileGlobalPortId, TileGlobalPortId> global_port_ids_;
vtr::vector<TileGlobalPortId, std::string> global_port_names_;
vtr::vector<TileGlobalPortId, std::string> global_port_tile_names_;
vtr::vector<TileGlobalPortId, BasicPort> global_port_tile_ports_;
vtr::vector<TileGlobalPortId, std::vector<std::string>> global_port_tile_names_;
vtr::vector<TileGlobalPortId, std::vector<vtr::Point<size_t>>> global_port_tile_coordinates_;
vtr::vector<TileGlobalPortId, std::vector<BasicPort>> global_port_tile_ports_;
vtr::vector<TileGlobalPortId, bool> global_port_is_clock_;
vtr::vector<TileGlobalPortId, bool> global_port_is_reset_;
vtr::vector<TileGlobalPortId, bool> global_port_is_set_;

View File

@ -51,11 +51,6 @@ void write_xml_tile_annotation_global_port(std::fstream& fp,
write_xml_attribute(fp, "name", tile_annotation.global_port_name(global_port_id).c_str());
std::string tile_port_attr = tile_annotation.global_port_tile_name(global_port_id)
+ "."
+ generate_tile_port_name(tile_annotation.global_port_tile_port(global_port_id));
write_xml_attribute(fp, "tile_port", tile_port_attr.c_str());
write_xml_attribute(fp, "is_clock", tile_annotation.global_port_is_clock(global_port_id));
write_xml_attribute(fp, "is_set", tile_annotation.global_port_is_set(global_port_id));
@ -64,7 +59,18 @@ void write_xml_tile_annotation_global_port(std::fstream& fp,
write_xml_attribute(fp, "default_value", tile_annotation.global_port_default_value(global_port_id));
fp << "/>" << "\n";
fp << ">" << "\n";
for (size_t tile_info_id = 0; tile_info_id < tile_annotation.global_port_tile_names(global_port_id).size(); ++tile_info_id) {
fp << "\t\t\t" << "<tile ";
write_xml_attribute(fp, "name", tile_annotation.global_port_tile_names(global_port_id)[tile_info_id].c_str());
write_xml_attribute(fp, "port", generate_tile_port_name(tile_annotation.global_port_tile_ports(global_port_id)[tile_info_id]).c_str());
write_xml_attribute(fp, "x", tile_annotation.global_port_tile_coordinates(global_port_id)[tile_info_id].x());
write_xml_attribute(fp, "y", tile_annotation.global_port_tile_coordinates(global_port_id)[tile_info_id].y());
fp << "/>";
}
fp << "\t\t" << "</global_port>";
}
/********************************************************************

View File

@ -13,7 +13,10 @@ namespace openfpga {
/* Top-level module name */
constexpr char* FPGA_TOP_MODULE_NAME = "fpga_top";
constexpr char* CONFIGURABLE_MEMORY_CHAIN_IN_NAME = "ccff_head";
constexpr char* CONFIGURABLE_MEMORY_CHAIN_OUT_NAME = "ccff_tail";
constexpr char* CONFIGURABLE_MEMORY_DATA_OUT_NAME = "mem_out";
constexpr char* CONFIGURABLE_MEMORY_INVERTED_DATA_OUT_NAME = "mem_outb";
/* IO PORT */
/* Prefix of global input, output and inout ports of FPGA fabric */

View File

@ -708,7 +708,7 @@ std::string generate_formal_verification_sram_port_name(const CircuitLibrary& ci
* TODO: This could be replaced as a constexpr string
*********************************************************************/
std::string generate_configuration_chain_head_name() {
return std::string("ccff_head");
return std::string(CONFIGURABLE_MEMORY_CHAIN_IN_NAME);
}
/*********************************************************************
@ -716,7 +716,7 @@ std::string generate_configuration_chain_head_name() {
* TODO: This could be replaced as a constexpr string
*********************************************************************/
std::string generate_configuration_chain_tail_name() {
return std::string("ccff_tail");
return std::string(CONFIGURABLE_MEMORY_CHAIN_OUT_NAME);
}
/*********************************************************************
@ -732,7 +732,7 @@ std::string generate_configurable_memory_data_out_name() {
* TODO: This could be replaced as a constexpr string
*********************************************************************/
std::string generate_configurable_memory_inverted_data_out_name() {
return std::string("mem_outb");
return std::string(CONFIGURABLE_MEMORY_INVERTED_DATA_OUT_NAME);
}
/*********************************************************************

View File

@ -77,8 +77,6 @@ void add_module_input_nets_to_mem_modules(ModuleManager& module_manager,
* j-th pin of output port of the i-th child module is wired to the j + i*W -th
* pin of output port of the memory module, where W is the size of port
* 3. It assumes fixed port name for output ports
*
* We cache the module nets that have been created because they will be used later
********************************************************************/
static
std::vector<ModuleNetId> add_module_output_nets_to_chain_mem_modules(ModuleManager& module_manager,
@ -165,15 +163,11 @@ void add_module_output_nets_to_mem_modules(ModuleManager& module_manager,
* add_module_nets_cmos_memory_chain_config_bus() !!!
*********************************************************************/
static
void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
const ModuleId& parent_module,
const std::vector<ModuleNetId>& output_nets,
const CircuitLibrary& circuit_lib,
const CircuitPortId& model_input_port,
const CircuitPortId& model_output_port) {
/* Counter for the nets */
size_t net_counter = 0;
void add_module_nets_to_cmos_memory_config_chain_module(ModuleManager& module_manager,
const ModuleId& parent_module,
const CircuitLibrary& circuit_lib,
const CircuitPortId& model_input_port,
const CircuitPortId& model_output_port) {
for (size_t mem_index = 0; mem_index < module_manager.configurable_children(parent_module).size(); ++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -219,21 +213,9 @@ void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
/* Create a net for each pin */
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
/* Create a net and add source and sink to it */
ModuleNetId net;
if (0 == mem_index) {
net = module_manager.create_module_net(parent_module);
} else {
net = output_nets[net_counter];
}
/* Add net source */
module_manager.add_module_net_source(parent_module, net, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
ModuleNetId net = create_module_source_pin_net(module_manager, parent_module, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
/* Add net sink */
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
/* Update net counter */
if (0 < mem_index) {
net_counter++;
}
}
}
@ -263,17 +245,90 @@ void add_module_nets_to_cmos_memory_chain_module(ModuleManager& module_manager,
/* Create a net for each pin */
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
/* Create a net and add source and sink to it */
ModuleNetId net = output_nets[net_counter];
/* Add net source */
module_manager.add_module_net_source(parent_module, net, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
ModuleNetId net = create_module_source_pin_net(module_manager, parent_module, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
/* Add net sink */
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
/* Update net counter */
net_counter++;
}
}
VTR_ASSERT(net_counter == output_nets.size());
/********************************************************************
* Connect the scan input of all the memory modules
* under the parent module in a chain
*
* +--------+ +--------+ +--------+
* ccff_head --->| Memory |--->| Memory |--->... --->| Memory |
* | Module | | Module | | Module |
* | [0] | | [1] | | [N-1] |
* +--------+ +--------+ +--------+
* For the 1st memory module:
* net source is the configuration chain head of the primitive module
* net sink is the scan input of the next memory module
*
* For the rest of memory modules:
* net source is the configuration chain tail of the previous memory module
* net sink is the scan input of the next memory module
*
* Note that:
* This function is designed for memory modules ONLY!
* Do not use it to replace the
* add_module_nets_cmos_memory_chain_config_bus() !!!
*********************************************************************/
static
void add_module_nets_to_cmos_memory_scan_chain_module(ModuleManager& module_manager,
const ModuleId& parent_module,
const CircuitLibrary& circuit_lib,
const CircuitPortId& model_input_port,
const CircuitPortId& model_output_port) {
for (size_t mem_index = 0; mem_index < module_manager.configurable_children(parent_module).size(); ++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
ModulePortId net_src_port_id;
ModuleId net_sink_module_id;
size_t net_sink_instance_id;
ModulePortId net_sink_port_id;
if (0 == mem_index) {
/* Find the port name of configuration chain head */
std::string src_port_name = generate_configuration_chain_head_name();
net_src_module_id = parent_module;
net_src_instance_id = 0;
net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id = module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_port_id = module_manager.find_module_port(net_sink_module_id, sink_port_name);
} else {
/* Find the port name of previous memory module */
std::string src_port_name = circuit_lib.port_prefix(model_output_port);
net_src_module_id = module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(parent_module)[mem_index - 1];
net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id = module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_port_id = module_manager.find_module_port(net_sink_module_id, sink_port_name);
}
/* Get the pin id for source port */
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
/* Get the pin id for sink port */
BasicPort net_sink_port = module_manager.module_port(net_sink_module_id, net_sink_port_id);
/* Port sizes of source and sink should match */
VTR_ASSERT(net_src_port.get_width() == net_sink_port.get_width());
/* Create a net for each pin */
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
/* Create a net and add source and sink to it */
ModuleNetId net = create_module_source_pin_net(module_manager, parent_module, net_src_module_id, net_src_instance_id, net_src_port_id, net_src_port.pins()[pin_id]);
/* Add net sink */
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
}
}
}
/*********************************************************************
@ -382,7 +437,7 @@ void build_memory_flatten_module(ModuleManager& module_manager,
* scan-chain--->| CCFF |--->| CCFF |--->... --->| CCFF |---->scan-chain
* input&clock | [0] | | [1] | | [N-1] | output
* +-------+ +-------+ +-------+
* | | ... |
* | | ... | config-memory output
* v v v
* +-----------------------------------------+
* | Multiplexer Configuration port |
@ -397,12 +452,15 @@ void build_memory_chain_module(ModuleManager& module_manager,
/* Get the input ports from the SRAM */
std::vector<CircuitPortId> sram_input_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_INPUT, true);
/* Should have only 1 input port */
VTR_ASSERT( 1 == sram_input_ports.size() );
/* Should have only 1 or 2 input port */
VTR_ASSERT( (1 == sram_input_ports.size())
|| (2 == sram_input_ports.size()) );
/* Get the output ports from the SRAM */
std::vector<CircuitPortId> sram_output_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
/* Should have only 1 or 2 output port */
VTR_ASSERT( (1 == sram_output_ports.size()) || ( 2 == sram_output_ports.size()) );
/* Should have only 1 or 2 or 3 output port */
VTR_ASSERT( (1 == sram_output_ports.size())
|| (2 == sram_output_ports.size())
|| (3 == sram_output_ports.size()) );
/* Create a module and add to the module manager */
ModuleId mem_module = module_manager.add_module(module_name);
@ -428,13 +486,27 @@ void build_memory_chain_module(ModuleManager& module_manager,
circuit_lib.port_size(sram_output_ports[0]));
module_manager.add_port(mem_module, chain_tail_port, ModuleManager::MODULE_OUTPUT_PORT);
/* Add each output port: port width should match the number of memories */
for (size_t iport = 0; iport < sram_output_ports.size(); ++iport) {
/* There could be 3 conditions w.r.t. the number of output ports:
* - Only one output port is defined. In this case, the 1st port is the Q
* In such case, only Q will be considered as data output ports
* - Two output port is defined. In this case, the 1st port is the Q while the 2nd port is the QN
* In such case, both Q and QN will be considered as data output ports
* - Three output port is defined.
* In this case:
* - the 1st port is the Q (the chain output)
* - the 2nd port is the QN (the inverted data output)
* - the 3nd port is the configure-enabled Q
* In such case, configure-enabled Q and QN will be considered as data output ports
*/
size_t num_data_output_ports = sram_output_ports.size();
if (3 == sram_output_ports.size()) {
num_data_output_ports = 2;
}
for (size_t iport = 0; iport < num_data_output_ports; ++iport) {
std::string port_name;
if (0 == iport) {
port_name = generate_configurable_memory_data_out_name();
} else {
VTR_ASSERT( 1 == iport);
} else if (1 == iport) {
port_name = generate_configurable_memory_inverted_data_out_name();
}
BasicPort output_port(port_name, num_mems);
@ -444,9 +516,6 @@ void build_memory_chain_module(ModuleManager& module_manager,
/* Find the sram module in the module manager */
ModuleId sram_mem_module = module_manager.find_module(circuit_lib.model_name(sram_model));
/* Cache the output nets for non-inverted data output */
std::vector<ModuleNetId> mem_output_nets;
/* Instanciate each submodule */
for (size_t i = 0; i < num_mems; ++i) {
size_t sram_mem_instance = module_manager.num_instance(mem_module, sram_mem_module);
@ -454,7 +523,7 @@ void build_memory_chain_module(ModuleManager& module_manager,
module_manager.add_configurable_child(mem_module, sram_mem_module, sram_mem_instance);
/* Build module nets to wire outputs of sram modules to outputs of memory module */
for (size_t iport = 0; iport < sram_output_ports.size(); ++iport) {
for (size_t iport = 0; iport < num_data_output_ports; ++iport) {
std::string port_name;
if (0 == iport) {
port_name = generate_configurable_memory_data_out_name();
@ -462,20 +531,32 @@ void build_memory_chain_module(ModuleManager& module_manager,
VTR_ASSERT( 1 == iport);
port_name = generate_configurable_memory_inverted_data_out_name();
}
/* Find the proper data output port
* The exception is when there are 3 output ports defined
* The 3rd port is the regular data output port to be used
*/
CircuitPortId data_output_port_to_connect = sram_output_ports[iport];
if ((3 == sram_output_ports.size()) && (0 == iport)) {
data_output_port_to_connect = sram_output_ports.back();
}
std::vector<ModuleNetId> output_nets = add_module_output_nets_to_chain_mem_modules(module_manager, mem_module,
port_name, circuit_lib, sram_output_ports[iport],
port_name, circuit_lib, data_output_port_to_connect,
sram_mem_module, i, sram_mem_instance);
/* Cache only for regular data outputs */
if (0 == iport) {
mem_output_nets.insert(mem_output_nets.end(), output_nets.begin(), output_nets.end());
}
}
}
/* Build module nets to wire the configuration chain */
add_module_nets_to_cmos_memory_chain_module(module_manager, mem_module, mem_output_nets,
circuit_lib, sram_input_ports[0], sram_output_ports[0]);
add_module_nets_to_cmos_memory_config_chain_module(module_manager, mem_module,
circuit_lib, sram_input_ports[0], sram_output_ports[0]);
/* If there is a second input defined,
* add nets to short wire the 2nd inputs to the first inputs
*/
if (2 == sram_input_ports.size()) {
add_module_nets_to_cmos_memory_scan_chain_module(module_manager, mem_module,
circuit_lib, sram_input_ports[1], sram_output_ports[0]);
}
/* Add global ports to the pb_module:
* This is a much easier job after adding sub modules (instances),

View File

@ -695,33 +695,42 @@ void add_top_module_nets_connect_grids_and_gsbs(ModuleManager& module_manager,
* that are defined as global in tile annotation
*******************************************************************/
static
void build_top_module_global_net_for_given_grid_module(ModuleManager& module_manager,
const ModuleId& top_module,
const ModulePortId& top_module_port,
const TileAnnotation& tile_annotation,
const TileGlobalPortId& tile_global_port,
const DeviceGrid& grids,
const vtr::Point<size_t>& grid_coordinate,
const e_side& border_side,
const vtr::Matrix<size_t>& grid_instance_ids) {
int build_top_module_global_net_for_given_grid_module(ModuleManager& module_manager,
const ModuleId& top_module,
const ModulePortId& top_module_port,
const TileAnnotation& tile_annotation,
const TileGlobalPortId& tile_global_port,
const BasicPort& tile_port_to_connect,
const DeviceGrid& grids,
const vtr::Point<size_t>& grid_coordinate,
const e_side& border_side,
const vtr::Matrix<size_t>& grid_instance_ids) {
t_physical_tile_type_ptr physical_tile = grids[grid_coordinate.x()][grid_coordinate.y()].type;
/* Ensure physical tile matches the global port definition */
VTR_ASSERT(std::string(physical_tile->name) == tile_annotation.global_port_tile_name(tile_global_port));
/* Find the port of the grid module according to the tile annotation */
int grid_pin_index = physical_tile->num_pins;
int grid_pin_start_index = physical_tile->num_pins;
for (const t_physical_tile_port& tile_port : physical_tile->ports) {
if (std::string(tile_port.name) == tile_annotation.global_port_tile_port(tile_global_port).get_name()) {
if (std::string(tile_port.name) == tile_port_to_connect.get_name()) {
BasicPort ref_tile_port(tile_port.name, tile_port.num_pins);
/* Port size must match!!! */
VTR_ASSERT(size_t(tile_port.num_pins) == tile_annotation.global_port_tile_port(tile_global_port).get_width());
/* TODO: Should check there is only port matching!!! */
grid_pin_index = tile_port.absolute_first_pin_index;
if (false == ref_tile_port.contained(tile_port_to_connect)) {
VTR_LOG_ERROR("Tile annotation '%s' port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!",
tile_annotation.global_port_name(tile_global_port).c_str(),
tile_port_to_connect.get_name().c_str(),
tile_port_to_connect.get_lsb(),
tile_port_to_connect.get_msb(),
ref_tile_port.get_name().c_str(),
ref_tile_port.get_lsb(),
ref_tile_port.get_msb());
return CMD_EXEC_FATAL_ERROR;
}
grid_pin_start_index = tile_port.absolute_first_pin_index;
break;
}
}
/* Ensure the pin index is valid */
VTR_ASSERT(grid_pin_index < physical_tile->num_pins);
VTR_ASSERT(grid_pin_start_index < physical_tile->num_pins);
/* Find the module name for this type of grid */
std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX);
@ -730,23 +739,39 @@ void build_top_module_global_net_for_given_grid_module(ModuleManager& module_man
VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
size_t grid_instance = grid_instance_ids[grid_coordinate.x()][grid_coordinate.y()];
/* Find the module pin */
size_t grid_pin_width = physical_tile->pin_width_offset[grid_pin_index];
size_t grid_pin_height = physical_tile->pin_height_offset[grid_pin_index];
std::vector<e_side> pin_sides = find_physical_tile_pin_side(physical_tile, grid_pin_index, border_side);
for (const e_side& pin_side : pin_sides) {
std::string grid_port_name = generate_grid_port_name(grid_coordinate,
grid_pin_width, grid_pin_height,
pin_side,
grid_pin_index, false);
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, grid_port_id));
VTR_ASSERT(1 == physical_tile->equivalent_sites.size());
/* Build nets */
add_module_bus_nets(module_manager, top_module,
top_module, 0, top_module_port,
grid_module, grid_instance, grid_port_id);
/* A tile may consist of multiple subtile, connect to all the pins from sub tiles */
for (int iz = 0; iz < physical_tile->capacity; ++iz) {
/* TODO: This should be replaced by using a pin mapping data structure from physical tile! */
int grid_pin_index = grid_pin_start_index + iz * physical_tile->equivalent_sites[0]->pb_type->num_pins;
/* Find the module pin */
size_t grid_pin_width = physical_tile->pin_width_offset[grid_pin_index];
size_t grid_pin_height = physical_tile->pin_height_offset[grid_pin_index];
std::vector<e_side> pin_sides = find_physical_tile_pin_side(physical_tile, grid_pin_index, border_side);
for (const e_side& pin_side : pin_sides) {
std::string grid_port_name = generate_grid_port_name(grid_coordinate,
grid_pin_width, grid_pin_height,
pin_side,
grid_pin_index, false);
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, grid_port_id));
/* Build nets */
BasicPort src_port = module_manager.module_port(top_module, top_module_port);
for (size_t pin_id = 0; pin_id < tile_port_to_connect.pins().size(); ++pin_id) {
ModuleNetId net = create_module_source_pin_net(module_manager, top_module,
top_module, 0,
top_module_port, src_port.pins()[pin_id]);
VTR_ASSERT(ModuleNetId::INVALID() != net);
/* Configure the net sink */
module_manager.add_module_net_sink(top_module, net, grid_module, grid_instance, grid_port_id, tile_port_to_connect.pins()[pin_id]);
}
}
}
return CMD_EXEC_SUCCESS;
}
/********************************************************************
@ -757,17 +782,23 @@ int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager,
const TileAnnotation& tile_annotation,
const DeviceGrid& grids,
const vtr::Matrix<size_t>& grid_instance_ids) {
int status = CMD_EXEC_SUCCESS;
/* Add the global ports which are yet added to the top-level module
/* Add the global ports which are NOT yet added to the top-level module
* (in different names than the global ports defined in circuit library
*/
std::vector<BasicPort> global_ports_to_add;
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
ModulePortId module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port));
/* The global port size is derived from the maximum port size among all the tile port defintion */
if (ModulePortId::INVALID() == module_port) {
BasicPort global_port_to_add;
global_port_to_add.set_name(tile_annotation.global_port_name(tile_global_port));
global_port_to_add.set_width(tile_annotation.global_port_tile_port(tile_global_port).get_width());
size_t max_port_size = 0;
for (const BasicPort& tile_port : tile_annotation.global_port_tile_ports(tile_global_port)) {
max_port_size = std::max(tile_port.get_width(), max_port_size);
}
global_port_to_add.set_width(max_port_size);
global_ports_to_add.push_back(global_port_to_add);
}
}
@ -784,72 +815,130 @@ int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager,
ModulePortId top_module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port));
VTR_ASSERT(ModulePortId::INVALID() != top_module_port);
/* Spot the port from child modules from core grids */
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
/* Bypass EMPTY tiles */
if (true == is_empty_type(grids[ix][iy].type)) {
continue;
}
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
if ( (0 < grids[ix][iy].width_offset)
|| (0 < grids[ix][iy].height_offset)) {
continue;
}
for (size_t tile_info_id = 0; tile_info_id < tile_annotation.global_port_tile_names(tile_global_port).size(); ++tile_info_id) {
std::string tile_name = tile_annotation.global_port_tile_names(tile_global_port)[tile_info_id];
BasicPort tile_port = tile_annotation.global_port_tile_ports(tile_global_port)[tile_info_id];
/* Find the coordinates for the wanted tiles */
vtr::Point<size_t> start_coord(1, 1);
vtr::Point<size_t> end_coord(grids.width() - 1, grids.height() - 1);
vtr::Point<size_t> range = tile_annotation.global_port_tile_coordinates(tile_global_port)[tile_info_id];
bool out_of_range = false;
/* Bypass the tiles whose names do not match */
if (std::string(grids[ix][iy].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) {
continue;
/* -1 means all the x should be considered */
if (size_t(-1) != range.x()) {
if ((range.x() < start_coord.x()) || (range.x() > end_coord.x())) {
out_of_range = true;
} else {
/* Set the range */
start_coord.set_x(range.x());
end_coord.set_x(range.x());
}
/* Create nets and finish connection build-up */
build_top_module_global_net_for_given_grid_module(module_manager,
top_module,
top_module_port,
tile_annotation,
tile_global_port,
grids,
vtr::Point<size_t>(ix, iy),
NUM_SIDES,
grid_instance_ids);
}
}
/* Walk through all the grids on the perimeter, which are I/O grids */
for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) {
for (const vtr::Point<size_t>& io_coordinate : io_coordinates[io_side]) {
/* Bypass EMPTY grid */
if (true == is_empty_type(grids[io_coordinate.x()][io_coordinate.y()].type)) {
continue;
}
/* -1 means all the y should be considered */
if (size_t(-1) != range.y()) {
if ((range.y() < start_coord.y()) || (range.y() > end_coord.y())) {
out_of_range = true;
} else {
/* Set the range */
start_coord.set_y(range.y());
end_coord.set_y(range.y());
}
}
/* Error out immediately if the coordinate is not valid! */
if (true == out_of_range) {
VTR_LOG_ERROR("Coordinate (%lu, %lu) in tile annotation for tile '%s' is out of range (%lu:%lu, %lu:%lu)!",
range.x(), range.y(), tile_name.c_str(),
start_coord.x(), end_coord.x(), start_coord.y(), end_coord.y());
return CMD_EXEC_FATAL_ERROR;
}
/* Spot the port from child modules from core grids */
for (size_t ix = start_coord.x(); ix < end_coord.x(); ++ix) {
for (size_t iy = start_coord.y(); iy < end_coord.y(); ++iy) {
/* Bypass EMPTY tiles */
if (true == is_empty_type(grids[ix][iy].type)) {
continue;
}
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
if ( (0 < grids[ix][iy].width_offset)
|| (0 < grids[ix][iy].height_offset)) {
continue;
}
/* Bypass the tiles whose names do not match */
if (std::string(grids[ix][iy].type->name) != tile_name) {
continue;
}
/* Create nets and finish connection build-up */
status = build_top_module_global_net_for_given_grid_module(module_manager,
top_module,
top_module_port,
tile_annotation,
tile_global_port,
tile_port,
grids,
vtr::Point<size_t>(ix, iy),
NUM_SIDES,
grid_instance_ids);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
}
/* Walk through all the grids on the perimeter, which are I/O grids */
for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) {
for (const vtr::Point<size_t>& io_coordinate : io_coordinates[io_side]) {
/* Bypass EMPTY grid */
if (true == is_empty_type(grids[io_coordinate.x()][io_coordinate.y()].type)) {
continue;
}
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
if ( (0 < grids[io_coordinate.x()][io_coordinate.y()].width_offset)
|| (0 < grids[io_coordinate.x()][io_coordinate.y()].height_offset)) {
continue;
}
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
if ( (0 < grids[io_coordinate.x()][io_coordinate.y()].width_offset)
|| (0 < grids[io_coordinate.x()][io_coordinate.y()].height_offset)) {
continue;
}
/* Bypass the tiles whose names do not match */
if (std::string(grids[io_coordinate.x()][io_coordinate.y()].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) {
continue;
}
/* Bypass the tiles whose names do not match */
if (std::string(grids[io_coordinate.x()][io_coordinate.y()].type->name) != tile_name) {
continue;
}
/* Create nets and finish connection build-up */
build_top_module_global_net_for_given_grid_module(module_manager,
top_module,
top_module_port,
tile_annotation,
tile_global_port,
grids,
io_coordinate,
io_side,
grid_instance_ids);
/* Check if the coordinate satisfy the tile coordinate defintion
* - Bypass if the x is a specific number (!= -1), and io_coordinate is different
* - Bypass if the y is a specific number (!= -1), and io_coordinate is different
*/
if ((size_t(-1) != range.x()) && (range.x() != io_coordinate.x())) {
continue;
}
if ((size_t(-1) != range.y()) && (range.y() != io_coordinate.y())) {
continue;
}
/* Create nets and finish connection build-up */
status = build_top_module_global_net_for_given_grid_module(module_manager,
top_module,
top_module_port,
tile_annotation,
tile_global_port,
tile_port,
grids,
io_coordinate,
io_side,
grid_instance_ids);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
}
}
}
return CMD_EXEC_SUCCESS;
return status;
}
} /* end namespace openfpga */

View File

@ -21,6 +21,9 @@ FabricBitstream::FabricBitstream() {
num_regions_ = 0;
invalid_region_ids_.clear();
use_address_ = false;
use_wl_address_ = false;
}
/**************************************************

View File

@ -102,107 +102,125 @@ int check_tile_annotation_conflicts_with_physical_tile(const TileAnnotation& til
int num_err = 0;
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
/* Must find a valid physical tile in the same name */
size_t found_matched_physical_tile = 0;
size_t found_matched_physical_tile_port = 0;
for (const t_physical_tile_type& physical_tile : physical_tile_types) {
if (std::string(physical_tile.name) != tile_annotation.global_port_tile_name(tile_global_port)) {
continue;
}
for (size_t tile_info_id = 0; tile_info_id < tile_annotation.global_port_tile_names(tile_global_port).size(); ++tile_info_id) {
/* Must find a valid physical tile in the same name */
size_t found_matched_physical_tile = 0;
size_t found_matched_physical_tile_port = 0;
/* Found a match, increment the counter */
found_matched_physical_tile++;
std::string required_tile_name = tile_annotation.global_port_tile_names(tile_global_port)[tile_info_id];
BasicPort required_tile_port = tile_annotation.global_port_tile_ports(tile_global_port)[tile_info_id];
/* Must found a valid port where both port name and port size must match!!! */
for (const t_physical_tile_port& tile_port : physical_tile.ports) {
if (std::string(tile_port.name) != tile_annotation.global_port_tile_port(tile_global_port).get_name()) {
for (const t_physical_tile_type& physical_tile : physical_tile_types) {
if (std::string(physical_tile.name) != required_tile_name) {
continue;
}
if (size_t(tile_port.num_pins) != tile_annotation.global_port_tile_port(tile_global_port).get_width()) {
continue;
/* Found a match, increment the counter */
found_matched_physical_tile++;
/* Must found a valid port where both port name and port size must match!!! */
for (const t_physical_tile_port& tile_port : physical_tile.ports) {
if (std::string(tile_port.name) != required_tile_port.get_name()) {
continue;
}
BasicPort ref_tile_port(tile_port.name, tile_port.num_pins);
/* Port size must be in range!!! */
if (false == ref_tile_port.contained(required_tile_port)) {
VTR_LOG_ERROR("Tile annotation port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!",
required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(),
required_tile_port.get_msb(),
ref_tile_port.get_name().c_str(),
ref_tile_port.get_lsb(),
ref_tile_port.get_msb());
num_err++;
continue;
}
/* Check if port property matches */
int grid_pin_index = tile_port.absolute_first_pin_index;
if (tile_port.is_clock != tile_annotation.global_port_is_clock(tile_global_port)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match physical tile port %s.%s in clock property (one is defined as clock while the other is not)!\n",
required_tile_name.c_str(),
required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(),
required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str(),
physical_tile.name, tile_port.name);
num_err++;
}
if ((false == tile_port.is_clock)
&& (false == tile_port.is_non_clock_global)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but is not defined as a non-clock global port!\n",
required_tile_name.c_str(),
required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(),
required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str(),
physical_tile.name, tile_port.name);
num_err++;
}
float pin_Fc = find_physical_tile_pin_Fc(&physical_tile, grid_pin_index);
if (0. != pin_Fc) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but its Fc is not zero '%g' !\n",
required_tile_name.c_str(),
required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(),
required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str(),
physical_tile.name, tile_port.name, pin_Fc);
}
found_matched_physical_tile_port++;
}
/* Check if port property matches */
int grid_pin_index = tile_port.absolute_first_pin_index;
if (tile_port.is_clock != tile_annotation.global_port_is_clock(tile_global_port)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match physical tile port %s.%s in clock property (one is defined as clock while the other is not)!\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str(),
physical_tile.name, tile_port.name);
num_err++;
}
if ((false == tile_port.is_clock)
&& (false == tile_port.is_non_clock_global)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but is not defined as a non-clock global port!\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str(),
physical_tile.name, tile_port.name);
num_err++;
}
float pin_Fc = find_physical_tile_pin_Fc(&physical_tile, grid_pin_index);
if (0. != pin_Fc) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but its Fc is not zero '%g' !\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str(),
physical_tile.name, tile_port.name, pin_Fc);
}
found_matched_physical_tile_port++;
}
}
/* If we found no match, error out */
if (0 == found_matched_physical_tile) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile name '%s' in tile annotation '%s' does not match any physical tile!\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (0 == found_matched_physical_tile_port) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match any physical tile port!\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
/* If we found no match, error out */
if (0 == found_matched_physical_tile) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile name '%s' in tile annotation '%s' does not match any physical tile!\n",
required_tile_name.c_str(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (0 == found_matched_physical_tile_port) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match any physical tile port!\n",
required_tile_name.c_str(),
required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(),
required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
/* If we found more than 1 match, error out */
if (1 < found_matched_physical_tile) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile name '%s' in tile annotation '%s' match more than 1 physical tile!\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (1 < found_matched_physical_tile_port) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more than 1physical tile port!\n",
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
/* If we found more than 1 match, error out */
if (1 < found_matched_physical_tile) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile name '%s' in tile annotation '%s' match more than 1 physical tile!\n",
required_tile_name.c_str(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (1 < found_matched_physical_tile_port) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more than 1 physical tile port!\n",
required_tile_name.c_str(),
required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(),
required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
}
}

View File

@ -0,0 +1,9 @@
clk 0.500000 2.000000
a 0.502000 0.197200
b 0.485400 0.202800
c 0.248000 0.176800
a_reg 0.502000 0.197200
b_reg 0.485400 0.202800
n10 0.248000 0.043259
n13 0.502000 0.098994
n17 0.485400 0.098439

View File

@ -0,0 +1,16 @@
# Benchmark "and2_pipelined" written by ABC on Sun Jan 10 10:26:01 2021
.model and2_pipelined
.inputs clk a b
.outputs c
.latch n10 c 2
.latch n13 a_reg 2
.latch n17 b_reg 2
.names a_reg b_reg n10
11 1
.names a n13
1 1
.names b n17
1 1
.end

View File

@ -0,0 +1,34 @@
/////////////////////////////////////////
// Functionality: a pipelined 2-input AND
// where inputs and outputs are registered
// Author: Xifan Tang
////////////////////////////////////////
`timescale 1ns / 1ps
module and2_pipelined(
clk,
a,
b,
c);
input wire clk;
input wire a;
input wire b;
output wire c;
reg a_reg;
reg b_reg;
reg c_reg;
always @(posedge clk) begin
a_reg <= a;
b_reg <= b;
end
always @(posedge clk) begin
c_reg <= a_reg & b_reg;
end
assign c = c_reg;
endmodule

View File

@ -0,0 +1,6 @@
# Yosys synthesis script for ${TOP_MODULE}
# Read verilog files
${READ_VERILOG_FILE}
synth_quicklogic -blif ${OUTPUT_BLIF} -openfpga -top ${TOP_MODULE}

View File

@ -21,6 +21,7 @@ Note that an OpenFPGA architecture can be applied to multiple VPR architecture f
- behavioral: If behavioral Verilog modeling is specified
- local\_encoder: If local encoders are used in routing multiplexer design
- spyio/spypad: If spy I/Os are used
- registerable\_io: If I/Os are registerable (can be either combinational or sequential)
- stdcell: If circuit designs are built with standard cells only
- tree\_mux: If routing multiplexers are built with a tree-like structure
- <feature_size>: The technology node which the delay numbers are extracted from.

View File

@ -169,7 +169,9 @@
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<tile_annotations>
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
<global_port name="clk" is_clock="true" default_val="0">
<tile name="clb" port="clk" x="-1" y="-1"/>
</global_port>
</tile_annotations>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->

View File

@ -0,0 +1,198 @@
<!-- Architecture annotation for OpenFPGA framework
This annotation supports the k6_N10_40nm.xml
- General purpose logic block
- K = 6, N = 10, I = 40
- Single mode
- Routing architecture
- L = 4, fc_in = 0.15, fc_out = 0.1
-->
<openfpga_architecture>
<technology_library>
<device_library>
<device_model name="logic" type="transistor">
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="0.9" pn_ratio="2"/>
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
</device_model>
<device_model name="io" type="transistor">
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="2.5" pn_ratio="3"/>
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
</device_model>
</device_library>
<variation_library>
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
</variation_library>
</technology_library>
<circuit_library>
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
<design_technology type="cmos" topology="inverter" size="1"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
<device_technology device_model_name="logic"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/> <!-- model_type could be T, res_val and cap_val DON'T CARE -->
</circuit_model>
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="0" C="0" num_level="1"/> <!-- model_type could be T, res_val cap_val should be defined -->
</circuit_model>
<circuit_model type="mux" name="mux_tree" prefix="mux_tree" dump_structural_verilog="true">
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_tree_tapbuf" prefix="mux_tree_tapbuf" is_default="true" dump_structural_verilog="true">
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
<circuit_model type="ff" name="DFFSRQ" prefix="DFFSRQ" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="set" lib_name="SET" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="reset" lib_name="RST" size="1" is_global="true" default_val="0" is_reset="true"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="clk" lib_name="CK" size="1" is_global="false" default_val="0"/>
</circuit_model>
<circuit_model type="lut" name="lut4" prefix="lut4" dump_structural_verilog="true">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="4"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="16"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="ccff" name="DFF" prefix="DFF" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="QN" size="1"/>
<port type="clock" prefix="prog_clk" lib_name="CK" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model>
<circuit_model type="iopad" name="GPIO" prefix="GPIO" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/gpio.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/gpio.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="PAD" size="1" is_global="true" is_io="true" is_data_io="true"/>
<port type="sram" prefix="DIR" size="1" mode_select="true" circuit_model_name="DFF" default_val="1"/>
<port type="input" prefix="outpad" lib_name="A" size="1"/>
<port type="output" prefix="inpad" lib_name="Y" size="1"/>
</circuit_model>
</circuit_library>
<configuration_protocol>
<organization type="scan_chain" circuit_model_name="DFF"/>
</configuration_protocol>
<connection_block>
<switch name="ipin_cblock" circuit_model_name="mux_tree_tapbuf"/>
</connection_block>
<switch_block>
<switch name="0" circuit_model_name="mux_tree_tapbuf"/>
</switch_block>
<routing_segment>
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<tile_annotations>
<global_port name="clk" is_clock="true" default_val="0">
<tile name="clb" port="clk" x="-1" y="-1"/>
<tile name="io" port="clk" x="-1" y="-1"/>
</global_port>
</tile_annotations>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
<pb_type name="io[physical].iopad" circuit_model_name="GPIO" mode_bits="1"/>
<pb_type name="io[physical].ff" circuit_model_name="DFFSRQ"/>
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[inpad_registered].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[inpad_registered].ff" physical_pb_type_name="io[physical].ff"/>
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
<!-- End physical pb_type binding in complex block IO -->
<!-- physical pb_type binding in complex block CLB -->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb">
<!-- Binding interconnect to circuit models as their physical implementation, if not defined, we use the default model -->
<interconnect name="crossbar" circuit_model_name="mux_tree"/>
</pb_type>
<pb_type name="clb.fle[n1_lut4].ble4.lut4" circuit_model_name="lut4"/>
<pb_type name="clb.fle[n1_lut4].ble4.ff" circuit_model_name="DFFSRQ"/>
<!-- End physical pb_type binding in complex block IO -->
</pb_type_annotations>
</openfpga_architecture>

View File

@ -0,0 +1,194 @@
<!-- Architecture annotation for OpenFPGA framework
This annotation supports the k6_N10_40nm.xml
- General purpose logic block
- K = 6, N = 10, I = 40
- Single mode
- Routing architecture
- L = 4, fc_in = 0.15, fc_out = 0.1
-->
<openfpga_architecture>
<technology_library>
<device_library>
<device_model name="logic" type="transistor">
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="0.9" pn_ratio="2"/>
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
</device_model>
<device_model name="io" type="transistor">
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="2.5" pn_ratio="3"/>
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
</device_model>
</device_library>
<variation_library>
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
</variation_library>
</technology_library>
<circuit_library>
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
<design_technology type="cmos" topology="inverter" size="1"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
<device_technology device_model_name="logic"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
<device_technology device_model_name="logic"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/> <!-- model_type could be T, res_val and cap_val DON'T CARE -->
</circuit_model>
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="0" C="0" num_level="1"/> <!-- model_type could be T, res_val cap_val should be defined -->
</circuit_model>
<circuit_model type="mux" name="mux_tree" prefix="mux_tree" dump_structural_verilog="true">
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_tree_tapbuf" prefix="mux_tree_tapbuf" is_default="true" dump_structural_verilog="true">
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
<circuit_model type="ff" name="DFFSRQ" prefix="DFFSRQ" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="set" lib_name="SET" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="reset" lib_name="RST" size="1" is_global="true" default_val="0" is_reset="true"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="clk" lib_name="CK" size="1" is_global="true" default_val="0" />
</circuit_model>
<circuit_model type="lut" name="lut4" prefix="lut4" dump_structural_verilog="true">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="4"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="16"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="ccff" name="CFGSDFFR" prefix="CFGSDFFR" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="pReset" lib_name="RST" size="1" is_global="true" default_val="0" is_reset="true" is_prog="true"/>
<port type="input" prefix="SE" size="1" is_global="true" default_val="0"/>
<port type="input" prefix="config_enable" lib_name="CFGE" size="1" is_global="true" default_val="0" is_config_enable="true"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="SI" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="CFGQN" size="1"/>
<port type="output" prefix="CFGQ" size="1"/>
<port type="clock" prefix="prog_clk" lib_name="CK" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model>
<circuit_model type="iopad" name="GPIO" prefix="GPIO" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/gpio.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/gpio.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="PAD" size="1" is_global="true" is_io="true" is_data_io="true"/>
<port type="sram" prefix="DIR" size="1" mode_select="true" circuit_model_name="CFGSDFFR" default_val="1"/>
<port type="input" prefix="outpad" lib_name="A" size="1"/>
<port type="output" prefix="inpad" lib_name="Y" size="1"/>
</circuit_model>
</circuit_library>
<configuration_protocol>
<organization type="scan_chain" circuit_model_name="CFGSDFFR"/>
</configuration_protocol>
<connection_block>
<switch name="ipin_cblock" circuit_model_name="mux_tree_tapbuf"/>
</connection_block>
<switch_block>
<switch name="0" circuit_model_name="mux_tree_tapbuf"/>
</switch_block>
<routing_segment>
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
<pb_type name="io[physical].iopad" circuit_model_name="GPIO" mode_bits="1"/>
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
<!-- End physical pb_type binding in complex block IO -->
<!-- physical pb_type binding in complex block CLB -->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb">
<!-- Binding interconnect to circuit models as their physical implementation, if not defined, we use the default model -->
<interconnect name="crossbar" circuit_model_name="mux_tree"/>
</pb_type>
<pb_type name="clb.fle[n1_lut4].ble4.lut4" circuit_model_name="lut4"/>
<pb_type name="clb.fle[n1_lut4].ble4.ff" circuit_model_name="DFFSRQ"/>
<!-- End physical pb_type binding in complex block IO -->
</pb_type_annotations>
</openfpga_architecture>

View File

@ -217,8 +217,12 @@
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
</direct_connection>
<tile_annotations>
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
<global_port name="reset" tile_port="clb.reset" is_reset="true" default_val="0"/>
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0">
<tile name="clb" port="clk"/>
</global_port>
<global_port name="reset" is_reset="true" default_val="0">
<tile name="clb" port="reset"/>
</global_port>
</tile_annotations>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->

View File

@ -397,3 +397,50 @@ end
assign Q = q_reg;
endmodule //End Of Module
//-----------------------------------------------------
// Function : D-type flip-flop with
// - asynchronous active high reset
// - scan-chain input
// - a scan-chain enable
// - a configure enable, when enabled the registered output will
// be released to the Q
//-----------------------------------------------------
module CFGSDFFR (
input RST, // Reset input
input CK, // Clock Input
input SE, // Scan-chain Enable
input D, // Data Input
input SI, // Scan-chain input
input CFGE, // Configure enable
output Q, // Regular Q output
output CFGQ, // Data Q output which is released when configure enable is activated
output CFGQN // Data Qb output which is released when configure enable is activated
);
//------------Internal Variables--------
reg q_reg;
wire QN;
//-------------Code Starts Here---------
always @ ( posedge CK or posedge RST)
if (RST) begin
q_reg <= 1'b0;
end else if (SE) begin
q_reg <= SI;
end else begin
q_reg <= D;
end
assign CFGQ = CFGE ? Q : 1'b0;
assign CFGQN = CFGE ? QN : 1'b1;
`ifndef ENABLE_FORMAL_VERIFICATION
// Wire q_reg to Q
assign Q = q_reg;
assign QN = !Q;
`else
assign Q = 1'bZ;
assign QN = !Q;
`endif
endmodule //End Of Module

View File

@ -0,0 +1,76 @@
# Run VPR for the 'and' design
# When the global clock is defined as a port of a tile, clock routing in VPR should be skipped
# This is due to the Fc_in of clock port is set to 0 for global wiring
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT}
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing #--verbose
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write fabric-dependent bitstream
write_fabric_bitstream --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator --explicit_port_mapping
# Write the SDC files for PnR backend
# - Turn on every options here
write_pnr_sdc --file ./SDC
# Write SDC to disable timing for configure ports
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
# Write the SDC to run timing analysis for a mapped FPGA fabric
write_analysis_sdc --file ./SDC_analysis
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -0,0 +1,77 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing #--verbose
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write fabric-dependent bitstream
write_fabric_bitstream --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator
# Write the SDC files for PnR backend
# - Turn on every options here
write_pnr_sdc --file ./SDC
# Write SDC to constrain timing of configuration chain
write_configuration_chain_sdc --file ./SDC/ccff_timing.sdc --time_unit ns --max_delay 5 --min_delay 2.5
# Write SDC to disable timing for configure ports
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
# Write the SDC to run timing analysis for a mapped FPGA fabric
write_analysis_sdc --file ./SDC_analysis
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -0,0 +1,42 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 1*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/configuration_chain_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_cfgscff_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
[SYNTHESIS_PARAM]
bench0_top = and2
bench0_chan_width = 300
bench1_top = or2
bench1_chan_width = 300
bench2_top = and2_latch
bench2_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -26,6 +26,7 @@ arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v
[SYNTHESIS_PARAM]
bench0_top = and2
@ -34,5 +35,8 @@ bench0_chan_width = 300
bench1_top = and2_latch
bench1_chan_width = 300
bench2_top = and2_pipelined
bench2_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,35 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_global_tile_clock_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_registerable_io_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_vpr_device_layout=2x2
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v
[SYNTHESIS_PARAM]
bench0_top = and2_pipelined
bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,36 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/quicklogic_flow_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter/counter.v
[SYNTHESIS_PARAM]
bench0_top = counter
bench0_chan_width = 100
bench0_yosys=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/quicklogic_yosys_flow_ap3.ys
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -15,6 +15,7 @@ Please reveal the following architecture features in the names to help quickly s
- aib: If the Advanced Interface Bus (AIB) is used in place of some I/Os.
- multi\_io\_capacity: If I/O capacity is different on each side of FPGAs.
- reduced\_io: If I/Os only appear a certain or multiple sides of FPGAs
- registerable\_io: If I/Os are registerable (can be either combinational or sequential)
- <feature\_size>: The technology node which the delay numbers are extracted from.
- TileOrgz<Type>: How tile is organized.
* Top-left (Tl): the pins of a tile are placed on the top side and left side only

View File

@ -0,0 +1,329 @@
<!--
Architecture with no fracturable LUTs
- 40 nm technology
- General purpose logic block:
K = 4, N = 4
- Routing architecture: L = 4, fc_in = 0.15, Fc_out = 0.1
Details on Modelling:
Based on flagship k6_frac_N10_mem32K_40nm.xml architecture. This architecture has no fracturable LUTs nor any heterogeneous blocks.
Authors: Jason Luu, Jeff Goeders, Vaughn Betz
-->
<architecture>
<!--
ODIN II specific config begins
Describes the types of user-specified netlist blocks (in blif, this corresponds to
".model [type_of_block]") that this architecture supports.
Note: Basic LUTs, I/Os, and flip-flops are not included here as there are
already special structures in blif (.names, .input, .output, and .latch)
that describe them.
-->
<models>
<!-- A virtual model for I/O to be used in the physical mode of io block -->
<model name="io">
<input_ports>
<port name="outpad"/>
</input_ports>
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
</models>
<tiles>
<tile name="io" capacity="8" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="clk" fc_type="frac" fc_val="0"/>
</fc>
<pinlocations pattern="custom">
<loc side="left">io.outpad io.inpad io.clk</loc>
<loc side="top">io.outpad io.inpad io.clk</loc>
<loc side="right">io.outpad io.inpad io.clk</loc>
<loc side="bottom">io.outpad io.inpad io.clk</loc>
</pinlocations>
</tile>
<tile name="clb" area="53894">
<equivalent_sites>
<site pb_type="clb"/>
</equivalent_sites>
<input name="I" num_pins="10" equivalent="full"/>
<output name="O" num_pins="4" equivalent="none"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="clk" fc_type="frac" fc_val="0"/>
</fc>
<pinlocations pattern="spread"/>
</tile>
</tiles>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<layout tileable="true">
<auto_layout aspect_ratio="1.0">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
</auto_layout>
<fixed_layout name="2x2" width="4" height="4">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
</fixed_layout>
</layout>
<device>
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
models. We are modifying the delay values however, to include metal C and R, which allows more architecture
experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS
(vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of
45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping
RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately
lined up with Stratix IV.
We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).
Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file
by 2.5x when looking up in Jeff's tables.
The delay values are lined up with Stratix IV, which has an architecture similar to this
proposed FPGA, and which is also 40 nm
C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage
4x minimum drive strength buffer. -->
<sizing R_minW_nmos="8926" R_minW_pmos="16067"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<chan_width_distr>
<x distr="uniform" peak="1.000000"/>
<y distr="uniform" peak="1.000000"/>
</chan_width_distr>
<switch_block type="wilton" fs="3"/>
<connection_block input_switch_name="ipin_cblock"/>
</device>
<switchlist>
<!-- VB: the mux_trans_size and buf_size data below is in minimum width transistor *areas*, assuming the purple
book area formula. This means the mux transistors are about 5x minimum drive strength.
We assume the first stage of the buffer is 3x min drive strength to be reasonable given the large
mux transistors, and this gives a reasonable stage ratio of a bit over 5x to the second stage. We assume
the n and p transistors in the first stage are equal-sized to lower the buffer trip point, since it's fed
by a pass transistor mux. We can then reverse engineer the buffer second stage to hit the specified
buf_size (really buffer area) - 16.2x minimum drive nmos and 1.8*16.2 = 29.2x minimum drive.
I then took the data from Jeff G.'s PTM modeling of 45 nm to get the Cin (gate of first stage) and Cout
(diff of second stage) listed below. Jeff's models are in tech/ptm_45nm, and are in min feature multiples.
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply the drive strength sizes above by
2.5x when looking up in Jeff's tables.
Finally, we choose a switch delay (58 ps) that leads to length 4 wires having a delay equal to that of SIV of 126 ps.
This also leads to the switch being 46% of the total wire delay, which is reasonable. -->
<switch type="mux" name="0" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<!--switch ipin_cblock resistance set to yeild for 4x minimum drive strength buffer-->
<switch type="mux" name="ipin_cblock" R="2231.5" Cout="0." Cin="1.47e-15" Tdel="7.247000e-11" mux_trans_size="1.222260" buf_size="auto"/>
</switchlist>
<segmentlist>
<!--- VB & JL: using ITRS metal stack data, 96 nm half pitch wires, which are intermediate metal width/space.
With the 96 nm half pitch, such wires would take 60 um of height, vs. a 90 nm high (approximated as square) Stratix IV tile so this seems
reasonable. Using a tile length of 90 nm, corresponding to the length of a Stratix IV tile if it were square. -->
<segment name="L4" freq="1.000000" length="4" type="unidir" Rmetal="101" Cmetal="22.5e-15">
<mux name="0"/>
<sb type="pattern">1 1 1 1 1</sb>
<cb type="pattern">1 1 1 1</cb>
</segment>
</segmentlist>
<complexblocklist>
<!-- Define I/O pads begin -->
<!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->
<!-- Not sure of the area of an I/O (varies widely), and it's not relevant to the design of the FPGA core, so we're setting it to 0. -->
<pb_type name="io">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- A mode denotes the physical implementation of an I/O
This mode will be not packable but is mainly used for fabric verilog generation
-->
<mode name="physical" packable="false">
<pb_type name="iopad" blif_model=".subckt io" num_pb="1">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clk" input="io.clk" output="ff.clk"/>
<direct name="outpad" input="io.outpad" output="iopad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="iopad.outpad"/>
</direct>
<!-- Create a selector between registered/combinational I/O -->
<direct name="inpad" input="iopad.inpad" output="ff.D"/>
<mux name="mux1" input="iopad.inpad ff.Q" output="io.inpad">
<delay_constant max="4.5e-11" in_port="iopad.inpad" out_port="io.inpad"/>
<delay_constant max="4.243e-11" in_port="ff.Q" out_port="io.inpad"/>
</mux>
</interconnect>
</mode>
<!-- IOs can operate as either inputs or outputs.
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io.inpad">
<delay_constant max="4.243e-11" in_port="inpad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="inpad_registered">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clk" input="io.clk" output="ff.clk"/>
<direct name="inpad" input="inpad.inpad" output="ff.D">
<pack_pattern name="registered_io" in_port="inpad.inpad" out_port="ff.D"/>
</direct>
<direct name="ff2inpad" input="ff.Q" output="io.inpad"/>
</interconnect>
</mode>
<mode name="outpad">
<pb_type name="outpad" blif_model=".output" num_pb="1">
<input name="outpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="outpad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="outpad.outpad"/>
</direct>
</interconnect>
</mode>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<!-- IOs go on the periphery of the FPGA, for consistency,
make it physically equivalent on all sides so that only one definition of I/Os is needed.
If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA
-->
<!-- Place I/Os on the sides of the FPGA -->
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends -->
<!-- Define general purpose logic block (CLB) begin -->
<!--- Area calculation: Total Stratix IV tile area is about 8100 um^2, and a minimum width transistor
area is 60 L^2 yields a tile area of 84375 MWTAs.
Routing at W=300 is 30481 MWTAs, leaving us with a total of 53000 MWTAs for logic block area
This means that only 37% of our area is in the general routing, and 63% is inside the logic
block. Note that the crossbar / local interconnect is considered part of the logic block
area in this analysis. That is a lower proportion of of routing area than most academics
assume, but note that the total routing area really includes the crossbar, which would push
routing area up significantly, we estimate into the ~70% range.
-->
<pb_type name="clb">
<input name="I" num_pins="10" equivalent="full"/>
<output name="O" num_pins="4" equivalent="none"/>
<clock name="clk" num_pins="1"/>
<!-- Describe basic logic element.
Each basic logic element has a 4-LUT that can be optionally registered
-->
<pb_type name="fle" num_pb="4">
<input name="in" num_pins="4"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- 4-LUT mode definition begin -->
<mode name="n1_lut4">
<!-- Define 4-LUT mode -->
<pb_type name="ble4" num_pb="1">
<input name="in" num_pins="4"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Define LUT -->
<pb_type name="lut4" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="4" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut4.in" out_port="lut4.out">
261e-12
261e-12
261e-12
261e-12
</delay_matrix>
</pb_type>
<!-- Define flip-flop -->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble4.in" output="lut4[0:0].in"/>
<direct name="direct2" input="lut4.out" output="ff.D">
<!-- Advanced user option that tells CAD tool to find LUT+FF pairs in netlist -->
<pack_pattern name="ble4" in_port="lut4.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble4.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut4.out" output="ble4.out">
<!-- LUT to output is faster than FF to output on a Stratix IV -->
<delay_constant max="25e-12" in_port="lut4.out" out_port="ble4.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="ble4.out"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="ble4.in"/>
<direct name="direct2" input="ble4.out" output="fle.out[0:0]"/>
<direct name="direct3" input="fle.clk" output="ble4.clk"/>
</interconnect>
</mode>
<!-- 6-LUT mode definition end -->
</pb_type>
<interconnect>
<!-- We use a full crossbar to get logical equivalence at inputs of CLB
The delays below come from Stratix IV. the delay through a connection block
input mux + the crossbar in Stratix IV is 167 ps. We already have a 72 ps
delay on the connection block input mux (modeled by Ian Kuon), so the remaining
delay within the crossbar is 95 ps.
The delays of cluster feedbacks in Stratix IV is 100 ps, when driven by a LUT.
Since all our outputs LUT outputs go to a BLE output, and have a delay of
25 ps to do so, we subtract 25 ps from the 100 ps delay of a feedback
to get the part that should be marked on the crossbar. -->
<complete name="crossbar" input="clb.I fle[3:0].out" output="fle[3:0].in">
<delay_constant max="95e-12" in_port="clb.I" out_port="fle[3:0].in"/>
<delay_constant max="75e-12" in_port="fle[3:0].out" out_port="fle[3:0].in"/>
</complete>
<complete name="clks" input="clb.clk" output="fle[3:0].clk">
</complete>
<!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins.
By grouping to output pins in this fashion, if a logic block is completely filled by 6-LUTs,
then the outputs those 6-LUTs take get evenly distributed across all four sides of the CLB instead of clumped on two sides (which is what happens with a more
naive specification).
-->
<direct name="clbouts1" input="fle[3:0].out" output="clb.O"/>
</interconnect>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<!-- Place this general purpose logic block in any unspecified column -->
</pb_type>
<!-- Define general purpose logic block (CLB) ends -->
</complexblocklist>
</architecture>

View File

@ -0,0 +1,737 @@
<!--
Low-cost homogeneous FPGA Architecture.
- Skywater 130 nm technology
- General purpose logic block:
K = 4, N = 8, fracturable 4 LUTs (can operate as one 4-LUT or two 3-LUTs with all 3 inputs shared)
with optionally registered outputs
- Routing architecture:
- 10% L = 1, fc_in = 0.15, Fc_out = 0.10
- 10% L = 2, fc_in = 0.15, Fc_out = 0.10
- 80% L = 4, fc_in = 0.15, Fc_out = 0.10
- 100 routing tracks per channel
Authors: Xifan Tang
-->
<architecture>
<!--
ODIN II specific config begins
Describes the types of user-specified netlist blocks (in blif, this corresponds to
".model [type_of_block]") that this architecture supports.
Note: Basic LUTs, I/Os, and flip-flops are not included here as there are
already special structures in blif (.names, .input, .output, and .latch)
that describe them.
-->
<models>
<!-- A virtual model for I/O to be used in the physical mode of io block -->
<model name="io">
<input_ports>
<port name="outpad"/>
</input_ports>
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
<model name="frac_lut4">
<input_ports>
<port name="in"/>
</input_ports>
<output_ports>
<port name="lut2_out"/>
<port name="lut3_out"/>
<port name="lut4_out"/>
</output_ports>
</model>
<model name="carry_follower">
<input_ports>
<port name="a"/>
<port name="b"/>
<port name="cin"/>
</input_ports>
<output_ports>
<port name="cout"/>
</output_ports>
</model>
<!-- A virtual model for scan-chain flip-flop to be used in the physical mode of FF -->
<model name="scff">
<input_ports>
<port name="D" clock="clk"/>
<port name="DI" clock="clk"/>
<port name="reset" clock="clk"/>
<port name="clk" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="clk"/>
</output_ports>
</model>
</models>
<tiles>
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
If you need to register the I/O, define clocks in the circuit models
These clocks can be handled in back-end
-->
<!-- Top-side has 1 I/O per tile -->
<tile name="io_top" capacity="1" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="bottom">io_top.outpad io_top.inpad</loc>
</pinlocations>
</tile>
<!-- Right-side has 1 I/O per tile -->
<tile name="io_right" capacity="1" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="left">io_right.outpad io_right.inpad</loc>
</pinlocations>
</tile>
<!-- Bottom-side has 9 I/O per tile -->
<tile name="io_bottom" capacity="9" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="top">io_bottom.outpad io_bottom.inpad</loc>
</pinlocations>
</tile>
<!-- Left-side has 1 I/O per tile -->
<tile name="io_left" capacity="1" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="right">io_left.outpad io_left.inpad</loc>
</pinlocations>
</tile>
<!-- CLB has most pins on the top and right sides -->
<tile name="clb" area="53894">
<equivalent_sites>
<site pb_type="clb"/>
</equivalent_sites>
<input name="I0" num_pins="2" equivalent="full"/>
<input name="I0i" num_pins="2" equivalent="none"/>
<input name="I1" num_pins="2" equivalent="full"/>
<input name="I1i" num_pins="2" equivalent="none"/>
<input name="I2" num_pins="2" equivalent="full"/>
<input name="I2i" num_pins="2" equivalent="none"/>
<input name="I3" num_pins="2" equivalent="full"/>
<input name="I3i" num_pins="2" equivalent="none"/>
<input name="I4" num_pins="2" equivalent="full"/>
<input name="I4i" num_pins="2" equivalent="none"/>
<input name="I5" num_pins="2" equivalent="full"/>
<input name="I5i" num_pins="2" equivalent="none"/>
<input name="I6" num_pins="2" equivalent="full"/>
<input name="I6i" num_pins="2" equivalent="none"/>
<input name="I7" num_pins="2" equivalent="full"/>
<input name="I7i" num_pins="2" equivalent="none"/>
<input name="reg_in" num_pins="1"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="reset" num_pins="1" is_non_clock_global="true"/>
<output name="O" num_pins="16" equivalent="none"/>
<output name="reg_out" num_pins="1"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="reg_in" fc_type="frac" fc_val="0"/>
<fc_override port_name="reg_out" fc_type="frac" fc_val="0"/>
<fc_override port_name="sc_in" fc_type="frac" fc_val="0"/>
<fc_override port_name="sc_out" fc_type="frac" fc_val="0"/>
<fc_override port_name="cin" fc_type="frac" fc_val="0"/>
<fc_override port_name="cout" fc_type="frac" fc_val="0"/>
<fc_override port_name="clk" fc_type="frac" fc_val="0"/>
<fc_override port_name="reset" fc_type="frac" fc_val="0"/>
</fc>
<!--pinlocations pattern="spread"/-->
<pinlocations pattern="custom">
<loc side="left">clb.clk clb.reset</loc>
<loc side="top">clb.reg_in clb.sc_in clb.cin clb.O[7:0] clb.I0 clb.I0i clb.I1 clb.I1i clb.I2 clb.I2i clb.I3 clb.I3i</loc>
<loc side="right">clb.O[15:8] clb.I4 clb.I4i clb.I5 clb.I5i clb.I6 clb.I6i clb.I7 clb.I7i</loc>
<loc side="bottom">clb.reg_out clb.sc_out clb.cout</loc>
</pinlocations>
</tile>
</tiles>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<layout tileable="true">
<auto_layout aspect_ratio="1.0">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<row type="io_top" starty="H-1" priority="100"/>
<row type="io_bottom" starty="0" priority="100"/>
<col type="io_left" startx="0" priority="100"/>
<col type="io_right" startx="W-1" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
</auto_layout>
<fixed_layout name="2x2" width="4" height="4">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<row type="io_top" starty="H-1" priority="100"/>
<row type="io_bottom" starty="0" priority="100"/>
<col type="io_left" startx="0" priority="100"/>
<col type="io_right" startx="W-1" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
</fixed_layout>
<fixed_layout name="12x12" width="14" height="14">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<row type="io_top" starty="H-1" priority="100"/>
<row type="io_bottom" starty="0" priority="100"/>
<col type="io_left" startx="0" priority="100"/>
<col type="io_right" startx="W-1" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
</fixed_layout>
</layout>
<device>
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
models. We are modifying the delay values however, to include metal C and R, which allows more architecture
experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS
(vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of
45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping
RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately
lined up with Stratix IV.
We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).
Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file
by 2.5x when looking up in Jeff's tables.
The delay values are lined up with Stratix IV, which has an architecture similar to this
proposed FPGA, and which is also 40 nm
C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage
4x minimum drive strength buffer. -->
<sizing R_minW_nmos="8926" R_minW_pmos="16067"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<chan_width_distr>
<x distr="uniform" peak="1.000000"/>
<y distr="uniform" peak="1.000000"/>
</chan_width_distr>
<switch_block type="wilton" fs="3" sub_type="subset" sub_fs="3"/>
<connection_block input_switch_name="ipin_cblock"/>
</device>
<switchlist>
<!-- VB: the mux_trans_size and buf_size data below is in minimum width transistor *areas*, assuming the purple
book area formula. This means the mux transistors are about 5x minimum drive strength.
We assume the first stage of the buffer is 3x min drive strength to be reasonable given the large
mux transistors, and this gives a reasonable stage ratio of a bit over 5x to the second stage. We assume
the n and p transistors in the first stage are equal-sized to lower the buffer trip point, since it's fed
by a pass transistor mux. We can then reverse engineer the buffer second stage to hit the specified
buf_size (really buffer area) - 16.2x minimum drive nmos and 1.8*16.2 = 29.2x minimum drive.
I then took the data from Jeff G.'s PTM modeling of 45 nm to get the Cin (gate of first stage) and Cout
(diff of second stage) listed below. Jeff's models are in tech/ptm_45nm, and are in min feature multiples.
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply the drive strength sizes above by
2.5x when looking up in Jeff's tables.
Finally, we choose a switch delay (58 ps) that leads to length 4 wires having a delay equal to that of SIV of 126 ps.
This also leads to the switch being 46% of the total wire delay, which is reasonable. -->
<switch type="mux" name="L1_mux" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<switch type="mux" name="L2_mux" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<switch type="mux" name="L4_mux" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<!--switch ipin_cblock resistance set to yeild for 4x minimum drive strength buffer-->
<switch type="mux" name="ipin_cblock" R="2231.5" Cout="0." Cin="1.47e-15" Tdel="7.247000e-11" mux_trans_size="1.222260" buf_size="auto"/>
</switchlist>
<segmentlist>
<!--- VB & JL: using ITRS metal stack data, 96 nm half pitch wires, which are intermediate metal width/space.
With the 96 nm half pitch, such wires would take 60 um of height, vs. a 90 nm high (approximated as square) Stratix IV tile so this seems
reasonable. Using a tile length of 90 nm, corresponding to the length of a Stratix IV tile if it were square. -->
<!-- GIVE a specific name for the segment! OpenFPGA appreciate that! -->
<segment name="L1" freq="0.10" length="1" type="unidir" Rmetal="101" Cmetal="22.5e-15">
<mux name="L1_mux"/>
<sb type="pattern">1 1</sb>
<cb type="pattern">1</cb>
</segment>
<segment name="L2" freq="0.10" length="2" type="unidir" Rmetal="101" Cmetal="22.5e-15">
<mux name="L2_mux"/>
<sb type="pattern">1 1 1</sb>
<cb type="pattern">1 1</cb>
</segment>
<segment name="L4" freq="0.80" length="4" type="unidir" Rmetal="101" Cmetal="22.5e-15">
<mux name="L4_mux"/>
<sb type="pattern">1 1 1 1 1</sb>
<cb type="pattern">1 1 1 1</cb>
</segment>
</segmentlist>
<directlist>
<direct name="carry_chain" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
<direct name="shift_register" from_pin="clb.reg_out" to_pin="clb.reg_in" x_offset="0" y_offset="-1" z_offset="0"/>
<direct name="scan_chain" from_pin="clb.sc_out" to_pin="clb.sc_in" x_offset="0" y_offset="-1" z_offset="0"/>
</directlist>
<complexblocklist>
<!-- Define input pads begin -->
<pb_type name="io">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
If you need to register the I/O, define clocks in the circuit models
These clocks can be handled in back-end
-->
<!-- A mode denotes the physical implementation of an I/O
This mode will be not packable but is mainly used for fabric verilog generation
-->
<mode name="physical" disabled_in_pack="true">
<pb_type name="iopad" blif_model=".subckt io" num_pb="1">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="iopad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="iopad.outpad"/>
</direct>
<direct name="inpad" input="iopad.inpad" output="io.inpad">
<delay_constant max="4.243e-11" in_port="iopad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<!-- IOs can operate as either inputs or outputs.
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io.inpad">
<delay_constant max="4.243e-11" in_port="inpad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="outpad">
<pb_type name="outpad" blif_model=".output" num_pb="1">
<input name="outpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="outpad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="outpad.outpad"/>
</direct>
</interconnect>
</mode>
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends -->
<!-- Define general purpose logic block (CLB) begin -->
<!-- -Due to the absence of local routing,
the 4 inputs of fracturable LUT4 are no longer equivalent,
because the 4th input can not be switched when the dual-LUT3 modes are used.
So pin equivalence should be applied to the first 3 inputs only
-->
<pb_type name="clb">
<input name="I0" num_pins="2" equivalent="full"/>
<input name="I0i" num_pins="2" equivalent="none"/>
<input name="I1" num_pins="2" equivalent="full"/>
<input name="I1i" num_pins="2" equivalent="none"/>
<input name="I2" num_pins="2" equivalent="full"/>
<input name="I2i" num_pins="2" equivalent="none"/>
<input name="I3" num_pins="2" equivalent="full"/>
<input name="I3i" num_pins="2" equivalent="none"/>
<input name="I4" num_pins="2" equivalent="full"/>
<input name="I4i" num_pins="2" equivalent="none"/>
<input name="I5" num_pins="2" equivalent="full"/>
<input name="I5i" num_pins="2" equivalent="none"/>
<input name="I6" num_pins="2" equivalent="full"/>
<input name="I6i" num_pins="2" equivalent="none"/>
<input name="I7" num_pins="2" equivalent="full"/>
<input name="I7i" num_pins="2" equivalent="none"/>
<input name="reg_in" num_pins="1"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="reset" num_pins="1" is_non_clock_global="true"/>
<output name="O" num_pins="16" equivalent="none"/>
<output name="reg_out" num_pins="1"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Describe fracturable logic element.
Each fracturable logic element has a 6-LUT that can alternatively operate as two 5-LUTs with shared inputs.
The outputs of the fracturable logic element can be optionally registered
-->
<pb_type name="fle" num_pb="8">
<input name="in" num_pins="4"/>
<input name="reg_in" num_pins="1"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="reset" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="reg_out" num_pins="1"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Physical mode definition begin (physical implementation of the fle) -->
<mode name="physical" disabled_in_pack="true">
<pb_type name="fabric" num_pb="1">
<input name="in" num_pins="4"/>
<input name="reg_in" num_pins="1"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="reset" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="reg_out" num_pins="1"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="frac_logic" num_pb="1">
<input name="in" num_pins="4"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<!-- Define LUT -->
<pb_type name="frac_lut4" blif_model=".subckt frac_lut4" num_pb="1">
<input name="in" num_pins="4"/>
<output name="lut2_out" num_pins="2"/>
<output name="lut3_out" num_pins="2"/>
<output name="lut4_out" num_pins="1"/>
</pb_type>
<pb_type name="carry_follower" blif_model=".subckt carry_follower" num_pb="1">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="direct1" input="frac_logic.in[0:1]" output="frac_lut4.in[0:1]"/>
<direct name="direct2" input="frac_logic.in[3:3]" output="frac_lut4.in[3:3]"/>
<direct name="direct3" input="frac_logic.cin" output="carry_follower.b"/>
<direct name="direct4" input="frac_lut4.lut2_out[1:1]" output="carry_follower.a"/>
<direct name="direct5" input="frac_lut4.lut2_out[0:0]" output="carry_follower.cin"/>
<direct name="direct6" input="carry_follower.cout" output="frac_logic.cout"/>
<direct name="direct7" input="frac_lut4.lut3_out[1]" output="frac_logic.out[1]"/>
<!-- Xifan Tang: I use out[0] because the output of lut6 in lut6 mode is wired to the out[0] -->
<mux name="mux1" input="frac_lut4.lut4_out frac_lut4.lut3_out[0]" output="frac_logic.out[0]"/>
<mux name="mux2" input="frac_logic.cin frac_logic.in[2:2]" output="frac_lut4.in[2:2]"/>
</interconnect>
</pb_type>
<!-- Define flip-flop with scan-chain capability, DI is the scan-chain data input -->
<pb_type name="ff" blif_model=".subckt scff" num_pb="2">
<input name="D" num_pins="1"/>
<input name="DI" num_pins="1"/>
<input name="reset" num_pins="1"/>
<output name="Q" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_setup value="66e-12" port="ff.DI" clock="clk"/>
<T_setup value="66e-12" port="ff.reset" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="fabric.in" output="frac_logic.in"/>
<direct name="direct2" input="fabric.sc_in" output="ff[0].DI"/>
<direct name="direct3" input="ff[0].Q" output="ff[1].DI"/>
<direct name="direct4" input="ff[1].Q" output="fabric.sc_out"/>
<direct name="direct5" input="ff[1].Q" output="fabric.reg_out"/>
<complete name="complete1" input="fabric.clk" output="ff[1:0].clk"/>
<complete name="complete2" input="fabric.reset" output="ff[1:0].reset"/>
<mux name="mux1" input="frac_logic.out[0:0] fabric.reg_in" output="ff[0:0].D">
<delay_constant max="25e-12" in_port="frac_logic.out[0:0]" out_port="ff[0:0].D"/>
<delay_constant max="45e-12" in_port="fabric.reg_in" out_port="ff[0:0].D"/>
</mux>
<mux name="mux2" input="frac_logic.out[1:1] ff[0:0].Q" output="ff[1:1].D">
<delay_constant max="25e-12" in_port="frac_logic.out[1:1]" out_port="ff[1:1].D"/>
<delay_constant max="45e-12" in_port="ff[0:0].Q" out_port="ff[1:1].D"/>
</mux>
<mux name="mux3" input="ff[0].Q frac_logic.out[0]" output="fabric.out[0]">
<!-- LUT to output is faster than FF to output on a Stratix IV -->
<delay_constant max="25e-12" in_port="frac_logic.out[0]" out_port="fabric.out[0]"/>
<delay_constant max="45e-12" in_port="ff[0].Q" out_port="fabric.out[0]"/>
</mux>
<mux name="mux4" input="ff[1].Q frac_logic.out[1]" output="fabric.out[1]">
<!-- LUT to output is faster than FF to output on a Stratix IV -->
<delay_constant max="25e-12" in_port="frac_logic.out[1]" out_port="fabric.out[1]"/>
<delay_constant max="45e-12" in_port="ff[1].Q" out_port="fabric.out[1]"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="fabric.in"/>
<direct name="direct2" input="fle.reg_in" output="fabric.reg_in"/>
<direct name="direct3" input="fle.sc_in" output="fabric.sc_in"/>
<direct name="direct4" input="fle.cin" output="fabric.cin"/>
<direct name="direct5" input="fabric.out" output="fle.out"/>
<direct name="direct6" input="fabric.reg_out" output="fle.reg_out"/>
<direct name="direct7" input="fabric.sc_out" output="fle.sc_out"/>
<direct name="direct8" input="fabric.cout" output="fle.cout"/>
<direct name="direct9" input="fle.clk" output="fabric.clk"/>
<direct name="direct10" input="fle.reset" output="fabric.reset"/>
</interconnect>
</mode>
<!-- Physical mode definition end (physical implementation of the fle) -->
<!-- Dual 3-LUT mode definition begin -->
<mode name="n2_lut3">
<pb_type name="lut3inter" num_pb="1">
<input name="in" num_pins="3"/>
<output name="out" num_pins="2"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ble3" num_pb="2">
<input name="in" num_pins="3"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Define the LUT -->
<pb_type name="lut3" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="3" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
398e-12
-->
<delay_matrix type="max" in_port="lut3.in" out_port="lut3.out">
235e-12
235e-12
235e-12
</delay_matrix>
</pb_type>
<!-- Define the flip-flop -->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble3.in[2:0]" output="lut3[0:0].in[2:0]"/>
<direct name="direct2" input="lut3[0:0].out" output="ff[0:0].D">
<!-- Advanced user option that tells CAD tool to find LUT+FF pairs in netlist -->
<pack_pattern name="ble3" in_port="lut3[0:0].out" out_port="ff[0:0].D"/>
</direct>
<direct name="direct3" input="ble3.clk" output="ff[0:0].clk"/>
<mux name="mux1" input="ff[0:0].Q lut3.out[0:0]" output="ble3.out[0:0]">
<!-- LUT to output is faster than FF to output on a Stratix IV -->
<delay_constant max="25e-12" in_port="lut3.out[0:0]" out_port="ble3.out[0:0]"/>
<delay_constant max="45e-12" in_port="ff[0:0].Q" out_port="ble3.out[0:0]"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="lut3inter.in" output="ble3[0:0].in"/>
<direct name="direct2" input="lut3inter.in" output="ble3[1:1].in"/>
<direct name="direct3" input="ble3[1:0].out" output="lut3inter.out"/>
<complete name="complete1" input="lut3inter.clk" output="ble3[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in[2:0]" output="lut3inter.in"/>
<direct name="direct2" input="lut3inter.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="lut3inter.clk"/>
</interconnect>
</mode>
<!-- Dual 3-LUT mode definition end -->
<!-- 4-LUT mode definition begin -->
<mode name="n1_lut4">
<!-- Define 4-LUT mode -->
<pb_type name="ble4" num_pb="1">
<input name="in" num_pins="4"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Define LUT -->
<pb_type name="lut4" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="4" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
398e-12
397e-12
-->
<delay_matrix type="max" in_port="lut4.in" out_port="lut4.out">
261e-12
261e-12
261e-12
261e-12
</delay_matrix>
</pb_type>
<!-- Define flip-flop -->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble4.in" output="lut4[0:0].in"/>
<direct name="direct2" input="lut4.out" output="ff.D">
<!-- Advanced user option that tells CAD tool to find LUT+FF pairs in netlist -->
<pack_pattern name="ble4" in_port="lut4.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble4.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut4.out" output="ble4.out">
<!-- LUT to output is faster than FF to output on a Stratix IV -->
<delay_constant max="25e-12" in_port="lut4.out" out_port="ble4.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="ble4.out"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="ble4.in"/>
<direct name="direct2" input="ble4.out" output="fle.out[0:0]"/>
<direct name="direct3" input="fle.clk" output="ble4.clk"/>
</interconnect>
</mode>
<!-- 4-LUT mode definition end -->
<!-- Define shift register begin -->
<mode name="shift_register">
<pb_type name="shift_reg" num_pb="1">
<input name="reg_in" num_pins="1"/>
<output name="ff_out" num_pins="2"/>
<output name="reg_out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ff" blif_model=".latch" num_pb="2" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="shift_reg.reg_in" output="ff[0].D"/>
<direct name="direct2" input="ff[0].Q" output="ff[1].D"/>
<direct name="direct3" input="ff[1].Q" output="shift_reg.reg_out"/>
<direct name="direct4" input="ff[0].Q" output="shift_reg.ff_out[0:0]"/>
<direct name="direct5" input="ff[1].Q" output="shift_reg.ff_out[1:1]"/>
<complete name="complete1" input="shift_reg.clk" output="ff.clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.reg_in" output="shift_reg.reg_in"/>
<direct name="direct2" input="shift_reg.reg_out" output="fle.reg_out"/>
<direct name="direct3" input="shift_reg.ff_out" output="fle.out"/>
<direct name="direct4" input="fle.clk" output="shift_reg.clk"/>
</interconnect>
</mode>
<!-- Define shift register end -->
</pb_type>
<interconnect>
<!-- We use direct connections to reduce the area to the most
The global local routing is going to compensate the loss in routability
-->
<!-- FIXME: The implicit port definition results in I0[0] connected to
in[2]. Such twisted connection is not expected.
I[0] should be connected to in[0]
-->
<direct name="direct_fle0" input="clb.I0[0:1]" output="fle[0:0].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle0i" input="clb.I0i[0:1]" output="fle[0:0].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle1" input="clb.I1[0:1]" output="fle[1:1].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle1i" input="clb.I1i[0:1]" output="fle[1:1].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle2" input="clb.I2[0:1]" output="fle[2:2].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle2i" input="clb.I2i[0:1]" output="fle[2:2].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle3" input="clb.I3[0:1]" output="fle[3:3].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle3i" input="clb.I3i[0:1]" output="fle[3:3].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle4" input="clb.I4[0:1]" output="fle[4:4].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle4i" input="clb.I4i[0:1]" output="fle[4:4].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle5" input="clb.I5[0:1]" output="fle[5:5].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle5i" input="clb.I5i[0:1]" output="fle[5:5].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle6" input="clb.I6[0:1]" output="fle[6:6].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle6i" input="clb.I6i[0:1]" output="fle[6:6].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle7" input="clb.I7[0:1]" output="fle[7:7].in[0:1]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<direct name="direct_fle7i" input="clb.I7i[0:1]" output="fle[7:7].in[2:3]">
<!-- TODO: Timing should be backannotated from post-PnR results -->
</direct>
<complete name="clks" input="clb.clk" output="fle[7:0].clk">
</complete>
<complete name="resets" input="clb.reset" output="fle[7:0].reset">
</complete>
<!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins.
By grouping to output pins in this fashion, if a logic block is completely filled by 6-LUTs,
then the outputs those 6-LUTs take get evenly distributed across all four sides of the CLB instead of clumped on two sides (which is what happens with a more
naive specification).
-->
<direct name="clbouts1" input="fle[3:0].out[0:1]" output="clb.O[7:0]"/>
<direct name="clbouts2" input="fle[7:4].out[0:1]" output="clb.O[15:8]"/>
<!-- Shift register chain links -->
<direct name="shift_register_in" input="clb.reg_in" output="fle[0:0].reg_in">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0.16e-9" in_port="clb.reg_in" out_port="fle[0:0].reg_in"/>
<!--pack_pattern name="chain" in_port="clb.reg_in" out_port="fle[0:0].reg_in"/-->
</direct>
<direct name="shift_register_out" input="fle[7:7].reg_out" output="clb.reg_out">
<!--pack_pattern name="chain" in_port="fle[7:7].reg_out" out_port="clb.reg_out"/-->
</direct>
<direct name="shift_register_link" input="fle[6:0].reg_out" output="fle[7:1].reg_in">
<!--pack_pattern name="chain" in_port="fle[6:0].reg_out" out_port="fle[7:1].reg_in"/-->
</direct>
<!-- Scan chain links -->
<direct name="scan_chain_in" input="clb.sc_in" output="fle[0:0].sc_in">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0.16e-9" in_port="clb.sc_in" out_port="fle[0:0].sc_in"/>
</direct>
<direct name="scan_chain_out" input="fle[7:7].sc_out" output="clb.sc_out">
</direct>
<direct name="scan_chain_link" input="fle[6:0].sc_out" output="fle[7:1].sc_in">
</direct>
<!-- Carry chain links -->
<direct name="carry_chain_in" input="clb.cin" output="fle[0:0].cin">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0.16e-9" in_port="clb.cin" out_port="fle[0:0].cin"/>
</direct>
<direct name="carry_chain_out" input="fle[7:7].cout" output="clb.cout">
</direct>
<direct name="carry_chain_link" input="fle[6:0].cout" output="fle[7:1].cin">
</direct>
</interconnect>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<!-- Place this general purpose logic block in any unspecified column -->
</pb_type>
<!-- Define general purpose logic block (CLB) ends -->
</complexblocklist>
</architecture>

2
yosys

@ -1 +1 @@
Subproject commit aec2c41441bffa981092095d25655e80dae6ef06
Subproject commit a0606e09f57df456ba9bcfc6a7cf7b64d814b8e4