diff --git a/docs/source/manual/arch_lang/fabric_key.rst b/docs/source/manual/arch_lang/fabric_key.rst
index 1739551b7..5ae208bc7 100644
--- a/docs/source/manual/arch_lang/fabric_key.rst
+++ b/docs/source/manual/arch_lang/fabric_key.rst
@@ -27,43 +27,45 @@ A fabric key follows an XML format. As shown in the following XML code, the key
- ``value`` indicates the instance id of the configurable memory block in the top-level FPGA fabric.
+ - ``alias`` indicates the instance name of the configurable memory block in the top-level FPGA fabric. If a valid alias is specified, the ``value`` will not be considered.
+
The following is an example of a fabric key generate by OpenFPGA for a 2 :math:`\times` 2 FPGA.
.. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libopenfpga/libfabrickey/src/fabric_key.cpp b/libopenfpga/libfabrickey/src/fabric_key.cpp
index 0c2c508bd..b4bf5efac 100644
--- a/libopenfpga/libfabrickey/src/fabric_key.cpp
+++ b/libopenfpga/libfabrickey/src/fabric_key.cpp
@@ -37,6 +37,13 @@ size_t FabricKey::key_value(const FabricKeyId& key_id) const {
return key_values_[key_id];
}
+/* Access the alias of a key */
+std::string FabricKey::key_alias(const FabricKeyId& key_id) const {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+ return key_alias_[key_id];
+}
+
bool FabricKey::empty() const {
return 0 == key_ids_.size();
}
@@ -48,6 +55,7 @@ void FabricKey::reserve_keys(const size_t& num_keys) {
key_ids_.reserve(num_keys);
key_names_.reserve(num_keys);
key_values_.reserve(num_keys);
+ key_alias_.reserve(num_keys);
}
/* Create a new key and add it to the library, return an id */
@@ -57,6 +65,7 @@ FabricKeyId FabricKey::create_key() {
key_ids_.push_back(key);
key_names_.emplace_back();
key_values_.emplace_back();
+ key_alias_.emplace_back();
return key;
}
@@ -77,6 +86,14 @@ void FabricKey::set_key_value(const FabricKeyId& key_id,
key_values_[key_id] = value;
}
+void FabricKey::set_key_alias(const FabricKeyId& key_id,
+ const std::string& alias) {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+
+ key_alias_[key_id] = alias;
+}
+
/************************************************************************
* Internal invalidators/validators
***********************************************************************/
diff --git a/libopenfpga/libfabrickey/src/fabric_key.h b/libopenfpga/libfabrickey/src/fabric_key.h
index 053e32e56..4ca678722 100644
--- a/libopenfpga/libfabrickey/src/fabric_key.h
+++ b/libopenfpga/libfabrickey/src/fabric_key.h
@@ -36,6 +36,7 @@ class FabricKey {
public: /* Public Accessors: Basic data query */
std::string key_name(const FabricKeyId& key_id) const;
size_t key_value(const FabricKeyId& key_id) const;
+ std::string key_alias(const FabricKeyId& key_id) const;
bool empty() const;
public: /* Public Mutators: model-related */
void reserve_keys(const size_t& num_keys);
@@ -44,6 +45,8 @@ class FabricKey {
const std::string& name);
void set_key_value(const FabricKeyId& key_id,
const size_t& value);
+ void set_key_alias(const FabricKeyId& key_id,
+ const std::string& alias);
public: /* Public invalidators/validators */
bool valid_key_id(const FabricKeyId& key_id) const;
private: /* Internal data */
@@ -55,6 +58,9 @@ class FabricKey {
/* Values for each key */
vtr::vector key_values_;
+
+ /* Optional alias for each key, with which a key can also be represented */
+ vtr::vector key_alias_;
};
#endif
diff --git a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp
index 8b1f03f11..291352eaa 100644
--- a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp
+++ b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp
@@ -42,6 +42,12 @@ void read_xml_component_key(pugi::xml_node& xml_component_key,
fabric_key.set_key_name(FabricKeyId(id), name);
fabric_key.set_key_value(FabricKeyId(id), value);
+
+ /* If we have an alias, set the value as well */
+ const std::string& alias = get_attribute(xml_component_key, "alias", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
+ if (!alias.empty()) {
+ fabric_key.set_key_alias(FabricKeyId(id), alias);
+ }
}
/********************************************************************
diff --git a/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp
index 1697f94a6..305d6d67e 100644
--- a/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp
+++ b/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp
@@ -43,6 +43,10 @@ int write_xml_fabric_component_key(std::fstream& fp,
write_xml_attribute(fp, "name", fabric_key.key_name(component_key).c_str());
write_xml_attribute(fp, "value", fabric_key.key_value(component_key));
+ if (!fabric_key.key_alias(component_key).empty()) {
+ write_xml_attribute(fp, "alias", fabric_key.key_alias(component_key).c_str());
+ }
+
fp << "/>" << "\n";
return 0;
diff --git a/openfpga/src/annotation/annotate_rr_graph.cpp b/openfpga/src/annotation/annotate_rr_graph.cpp
index 644f4541c..3815c6305 100644
--- a/openfpga/src/annotation/annotate_rr_graph.cpp
+++ b/openfpga/src/annotation/annotate_rr_graph.cpp
@@ -446,20 +446,38 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx,
* output ports of the GSB
*******************************************************************/
void sort_device_rr_gsb_chan_node_in_edges(const RRGraph& rr_graph,
- DeviceRRGSB& device_rr_gsb) {
+ DeviceRRGSB& device_rr_gsb,
+ const bool& verbose_output) {
vtr::ScopedStartFinishTimer timer("Sort incoming edges for each routing track output node of General Switch Block(GSB)");
/* Note that the GSB array is smaller than the grids by 1 column and 1 row!!! */
vtr::Point gsb_range = device_rr_gsb.get_gsb_range();
+ VTR_LOGV(verbose_output,
+ "Start sorting edges for GSBs up to [%lu][%lu]\n",
+ gsb_range.x(), gsb_range.y());
+
+ size_t gsb_cnt = 0;
+
/* For each switch block, determine the size of array */
for (size_t ix = 0; ix < gsb_range.x(); ++ix) {
for (size_t iy = 0; iy < gsb_range.y(); ++iy) {
vtr::Point gsb_coordinate(ix, iy);
RRGSB& rr_gsb = device_rr_gsb.get_mutable_gsb(gsb_coordinate);
rr_gsb.sort_chan_node_in_edges(rr_graph);
+
+ gsb_cnt++; /* Update counter */
+
+ /* Print info */
+ VTR_LOG("[%lu%] Sorted edges for GSB[%lu][%lu]\r",
+ 100 * gsb_cnt / (gsb_range.x() * gsb_range.y()),
+ ix, iy);
}
}
+
+ /* Report number of unique mirrors */
+ VTR_LOG("Sorted edges for %d General Switch Blocks (GSBs).\n",
+ gsb_range.x() * gsb_range.y());
}
/********************************************************************
diff --git a/openfpga/src/annotation/annotate_rr_graph.h b/openfpga/src/annotation/annotate_rr_graph.h
index 69346a481..9ba879553 100644
--- a/openfpga/src/annotation/annotate_rr_graph.h
+++ b/openfpga/src/annotation/annotate_rr_graph.h
@@ -20,7 +20,8 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx,
const bool& verbose_output);
void sort_device_rr_gsb_chan_node_in_edges(const RRGraph& rr_graph,
- DeviceRRGSB& device_rr_gsb);
+ DeviceRRGSB& device_rr_gsb,
+ const bool& verbose_output);
void annotate_rr_graph_circuit_models(const DeviceContext& vpr_device_ctx,
const Arch& openfpga_arch,
diff --git a/openfpga/src/base/openfpga_bitstream.cpp b/openfpga/src/base/openfpga_bitstream.cpp
index 32fb8b945..3fbffc45d 100644
--- a/openfpga/src/base/openfpga_bitstream.cpp
+++ b/openfpga/src/base/openfpga_bitstream.cpp
@@ -74,19 +74,21 @@ int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
cmd_context.option_enable(cmd, opt_verbose));
/* Write fabric bitstream if required */
+ int status = CMD_EXEC_SUCCESS;
if (true == cmd_context.option_enable(cmd, opt_file)) {
std::string src_dir_path = find_path_dir_name(cmd_context.option_value(cmd, opt_file));
/* Create directories */
create_directory(src_dir_path);
- write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(),
- openfpga_ctx.fabric_bitstream(),
- cmd_context.option_value(cmd, opt_file));
+ status = write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(),
+ openfpga_ctx.fabric_bitstream(),
+ openfpga_ctx.arch().config_protocol,
+ cmd_context.option_value(cmd, opt_file));
}
/* TODO: should identify the error code from internal function execution */
- return CMD_EXEC_SUCCESS;
+ return status;
}
} /* end namespace openfpga */
diff --git a/openfpga/src/base/openfpga_link_arch.cpp b/openfpga/src/base/openfpga_link_arch.cpp
index ff8bd6151..06ad2ac27 100644
--- a/openfpga/src/base/openfpga_link_arch.cpp
+++ b/openfpga/src/base/openfpga_link_arch.cpp
@@ -124,7 +124,8 @@ int link_arch(OpenfpgaContext& openfpga_ctx,
if (true == cmd_context.option_enable(cmd, opt_sort_edge)) {
sort_device_rr_gsb_chan_node_in_edges(g_vpr_ctx.device().rr_graph,
- openfpga_ctx.mutable_device_rr_gsb());
+ openfpga_ctx.mutable_device_rr_gsb(),
+ cmd_context.option_enable(cmd, opt_verbose));
}
/* Build multiplexer library */
diff --git a/openfpga/src/base/openfpga_naming.cpp b/openfpga/src/base/openfpga_naming.cpp
index 38f20f0ee..84366b1ab 100644
--- a/openfpga/src/base/openfpga_naming.cpp
+++ b/openfpga/src/base/openfpga_naming.cpp
@@ -348,7 +348,6 @@ std::string generate_routing_track_port_name(const t_rr_type& chan_type,
*********************************************************************/
std::string generate_sb_module_track_port_name(const t_rr_type& chan_type,
const e_side& module_side,
- const size_t& track_id,
const PORTS& port_direction) {
/* Channel must be either CHANX or CHANY */
VTR_ASSERT( (CHANX == chan_type) || (CHANY == chan_type) );
@@ -368,19 +367,16 @@ std::string generate_sb_module_track_port_name(const t_rr_type& chan_type,
switch (port_direction) {
case OUT_PORT:
- port_name += std::string("out_");
+ port_name += std::string("out");
break;
case IN_PORT:
- port_name += std::string("in_");
+ port_name += std::string("in");
break;
default:
VTR_LOG_ERROR("Invalid direction of chan_rr_node!\n");
exit(1);
}
- /* Add the track id to the port name */
- port_name += std::to_string(track_id) + std::string("_");
-
return port_name;
}
@@ -392,37 +388,46 @@ std::string generate_sb_module_track_port_name(const t_rr_type& chan_type,
* Instead, we use the relative location of the pins in the context of routing modules
* so that each module can be instanciated across the fabric
* Even though, port direction must be provided!
+ *
+ * Upper_location: specify if an upper/lower prefix to be added.
+ * The location indicates where the bus port should be
+ * placed on the perimeter of the connection block
+ * - For X-directional CB:
+ * - upper is the left side
+ * - lower is the right side
+ * - For Y-directional CB:
+ * - upper is the bottom side
+ * - lower is the top side
*********************************************************************/
std::string generate_cb_module_track_port_name(const t_rr_type& chan_type,
- const size_t& track_id,
- const PORTS& port_direction) {
+ const PORTS& port_direction,
+ const bool& upper_location) {
/* Channel must be either CHANX or CHANY */
VTR_ASSERT( (CHANX == chan_type) || (CHANY == chan_type) );
/* Create a map between chan_type and module_prefix */
- std::map module_prefix_map;
+ std::map> module_prefix_map;
/* TODO: use a constexpr string to replace the fixed name? */
- module_prefix_map[CHANX] = std::string("chanx");
- module_prefix_map[CHANY] = std::string("chany");
+ module_prefix_map[CHANX][true] = std::string("chanx_left");
+ module_prefix_map[CHANX][false] = std::string("chanx_right");
+ module_prefix_map[CHANY][true] = std::string("chany_bottom");
+ module_prefix_map[CHANY][false] = std::string("chany_top");
- std::string port_name = module_prefix_map[chan_type];
+ std::string port_name = module_prefix_map[chan_type][upper_location];
port_name += std::string("_");
switch (port_direction) {
case OUT_PORT:
- port_name += std::string("out_");
+ port_name += std::string("out");
break;
case IN_PORT:
- port_name += std::string("in_");
+ port_name += std::string("in");
break;
default:
VTR_LOG_ERROR("Invalid direction of chan_rr_node!\n");
exit(1);
}
- /* Add the track id to the port name */
- port_name += std::to_string(track_id) + std::string("_");
-
return port_name;
}
diff --git a/openfpga/src/base/openfpga_naming.h b/openfpga/src/base/openfpga_naming.h
index 3634be27a..3f374b8e5 100644
--- a/openfpga/src/base/openfpga_naming.h
+++ b/openfpga/src/base/openfpga_naming.h
@@ -91,12 +91,11 @@ std::string generate_routing_track_port_name(const t_rr_type& chan_type,
std::string generate_sb_module_track_port_name(const t_rr_type& chan_type,
const e_side& module_side,
- const size_t& track_id,
const PORTS& port_direction);
std::string generate_cb_module_track_port_name(const t_rr_type& chan_type,
- const size_t& track_id,
- const PORTS& port_direction);
+ const PORTS& port_direction,
+ const bool& upper_location);
std::string generate_routing_track_middle_output_port_name(const t_rr_type& chan_type,
const vtr::Point& coordinate,
diff --git a/openfpga/src/fabric/build_routing_module_utils.cpp b/openfpga/src/fabric/build_routing_module_utils.cpp
index c717604c5..320823ec2 100644
--- a/openfpga/src/fabric/build_routing_module_utils.cpp
+++ b/openfpga/src/fabric/build_routing_module_utils.cpp
@@ -18,28 +18,29 @@
namespace openfpga {
/*********************************************************************
- * Generate a port for a routing track of a swtich block
+ * Find the port id and pin id for a routing track in the switch
+ * block module with a given rr_node
********************************************************************/
-ModulePortId find_switch_block_module_chan_port(const ModuleManager& module_manager,
- const ModuleId& sb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const e_side& chan_side,
- const RRNodeId& cur_rr_node,
- const PORTS& cur_rr_node_direction) {
+ModulePinInfo find_switch_block_module_chan_port(const ModuleManager& module_manager,
+ const ModuleId& sb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const e_side& chan_side,
+ const RRNodeId& cur_rr_node,
+ const PORTS& cur_rr_node_direction) {
/* Get the index in sb_info of cur_rr_node */
int index = rr_gsb.get_node_index(rr_graph, cur_rr_node, chan_side, cur_rr_node_direction);
/* Make sure this node is included in this sb_info */
VTR_ASSERT((-1 != index) && (NUM_SIDES != chan_side));
std::string chan_port_name = generate_sb_module_track_port_name(rr_graph.node_type(rr_gsb.get_chan_node(chan_side, index)),
- chan_side, index,
+ chan_side,
rr_gsb.get_chan_node_direction(chan_side, index));
/* Must find a valid port id in the Switch Block module */
ModulePortId chan_port_id = module_manager.find_module_port(sb_module, chan_port_name);
VTR_ASSERT(true == module_manager.valid_module_port_id(sb_module, chan_port_id));
- return chan_port_id;
+ return ModulePinInfo(chan_port_id, index / 2);
}
/*********************************************************************
@@ -61,14 +62,14 @@ ModulePortId find_switch_block_module_chan_port(const ModuleManager& module_mana
* 2. When the input is a routing track, the input_side should be
* the side of the node locating on the switch block
********************************************************************/
-ModulePortId find_switch_block_module_input_port(const ModuleManager& module_manager,
- const ModuleId& sb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const e_side& input_side,
- const RRNodeId& input_rr_node) {
+ModulePinInfo find_switch_block_module_input_port(const ModuleManager& module_manager,
+ const ModuleId& sb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const e_side& input_side,
+ const RRNodeId& input_rr_node) {
/* Deposit an invalid value */
- ModulePortId input_port_id = ModulePortId::INVALID();
+ ModulePinInfo input_port(ModulePortId::INVALID(), 0);
/* Generate the input port object */
switch (rr_graph.node_type(input_rr_node)) {
/* case SOURCE: */
@@ -85,14 +86,14 @@ ModulePortId find_switch_block_module_input_port(const ModuleManager& module_man
grid_pin_side,
rr_graph.node_pin_num(input_rr_node));
/* Must find a valid port id in the Switch Block module */
- input_port_id = module_manager.find_module_port(sb_module, input_port_name);
- VTR_ASSERT(true == module_manager.valid_module_port_id(sb_module, input_port_id));
+ input_port.first = module_manager.find_module_port(sb_module, input_port_name);
+ VTR_ASSERT(true == module_manager.valid_module_port_id(sb_module, input_port.first));
break;
}
case CHANX:
case CHANY: {
- input_port_id = find_switch_block_module_chan_port(module_manager, sb_module, rr_graph,
- rr_gsb, input_side, input_rr_node, IN_PORT);
+ input_port = find_switch_block_module_chan_port(module_manager, sb_module, rr_graph,
+ rr_gsb, input_side, input_rr_node, IN_PORT);
break;
}
default: /* SOURCE, IPIN, SINK are invalid*/
@@ -100,18 +101,18 @@ ModulePortId find_switch_block_module_input_port(const ModuleManager& module_man
exit(1);
}
- return input_port_id;
+ return input_port;
}
/*********************************************************************
* Generate a list of input ports for routing multiplexer inside the switch block
********************************************************************/
-std::vector find_switch_block_module_input_ports(const ModuleManager& module_manager,
- const ModuleId& sb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const std::vector& input_rr_nodes) {
- std::vector input_ports;
+std::vector find_switch_block_module_input_ports(const ModuleManager& module_manager,
+ const ModuleId& sb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const std::vector& input_rr_nodes) {
+ std::vector input_ports;
for (const RRNodeId& input_rr_node : input_rr_nodes) {
/* Find the side where the input locates in the Switch Block */
@@ -132,27 +133,27 @@ std::vector find_switch_block_module_input_ports(const ModuleManag
* Generate an input port for routing multiplexer inside the connection block
* which is the middle output of a routing track
********************************************************************/
-ModulePortId find_connection_block_module_chan_port(const ModuleManager& module_manager,
- const ModuleId& cb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const t_rr_type& cb_type,
- const RRNodeId& chan_rr_node) {
- ModulePortId input_port_id;
+ModulePinInfo find_connection_block_module_chan_port(const ModuleManager& module_manager,
+ const ModuleId& cb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const t_rr_type& cb_type,
+ const RRNodeId& chan_rr_node) {
+ ModulePinInfo input_port_info;
/* Generate the input port object */
switch (rr_graph.node_type(chan_rr_node)) {
case CHANX:
case CHANY: {
/* Create port description for the routing track middle output */
- vtr::Point port_coord(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
int chan_node_track_id = rr_gsb.get_cb_chan_node_index(cb_type, chan_rr_node);
/* Create a port description for the middle output */
std::string input_port_name = generate_cb_module_track_port_name(cb_type,
- chan_node_track_id,
- IN_PORT);
+ IN_PORT,
+ 0 == chan_node_track_id % 2);
/* Must find a valid port id in the Switch Block module */
- input_port_id = module_manager.find_module_port(cb_module, input_port_name);
- VTR_ASSERT(true == module_manager.valid_module_port_id(cb_module, input_port_id));
+ input_port_info.first = module_manager.find_module_port(cb_module, input_port_name);
+ input_port_info.second = chan_node_track_id / 2;
+ VTR_ASSERT(true == module_manager.valid_module_port_id(cb_module, input_port_info.first));
break;
}
default: /* OPIN, SOURCE, IPIN, SINK are invalid*/
@@ -160,7 +161,7 @@ ModulePortId find_connection_block_module_chan_port(const ModuleManager& module_
exit(1);
}
- return input_port_id;
+ return input_port_info;
}
/*********************************************************************
@@ -195,13 +196,13 @@ ModulePortId find_connection_block_module_ipin_port(const ModuleManager& module_
* Generate a list of routing track middle output ports
* for routing multiplexer inside the connection block
********************************************************************/
-std::vector find_connection_block_module_input_ports(const ModuleManager& module_manager,
- const ModuleId& cb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const t_rr_type& cb_type,
- const std::vector& input_rr_nodes) {
- std::vector input_ports;
+std::vector find_connection_block_module_input_ports(const ModuleManager& module_manager,
+ const ModuleId& cb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const t_rr_type& cb_type,
+ const std::vector& input_rr_nodes) {
+ std::vector 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));
diff --git a/openfpga/src/fabric/build_routing_module_utils.h b/openfpga/src/fabric/build_routing_module_utils.h
index 257a788cb..3684a5d8b 100644
--- a/openfpga/src/fabric/build_routing_module_utils.h
+++ b/openfpga/src/fabric/build_routing_module_utils.h
@@ -6,6 +6,7 @@
*******************************************************************/
#include
+#include
#include "rr_gsb.h"
#include "module_manager.h"
#include "vpr_types.h"
@@ -17,33 +18,35 @@
/* begin namespace openfpga */
namespace openfpga {
-ModulePortId find_switch_block_module_chan_port(const ModuleManager& module_manager,
- const ModuleId& sb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const e_side& chan_side,
- const RRNodeId& cur_rr_node,
- const PORTS& cur_rr_node_direction);
+typedef std::pair ModulePinInfo;
-ModulePortId find_switch_block_module_input_port(const ModuleManager& module_manager,
- const ModuleId& sb_module,
+ModulePinInfo find_switch_block_module_chan_port(const ModuleManager& module_manager,
+ const ModuleId& sb_module,
const RRGraph& rr_graph,
const RRGSB& rr_gsb,
- const e_side& input_side,
- const RRNodeId& input_rr_node);
+ const e_side& chan_side,
+ const RRNodeId& cur_rr_node,
+ const PORTS& cur_rr_node_direction);
-std::vector find_switch_block_module_input_ports(const ModuleManager& module_manager,
- const ModuleId& sb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const std::vector& input_rr_nodes);
+ModulePinInfo find_switch_block_module_input_port(const ModuleManager& module_manager,
+ const ModuleId& sb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const e_side& input_side,
+ const RRNodeId& input_rr_node);
-ModulePortId find_connection_block_module_chan_port(const ModuleManager& module_manager,
- const ModuleId& cb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const t_rr_type& cb_type,
- const RRNodeId& chan_rr_node);
+std::vector find_switch_block_module_input_ports(const ModuleManager& module_manager,
+ const ModuleId& sb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const std::vector& input_rr_nodes);
+
+ModulePinInfo find_connection_block_module_chan_port(const ModuleManager& module_manager,
+ const ModuleId& cb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const t_rr_type& cb_type,
+ const RRNodeId& chan_rr_node);
ModulePortId find_connection_block_module_ipin_port(const ModuleManager& module_manager,
const ModuleId& cb_module,
@@ -51,12 +54,12 @@ ModulePortId find_connection_block_module_ipin_port(const ModuleManager& module_
const RRGSB& rr_gsb,
const RRNodeId& src_rr_node);
-std::vector find_connection_block_module_input_ports(const ModuleManager& module_manager,
- const ModuleId& cb_module,
- const RRGraph& rr_graph,
- const RRGSB& rr_gsb,
- const t_rr_type& cb_type,
- const std::vector& input_rr_nodes);
+std::vector find_connection_block_module_input_ports(const ModuleManager& module_manager,
+ const ModuleId& cb_module,
+ const RRGraph& rr_graph,
+ const RRGSB& rr_gsb,
+ const t_rr_type& cb_type,
+ const std::vector& input_rr_nodes);
} /* end namespace openfpga */
diff --git a/openfpga/src/fabric/build_routing_modules.cpp b/openfpga/src/fabric/build_routing_modules.cpp
index 98a94baa8..dda29cdc5 100644
--- a/openfpga/src/fabric/build_routing_modules.cpp
+++ b/openfpga/src/fabric/build_routing_modules.cpp
@@ -47,11 +47,11 @@ void build_switch_block_module_short_interc(ModuleManager& module_manager,
const e_side& chan_side,
const RRNodeId& cur_rr_node,
const RRNodeId& drive_rr_node,
- const std::map& input_port_to_module_nets) {
+ const std::map& input_port_to_module_nets) {
/* Find the name of output port */
- ModulePortId output_port_id = find_switch_block_module_chan_port(module_manager, sb_module,
- rr_graph, rr_gsb,
- chan_side, cur_rr_node, OUT_PORT);
+ ModulePinInfo output_port_info = find_switch_block_module_chan_port(module_manager, sb_module,
+ rr_graph, rr_gsb,
+ chan_side, cur_rr_node, OUT_PORT);
enum e_side input_pin_side = chan_side;
int index = -1;
@@ -81,20 +81,17 @@ void build_switch_block_module_short_interc(ModuleManager& module_manager,
exit(1);
}
/* Find the name of input port */
- ModulePortId input_port_id = find_switch_block_module_input_port(module_manager, sb_module, rr_graph, rr_gsb, input_pin_side, drive_rr_node);
+ ModulePinInfo input_port_info = find_switch_block_module_input_port(module_manager, sb_module, rr_graph, rr_gsb, input_pin_side, drive_rr_node);
/* The input port and output port must match in size */
- BasicPort input_port = module_manager.module_port(sb_module, input_port_id);
- BasicPort output_port = module_manager.module_port(sb_module, output_port_id);
- VTR_ASSERT(input_port.get_width() == output_port.get_width());
+ BasicPort input_port = module_manager.module_port(sb_module, input_port_info.first);
+ BasicPort output_port = module_manager.module_port(sb_module, output_port_info.first);
/* Create a module net for this short-wire connection */
- for (size_t pin_id = 0; pin_id < input_port.pins().size(); ++pin_id) {
- ModuleNetId net = input_port_to_module_nets.at(input_port_id);
- /* Skip Configuring the net source, it is done before */
- /* Configure the net sink */
- module_manager.add_module_net_sink(sb_module, net, sb_module, 0, output_port_id, output_port.pins()[pin_id]);
- }
+ ModuleNetId net = input_port_to_module_nets.at(input_port_info);
+ /* Skip Configuring the net source, it is done before */
+ /* Configure the net sink */
+ module_manager.add_module_net_sink(sb_module, net, sb_module, 0, output_port_info.first, output_port_info.second);
}
/*********************************************************************
@@ -113,7 +110,7 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
const RRNodeId& cur_rr_node,
const std::vector& driver_rr_nodes,
const RRSwitchId& switch_index,
- const std::map& input_port_to_module_nets) {
+ const std::map& input_port_to_module_nets) {
/* Check current rr_node is CHANX or CHANY*/
VTR_ASSERT((CHANX == rr_graph.node_type(cur_rr_node)) || (CHANY == rr_graph.node_type(cur_rr_node)));
@@ -140,7 +137,7 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
module_manager.set_child_instance_name(sb_module, mux_module, mux_instance_id, mux_instance_name);
/* Generate input ports that are wired to the input bus of the routing multiplexer */
- std::vector sb_input_port_ids = find_switch_block_module_input_ports(module_manager, sb_module, rr_graph, rr_gsb, driver_rr_nodes);
+ std::vector sb_input_port_ids = find_switch_block_module_input_ports(module_manager, sb_module, rr_graph, rr_gsb, driver_rr_nodes);
/* Link input bus port to Switch Block inputs */
std::vector mux_model_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true);
@@ -156,8 +153,8 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
/* Use the exising net */
ModuleNetId net = input_port_to_module_nets.at(sb_input_port_ids[pin_id]);
/* Configure the net source only if it is not yet in the source list */
- if (false == module_manager.net_source_exist(sb_module, net, sb_module, 0, sb_input_port_ids[pin_id], 0)) {
- module_manager.add_module_net_source(sb_module, net, sb_module, 0, sb_input_port_ids[pin_id], 0);
+ if (false == module_manager.net_source_exist(sb_module, net, sb_module, 0, sb_input_port_ids[pin_id].first, sb_input_port_ids[pin_id].second)) {
+ module_manager.add_module_net_source(sb_module, net, sb_module, 0, sb_input_port_ids[pin_id].first, sb_input_port_ids[pin_id].second);
}
/* Configure the net sink */
module_manager.add_module_net_sink(sb_module, net, mux_module, mux_instance_id, mux_input_port_id, mux_input_port.pins()[pin_id]);
@@ -170,17 +167,16 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
ModulePortId mux_output_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_prefix(mux_model_output_ports[0]));
VTR_ASSERT(true == module_manager.valid_module_port_id(mux_module, mux_output_port_id));
BasicPort mux_output_port = module_manager.module_port(mux_module, mux_output_port_id);
- ModulePortId sb_output_port_id = find_switch_block_module_chan_port(module_manager, sb_module, rr_graph, rr_gsb, chan_side, cur_rr_node, OUT_PORT);
- BasicPort sb_output_port = module_manager.module_port(sb_module, sb_output_port_id);
+ ModulePinInfo sb_output_port_id = find_switch_block_module_chan_port(module_manager, sb_module, rr_graph, rr_gsb, chan_side, cur_rr_node, OUT_PORT);
+ BasicPort sb_output_port = module_manager.module_port(sb_module, sb_output_port_id.first);
/* Check port size should match */
- VTR_ASSERT(sb_output_port.get_width() == mux_output_port.get_width());
+ VTR_ASSERT(1 == mux_output_port.get_width());
for (size_t pin_id = 0; pin_id < mux_output_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(sb_module);
/* Configuring the net source */
- module_manager.add_module_net_source(sb_module, net, mux_module, mux_instance_id, mux_output_port_id, mux_output_port.pins()[pin_id]);
+ ModuleNetId net = create_module_source_pin_net(module_manager, sb_module, mux_module, mux_instance_id, mux_output_port_id, mux_output_port.pins()[pin_id]);
/* Configure the net sink */
- module_manager.add_module_net_sink(sb_module, net, sb_module, 0, sb_output_port_id, sb_output_port.pins()[pin_id]);
+ module_manager.add_module_net_sink(sb_module, net, sb_module, 0, sb_output_port_id.first, sb_output_port_id.second);
}
/* Instanciate memory modules */
@@ -220,7 +216,7 @@ void build_switch_block_interc_modules(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const e_side& chan_side,
const size_t& chan_node_id,
- const std::map& input_port_to_module_nets) {
+ const std::map& input_port_to_module_nets) {
std::vector driver_rr_nodes;
/* Get the node */
@@ -346,30 +342,24 @@ void build_switch_block_module(ModuleManager& module_manager,
generate_switch_block_module_name(gsb_coordinate).c_str());
/* Create a cache (fast look up) for module nets whose source are input ports */
- std::map input_port_to_module_nets;
+ std::map input_port_to_module_nets;
/* Add routing channel ports at each side of the GSB */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
SideManager side_manager(side);
- for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
- std::string port_name = generate_sb_module_track_port_name(rr_graph.node_type(rr_gsb.get_chan_node(side_manager.get_side(), itrack)),
- side_manager.get_side(), itrack,
- rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack));
- BasicPort module_port(port_name, 1); /* Every track has a port size of 1 */
+ /* Count input and output port sizes */
+ size_t chan_input_port_size = 0;
+ size_t chan_output_port_size = 0;
+ for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
switch (rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
case OUT_PORT:
- module_manager.add_port(sb_module, module_port, ModuleManager::MODULE_OUTPUT_PORT);
+ chan_output_port_size++;
break;
- case IN_PORT: {
- ModulePortId input_port_id = module_manager.add_port(sb_module, module_port, ModuleManager::MODULE_INPUT_PORT);
- /* Cache the input net */
- ModuleNetId net = module_manager.create_module_net(sb_module);
- module_manager.add_module_net_source(sb_module, net, sb_module, 0, input_port_id, 0);
- input_port_to_module_nets[input_port_id] = net;
+ case IN_PORT:
+ chan_input_port_size++;
break;
- }
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid direction of chan[%d][%d]_track[%d]!\n",
@@ -377,6 +367,30 @@ void build_switch_block_module(ModuleManager& module_manager,
exit(1);
}
}
+
+ /* Do only when we have routing tracks */
+ if (0 < rr_gsb.get_chan_width(side_manager.get_side())) {
+ t_rr_type chan_type = rr_gsb.get_chan_type(side_manager.get_side());
+
+ std::string chan_input_port_name = generate_sb_module_track_port_name(chan_type,
+ side_manager.get_side(),
+ IN_PORT);
+ BasicPort chan_input_port(chan_input_port_name, chan_input_port_size);
+ ModulePortId chan_input_port_id = module_manager.add_port(sb_module, chan_input_port, ModuleManager::MODULE_INPUT_PORT);
+
+ /* Cache the input net */
+ for (const size_t& pin : chan_input_port.pins()) {
+ ModuleNetId net = create_module_source_pin_net(module_manager, sb_module, sb_module, 0, chan_input_port_id, pin);
+ input_port_to_module_nets[ModulePinInfo(chan_input_port_id, pin)] = net;
+ }
+
+ std::string chan_output_port_name = generate_sb_module_track_port_name(chan_type,
+ side_manager.get_side(),
+ OUT_PORT);
+ BasicPort chan_output_port(chan_output_port_name, chan_output_port_size);
+ module_manager.add_port(sb_module, chan_output_port, ModuleManager::MODULE_OUTPUT_PORT);
+ }
+
/* Dump OPINs of adjacent CLBs */
for (size_t inode = 0; inode < rr_gsb.get_num_opin_nodes(side_manager.get_side()); ++inode) {
vtr::Point port_coord(rr_graph.node_xlow(rr_gsb.get_opin_node(side_manager.get_side(), inode)),
@@ -389,9 +403,8 @@ void build_switch_block_module(ModuleManager& module_manager,
ModulePortId input_port_id = module_manager.add_port(sb_module, module_port, ModuleManager::MODULE_INPUT_PORT);
/* Cache the input net */
- ModuleNetId net = module_manager.create_module_net(sb_module);
- module_manager.add_module_net_source(sb_module, net, sb_module, 0, input_port_id, 0);
- input_port_to_module_nets[input_port_id] = net;
+ ModuleNetId net = create_module_source_pin_net(module_manager, sb_module, sb_module, 0, input_port_id, 0);
+ input_port_to_module_nets[ModulePinInfo(input_port_id, 0)] = net;
}
}
@@ -399,7 +412,7 @@ void build_switch_block_module(ModuleManager& module_manager,
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
SideManager side_manager(side);
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) {
- /* We care INC_DIRECTION tracks at this side*/
+ /* We care OUTPUT tracks at this time only */
if (OUT_PORT == rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
build_switch_block_interc_modules(module_manager,
sb_module, device_annotation, rr_graph, rr_gsb,
@@ -457,7 +470,7 @@ void build_connection_block_module_short_interc(ModuleManager& module_manager,
const RRGSB& rr_gsb,
const t_rr_type& cb_type,
const RRNodeId& src_rr_node,
- const std::map& input_port_to_module_nets) {
+ const std::map& input_port_to_module_nets) {
/* Ensure we have only one 1 driver node */
std::vector driver_rr_nodes = get_rr_graph_configurable_driver_nodes(rr_graph, src_rr_node);
@@ -488,23 +501,21 @@ void build_connection_block_module_short_interc(ModuleManager& module_manager,
VTR_ASSERT((CHANX == rr_graph.node_type(driver_rr_node)) || (CHANY == rr_graph.node_type(driver_rr_node)));
/* Create port description for the routing track middle output */
- ModulePortId input_port_id = find_connection_block_module_chan_port(module_manager, cb_module, rr_graph, rr_gsb, cb_type, driver_rr_node);
+ ModulePinInfo input_port_info = find_connection_block_module_chan_port(module_manager, cb_module, rr_graph, rr_gsb, cb_type, driver_rr_node);
/* Create port description for input pin of a CLB */
ModulePortId ipin_port_id = find_connection_block_module_ipin_port(module_manager, cb_module, rr_graph, rr_gsb, src_rr_node);
/* The input port and output port must match in size */
- BasicPort input_port = module_manager.module_port(cb_module, input_port_id);
+ BasicPort input_port = module_manager.module_port(cb_module, input_port_info.first);
BasicPort ipin_port = module_manager.module_port(cb_module, ipin_port_id);
- VTR_ASSERT(input_port.get_width() == ipin_port.get_width());
+ VTR_ASSERT(1 == ipin_port.get_width());
/* Create a module net for this short-wire connection */
- for (size_t pin_id = 0; pin_id < input_port.pins().size(); ++pin_id) {
- ModuleNetId net = input_port_to_module_nets.at(input_port_id);
- /* Skip Configuring the net source, it is done before */
- /* Configure the net sink */
- module_manager.add_module_net_sink(cb_module, net, cb_module, 0, ipin_port_id, ipin_port.pins()[pin_id]);
- }
+ ModuleNetId net = input_port_to_module_nets.at(input_port_info);
+ /* Skip Configuring the net source, it is done before */
+ /* Configure the net sink */
+ module_manager.add_module_net_sink(cb_module, net, cb_module, 0, ipin_port_id, ipin_port.pins()[0]);
}
/*********************************************************************
@@ -521,7 +532,7 @@ void build_connection_block_mux_module(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const e_side& cb_ipin_side,
const size_t& ipin_index,
- const std::map& input_port_to_module_nets) {
+ const std::map& input_port_to_module_nets) {
const RRNodeId& cur_rr_node = rr_gsb.get_ipin_node(cb_ipin_side, ipin_index);
/* Check current rr_node is an input pin of a CLB */
VTR_ASSERT(IPIN == rr_graph.node_type(cur_rr_node));
@@ -554,7 +565,7 @@ void build_connection_block_mux_module(ModuleManager& module_manager,
module_manager.set_child_instance_name(cb_module, mux_module, mux_instance_id, mux_instance_name);
/* TODO: Generate input ports that are wired to the input bus of the routing multiplexer */
- std::vector cb_input_port_ids = find_connection_block_module_input_ports(module_manager, cb_module, rr_graph, rr_gsb, cb_type, driver_rr_nodes);
+ std::vector cb_input_port_ids = find_connection_block_module_input_ports(module_manager, cb_module, rr_graph, rr_gsb, cb_type, driver_rr_nodes);
/* Link input bus port to Switch Block inputs */
std::vector mux_model_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true);
@@ -587,9 +598,8 @@ void build_connection_block_mux_module(ModuleManager& module_manager,
/* Check port size should match */
VTR_ASSERT(cb_output_port.get_width() == mux_output_port.get_width());
for (size_t pin_id = 0; pin_id < mux_output_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(cb_module);
/* Configuring the net source */
- module_manager.add_module_net_source(cb_module, net, mux_module, mux_instance_id, mux_output_port_id, mux_output_port.pins()[pin_id]);
+ ModuleNetId net = create_module_source_pin_net(module_manager, cb_module, mux_module, mux_instance_id, mux_output_port_id, mux_output_port.pins()[pin_id]);
/* Configure the net sink */
module_manager.add_module_net_sink(cb_module, net, cb_module, 0, cb_output_port_id, cb_output_port.pins()[pin_id]);
}
@@ -635,7 +645,7 @@ void build_connection_block_interc_modules(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const e_side& cb_ipin_side,
const size_t& ipin_index,
- const std::map& input_port_to_module_nets) {
+ const std::map& input_port_to_module_nets) {
const RRNodeId& src_rr_node = rr_gsb.get_ipin_node(cb_ipin_side, ipin_index);
if (1 > rr_graph.node_in_edges(src_rr_node).size()) {
@@ -733,22 +743,47 @@ void build_connection_block_module(ModuleManager& module_manager,
/* Add the input and output ports of routing tracks in the channel
* Routing tracks pass through the connection blocks
*/
- for (size_t itrack = 0; itrack < rr_gsb.get_cb_chan_width(cb_type); ++itrack) {
- vtr::Point port_coord(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
- std::string port_name = generate_cb_module_track_port_name(cb_type,
- itrack,
- IN_PORT);
- BasicPort module_port(port_name, 1); /* Every track has a port size of 1 */
- module_manager.add_port(cb_module, module_port, ModuleManager::MODULE_INPUT_PORT);
- }
- for (size_t itrack = 0; itrack < rr_gsb.get_cb_chan_width(cb_type); ++itrack) {
- vtr::Point port_coord(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
- std::string port_name = generate_cb_module_track_port_name(cb_type,
- itrack,
- OUT_PORT);
- BasicPort module_port(port_name, 1); /* Every track has a port size of 1 */
- module_manager.add_port(cb_module, module_port, ModuleManager::MODULE_OUTPUT_PORT);
- }
+ VTR_ASSERT(0 == rr_gsb.get_cb_chan_width(cb_type) % 2);
+
+ /* Upper input port: W/2 == 0 tracks */
+ std::string chan_upper_input_port_name = generate_cb_module_track_port_name(cb_type,
+ IN_PORT,
+ true);
+ BasicPort chan_upper_input_port(chan_upper_input_port_name,
+ rr_gsb.get_cb_chan_width(cb_type) / 2);
+ ModulePortId chan_upper_input_port_id = module_manager.add_port(cb_module,
+ chan_upper_input_port,
+ ModuleManager::MODULE_INPUT_PORT);
+
+ /* Lower input port: W/2 == 1 tracks */
+ std::string chan_lower_input_port_name = generate_cb_module_track_port_name(cb_type,
+ IN_PORT,
+ false);
+ BasicPort chan_lower_input_port(chan_lower_input_port_name,
+ rr_gsb.get_cb_chan_width(cb_type) / 2);
+ ModulePortId chan_lower_input_port_id = module_manager.add_port(cb_module,
+ chan_lower_input_port,
+ ModuleManager::MODULE_INPUT_PORT);
+
+ /* Upper output port: W/2 == 0 tracks */
+ std::string chan_upper_output_port_name = generate_cb_module_track_port_name(cb_type,
+ OUT_PORT,
+ true);
+ BasicPort chan_upper_output_port(chan_upper_output_port_name,
+ rr_gsb.get_cb_chan_width(cb_type) / 2);
+ ModulePortId chan_upper_output_port_id = module_manager.add_port(cb_module,
+ chan_upper_output_port,
+ ModuleManager::MODULE_OUTPUT_PORT);
+
+ /* Lower output port: W/2 == 1 tracks */
+ std::string chan_lower_output_port_name = generate_cb_module_track_port_name(cb_type,
+ OUT_PORT,
+ false);
+ BasicPort chan_lower_output_port(chan_lower_output_port_name,
+ rr_gsb.get_cb_chan_width(cb_type) / 2);
+ ModulePortId chan_lower_output_port_id = module_manager.add_port(cb_module,
+ chan_lower_output_port,
+ ModuleManager::MODULE_OUTPUT_PORT);
/* Add the input pins of grids, which are output ports of the connection block */
std::vector cb_ipin_sides = rr_gsb.get_cb_ipin_sides(cb_type);
@@ -766,45 +801,29 @@ void build_connection_block_module(ModuleManager& module_manager,
}
/* Create a cache (fast look up) for module nets whose source are input ports */
- std::map input_port_to_module_nets;
+ std::map input_port_to_module_nets;
/* Generate short-wire connection for each routing track :
- * Each input port is short-wired to its output port and middle output port
+ * Each input port is short-wired to its output port
*
- * in[i] ----------> out[i]
- * |
- * +-----> mid_out[i]
+ * upper_in[i] ----------> lower_out[i]
+ * lower_in[i] <---------- upper_out[i]
*/
- for (size_t itrack = 0; itrack < rr_gsb.get_cb_chan_width(cb_type); ++itrack) {
- vtr::Point port_coord(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
- /* Create a port description for the input */
- std::string input_port_name = generate_cb_module_track_port_name(cb_type,
- itrack,
- IN_PORT);
- ModulePortId input_port_id = module_manager.find_module_port(cb_module, input_port_name);
- BasicPort input_port = module_manager.module_port(cb_module, input_port_id);
+ /* Create short-wires: input port ---> output port */
+ VTR_ASSERT(chan_upper_input_port.get_width() == chan_lower_output_port.get_width());
+ for (size_t pin_id = 0; pin_id < chan_upper_input_port.pins().size(); ++pin_id) {
+ ModuleNetId net = create_module_source_pin_net(module_manager, cb_module, cb_module, 0, chan_upper_input_port_id, chan_upper_input_port.pins()[pin_id]);
+ module_manager.add_module_net_sink(cb_module, net, cb_module, 0, chan_lower_output_port_id, chan_lower_output_port.pins()[pin_id]);
+ /* Cache the module net */
+ input_port_to_module_nets[ModulePinInfo(chan_upper_input_port_id, chan_upper_input_port.pins()[pin_id])] = net;
+ }
- /* Create a port description for the output */
- std::string output_port_name = generate_cb_module_track_port_name(cb_type,
- itrack,
- OUT_PORT);
- ModulePortId output_port_id = module_manager.find_module_port(cb_module, output_port_name);
- BasicPort output_port = module_manager.module_port(cb_module, output_port_id);
-
- /* Ensure port size matching */
- VTR_ASSERT(1 == input_port.get_width());
- VTR_ASSERT(input_port.get_width() == output_port.get_width());
-
- /* Create short-wires: input port ---> output port
- * Do short-wires: input port ---> middle output port
- */
- for (size_t pin_id = 0; pin_id < input_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(cb_module);
- module_manager.add_module_net_source(cb_module, net, cb_module, 0, input_port_id, input_port.pins()[pin_id]);
- module_manager.add_module_net_sink(cb_module, net, cb_module, 0, output_port_id, output_port.pins()[pin_id]);
- /* Cache the module net */
- input_port_to_module_nets[input_port_id] = net;
- }
+ VTR_ASSERT(chan_lower_input_port.get_width() == chan_upper_output_port.get_width());
+ for (size_t pin_id = 0; pin_id < chan_lower_input_port.pins().size(); ++pin_id) {
+ ModuleNetId net = create_module_source_pin_net(module_manager, cb_module, cb_module, 0, chan_lower_input_port_id, chan_lower_input_port.pins()[pin_id]);
+ module_manager.add_module_net_sink(cb_module, net, cb_module, 0, chan_upper_output_port_id, chan_upper_output_port.pins()[pin_id]);
+ /* Cache the module net */
+ input_port_to_module_nets[ModulePinInfo(chan_lower_input_port_id, chan_lower_input_port.pins()[pin_id])] = net;
}
/* Add sub modules of routing multiplexers or direct interconnect*/
diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp
index 6c2d94a00..edb25941e 100644
--- a/openfpga/src/fabric/build_top_module.cpp
+++ b/openfpga/src/fabric/build_top_module.cpp
@@ -91,6 +91,9 @@ vtr::Matrix add_top_module_grid_instances(ModuleManager& module_manager,
const ModuleId& top_module,
IoLocationMap& io_location_map,
const DeviceGrid& grids) {
+
+ vtr::ScopedStartFinishTimer timer("Add grid instances to top module");
+
/* Reserve an array for the instance ids */
vtr::Matrix grid_instance_ids({grids.width(), grids.height()});
grid_instance_ids.fill(size_t(-1));
@@ -203,6 +206,9 @@ vtr::Matrix add_top_module_switch_block_instances(ModuleManager& module_
const ModuleId& top_module,
const DeviceRRGSB& device_rr_gsb,
const bool& compact_routing_hierarchy) {
+
+ vtr::ScopedStartFinishTimer timer("Add switch block instances to top module");
+
vtr::Point sb_range = device_rr_gsb.get_gsb_range();
/* Reserve an array for the instance ids */
@@ -253,6 +259,9 @@ vtr::Matrix add_top_module_connection_block_instances(ModuleManager& mod
const DeviceRRGSB& device_rr_gsb,
const t_rr_type& cb_type,
const bool& compact_routing_hierarchy) {
+
+ vtr::ScopedStartFinishTimer timer("Add connection block instances to top module");
+
vtr::Point cb_range = device_rr_gsb.get_gsb_range();
/* Reserve an array for the instance ids */
@@ -342,6 +351,9 @@ void build_top_module(ModuleManager& module_manager,
cb_instance_ids[CHANX] = add_top_module_connection_block_instances(module_manager, top_module, device_rr_gsb, CHANX, compact_routing_hierarchy);
cb_instance_ids[CHANY] = add_top_module_connection_block_instances(module_manager, top_module, device_rr_gsb, CHANY, compact_routing_hierarchy);
+ /* Reserve nets to be memory efficient */
+ reserve_module_manager_module_nets(module_manager, top_module);
+
/* Add module nets to connect the sub modules */
add_top_module_nets_connect_grids_and_gsbs(module_manager, top_module,
grids, grid_instance_ids,
diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp
index 629129669..060639136 100644
--- a/openfpga/src/fabric/build_top_module_connection.cpp
+++ b/openfpga/src/fabric/build_top_module_connection.cpp
@@ -4,6 +4,7 @@
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_assert.h"
+#include "vtr_time.h"
/* Headers from openfpgautil library */
#include "openfpga_side_manager.h"
@@ -13,6 +14,7 @@
#include "pb_type_utils.h"
#include "rr_gsb_utils.h"
#include "openfpga_physical_tile_utils.h"
+#include "module_manager_utils.h"
#include "build_top_module_utils.h"
#include "build_top_module_connection.h"
@@ -128,9 +130,7 @@ void add_top_module_nets_connect_grids_and_sb(ModuleManager& module_manager,
/* Create a net for each pin */
for (size_t pin_id = 0; pin_id < src_grid_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(top_module);
- /* Configure the net source */
- module_manager.add_module_net_source(top_module, net, src_grid_module, src_grid_instance, src_grid_port_id, src_grid_port.pins()[pin_id]);
+ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, src_grid_module, src_grid_instance, src_grid_port_id, src_grid_port.pins()[pin_id]);
/* Configure the net sink */
module_manager.add_module_net_sink(top_module, net, sink_sb_module, sink_sb_instance, sink_sb_port_id, sink_sb_port.pins()[pin_id]);
}
@@ -273,9 +273,7 @@ void add_top_module_nets_connect_grids_and_sb_with_duplicated_pins(ModuleManager
/* Create a net for each pin */
for (size_t pin_id = 0; pin_id < src_grid_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(top_module);
- /* Configure the net source */
- module_manager.add_module_net_source(top_module, net, src_grid_module, src_grid_instance, src_grid_port_id, src_grid_port.pins()[pin_id]);
+ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, src_grid_module, src_grid_instance, src_grid_port_id, src_grid_port.pins()[pin_id]);
/* Configure the net sink */
module_manager.add_module_net_sink(top_module, net, sink_sb_module, sink_sb_instance, sink_sb_port_id, sink_sb_port.pins()[pin_id]);
}
@@ -423,9 +421,7 @@ void add_top_module_nets_connect_grids_and_cb(ModuleManager& module_manager,
/* Create a net for each pin */
for (size_t pin_id = 0; pin_id < src_cb_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(top_module);
- /* Configure the net source */
- module_manager.add_module_net_source(top_module, net, src_cb_module, src_cb_instance, src_cb_port_id, src_cb_port.pins()[pin_id]);
+ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, src_cb_module, src_cb_instance, src_cb_port_id, src_cb_port.pins()[pin_id]);
/* Configure the net sink */
module_manager.add_module_net_sink(top_module, net, sink_grid_module, sink_grid_instance, sink_grid_port_id, sink_grid_port.pins()[pin_id]);
}
@@ -559,7 +555,7 @@ void add_top_module_nets_connect_sb_and_cb(ModuleManager& module_manager,
for (size_t itrack = 0; itrack < module_sb.get_chan_width(side_manager.get_side()); ++itrack) {
std::string sb_port_name = generate_sb_module_track_port_name(rr_graph.node_type(module_sb.get_chan_node(side_manager.get_side(), itrack)),
- side_manager.get_side(), itrack,
+ side_manager.get_side(),
module_sb.get_chan_node_direction(side_manager.get_side(), itrack));
/* Prepare SB-related port information */
ModulePortId sb_port_id = module_manager.find_module_port(sb_module_id, sb_port_name);
@@ -574,31 +570,29 @@ void add_top_module_nets_connect_sb_and_cb(ModuleManager& module_manager,
} else {
VTR_ASSERT(IN_PORT == module_sb.get_chan_node_direction(side_manager.get_side(), itrack));
}
+
+ /* Upper CB port is required if the routing tracks are on the top or right sides of
+ * the switch block, which indicated bottom and left sides of the connection blocks
+ */
+ bool use_cb_upper_port = (TOP == side_manager.get_side()) || (RIGHT == side_manager.get_side());
std::string cb_port_name = generate_cb_module_track_port_name(cb_type,
- itrack,
- cb_port_direction);
+ cb_port_direction,
+ use_cb_upper_port);
ModulePortId cb_port_id = module_manager.find_module_port(cb_module_id, cb_port_name);
VTR_ASSERT(true == module_manager.valid_module_port_id(cb_module_id, cb_port_id));
BasicPort cb_port = module_manager.module_port(cb_module_id, cb_port_id);
- /* Source and sink port should match in size */
- VTR_ASSERT(cb_port.get_width() == sb_port.get_width());
-
- /* Create a net for each pin */
- for (size_t pin_id = 0; pin_id < cb_port.pins().size(); ++pin_id) {
- ModuleNetId net = module_manager.create_module_net(top_module);
- /* Configure the net source and sink:
- * If sb port is an output (source), cb port is an input (sink)
- * If sb port is an input (sink), cb port is an output (source)
- */
- if (OUT_PORT == module_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
- module_manager.add_module_net_sink(top_module, net, cb_module_id, cb_instance, cb_port_id, cb_port.pins()[pin_id]);
- module_manager.add_module_net_source(top_module, net, sb_module_id, sb_instance, sb_port_id, sb_port.pins()[pin_id]);
- } else {
- VTR_ASSERT(IN_PORT == module_sb.get_chan_node_direction(side_manager.get_side(), itrack));
- module_manager.add_module_net_source(top_module, net, cb_module_id, cb_instance, cb_port_id, cb_port.pins()[pin_id]);
- module_manager.add_module_net_sink(top_module, net, sb_module_id, sb_instance, sb_port_id, sb_port.pins()[pin_id]);
- }
+ /* Configure the net source and sink:
+ * If sb port is an output (source), cb port is an input (sink)
+ * If sb port is an input (sink), cb port is an output (source)
+ */
+ if (OUT_PORT == module_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
+ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, sb_module_id, sb_instance, sb_port_id, itrack / 2);
+ module_manager.add_module_net_sink(top_module, net, cb_module_id, cb_instance, cb_port_id, itrack / 2);
+ } else {
+ VTR_ASSERT(IN_PORT == module_sb.get_chan_node_direction(side_manager.get_side(), itrack));
+ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, cb_module_id, cb_instance, cb_port_id, itrack / 2);
+ module_manager.add_module_net_sink(top_module, net, sb_module_id, sb_instance, sb_port_id, itrack / 2);
}
}
}
@@ -648,6 +642,8 @@ void add_top_module_nets_connect_grids_and_gsbs(ModuleManager& module_manager,
const bool& compact_routing_hierarchy,
const bool& duplicate_grid_pin) {
+ vtr::ScopedStartFinishTimer timer("Add module nets between grids and GSBs");
+
vtr::Point gsb_range = device_rr_gsb.get_gsb_range();
for (size_t ix = 0; ix < gsb_range.x(); ++ix) {
diff --git a/openfpga/src/fabric/build_top_module_directs.cpp b/openfpga/src/fabric/build_top_module_directs.cpp
index 81f589adb..5f53fdd5b 100644
--- a/openfpga/src/fabric/build_top_module_directs.cpp
+++ b/openfpga/src/fabric/build_top_module_directs.cpp
@@ -8,6 +8,7 @@
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
+#include "vtr_time.h"
/* Headers from openfpgautil library */
#include "openfpga_port.h"
@@ -124,10 +125,10 @@ void add_module_nets_tile_direct_connection(ModuleManager& module_manager,
module_manager.add_module_net_source(top_module, net_direct_src, src_grid_module, src_grid_instance, src_port_id, 0);
module_manager.add_module_net_sink(top_module, net_direct_src, direct_module, direct_instance_id, direct_input_port_id, 0);
- /* Create the 2nd module net */
- ModuleNetId net_direct_sink = module_manager.create_module_net(top_module);
- /* Connect the wire between direct_instance output and sink_pin of clb */
- module_manager.add_module_net_source(top_module, net_direct_sink, direct_module, direct_instance_id, direct_output_port_id, 0);
+ /* Create the 2nd module net
+ * Connect the wire between direct_instance output and sink_pin of clb
+ */
+ ModuleNetId net_direct_sink = create_module_source_pin_net(module_manager, top_module, direct_module, direct_instance_id, direct_output_port_id, 0);
module_manager.add_module_net_sink(top_module, net_direct_sink, sink_grid_module, sink_grid_instance, sink_port_id, 0);
}
@@ -145,6 +146,8 @@ void add_top_module_nets_tile_direct_connections(ModuleManager& module_manager,
const TileDirect& tile_direct,
const ArchDirect& arch_direct) {
+ vtr::ScopedStartFinishTimer timer("Add module nets for inter-tile connections");
+
for (const TileDirectId& tile_direct_id : tile_direct.directs()) {
add_module_nets_tile_direct_connection(module_manager, top_module, circuit_lib,
grids, grid_instance_ids,
diff --git a/openfpga/src/fabric/build_top_module_memory.cpp b/openfpga/src/fabric/build_top_module_memory.cpp
index 158a0f44a..219426c79 100644
--- a/openfpga/src/fabric/build_top_module_memory.cpp
+++ b/openfpga/src/fabric/build_top_module_memory.cpp
@@ -7,6 +7,7 @@
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
+#include "vtr_time.h"
/* Headers from vpr library */
#include "vpr_utils.h"
@@ -429,6 +430,11 @@ int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager
/* Find if instance id is valid */
size_t child_instance = fabric_key.key_value(key);
+ /* If we have alias, we try to find a instance in this name */
+ if (!fabric_key.key_alias(key).empty()) {
+ child_instance = module_manager.instance_id(top_module, child_module, fabric_key.key_alias(key));
+ }
+
if (child_instance >= module_manager.num_instance(top_module, child_module)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid key value '%ld'!\n",
@@ -906,6 +912,9 @@ void add_top_module_nets_memory_config_bus(ModuleManager& module_manager,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_design_tech& mem_tech,
const size_t& num_config_bits) {
+
+ vtr::ScopedStartFinishTimer timer("Add module nets for configuration buses");
+
switch (mem_tech) {
case CIRCUIT_MODEL_DESIGN_CMOS:
add_top_module_nets_cmos_memory_config_bus(module_manager, decoder_lib,
diff --git a/openfpga/src/fabric/fabric_key_writer.cpp b/openfpga/src/fabric/fabric_key_writer.cpp
index 40770965f..1af6d77fd 100644
--- a/openfpga/src/fabric/fabric_key_writer.cpp
+++ b/openfpga/src/fabric/fabric_key_writer.cpp
@@ -65,6 +65,10 @@ int write_fabric_key_to_xml_file(const ModuleManager& module_manager,
FabricKeyId key = fabric_key.create_key();
fabric_key.set_key_name(key, module_manager.module_name(child_module));
fabric_key.set_key_value(key, child_instance);
+
+ if (false == module_manager.instance_name(top_module, child_module, child_instance).empty()) {
+ fabric_key.set_key_alias(key, module_manager.instance_name(top_module, child_module, child_instance));
+ }
}
VTR_LOGV(verbose,
diff --git a/openfpga/src/fabric/module_manager.cpp b/openfpga/src/fabric/module_manager.cpp
index 3f5cfdbfb..371c07608 100644
--- a/openfpga/src/fabric/module_manager.cpp
+++ b/openfpga/src/fabric/module_manager.cpp
@@ -35,7 +35,8 @@ ModuleManager::module_port_range ModuleManager::module_ports(const ModuleId& mod
ModuleManager::module_net_range ModuleManager::module_nets(const ModuleId& module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module));
- return vtr::make_range(net_ids_[module].begin(), net_ids_[module].end());
+ return vtr::make_range(module_net_iterator(ModuleNetId(0), invalid_net_ids_[module]),
+ module_net_iterator(ModuleNetId(num_nets_[module]), invalid_net_ids_[module]));
}
/* Find all the child modules under a parent module */
@@ -108,7 +109,7 @@ size_t ModuleManager::num_modules() const {
size_t ModuleManager::num_nets(const ModuleId& module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module));
- return net_ids_[module].size();
+ return num_nets_[module];
}
/* Find the name of a module */
@@ -302,7 +303,13 @@ vtr::vector ModuleManager::net_source_modules(const Mo
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
- return net_src_module_ids_[module][net];
+ vtr::vector src_modules;
+ src_modules.reserve(net_src_terminal_ids_[module][net].size());
+ for (const size_t& id : net_src_terminal_ids_[module][net]) {
+ src_modules.push_back(net_terminal_storage_[id].first);
+ }
+
+ return src_modules;
}
/* Find the ids of source instances of a net */
@@ -318,7 +325,13 @@ vtr::vector ModuleManager::net_source_ports(const
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
- return net_src_port_ids_[module][net];
+ vtr::vector src_ports;
+ src_ports.reserve(net_src_terminal_ids_[module][net].size());
+ for (const size_t& id : net_src_terminal_ids_[module][net]) {
+ src_ports.push_back(net_terminal_storage_[id].second);
+ }
+
+ return src_ports;
}
/* Find the source pin indices of a net */
@@ -341,9 +354,9 @@ bool ModuleManager::net_source_exist(const ModuleId& module, const ModuleNetId&
* we can say that the source has already been added to this net!
*/
for (const ModuleNetSrcId& net_src : module_net_sources(module, net)) {
- if ( (src_module == net_source_modules(module, net)[net_src])
+ if ( (src_module == net_terminal_storage_[net_src_terminal_ids_[module][net][net_src]].first)
&& (instance_id == net_source_instances(module, net)[net_src])
- && (src_port == net_source_ports(module, net)[net_src])
+ && (src_port == net_terminal_storage_[net_src_terminal_ids_[module][net][net_src]].second)
&& (src_pin == net_source_pins(module, net)[net_src]) ) {
return true;
}
@@ -358,7 +371,13 @@ vtr::vector ModuleManager::net_sink_modules(const Mod
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
- return net_sink_module_ids_[module][net];
+ vtr::vector sink_modules;
+ sink_modules.reserve(net_sink_terminal_ids_[module][net].size());
+ for (const size_t& id : net_sink_terminal_ids_[module][net]) {
+ sink_modules.push_back(net_terminal_storage_[id].first);
+ }
+
+ return sink_modules;
}
/* Find the ids of sink instances of a net */
@@ -374,7 +393,13 @@ vtr::vector ModuleManager::net_sink_ports(const M
/* Validate module net */
VTR_ASSERT(valid_module_net_id(module, net));
- return net_sink_port_ids_[module][net];
+ vtr::vector sink_ports;
+ sink_ports.reserve(net_sink_terminal_ids_[module][net].size());
+ for (const size_t& id : net_sink_terminal_ids_[module][net]) {
+ sink_ports.push_back(net_terminal_storage_[id].second);
+ }
+
+ return sink_ports;
}
/* Find the sink pin indices of a net */
@@ -397,9 +422,9 @@ bool ModuleManager::net_sink_exist(const ModuleId& module, const ModuleNetId& ne
* we can say that the sink has already been added to this net!
*/
for (const ModuleNetSinkId& net_sink : module_net_sinks(module, net)) {
- if ( (sink_module == net_sink_modules(module, net)[net_sink])
+ if ( (sink_module == net_terminal_storage_[net_sink_terminal_ids_[module][net][net_sink]].first)
&& (instance_id == net_sink_instances(module, net)[net_sink])
- && (sink_port == net_sink_ports(module, net)[net_sink])
+ && (sink_port == net_terminal_storage_[net_sink_terminal_ids_[module][net][net_sink]].second)
&& (sink_pin == net_sink_pins(module, net)[net_sink]) ) {
return true;
}
@@ -458,18 +483,17 @@ ModuleId ModuleManager::add_module(const std::string& name) {
port_is_register_.emplace_back();
port_preproc_flags_.emplace_back();
- net_ids_.emplace_back();
+ num_nets_.emplace_back(0);
+ invalid_net_ids_.emplace_back();
net_names_.emplace_back();
net_src_ids_.emplace_back();
- net_src_module_ids_.emplace_back();
+ net_src_terminal_ids_.emplace_back();
net_src_instance_ids_.emplace_back();
- net_src_port_ids_.emplace_back();
net_src_pin_ids_.emplace_back();
net_sink_ids_.emplace_back();
- net_sink_module_ids_.emplace_back();
+ net_sink_terminal_ids_.emplace_back();
net_sink_instance_ids_.emplace_back();
- net_sink_port_ids_.emplace_back();
net_sink_pin_ids_.emplace_back();
/* Register in the name-to-id map */
@@ -638,29 +662,50 @@ void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
}
}
+void ModuleManager::reserve_module_nets(const ModuleId& module,
+ const size_t& num_nets) {
+ /* Validate the module id */
+ VTR_ASSERT ( valid_module_id(module) );
+
+ net_names_[module].reserve(num_nets);
+ net_src_ids_[module].reserve(num_nets);
+ net_src_terminal_ids_[module].reserve(num_nets);
+ net_src_instance_ids_[module].reserve(num_nets);
+ net_src_pin_ids_[module].reserve(num_nets);
+
+ net_sink_ids_[module].reserve(num_nets);
+ net_sink_terminal_ids_[module].reserve(num_nets);
+ net_sink_instance_ids_[module].reserve(num_nets);
+ net_sink_pin_ids_[module].reserve(num_nets);
+}
+
/* Add a net to the connection graph of the module */
ModuleNetId ModuleManager::create_module_net(const ModuleId& module) {
/* Validate the module id */
VTR_ASSERT ( valid_module_id(module) );
/* Create an new id */
- ModuleNetId net = ModuleNetId(net_ids_[module].size());
- net_ids_[module].push_back(net);
+ ModuleNetId net = ModuleNetId(num_nets_[module]);
+ num_nets_[module]++;
/* Allocate net-related data structures */
net_names_[module].emplace_back();
net_src_ids_[module].emplace_back();
- net_src_module_ids_[module].emplace_back();
+ net_src_terminal_ids_[module].emplace_back();
net_src_instance_ids_[module].emplace_back();
- net_src_port_ids_[module].emplace_back();
net_src_pin_ids_[module].emplace_back();
+ /* Reserve a source */
+ reserve_module_net_sources(module, net, 1);
+
net_sink_ids_[module].emplace_back();
- net_sink_module_ids_[module].emplace_back();
+ net_sink_terminal_ids_[module].emplace_back();
net_sink_instance_ids_[module].emplace_back();
- net_sink_port_ids_[module].emplace_back();
net_sink_pin_ids_[module].emplace_back();
+ /* Reserve a source */
+ reserve_module_net_sinks(module, net, 1);
+
return net;
}
@@ -673,6 +718,17 @@ void ModuleManager::set_net_name(const ModuleId& module, const ModuleNetId& net,
net_names_[module][net] = name;
}
+void ModuleManager::reserve_module_net_sources(const ModuleId& module, const ModuleNetId& net,
+ const size_t& num_sources) {
+ /* Validate module net */
+ VTR_ASSERT(valid_module_net_id(module, net));
+
+ net_src_ids_[module][net].reserve(num_sources);
+ net_src_terminal_ids_[module][net].reserve(num_sources);
+ net_src_instance_ids_[module][net].reserve(num_sources);
+ net_src_pin_ids_[module][net].reserve(num_sources);
+}
+
/* Add a source to a net in the connection graph */
ModuleNetSrcId ModuleManager::add_module_net_source(const ModuleId& module, const ModuleNetId& net,
const ModuleId& src_module, const size_t& instance_id,
@@ -686,7 +742,25 @@ ModuleNetSrcId ModuleManager::add_module_net_source(const ModuleId& module, cons
/* Validate the source module */
VTR_ASSERT(valid_module_id(src_module));
- net_src_module_ids_[module][net].push_back(src_module);
+
+ /* Validate the port exists in the src module */
+ VTR_ASSERT(valid_module_port_id(src_module, src_port));
+
+ /* Create pair of module and port
+ * Search in the storage. If found, use the existing pair
+ * Otherwise, add the pair
+ */
+ std::pair terminal(src_module, src_port);
+ std::vector>::iterator it = std::find(net_terminal_storage_.begin(),
+ net_terminal_storage_.end(),
+ terminal);
+ if (it == net_terminal_storage_.end()) {
+ net_src_terminal_ids_[module][net].push_back(net_terminal_storage_.size());
+ net_terminal_storage_.push_back(terminal);
+ } else {
+ VTR_ASSERT_SAFE(it != net_terminal_storage_.end());
+ net_src_terminal_ids_[module][net].push_back(std::distance(net_terminal_storage_.begin(), it));
+ }
/* if it has the same id as module, our instance id will be by default 0 */
size_t src_instance_id = instance_id;
@@ -699,10 +773,6 @@ ModuleNetSrcId ModuleManager::add_module_net_source(const ModuleId& module, cons
net_src_instance_ids_[module][net].push_back(src_instance_id);
}
- /* Validate the port exists in the src module */
- VTR_ASSERT(valid_module_port_id(src_module, src_port));
- net_src_port_ids_[module][net].push_back(src_port);
-
/* Validate the pin id is in the range of the port width */
VTR_ASSERT(src_pin < module_port(src_module, src_port).get_width());
net_src_pin_ids_[module][net].push_back(src_pin);
@@ -713,6 +783,17 @@ ModuleNetSrcId ModuleManager::add_module_net_source(const ModuleId& module, cons
return net_src;
}
+void ModuleManager::reserve_module_net_sinks(const ModuleId& module, const ModuleNetId& net,
+ const size_t& num_sinks) {
+ /* Validate module net */
+ VTR_ASSERT(valid_module_net_id(module, net));
+
+ net_sink_ids_[module][net].reserve(num_sinks);
+ net_sink_terminal_ids_[module][net].reserve(num_sinks);
+ net_sink_instance_ids_[module][net].reserve(num_sinks);
+ net_sink_pin_ids_[module][net].reserve(num_sinks);
+}
+
/* Add a sink to a net in the connection graph */
ModuleNetSinkId ModuleManager::add_module_net_sink(const ModuleId& module, const ModuleNetId& net,
const ModuleId& sink_module, const size_t& instance_id,
@@ -726,7 +807,25 @@ ModuleNetSinkId ModuleManager::add_module_net_sink(const ModuleId& module, const
/* Validate the source module */
VTR_ASSERT(valid_module_id(sink_module));
- net_sink_module_ids_[module][net].push_back(sink_module);
+
+ /* Validate the port exists in the sink module */
+ VTR_ASSERT(valid_module_port_id(sink_module, sink_port));
+
+ /* Create pair of module and port
+ * Search in the storage. If found, use the existing pair
+ * Otherwise, add the pair
+ */
+ std::pair terminal(sink_module, sink_port);
+ std::vector>::iterator it = std::find(net_terminal_storage_.begin(),
+ net_terminal_storage_.end(),
+ terminal);
+ if (it == net_terminal_storage_.end()) {
+ net_sink_terminal_ids_[module][net].push_back(net_terminal_storage_.size());
+ net_terminal_storage_.push_back(terminal);
+ } else {
+ VTR_ASSERT_SAFE(it != net_terminal_storage_.end());
+ net_sink_terminal_ids_[module][net].push_back(std::distance(net_terminal_storage_.begin(), it));
+ }
/* if it has the same id as module, our instance id will be by default 0 */
size_t sink_instance_id = instance_id;
@@ -739,10 +838,6 @@ ModuleNetSinkId ModuleManager::add_module_net_sink(const ModuleId& module, const
net_sink_instance_ids_[module][net].push_back(sink_instance_id);
}
- /* Validate the port exists in the sink module */
- VTR_ASSERT(valid_module_port_id(sink_module, sink_port));
- net_sink_port_ids_[module][net].push_back(sink_port);
-
/* Validate the pin id is in the range of the port width */
VTR_ASSERT(sink_pin < module_port(sink_module, sink_port).get_width());
net_sink_pin_ids_[module][net].push_back(sink_pin);
@@ -781,7 +876,7 @@ bool ModuleManager::valid_module_net_id(const ModuleId& module, const ModuleNetI
if (false == valid_module_id(module)) {
return false;
}
- return ( size_t(net) < net_ids_[module].size() ) && ( net == net_ids_[module][net] );
+ return ( size_t(net) < num_nets_[module] );
}
void ModuleManager::invalidate_name2id_map() {
diff --git a/openfpga/src/fabric/module_manager.h b/openfpga/src/fabric/module_manager.h
index ee06f1415..3cd0c9635 100644
--- a/openfpga/src/fabric/module_manager.h
+++ b/openfpga/src/fabric/module_manager.h
@@ -3,6 +3,10 @@
#include
#include