Merge pull request #1678 from lnis-uofu/xt_ecb
Support Enhanced Connection Block
This commit is contained in:
commit
9fa3b53aab
|
@ -1,12 +1,12 @@
|
|||
.. _direct_interconnect:
|
||||
|
||||
Inter-Tile Direct Interconnection extensions
|
||||
--------------------------------------------
|
||||
Direct Interconnect
|
||||
-------------------
|
||||
|
||||
This section introduces extensions on the architecture description file about existing interconnection description.
|
||||
This section introduces extensions on the architecture description file about direct connections between programmable blocks.
|
||||
|
||||
Directlist
|
||||
~~~~~~~~~~
|
||||
Syntax
|
||||
~~~~~~
|
||||
|
||||
The original direct connections in the directlist section are documented here_. Its description is given below:
|
||||
|
||||
|
@ -20,20 +20,26 @@ The original direct connections in the directlist section are documented here_.
|
|||
|
||||
.. note:: These options are required
|
||||
|
||||
Our extension include three more options:
|
||||
In the OpenFPGA architecture file, you may define additional attributes for each VPR's direct connection:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<directlist>
|
||||
<direct name="string" from_pin="string" to_pin="string" x_offset="int" y_offset="int" z_offset="int" switch_name="string" interconnection_type="string" x_dir="string" y_dir="string"/>
|
||||
<direct_connection>
|
||||
<direct name="string" circuit_model_name="string" interconnection_type="string" x_dir="string" y_dir="string"/>
|
||||
</directlist>
|
||||
|
||||
.. note:: these options are optional. However, if `interconnection_type` is set `x_dir` and `y_dir` are required.
|
||||
.. note:: these options are optional. However, if ``interconnection_type`` is set to ``inter_column`` or ``inter_row``, then ``x_dir`` and ``y_dir`` are required.
|
||||
|
||||
.. option:: interconnection_type="<string>"
|
||||
|
||||
the type of interconnection should be a string.
|
||||
Available types are ``NONE`` | ``column`` | ``row``, specifies if it applies on a column or a row ot if it doesn't apply.
|
||||
Available types are ``inner_column_or_row`` | ``part_of_cb`` | ``inter_column`` | ``inter_row``
|
||||
|
||||
- ``inner_column_or_row`` indicates the direct connections are between tiles in the same column or row. This is the default value.
|
||||
- ``part_of_cb`` indicates the direct connections will drive routing multiplexers in connection blocks. Therefore, it is no longer a strict point-to-point direct connection.
|
||||
- ``inter_column`` indicates the direct connections are between tiles in two columns
|
||||
- ``inter_row`` indicates the direct connections are between tiles in two rows
|
||||
|
||||
.. note:: The following syntax is only applicable to ``inter_column`` and ``inter_row``
|
||||
|
||||
.. option:: x_dir="<string>"
|
||||
|
||||
|
@ -42,15 +48,15 @@ Our extension include three more options:
|
|||
|
||||
- x_dir="positive":
|
||||
|
||||
- interconnection_type="column": a column will be connected to a column on the ``right``, if it exists.
|
||||
- interconnection_type="inter_column": a column will be connected to a column on the ``right``, if it exists.
|
||||
|
||||
- interconnection_type="row": the most on the ``right`` cell from a row connection will connect the most on the ``left`` cell of next row, if it exists.
|
||||
- interconnection_type="inter_row": the most on the ``right`` cell from a row connection will connect the most on the ``left`` cell of next row, if it exists.
|
||||
|
||||
- x_dir="negative":
|
||||
|
||||
- interconnection_type="column": a column will be connected to a column on the ``left``, if it exists.
|
||||
- interconnection_type="inter_column": a column will be connected to a column on the ``left``, if it exists.
|
||||
|
||||
- interconnection_type="row": the most on the ``left`` cell from a row connection will connect the most on the ``right`` cell of next row, if it exists.
|
||||
- interconnection_type="inter_row": the most on the ``left`` cell from a row connection will connect the most on the ``right`` cell of next row, if it exists.
|
||||
|
||||
.. option:: y_dir="<string>"
|
||||
|
||||
|
@ -59,27 +65,96 @@ Our extension include three more options:
|
|||
|
||||
- y_dir="positive":
|
||||
|
||||
- interconnection_type="column": the ``bottom`` cell of a column will be connected to the next column ``top`` cell, if it exists.
|
||||
- interconnection_type="inter_column": the ``bottom`` cell of a column will be connected to the next column ``top`` cell, if it exists.
|
||||
|
||||
- interconnection_type="row": a row will be connected on an ``above`` row, if it exists.
|
||||
- interconnection_type="inter_row": a row will be connected on an ``above`` row, if it exists.
|
||||
|
||||
- y_dir="negative":
|
||||
|
||||
- interconnection_type="column": the ``top`` cell of a column will be connected to the next column ``bottom`` cell, if it exists.
|
||||
- interconnection_type="inter_column": the ``top`` cell of a column will be connected to the next column ``bottom`` cell, if it exists.
|
||||
|
||||
- interconnection_type="row": a row will be connected on a row ``below``, if it exists.
|
||||
- interconnection_type="inter_row": a row will be connected on a row ``below``, if it exists.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
Enhanced Connection Block
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For this example, we will study a scan-chain implementation. The description could be:
|
||||
The direct connection can also drive routing multiplexers of connection blocks. When such connection occures in a connection block, it is called enhanced connection block.
|
||||
:numref:`fig_ecb` illustrates the difference between a regular connection block and an enhanced connection block.
|
||||
|
||||
.. _fig_ecb:
|
||||
|
||||
.. figure:: ./figures/ecb.png
|
||||
|
||||
Enhanced connection block vs. Regular connection block
|
||||
|
||||
In such scenario, the type ``part_of_cb`` is required.
|
||||
|
||||
.. warning:: Restrictions may be applied when building the direct connections as part of a connection block.
|
||||
|
||||
Direct connections can be inside a tile or across two tiles. Currently, across more than two tiles are not supported!
|
||||
:numref:`fig_ecb_allowed_direct_connection`` illustrates the region (in red) where any input pin is allowed to be driven by any output pin.
|
||||
|
||||
.. _fig_ecb_allowed_direct_connection:
|
||||
|
||||
.. figure:: ./figures/ecb_allowed_direct_connection.png
|
||||
|
||||
Allowed connections inside a tile for enhanced connection block (see the highlighted region)
|
||||
|
||||
:numref:`fig_ecb_allowed_direct_connection_inner_tile_example`` shows a few feedback connections which can be built inside connection blocks. Note that feedback connections are fully allowed between any pins on the same side of a programmable block.
|
||||
|
||||
.. _fig_ecb_allowed_direct_connection_inner_tile_example:
|
||||
|
||||
.. figure:: ./figures/ecb_allowed_direct_connection_inner_tile_example.png
|
||||
|
||||
Example of feedback connections inside a tile for enhanced connection block
|
||||
|
||||
For instance, VPR architecture defines feedback connections like:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<directlist>
|
||||
<direct name="scff_chain" from_pin="clb.sc_out" to_pin="clb.sc_in" x_offset="0" y_offset="-1" z_offset="0" interconnection_type="column" x_dir="positive" y_dir="positive"/>
|
||||
<!-- Add 2 inputs to the routing multiplexers inside a connection block which drives pin 'clb.I_top[0]' -->
|
||||
<direct name="feedback" from_pin="clb.O_top[0:0]" to_pin="clb.I_top[0:0]" x_offset="0" y_offset="0" z_offset="0"/>
|
||||
<direct name="feedback" from_pin="clb.O_top[1:1]" to_pin="clb.I_top[0:0]" x_offset="0" y_offset="0" z_offset="0"/>
|
||||
</directlist>
|
||||
|
||||
:numref:`fig_ecb_allowed_direct_connection_inter_tile_example`` shows a few inter-tile connections which can be built inside connection blocks. Note that inter-tile connections are subjected to the restrictions depicted in :numref:`fig_ecb_allowed_direct_connection``
|
||||
|
||||
.. _fig_ecb_allowed_direct_connection_inter_tile_example:
|
||||
|
||||
.. figure:: ./figures/ecb_allowed_direct_connection_inter_tile_example.png
|
||||
|
||||
Example of connections across two tiles for enhanced connection block
|
||||
|
||||
:numref:`fig_ecb_forbid_direct_connection_example`` illustrates some inner-tile and inter-tile connections which are not allowed. Note that feedback connections across different sides are restricted!
|
||||
|
||||
.. _fig_ecb_forbid_direct_connection_example:
|
||||
|
||||
.. figure:: ./figures/ecb_forbid_direct_connection_example.png
|
||||
|
||||
Restrictions on building direct connections as part of a connection block
|
||||
|
||||
Inter-tile Connections
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For this example, we will study a scan-chain implementation. The description could be:
|
||||
|
||||
In VPR architecture:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<directlist>
|
||||
<direct name="scff_chain" from_pin="clb.sc_out" to_pin="clb.sc_in" x_offset="0" y_offset="-1" z_offset="0"/>
|
||||
</directlist>
|
||||
|
||||
In OpenFPGA architecture:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<direct_connection>
|
||||
<direct name="scff_chain" interconnection_type="column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
|
||||
:numref:`fig_p2p_exple` is the graphical representation of the above scan-chain description on a 4x4 FPGA.
|
||||
|
||||
.. _fig_p2p_exple:
|
||||
|
@ -91,9 +166,6 @@ For this example, we will study a scan-chain implementation. The description cou
|
|||
|
||||
In this figure, the red arrows represent the initial direct connection. The green arrows represent the point to point connection to connect all the columns of CLB.
|
||||
|
||||
Truth table
|
||||
~~~~~~~~~~~
|
||||
|
||||
A point to point connection can be applied in different ways than showed in the example section. To help the designer implement his point to point connection, a truth table with our new parameters id provided below.
|
||||
|
||||
:numref:`fig_p2p_trtable` provides all possible variable combination and the connection it will generate.
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 494 KiB |
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
|
@ -71,7 +71,7 @@ ArchDirectId ArchDirect::add_direct(const std::string& name) {
|
|||
direct_ids_.push_back(direct);
|
||||
names_.push_back(name);
|
||||
circuit_models_.push_back(CircuitModelId::INVALID());
|
||||
types_.emplace_back(NUM_DIRECT_TYPES);
|
||||
types_.emplace_back(e_direct_type::NUM_DIRECT_TYPES);
|
||||
directions_.emplace_back(vtr::Point<e_direct_direction>(
|
||||
NUM_DIRECT_DIRECTIONS, NUM_DIRECT_DIRECTIONS));
|
||||
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
* These types are supplementary to the original VPR direct connections
|
||||
* Here we extend to the cross-row and cross-column connections
|
||||
********************************************************************/
|
||||
enum e_direct_type {
|
||||
INNER_COLUMN,
|
||||
INNER_ROW,
|
||||
enum class e_direct_type {
|
||||
INNER_COLUMN_OR_ROW,
|
||||
PART_OF_CB,
|
||||
INTER_COLUMN,
|
||||
INTER_ROW,
|
||||
NUM_DIRECT_TYPES
|
||||
};
|
||||
constexpr std::array<const char*, NUM_DIRECT_TYPES> DIRECT_TYPE_STRING = {
|
||||
{"inner_column", "inner_row", "inter_column", "inter_row"}};
|
||||
constexpr std::array<const char*, (size_t)e_direct_type::NUM_DIRECT_TYPES>
|
||||
DIRECT_TYPE_STRING = {
|
||||
{"inner_column_or_row", "part_of_cb", "inter_column", "inter_row"}};
|
||||
|
||||
enum e_direct_direction { POSITIVE_DIR, NEGATIVE_DIR, NUM_DIRECT_DIRECTIONS };
|
||||
constexpr std::array<const char*, NUM_DIRECT_DIRECTIONS>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
/* Headers from vtr util library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from libarchfpga */
|
||||
#include "arch_error.h"
|
||||
|
@ -198,15 +199,20 @@ std::map<std::string, CircuitModelId> read_xml_routing_segment_circuit(
|
|||
* Convert string to the enumerate of direct type
|
||||
*******************************************************************/
|
||||
static e_direct_type string_to_direct_type(const std::string& type_string) {
|
||||
if (std::string("column") == type_string) {
|
||||
return INTER_COLUMN;
|
||||
if (std::string("part_of_cb") == type_string) {
|
||||
return e_direct_type::PART_OF_CB;
|
||||
}
|
||||
if (std::string("inner_column_or_row") == type_string) {
|
||||
return e_direct_type::INNER_COLUMN_OR_ROW;
|
||||
}
|
||||
if (std::string("inter_column") == type_string) {
|
||||
return e_direct_type::INTER_COLUMN;
|
||||
}
|
||||
if (std::string("inter_row") == type_string) {
|
||||
return e_direct_type::INTER_ROW;
|
||||
}
|
||||
|
||||
if (std::string("row") == type_string) {
|
||||
return INTER_ROW;
|
||||
}
|
||||
|
||||
return NUM_DIRECT_TYPES;
|
||||
return e_direct_type::NUM_DIRECT_TYPES;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -255,13 +261,6 @@ ArchDirect read_xml_direct_circuit(pugi::xml_node& Node,
|
|||
std::string direct_name =
|
||||
get_attribute(xml_direct, "name", loc_data).as_string();
|
||||
|
||||
/* Get the routing segment circuit model name */
|
||||
std::string direct_model_name =
|
||||
get_attribute(xml_direct, "circuit_model_name", loc_data).as_string();
|
||||
|
||||
CircuitModelId direct_model = find_routing_circuit_model(
|
||||
xml_direct, loc_data, circuit_lib, direct_model_name, CIRCUIT_MODEL_WIRE);
|
||||
|
||||
/* Add to the Arch direct database */
|
||||
ArchDirectId direct = arch_direct.add_direct(direct_name);
|
||||
if (false == arch_direct.valid_direct_id(direct)) {
|
||||
|
@ -269,28 +268,48 @@ ArchDirect read_xml_direct_circuit(pugi::xml_node& Node,
|
|||
"Direct name '%s' has been defined more than once!\n",
|
||||
direct_name.c_str());
|
||||
}
|
||||
arch_direct.set_circuit_model(direct, direct_model);
|
||||
|
||||
/* Add more information*/
|
||||
std::string direct_type_name =
|
||||
get_attribute(xml_direct, "type", loc_data, pugiutil::ReqOpt::OPTIONAL)
|
||||
.as_string("none");
|
||||
/* If not defined, we go to the next */
|
||||
if (std::string("none") == direct_type_name) {
|
||||
continue;
|
||||
}
|
||||
.as_string(
|
||||
DIRECT_TYPE_STRING[size_t(e_direct_type::INNER_COLUMN_OR_ROW)]);
|
||||
|
||||
e_direct_type direct_type = string_to_direct_type(direct_type_name);
|
||||
|
||||
if (NUM_DIRECT_TYPES == direct_type) {
|
||||
if (e_direct_type::NUM_DIRECT_TYPES == direct_type) {
|
||||
archfpga_throw(
|
||||
loc_data.filename_c_str(), loc_data.line(xml_direct),
|
||||
"Direct type '%s' is not support! Acceptable values are [column|row]\n",
|
||||
"Direct type '%s' is not support! Acceptable values are "
|
||||
"[inner_column_or_row|part_of_cb|inter_column|inter_row]\n",
|
||||
direct_type_name.c_str());
|
||||
}
|
||||
|
||||
arch_direct.set_type(direct, direct_type);
|
||||
|
||||
/* Get the routing segment circuit model name */
|
||||
std::string direct_model_name =
|
||||
get_attribute(xml_direct, "circuit_model_name", loc_data).as_string();
|
||||
|
||||
/* If a direct connection is part of a connection block, the circuit model
|
||||
* should be a MUX */
|
||||
e_circuit_model_type expected_circuit_model_type = CIRCUIT_MODEL_WIRE;
|
||||
if (arch_direct.type(direct) == e_direct_type::PART_OF_CB) {
|
||||
VTR_LOG("Direct '%s' will modelled as part of a connection block.\n",
|
||||
direct_name.c_str());
|
||||
expected_circuit_model_type = CIRCUIT_MODEL_MUX;
|
||||
}
|
||||
CircuitModelId direct_model = find_routing_circuit_model(
|
||||
xml_direct, loc_data, circuit_lib, direct_model_name,
|
||||
expected_circuit_model_type);
|
||||
arch_direct.set_circuit_model(direct, direct_model);
|
||||
|
||||
/* The following syntax is only available for inter-column/row */
|
||||
if (arch_direct.type(direct) != e_direct_type::INTER_COLUMN &&
|
||||
arch_direct.type(direct) != e_direct_type::INTER_ROW) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string x_dir_name =
|
||||
get_attribute(xml_direct, "x_dir", loc_data).as_string();
|
||||
std::string y_dir_name =
|
||||
|
|
|
@ -57,7 +57,7 @@ static void write_xml_direct_component_circuit(
|
|||
fp, "circuit_model_name",
|
||||
circuit_lib.model_name(arch_direct.circuit_model(direct_id)).c_str());
|
||||
write_xml_attribute(fp, "type",
|
||||
DIRECT_TYPE_STRING[arch_direct.type(direct_id)]);
|
||||
DIRECT_TYPE_STRING[size_t(arch_direct.type(direct_id))]);
|
||||
write_xml_attribute(fp, "x_dir",
|
||||
DIRECT_DIRECTION_STRING[arch_direct.x_dir(direct_id)]);
|
||||
write_xml_attribute(fp, "y_dir",
|
||||
|
|
|
@ -398,6 +398,9 @@ static RRGSB build_rr_gsb(const DeviceContext& vpr_device_ctx,
|
|||
temp_ipin_rr_nodes.clear();
|
||||
}
|
||||
|
||||
/* Build OPIN node lists for connection blocks */
|
||||
rr_gsb.build_cb_opin_nodes(vpr_device_ctx.rr_graph);
|
||||
|
||||
return rr_gsb;
|
||||
}
|
||||
|
||||
|
@ -701,14 +704,26 @@ static void annotate_direct_circuit_models(
|
|||
}
|
||||
|
||||
/* Check the circuit model type */
|
||||
if (CIRCUIT_MODEL_WIRE !=
|
||||
openfpga_arch.circuit_lib.model_type(circuit_model)) {
|
||||
if (openfpga_arch.arch_direct.type(direct_id) !=
|
||||
e_direct_type::PART_OF_CB &&
|
||||
CIRCUIT_MODEL_WIRE !=
|
||||
openfpga_arch.circuit_lib.model_type(circuit_model)) {
|
||||
VTR_LOG_ERROR(
|
||||
"Require circuit model type '%s' for a direct connection '%s'!\nPlease "
|
||||
"check your OpenFPGA architecture XML!\n",
|
||||
CIRCUIT_MODEL_TYPE_STRING[CIRCUIT_MODEL_WIRE], direct_name.c_str());
|
||||
exit(1);
|
||||
}
|
||||
if (openfpga_arch.arch_direct.type(direct_id) ==
|
||||
e_direct_type::PART_OF_CB &&
|
||||
CIRCUIT_MODEL_MUX !=
|
||||
openfpga_arch.circuit_lib.model_type(circuit_model)) {
|
||||
VTR_LOG_ERROR(
|
||||
"Require circuit model type '%s' for a direct connection '%s'!\nPlease "
|
||||
"check your OpenFPGA architecture XML!\n",
|
||||
CIRCUIT_MODEL_TYPE_STRING[CIRCUIT_MODEL_MUX], direct_name.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Now update the device annotation */
|
||||
vpr_device_annotation.add_direct_annotation(idirect, direct_id);
|
||||
|
|
|
@ -320,19 +320,58 @@ ModulePortId find_connection_block_module_ipin_port(
|
|||
return ipin_port_id;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate a port for a connection block
|
||||
********************************************************************/
|
||||
ModulePortId find_connection_block_module_opin_port(
|
||||
const ModuleManager& module_manager, const ModuleId& cb_module,
|
||||
const DeviceGrid& grids, const VprDeviceAnnotation& vpr_device_annotation,
|
||||
const RRGraphView& rr_graph, const RRGSB& rr_gsb,
|
||||
const RRNodeId& src_rr_node) {
|
||||
/* Ensure the src_rr_node is an input pin of a CLB */
|
||||
VTR_ASSERT(OPIN == rr_graph.node_type(src_rr_node));
|
||||
/* Search all the sides of a SB, see this drive_rr_node is an INPUT of this SB
|
||||
*/
|
||||
enum e_side cb_opin_side = NUM_SIDES;
|
||||
int cb_opin_index = -1;
|
||||
rr_gsb.get_node_side_and_index(rr_graph, src_rr_node, IN_PORT, cb_opin_side,
|
||||
cb_opin_index);
|
||||
/* We need to be sure that drive_rr_node is part of the CB */
|
||||
VTR_ASSERT((-1 != cb_opin_index) && (NUM_SIDES != cb_opin_side));
|
||||
std::string port_name = generate_cb_module_grid_port_name(
|
||||
cb_opin_side, grids, vpr_device_annotation, rr_graph,
|
||||
rr_gsb.get_opin_node(cb_opin_side, cb_opin_index));
|
||||
|
||||
/* Must find a valid port id in the Switch Block module */
|
||||
ModulePortId opin_port_id =
|
||||
module_manager.find_module_port(cb_module, port_name);
|
||||
VTR_ASSERT(true ==
|
||||
module_manager.valid_module_port_id(cb_module, opin_port_id));
|
||||
return opin_port_id;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate a list of routing track middle output ports
|
||||
* for routing multiplexer inside the connection block
|
||||
********************************************************************/
|
||||
std::vector<ModulePinInfo> find_connection_block_module_input_ports(
|
||||
const ModuleManager& module_manager, const ModuleId& cb_module,
|
||||
const DeviceGrid& grids, const VprDeviceAnnotation& vpr_device_annotation,
|
||||
const RRGraphView& rr_graph, const RRGSB& rr_gsb, const t_rr_type& cb_type,
|
||||
const std::vector<RRNodeId>& input_rr_nodes) {
|
||||
std::vector<ModulePinInfo> input_ports;
|
||||
|
||||
for (auto input_rr_node : input_rr_nodes) {
|
||||
input_ports.push_back(find_connection_block_module_chan_port(
|
||||
module_manager, cb_module, rr_graph, rr_gsb, cb_type, input_rr_node));
|
||||
if (OPIN == rr_graph.node_type(input_rr_node)) {
|
||||
input_ports.push_back(ModulePinInfo(
|
||||
find_connection_block_module_opin_port(module_manager, cb_module, grids,
|
||||
vpr_device_annotation, rr_graph,
|
||||
rr_gsb, input_rr_node),
|
||||
0));
|
||||
} else {
|
||||
input_ports.push_back(find_connection_block_module_chan_port(
|
||||
module_manager, cb_module, rr_graph, rr_gsb, cb_type, input_rr_node));
|
||||
}
|
||||
}
|
||||
|
||||
return input_ports;
|
||||
|
|
|
@ -62,8 +62,15 @@ ModulePortId find_connection_block_module_ipin_port(
|
|||
const RRGraphView& rr_graph, const RRGSB& rr_gsb,
|
||||
const RRNodeId& src_rr_node);
|
||||
|
||||
ModulePortId find_connection_block_module_opin_port(
|
||||
const ModuleManager& module_manager, const ModuleId& cb_module,
|
||||
const DeviceGrid& grids, const VprDeviceAnnotation& vpr_device_annotation,
|
||||
const RRGraphView& rr_graph, const RRGSB& rr_gsb,
|
||||
const RRNodeId& src_rr_node);
|
||||
|
||||
std::vector<ModulePinInfo> find_connection_block_module_input_ports(
|
||||
const ModuleManager& module_manager, const ModuleId& cb_module,
|
||||
const DeviceGrid& grids, const VprDeviceAnnotation& vpr_device_annotation,
|
||||
const RRGraphView& rr_graph, const RRGSB& rr_gsb, const t_rr_type& cb_type,
|
||||
const std::vector<RRNodeId>& input_rr_nodes);
|
||||
|
||||
|
|
|
@ -691,8 +691,9 @@ static void build_connection_block_mux_module(
|
|||
/* TODO: Generate input ports that are wired to the input bus of the routing
|
||||
* multiplexer */
|
||||
std::vector<ModulePinInfo> cb_input_port_ids =
|
||||
find_connection_block_module_input_ports(
|
||||
module_manager, cb_module, rr_graph, rr_gsb, cb_type, driver_rr_nodes);
|
||||
find_connection_block_module_input_ports(module_manager, cb_module, grids,
|
||||
device_annotation, rr_graph,
|
||||
rr_gsb, cb_type, driver_rr_nodes);
|
||||
|
||||
/* Link input bus port to Switch Block inputs */
|
||||
std::vector<CircuitPortId> mux_model_input_ports =
|
||||
|
@ -978,9 +979,7 @@ static void build_connection_block_module(
|
|||
enum e_side cb_ipin_side = cb_ipin_sides[iside];
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side);
|
||||
++inode) {
|
||||
const RRNodeId& ipin_node = rr_gsb.get_ipin_node(cb_ipin_side, inode);
|
||||
vtr::Point<size_t> port_coord(rr_graph.node_xlow(ipin_node),
|
||||
rr_graph.node_ylow(ipin_node));
|
||||
RRNodeId ipin_node = rr_gsb.get_ipin_node(cb_ipin_side, inode);
|
||||
std::string port_name = generate_cb_module_grid_port_name(
|
||||
cb_ipin_side, grids, device_annotation, rr_graph, ipin_node);
|
||||
BasicPort module_port(port_name,
|
||||
|
@ -993,6 +992,29 @@ static void build_connection_block_module(
|
|||
}
|
||||
}
|
||||
|
||||
/* Add the output pins of grids which are input ports of the connection block,
|
||||
* if there is any */
|
||||
std::vector<ModulePortId> opin_module_port_ids;
|
||||
std::vector<enum e_side> cb_opin_sides = rr_gsb.get_cb_opin_sides(cb_type);
|
||||
for (size_t iside = 0; iside < cb_opin_sides.size(); ++iside) {
|
||||
enum e_side cb_opin_side = cb_opin_sides[iside];
|
||||
for (size_t inode = 0;
|
||||
inode < rr_gsb.get_num_cb_opin_nodes(cb_type, cb_opin_side); ++inode) {
|
||||
RRNodeId opin_node =
|
||||
rr_gsb.get_cb_opin_node(cb_type, cb_opin_side, inode);
|
||||
std::string port_name = generate_cb_module_grid_port_name(
|
||||
cb_opin_side, grids, device_annotation, rr_graph, opin_node);
|
||||
BasicPort module_port(port_name,
|
||||
1); /* Every grid output has a port size of 1 */
|
||||
/* Grid outputs are inputs of switch blocks */
|
||||
ModulePortId module_port_id = module_manager.add_port(
|
||||
cb_module, module_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
/* Add side to the port */
|
||||
module_manager.set_port_side(cb_module, module_port_id, cb_opin_side);
|
||||
opin_module_port_ids.push_back(module_port_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a cache (fast look up) for module nets whose source are input ports
|
||||
*/
|
||||
std::map<ModulePinInfo, ModuleNetId> input_port_to_module_nets;
|
||||
|
@ -1034,6 +1056,13 @@ static void build_connection_block_module(
|
|||
chan_lower_input_port_id, chan_lower_input_port.pins()[pin_id])] = net;
|
||||
}
|
||||
|
||||
for (ModulePortId opin_module_port_id : opin_module_port_ids) {
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, cb_module, cb_module, 0, opin_module_port_id, 0);
|
||||
/* Cache the module net */
|
||||
input_port_to_module_nets[ModulePinInfo(opin_module_port_id, 0)] = net;
|
||||
}
|
||||
|
||||
/* Add sub modules of routing multiplexers or direct interconnect*/
|
||||
for (size_t iside = 0; iside < cb_ipin_sides.size(); ++iside) {
|
||||
enum e_side cb_ipin_side = cb_ipin_sides[iside];
|
||||
|
|
|
@ -471,6 +471,158 @@ static int build_tile_module_port_and_nets_between_cb_and_pb(
|
|||
}
|
||||
}
|
||||
}
|
||||
/* Iterate over the output pins of the Connection Block */
|
||||
std::vector<enum e_side> cb_opin_sides = module_cb.get_cb_opin_sides(cb_type);
|
||||
for (size_t iside = 0; iside < cb_opin_sides.size(); ++iside) {
|
||||
enum e_side cb_opin_side = cb_opin_sides[iside];
|
||||
for (size_t inode = 0;
|
||||
inode < module_cb.get_num_cb_opin_nodes(cb_type, cb_opin_side);
|
||||
++inode) {
|
||||
/* Collect source-related information */
|
||||
RRNodeId module_opin_node =
|
||||
module_cb.get_cb_opin_node(cb_type, cb_opin_side, inode);
|
||||
vtr::Point<size_t> cb_src_port_coord(
|
||||
rr_graph.node_xlow(module_opin_node),
|
||||
rr_graph.node_ylow(module_opin_node));
|
||||
std::string src_cb_port_name = generate_cb_module_grid_port_name(
|
||||
cb_opin_side, grids, vpr_device_annotation, rr_graph, module_opin_node);
|
||||
ModulePortId src_cb_port_id =
|
||||
module_manager.find_module_port(src_cb_module, src_cb_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(src_cb_module,
|
||||
src_cb_port_id));
|
||||
BasicPort src_cb_port =
|
||||
module_manager.module_port(src_cb_module, src_cb_port_id);
|
||||
|
||||
/* Collect sink-related information */
|
||||
/* Note that we use the instance cb pin here!!!
|
||||
* because it has the correct coordinator for the grid!!!
|
||||
*/
|
||||
RRNodeId instance_opin_node =
|
||||
rr_gsb.get_cb_opin_node(cb_type, cb_opin_side, inode);
|
||||
vtr::Point<size_t> grid_coordinate(
|
||||
rr_graph.node_xlow(instance_opin_node),
|
||||
rr_graph.node_ylow(instance_opin_node));
|
||||
std::string sink_grid_module_name =
|
||||
generate_grid_block_module_name_in_top_module(
|
||||
std::string(GRID_MODULE_NAME_PREFIX), grids, grid_coordinate);
|
||||
ModuleId sink_grid_module =
|
||||
module_manager.find_module(sink_grid_module_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(sink_grid_module));
|
||||
size_t sink_grid_pin_index = rr_graph.node_pin_num(instance_opin_node);
|
||||
|
||||
t_physical_tile_type_ptr grid_type_descriptor = grids.get_physical_type(
|
||||
t_physical_tile_loc(grid_coordinate.x(), grid_coordinate.y(), layer));
|
||||
size_t sink_grid_pin_width =
|
||||
grid_type_descriptor->pin_width_offset[sink_grid_pin_index];
|
||||
size_t sink_grid_pin_height =
|
||||
grid_type_descriptor->pin_height_offset[sink_grid_pin_index];
|
||||
BasicPort sink_grid_pin_info =
|
||||
vpr_device_annotation.physical_tile_pin_port_info(grid_type_descriptor,
|
||||
sink_grid_pin_index);
|
||||
VTR_ASSERT(true == sink_grid_pin_info.is_valid());
|
||||
int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(
|
||||
grid_type_descriptor, sink_grid_pin_index);
|
||||
VTR_ASSERT(OPEN != subtile_index &&
|
||||
subtile_index < grid_type_descriptor->capacity);
|
||||
std::string sink_grid_port_name = generate_grid_port_name(
|
||||
sink_grid_pin_width, sink_grid_pin_height, subtile_index,
|
||||
get_rr_graph_single_node_side(
|
||||
rr_graph, rr_gsb.get_cb_opin_node(cb_type, cb_opin_side, inode)),
|
||||
sink_grid_pin_info);
|
||||
ModulePortId sink_grid_port_id =
|
||||
module_manager.find_module_port(sink_grid_module, sink_grid_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||
sink_grid_module, sink_grid_port_id));
|
||||
BasicPort sink_grid_port =
|
||||
module_manager.module_port(sink_grid_module, sink_grid_port_id);
|
||||
|
||||
/* Check if the grid is inside the tile, if not, create ports */
|
||||
if (fabric_tile.pb_in_tile(fabric_tile_id, grid_coordinate)) {
|
||||
if (!frame_view) {
|
||||
size_t sink_grid_instance =
|
||||
pb_instances[fabric_tile.find_pb_index_in_tile(fabric_tile_id,
|
||||
grid_coordinate)];
|
||||
|
||||
/* Source and sink port should match in size */
|
||||
VTR_ASSERT(src_cb_port.get_width() == sink_grid_port.get_width());
|
||||
|
||||
/* Create a net for each pin. Note that the sink and source tags are
|
||||
* reverted in the following code!!! */
|
||||
for (size_t pin_id = 0; pin_id < src_cb_port.pins().size();
|
||||
++pin_id) {
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, tile_module, sink_grid_module, sink_grid_instance,
|
||||
sink_grid_port_id, sink_grid_port.pins()[pin_id]);
|
||||
/* Configure the net sink */
|
||||
module_manager.add_module_net_sink(tile_module, net, src_cb_module,
|
||||
src_cb_instance, src_cb_port_id,
|
||||
src_cb_port.pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Special: No need to create a new port! Since we only support OPINs
|
||||
* from Switch blocks. Walk through all the switch blocks and find the
|
||||
* new port that it is created when connecting pb and sb */
|
||||
if (!frame_view) {
|
||||
/* This is the source sb that is added to the top module */
|
||||
const RRGSB& module_sb = device_rr_gsb.get_gsb(module_gsb_coordinate);
|
||||
vtr::Point<size_t> module_sb_coordinate(module_sb.get_sb_x(),
|
||||
module_sb.get_sb_y());
|
||||
|
||||
/* Collect sink-related information */
|
||||
std::string sink_sb_module_name =
|
||||
generate_switch_block_module_name(module_sb_coordinate);
|
||||
ModuleId sink_sb_module =
|
||||
module_manager.find_module(sink_sb_module_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(sink_sb_module));
|
||||
size_t isb = fabric_tile.find_sb_index_in_tile(fabric_tile_id,
|
||||
module_sb_coordinate);
|
||||
std::string temp_sb_module_name = generate_switch_block_module_name(
|
||||
fabric_tile.sb_coordinates(fabric_tile_id)[isb]);
|
||||
if (name_module_using_index) {
|
||||
temp_sb_module_name =
|
||||
generate_switch_block_module_name_using_index(isb);
|
||||
}
|
||||
/* FIXME: may find a way to determine the side. Currently using
|
||||
* cb_opin_side is fine */
|
||||
vtr::Point<size_t> sink_sb_port_coord(
|
||||
rr_graph.node_xlow(module_sb.get_opin_node(cb_opin_side, inode)),
|
||||
rr_graph.node_ylow(module_sb.get_opin_node(cb_opin_side, inode)));
|
||||
std::string sink_sb_port_name = generate_sb_module_grid_port_name(
|
||||
cb_opin_side,
|
||||
get_rr_graph_single_node_side(
|
||||
rr_graph, module_sb.get_opin_node(cb_opin_side, inode)),
|
||||
grids, vpr_device_annotation, rr_graph,
|
||||
module_sb.get_opin_node(cb_opin_side, inode));
|
||||
ModulePortId sink_sb_port_id =
|
||||
module_manager.find_module_port(sink_sb_module, sink_sb_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||
sink_sb_module, sink_sb_port_id));
|
||||
BasicPort sink_sb_port =
|
||||
module_manager.module_port(sink_sb_module, sink_sb_port_id);
|
||||
|
||||
sink_sb_port.set_name(generate_tile_module_port_name(
|
||||
temp_sb_module_name, sink_sb_port.get_name()));
|
||||
ModulePortId src_tile_port_id = module_manager.find_module_port(
|
||||
tile_module, sink_sb_port.get_name());
|
||||
|
||||
/* Create a net for each pin */
|
||||
VTR_ASSERT(src_cb_port.pins().size() == sink_sb_port.pins().size());
|
||||
for (size_t pin_id = 0; pin_id < src_cb_port.pins().size();
|
||||
++pin_id) {
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, tile_module, tile_module, 0, src_tile_port_id,
|
||||
sink_sb_port.pins()[pin_id]);
|
||||
/* Configure the net sink */
|
||||
module_manager.add_module_net_sink(tile_module, net, src_cb_module,
|
||||
src_cb_instance, src_cb_port_id,
|
||||
src_cb_port.pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -563,6 +563,90 @@ static void add_top_module_nets_connect_grids_and_cb(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate over the input pins of the Connection Block */
|
||||
std::vector<enum e_side> cb_opin_sides = module_cb.get_cb_opin_sides(cb_type);
|
||||
for (size_t iside = 0; iside < cb_opin_sides.size(); ++iside) {
|
||||
enum e_side cb_opin_side = cb_opin_sides[iside];
|
||||
for (size_t inode = 0;
|
||||
inode < module_cb.get_num_cb_opin_nodes(cb_type, cb_opin_side);
|
||||
++inode) {
|
||||
/* Collect source-related information */
|
||||
RRNodeId module_opin_node =
|
||||
module_cb.get_cb_opin_node(cb_type, cb_opin_side, inode);
|
||||
vtr::Point<size_t> cb_src_port_coord(
|
||||
rr_graph.node_xlow(module_opin_node),
|
||||
rr_graph.node_ylow(module_opin_node));
|
||||
std::string src_cb_port_name = generate_cb_module_grid_port_name(
|
||||
cb_opin_side, grids, vpr_device_annotation, rr_graph, module_opin_node);
|
||||
ModulePortId src_cb_port_id =
|
||||
module_manager.find_module_port(src_cb_module, src_cb_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(src_cb_module,
|
||||
src_cb_port_id));
|
||||
BasicPort src_cb_port =
|
||||
module_manager.module_port(src_cb_module, src_cb_port_id);
|
||||
|
||||
/* Collect sink-related information */
|
||||
/* Note that we use the instance cb pin here!!!
|
||||
* because it has the correct coordinator for the grid!!!
|
||||
*/
|
||||
RRNodeId instance_opin_node =
|
||||
rr_gsb.get_cb_opin_node(cb_type, cb_opin_side, inode);
|
||||
vtr::Point<size_t> grid_coordinate(
|
||||
rr_graph.node_xlow(instance_opin_node),
|
||||
rr_graph.node_ylow(instance_opin_node));
|
||||
std::string sink_grid_module_name =
|
||||
generate_grid_block_module_name_in_top_module(
|
||||
std::string(GRID_MODULE_NAME_PREFIX), grids, grid_coordinate);
|
||||
ModuleId sink_grid_module =
|
||||
module_manager.find_module(sink_grid_module_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(sink_grid_module));
|
||||
size_t sink_grid_instance =
|
||||
grid_instance_ids[grid_coordinate.x()][grid_coordinate.y()];
|
||||
size_t sink_grid_pin_index = rr_graph.node_pin_num(instance_opin_node);
|
||||
|
||||
t_physical_tile_type_ptr grid_type_descriptor = grids.get_physical_type(
|
||||
t_physical_tile_loc(grid_coordinate.x(), grid_coordinate.y(), layer));
|
||||
size_t sink_grid_pin_width =
|
||||
grid_type_descriptor->pin_width_offset[sink_grid_pin_index];
|
||||
size_t sink_grid_pin_height =
|
||||
grid_type_descriptor->pin_height_offset[sink_grid_pin_index];
|
||||
BasicPort sink_grid_pin_info =
|
||||
vpr_device_annotation.physical_tile_pin_port_info(grid_type_descriptor,
|
||||
sink_grid_pin_index);
|
||||
VTR_ASSERT(true == sink_grid_pin_info.is_valid());
|
||||
int subtile_index = vpr_device_annotation.physical_tile_pin_subtile_index(
|
||||
grid_type_descriptor, sink_grid_pin_index);
|
||||
VTR_ASSERT(OPEN != subtile_index &&
|
||||
subtile_index < grid_type_descriptor->capacity);
|
||||
std::string sink_grid_port_name = generate_grid_port_name(
|
||||
sink_grid_pin_width, sink_grid_pin_height, subtile_index,
|
||||
get_rr_graph_single_node_side(
|
||||
rr_graph, rr_gsb.get_cb_opin_node(cb_type, cb_opin_side, inode)),
|
||||
sink_grid_pin_info);
|
||||
ModulePortId sink_grid_port_id =
|
||||
module_manager.find_module_port(sink_grid_module, sink_grid_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||
sink_grid_module, sink_grid_port_id));
|
||||
BasicPort sink_grid_port =
|
||||
module_manager.module_port(sink_grid_module, sink_grid_port_id);
|
||||
|
||||
/* Source and sink port should match in size */
|
||||
VTR_ASSERT(src_cb_port.get_width() == sink_grid_port.get_width());
|
||||
|
||||
/* Create a net for each pin. Note that the src/sink tag is reverted in
|
||||
* the following code. */
|
||||
for (size_t pin_id = 0; pin_id < src_cb_port.pins().size(); ++pin_id) {
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, top_module, sink_grid_module, sink_grid_instance,
|
||||
sink_grid_port_id, sink_grid_port.pins()[pin_id]);
|
||||
/* Configure the net sink */
|
||||
module_manager.add_module_net_sink(top_module, net, src_cb_module,
|
||||
src_cb_instance, src_cb_port_id,
|
||||
src_cb_port.pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
|
@ -317,8 +317,9 @@ static void print_pnr_sdc_constrain_cb_mux_timing(
|
|||
/* Find the module port corresponding to the fan-in rr_nodes of the output
|
||||
* rr_node */
|
||||
std::vector<ModulePinInfo> module_input_ports =
|
||||
find_connection_block_module_input_ports(
|
||||
module_manager, cb_module, rr_graph, rr_gsb, cb_type, input_rr_nodes);
|
||||
find_connection_block_module_input_ports(module_manager, cb_module, grids,
|
||||
device_annotation, rr_graph,
|
||||
rr_gsb, cb_type, input_rr_nodes);
|
||||
|
||||
/* Find timing constraints for each path (edge) */
|
||||
std::map<ModulePinInfo, float> switch_delays;
|
||||
|
|
|
@ -197,7 +197,7 @@ static vtr::Point<size_t> find_inter_direct_destination_coordinate(
|
|||
* Our search space will start from the next column
|
||||
* and ends at the RIGHT side of fabric
|
||||
*/
|
||||
if (INTER_COLUMN == arch_direct.type(arch_direct_id)) {
|
||||
if (e_direct_type::INTER_COLUMN == arch_direct.type(arch_direct_id)) {
|
||||
if (POSITIVE_DIR == arch_direct.x_dir(arch_direct_id)) {
|
||||
/* Our first search space will be in x-direction:
|
||||
*
|
||||
|
@ -262,7 +262,7 @@ static vtr::Point<size_t> find_inter_direct_destination_coordinate(
|
|||
* Our search space will start from the next column
|
||||
* and ends at the RIGHT side of fabric
|
||||
*/
|
||||
if (INTER_ROW == arch_direct.type(arch_direct_id)) {
|
||||
if (e_direct_type::INTER_ROW == arch_direct.type(arch_direct_id)) {
|
||||
if (POSITIVE_DIR == arch_direct.y_dir(arch_direct_id)) {
|
||||
/* Our first search space will be in y-direction:
|
||||
*
|
||||
|
@ -326,10 +326,11 @@ static vtr::Point<size_t> find_inter_direct_destination_coordinate(
|
|||
for (size_t ix : first_search_space) {
|
||||
std::vector<vtr::Point<size_t>> next_col_row_coords;
|
||||
for (size_t iy : second_search_space) {
|
||||
if (INTER_COLUMN == arch_direct.type(arch_direct_id)) {
|
||||
if (e_direct_type::INTER_COLUMN == arch_direct.type(arch_direct_id)) {
|
||||
next_col_row_coords.push_back(vtr::Point<size_t>(ix, iy));
|
||||
} else {
|
||||
VTR_ASSERT(INTER_ROW == arch_direct.type(arch_direct_id));
|
||||
VTR_ASSERT(e_direct_type::INTER_ROW ==
|
||||
arch_direct.type(arch_direct_id));
|
||||
/* For cross-row connection, our search space is flipped */
|
||||
next_col_row_coords.push_back(vtr::Point<size_t>(iy, ix));
|
||||
}
|
||||
|
@ -549,8 +550,8 @@ static void build_inter_column_row_tile_direct(
|
|||
|
||||
/* Go through the direct connection list, see if we need intra-column/row
|
||||
* connection here */
|
||||
if ((INTER_COLUMN != arch_direct.type(arch_direct_id)) &&
|
||||
(INTER_ROW != arch_direct.type(arch_direct_id))) {
|
||||
if ((e_direct_type::INTER_COLUMN != arch_direct.type(arch_direct_id)) &&
|
||||
(e_direct_type::INTER_ROW != arch_direct.type(arch_direct_id))) {
|
||||
return;
|
||||
}
|
||||
/* For cross-column connection, we will search the first valid grid in each
|
||||
|
@ -568,7 +569,7 @@ static void build_inter_column_row_tile_direct(
|
|||
* +------+
|
||||
*
|
||||
*/
|
||||
if (INTER_COLUMN == arch_direct.type(arch_direct_id)) {
|
||||
if (e_direct_type::INTER_COLUMN == arch_direct.type(arch_direct_id)) {
|
||||
for (size_t ix = 1; ix < device_ctx.grid.width() - 1; ++ix) {
|
||||
std::vector<vtr::Point<size_t>> next_col_src_grid_coords;
|
||||
/* For negative y- direction, we should start from y = ny */
|
||||
|
@ -671,7 +672,7 @@ static void build_inter_column_row_tile_direct(
|
|||
}
|
||||
|
||||
/* Reach here, it must be a cross-row connection */
|
||||
VTR_ASSERT(INTER_ROW == arch_direct.type(arch_direct_id));
|
||||
VTR_ASSERT(e_direct_type::INTER_ROW == arch_direct.type(arch_direct_id));
|
||||
/* For cross-row connection, we will search the first valid grid in each
|
||||
* column from x = 1 to x = nx
|
||||
*
|
||||
|
@ -804,9 +805,14 @@ TileDirect build_device_tile_direct(const DeviceContext& device_ctx,
|
|||
exit(1);
|
||||
}
|
||||
/* Build from original VPR arch definition */
|
||||
build_inner_column_row_tile_direct(tile_direct,
|
||||
device_ctx.arch->Directs[idirect],
|
||||
device_ctx, arch_direct_id, verbose);
|
||||
if (e_direct_type::INNER_COLUMN_OR_ROW ==
|
||||
arch_direct.type(arch_direct_id)) {
|
||||
build_inner_column_row_tile_direct(tile_direct,
|
||||
device_ctx.arch->Directs[idirect],
|
||||
device_ctx, arch_direct_id, verbose);
|
||||
/* Skip those direct connections which belong part of a connection block
|
||||
*/
|
||||
}
|
||||
/* Build from OpenFPGA arch definition */
|
||||
build_inter_column_row_tile_direct(
|
||||
tile_direct, device_ctx.arch->Directs[idirect], device_ctx, arch_direct,
|
||||
|
|
|
@ -37,5 +37,6 @@ Note that an OpenFPGA architecture can be applied to multiple VPR architecture f
|
|||
* <Int> is the number of clocks
|
||||
* <Pin> When specified, multiple clocks are in separated pins with different names
|
||||
- abspath: All the paths in the architecture file are absolute and hardcoded.
|
||||
- ecb: *Enhanced Connection Block* where connection blocks includes feedback connections
|
||||
|
||||
Other features are used in naming should be listed here.
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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="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>
|
||||
<direct_connection>
|
||||
<direct name="clb_feedback0_to_I00" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I00" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I00" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I00" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I01" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I01" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I01" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I01" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I02" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I02" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I02" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I02" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I03" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I03" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I03" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I03" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I10" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I10" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I10" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I10" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I11" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I11" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I11" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I11" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I12" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I12" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I12" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I12" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I13" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I13" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I13" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I13" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I20" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I20" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I20" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I20" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I21" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I21" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I21" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I21" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I22" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I22" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I22" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I22" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I23" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I23" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I23" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I23" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I30" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I30" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I30" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I30" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I31" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I31" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I31" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I31" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I32" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I32" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I32" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I32" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback0_to_I33" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback1_to_I33" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback2_to_I33" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
<direct name="clb_feedback3_to_I33" circuit_model_name="mux_tree_tapbuf" type="part_of_cb"/>
|
||||
</direct_connection>
|
||||
<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.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>
|
|
@ -210,7 +210,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<!-- direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/-->
|
||||
<!-- direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/-->
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
|
|
|
@ -210,7 +210,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<!-- direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/-->
|
||||
<!-- direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/-->
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
|
|
|
@ -222,7 +222,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -228,7 +228,7 @@
|
|||
<segment name="L2y" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -226,7 +226,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -232,7 +232,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -213,8 +213,8 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -217,8 +217,8 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -215,7 +215,7 @@
|
|||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_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">
|
||||
|
|
|
@ -230,7 +230,7 @@
|
|||
<direct_connection>
|
||||
<direct name="carry_chain" circuit_model_name="direct_interc"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
<direct_connection>
|
||||
<direct name="carry_chain" circuit_model_name="direct_interc"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -235,7 +235,7 @@
|
|||
<direct_connection>
|
||||
<direct name="carry_chain" circuit_model_name="direct_interc"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -236,7 +236,7 @@
|
|||
<direct_connection>
|
||||
<direct name="carry_chain" circuit_model_name="direct_interc"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -233,7 +233,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="op_clk" tile_port="clb.clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -237,7 +237,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -237,7 +237,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -223,7 +223,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -233,7 +233,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block AIB-->
|
||||
|
|
|
@ -223,7 +223,7 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<tile_annotations>
|
||||
<global_port name="clk" is_clock="true" default_val="0">
|
||||
|
|
|
@ -211,8 +211,8 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -216,9 +216,9 @@
|
|||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="shift_register" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -217,7 +217,7 @@
|
|||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc"/>
|
||||
<direct name="scff_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scff_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -232,7 +232,7 @@
|
|||
</routing_segment>
|
||||
<direct_connection>
|
||||
<direct name="adder_carry" circuit_model_name="direct_interc"/>
|
||||
<direct name="scff_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||
<direct name="scff_chain" circuit_model_name="direct_interc" type="inter_column" x_dir="positive" y_dir="positive"/>
|
||||
</direct_connection>
|
||||
<pb_type_annotations>
|
||||
<!-- physical pb_type binding in complex block IO -->
|
||||
|
|
|
@ -175,6 +175,8 @@ echo -e "Testing K4N4 support clock generation by internal resources";
|
|||
run-task basic_tests/k4_series/k4n4_clk_gen $@
|
||||
echo -e "Testing K4N4 support reset generation by internal resources";
|
||||
run-task basic_tests/k4_series/k4n4_rst_gen $@
|
||||
echo -e "Testing enhanced connection blocks"
|
||||
run-task basic_tests/k4_series/k4n4_ecb $@
|
||||
|
||||
echo -e "Testing different tile organizations";
|
||||
echo -e "Testing tiles with pins only on top and left sides";
|
||||
|
@ -199,6 +201,7 @@ run-task basic_tests/tile_organization/homo_fabric_tile_global_tile_clock $@
|
|||
run-task basic_tests/tile_organization/homo_fabric_tile_adder_chain $@
|
||||
run-task basic_tests/tile_organization/homo_fabric_tile_clkntwk $@
|
||||
run-task basic_tests/tile_organization/hetero_fabric_tile $@
|
||||
run-task basic_tests/tile_organization/homo_fabric_tile_ecb_2x2_preconfig $@
|
||||
|
||||
echo -e "Testing group config block";
|
||||
run-task basic_tests/group_config_block/group_config_block_homo_full_testbench $@
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# Configuration file for running experiments
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
|
||||
# Each job execute fpga_flow script on combination of architecture & benchmark
|
||||
# timeout_each_job is timeout for each job
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
|
||||
[GENERAL]
|
||||
run_engine=openfpga_shell
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=vpr_blif
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_pbPinFixup_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_ecb_40nm_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_vpr_device_layout=2x2
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_ecb_tileable_TileOrgzBr_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench0_top = and2
|
||||
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
|
||||
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
|
@ -0,0 +1,41 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# Configuration file for running experiments
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
|
||||
# Each job execute fpga_flow script on combination of architecture & benchmark
|
||||
# timeout_each_job is timeout for each job
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
|
||||
[GENERAL]
|
||||
run_engine=openfpga_shell
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_tile_preconfig_testbench_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_ecb_40nm_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_vpr_extra_options=--skip_sync_clustering_and_routing_results on
|
||||
openfpga_pb_pin_fixup_command=pb_pin_fixup
|
||||
openfpga_vpr_device=2x2
|
||||
openfpga_vpr_route_chan_width=20
|
||||
openfpga_group_tile_config_file=${PATH:TASK_DIR}/config/tile_config.xml
|
||||
openfpga_verilog_testbench_options=--explicit_port_mapping
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_ecb_tileable_TileOrgzBr_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
bench0_top = or2
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
|
@ -0,0 +1 @@
|
|||
<tiles style="top_left"/>
|
|
@ -33,6 +33,7 @@ Please reveal the following architecture features in the names to help quickly s
|
|||
* Top-right (Tr): the pins of a tile are placed on the top side and right side only
|
||||
* Bottom-right (Br): the pins of a tile are placed on the bottom side and right side only
|
||||
- GlobalTile<Int>Clk: How many clocks are defined through global ports from physical tiles. <Int> is the number of clocks
|
||||
- ecb: *Enhanced Connection Block* where connection blocks includes feedback connections
|
||||
|
||||
Other features are used in naming should be listed here.
|
||||
|
||||
|
|
|
@ -0,0 +1,373 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
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" area="0">
|
||||
<sub_tile name="io" capacity="8">
|
||||
<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.outpad io.inpad</loc>
|
||||
<loc side="top">io.outpad io.inpad</loc>
|
||||
<loc side="right">io.outpad io.inpad</loc>
|
||||
<loc side="bottom">io.outpad io.inpad</loc>
|
||||
</pinlocations>
|
||||
</sub_tile>
|
||||
</tile>
|
||||
<tile name="clb" area="53894">
|
||||
<sub_tile name="clb">
|
||||
<equivalent_sites>
|
||||
<site pb_type="clb"/>
|
||||
</equivalent_sites>
|
||||
<input name="I0" num_pins="4" equivalent="full"/>
|
||||
<input name="I1" num_pins="4" equivalent="full"/>
|
||||
<input name="I2" num_pins="4" equivalent="full"/>
|
||||
<input name="I3" num_pins="4" 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"/>
|
||||
<pinlocations pattern="custom">
|
||||
<loc side="top">clb.clk</loc>
|
||||
<loc side="right">clb.I2[0:3] clb.I3[0:3] clb.O[2:3]</loc>
|
||||
<loc side="left"/>
|
||||
<loc side="bottom">clb.I0[0:3] clb.I1[0:3] clb.O[0:1]</loc>
|
||||
</pinlocations>
|
||||
</sub_tile>
|
||||
</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>
|
||||
<fixed_layout name="4x4" width="6" height="6">
|
||||
<!--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>
|
||||
<directlist>
|
||||
<direct name="clb_feedback0_to_I00" from_pin="clb.O[0:0]" to_pin="clb.I0[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I00" from_pin="clb.O[1:1]" to_pin="clb.I0[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I00" from_pin="clb.O[2:2]" to_pin="clb.I0[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I00" from_pin="clb.O[3:3]" to_pin="clb.I0[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I01" from_pin="clb.O[0:0]" to_pin="clb.I0[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I01" from_pin="clb.O[1:1]" to_pin="clb.I0[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I01" from_pin="clb.O[2:2]" to_pin="clb.I0[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I01" from_pin="clb.O[3:3]" to_pin="clb.I0[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I02" from_pin="clb.O[0:0]" to_pin="clb.I0[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I02" from_pin="clb.O[1:1]" to_pin="clb.I0[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I02" from_pin="clb.O[2:2]" to_pin="clb.I0[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I02" from_pin="clb.O[3:3]" to_pin="clb.I0[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I03" from_pin="clb.O[0:0]" to_pin="clb.I0[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I03" from_pin="clb.O[1:1]" to_pin="clb.I0[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I03" from_pin="clb.O[2:2]" to_pin="clb.I0[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I03" from_pin="clb.O[3:3]" to_pin="clb.I0[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I10" from_pin="clb.O[0:0]" to_pin="clb.I1[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I10" from_pin="clb.O[1:1]" to_pin="clb.I1[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I10" from_pin="clb.O[2:2]" to_pin="clb.I1[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I10" from_pin="clb.O[3:3]" to_pin="clb.I1[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I11" from_pin="clb.O[0:0]" to_pin="clb.I1[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I11" from_pin="clb.O[1:1]" to_pin="clb.I1[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I11" from_pin="clb.O[2:2]" to_pin="clb.I1[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I11" from_pin="clb.O[3:3]" to_pin="clb.I1[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I12" from_pin="clb.O[0:0]" to_pin="clb.I1[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I12" from_pin="clb.O[1:1]" to_pin="clb.I1[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I12" from_pin="clb.O[2:2]" to_pin="clb.I1[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I12" from_pin="clb.O[3:3]" to_pin="clb.I1[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I13" from_pin="clb.O[0:0]" to_pin="clb.I1[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I13" from_pin="clb.O[1:1]" to_pin="clb.I1[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I13" from_pin="clb.O[2:2]" to_pin="clb.I1[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I13" from_pin="clb.O[3:3]" to_pin="clb.I1[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I20" from_pin="clb.O[0:0]" to_pin="clb.I2[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I20" from_pin="clb.O[1:1]" to_pin="clb.I2[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I20" from_pin="clb.O[2:2]" to_pin="clb.I2[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I20" from_pin="clb.O[3:3]" to_pin="clb.I2[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I21" from_pin="clb.O[0:0]" to_pin="clb.I2[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I21" from_pin="clb.O[1:1]" to_pin="clb.I2[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I21" from_pin="clb.O[2:2]" to_pin="clb.I2[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I21" from_pin="clb.O[3:3]" to_pin="clb.I2[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I22" from_pin="clb.O[0:0]" to_pin="clb.I2[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I22" from_pin="clb.O[1:1]" to_pin="clb.I2[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I22" from_pin="clb.O[2:2]" to_pin="clb.I2[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I22" from_pin="clb.O[3:3]" to_pin="clb.I2[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I23" from_pin="clb.O[0:0]" to_pin="clb.I2[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I23" from_pin="clb.O[1:1]" to_pin="clb.I2[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I23" from_pin="clb.O[2:2]" to_pin="clb.I2[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I23" from_pin="clb.O[3:3]" to_pin="clb.I2[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I30" from_pin="clb.O[0:0]" to_pin="clb.I3[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I30" from_pin="clb.O[1:1]" to_pin="clb.I3[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I30" from_pin="clb.O[2:2]" to_pin="clb.I3[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I30" from_pin="clb.O[3:3]" to_pin="clb.I3[0:0]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I31" from_pin="clb.O[0:0]" to_pin="clb.I3[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I31" from_pin="clb.O[1:1]" to_pin="clb.I3[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I31" from_pin="clb.O[2:2]" to_pin="clb.I3[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I31" from_pin="clb.O[3:3]" to_pin="clb.I3[1:1]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I32" from_pin="clb.O[0:0]" to_pin="clb.I3[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I32" from_pin="clb.O[1:1]" to_pin="clb.I3[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I32" from_pin="clb.O[2:2]" to_pin="clb.I3[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I32" from_pin="clb.O[3:3]" to_pin="clb.I3[2:2]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback0_to_I33" from_pin="clb.O[0:0]" to_pin="clb.I3[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback1_to_I33" from_pin="clb.O[1:1]" to_pin="clb.I3[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback2_to_I33" from_pin="clb.O[2:2]" to_pin="clb.I3[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
<direct name="clb_feedback3_to_I33" from_pin="clb.O[3:3]" to_pin="clb.I3[3:3]" x_offset="0" y_offset="0" z_offset="0" switch_name="ipin_cblock"/>
|
||||
</directlist>
|
||||
<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"/>
|
||||
<!-- 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" disable_packing="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>
|
||||
<!-- 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="I0" num_pins="4" equivalent="full"/>
|
||||
<input name="I1" num_pins="4" equivalent="full"/>
|
||||
<input name="I2" num_pins="4" equivalent="full"/>
|
||||
<input name="I3" num_pins="4" 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>
|
||||
<direct name="I0_to_fle" input="clb.I0" output="fle[0:0].in"/>
|
||||
<direct name="I1_to_fle" input="clb.I1" output="fle[1:1].in"/>
|
||||
<direct name="I2_to_fle" input="clb.I2" output="fle[2:2].in"/>
|
||||
<direct name="I3_to_fle" input="clb.I3" output="fle[3:3].in"/>
|
||||
<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>
|
Loading…
Reference in New Issue