adapt SB module builder to use bus ports

This commit is contained in:
tangxifan 2020-06-30 16:02:40 -06:00
parent f023652ac4
commit 2ef083c49d
11 changed files with 172 additions and 133 deletions

View File

@ -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, std::string generate_sb_module_track_port_name(const t_rr_type& chan_type,
const e_side& module_side, const e_side& module_side,
const size_t& track_id,
const PORTS& port_direction) { const PORTS& port_direction) {
/* Channel must be either CHANX or CHANY */ /* Channel must be either CHANX or CHANY */
VTR_ASSERT( (CHANX == chan_type) || (CHANY == chan_type) ); 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) { switch (port_direction) {
case OUT_PORT: case OUT_PORT:
port_name += std::string("out_"); port_name += std::string("out");
break; break;
case IN_PORT: case IN_PORT:
port_name += std::string("in_"); port_name += std::string("in");
break; break;
default: default:
VTR_LOG_ERROR("Invalid direction of chan_rr_node!\n"); VTR_LOG_ERROR("Invalid direction of chan_rr_node!\n");
exit(1); exit(1);
} }
/* Add the track id to the port name */
port_name += std::to_string(track_id) + std::string("_");
return port_name; return port_name;
} }

View File

@ -91,7 +91,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, std::string generate_sb_module_track_port_name(const t_rr_type& chan_type,
const e_side& module_side, const e_side& module_side,
const size_t& track_id,
const PORTS& port_direction); const PORTS& port_direction);
std::string generate_cb_module_track_port_name(const t_rr_type& chan_type, std::string generate_cb_module_track_port_name(const t_rr_type& chan_type,

View File

@ -18,28 +18,29 @@
namespace openfpga { 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, std::pair<ModulePortId, size_t> find_switch_block_module_chan_port(const ModuleManager& module_manager,
const ModuleId& sb_module, const ModuleId& sb_module,
const RRGraph& rr_graph, const RRGraph& rr_graph,
const RRGSB& rr_gsb, const RRGSB& rr_gsb,
const e_side& chan_side, const e_side& chan_side,
const RRNodeId& cur_rr_node, const RRNodeId& cur_rr_node,
const PORTS& cur_rr_node_direction) { const PORTS& cur_rr_node_direction) {
/* Get the index in sb_info of cur_rr_node */ /* 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); 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 */ /* Make sure this node is included in this sb_info */
VTR_ASSERT((-1 != index) && (NUM_SIDES != chan_side)); 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)), 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)); rr_gsb.get_chan_node_direction(chan_side, index));
/* Must find a valid port id in the Switch Block module */ /* 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); 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)); VTR_ASSERT(true == module_manager.valid_module_port_id(sb_module, chan_port_id));
return chan_port_id; return std::pair<ModulePortId, size_t>(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 * 2. When the input is a routing track, the input_side should be
* the side of the node locating on the switch block * the side of the node locating on the switch block
********************************************************************/ ********************************************************************/
ModulePortId find_switch_block_module_input_port(const ModuleManager& module_manager, std::pair<ModulePortId, size_t> find_switch_block_module_input_port(const ModuleManager& module_manager,
const ModuleId& sb_module, const ModuleId& sb_module,
const RRGraph& rr_graph, const RRGraph& rr_graph,
const RRGSB& rr_gsb, const RRGSB& rr_gsb,
const e_side& input_side, const e_side& input_side,
const RRNodeId& input_rr_node) { const RRNodeId& input_rr_node) {
/* Deposit an invalid value */ /* Deposit an invalid value */
ModulePortId input_port_id = ModulePortId::INVALID(); std::pair<ModulePortId, size_t> input_port(ModulePortId::INVALID(), 0);
/* Generate the input port object */ /* Generate the input port object */
switch (rr_graph.node_type(input_rr_node)) { switch (rr_graph.node_type(input_rr_node)) {
/* case SOURCE: */ /* case SOURCE: */
@ -85,14 +86,14 @@ ModulePortId find_switch_block_module_input_port(const ModuleManager& module_man
grid_pin_side, grid_pin_side,
rr_graph.node_pin_num(input_rr_node)); rr_graph.node_pin_num(input_rr_node));
/* Must find a valid port id in the Switch Block module */ /* Must find a valid port id in the Switch Block module */
input_port_id = module_manager.find_module_port(sb_module, input_port_name); 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_id)); VTR_ASSERT(true == module_manager.valid_module_port_id(sb_module, input_port.first));
break; break;
} }
case CHANX: case CHANX:
case CHANY: { case CHANY: {
input_port_id = find_switch_block_module_chan_port(module_manager, sb_module, rr_graph, input_port = find_switch_block_module_chan_port(module_manager, sb_module, rr_graph,
rr_gsb, input_side, input_rr_node, IN_PORT); rr_gsb, input_side, input_rr_node, IN_PORT);
break; break;
} }
default: /* SOURCE, IPIN, SINK are invalid*/ default: /* SOURCE, IPIN, SINK are invalid*/
@ -100,18 +101,18 @@ ModulePortId find_switch_block_module_input_port(const ModuleManager& module_man
exit(1); exit(1);
} }
return input_port_id; return input_port;
} }
/********************************************************************* /*********************************************************************
* Generate a list of input ports for routing multiplexer inside the switch block * Generate a list of input ports for routing multiplexer inside the switch block
********************************************************************/ ********************************************************************/
std::vector<ModulePortId> find_switch_block_module_input_ports(const ModuleManager& module_manager, std::vector<std::pair<ModulePortId, size_t>> find_switch_block_module_input_ports(const ModuleManager& module_manager,
const ModuleId& sb_module, const ModuleId& sb_module,
const RRGraph& rr_graph, const RRGraph& rr_graph,
const RRGSB& rr_gsb, const RRGSB& rr_gsb,
const std::vector<RRNodeId>& input_rr_nodes) { const std::vector<RRNodeId>& input_rr_nodes) {
std::vector<ModulePortId> input_ports; std::vector<std::pair<ModulePortId, size_t>> input_ports;
for (const RRNodeId& input_rr_node : input_rr_nodes) { for (const RRNodeId& input_rr_node : input_rr_nodes) {
/* Find the side where the input locates in the Switch Block */ /* Find the side where the input locates in the Switch Block */

View File

@ -6,6 +6,7 @@
*******************************************************************/ *******************************************************************/
#include <vector> #include <vector>
#include <tuple>
#include "rr_gsb.h" #include "rr_gsb.h"
#include "module_manager.h" #include "module_manager.h"
#include "vpr_types.h" #include "vpr_types.h"
@ -17,26 +18,26 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
ModulePortId find_switch_block_module_chan_port(const ModuleManager& module_manager, std::pair<ModulePortId, size_t> find_switch_block_module_chan_port(const ModuleManager& module_manager,
const ModuleId& sb_module, const ModuleId& sb_module,
const RRGraph& rr_graph, const RRGraph& rr_graph,
const RRGSB& rr_gsb, const RRGSB& rr_gsb,
const e_side& chan_side, const e_side& chan_side,
const RRNodeId& cur_rr_node, const RRNodeId& cur_rr_node,
const PORTS& cur_rr_node_direction); const PORTS& cur_rr_node_direction);
ModulePortId find_switch_block_module_input_port(const ModuleManager& module_manager, std::pair<ModulePortId, size_t> find_switch_block_module_input_port(const ModuleManager& module_manager,
const ModuleId& sb_module, const ModuleId& sb_module,
const RRGraph& rr_graph, const RRGraph& rr_graph,
const RRGSB& rr_gsb, const RRGSB& rr_gsb,
const e_side& input_side, const e_side& input_side,
const RRNodeId& input_rr_node); const RRNodeId& input_rr_node);
std::vector<ModulePortId> find_switch_block_module_input_ports(const ModuleManager& module_manager, std::vector<std::pair<ModulePortId, size_t>> find_switch_block_module_input_ports(const ModuleManager& module_manager,
const ModuleId& sb_module, const ModuleId& sb_module,
const RRGraph& rr_graph, const RRGraph& rr_graph,
const RRGSB& rr_gsb, const RRGSB& rr_gsb,
const std::vector<RRNodeId>& input_rr_nodes); const std::vector<RRNodeId>& input_rr_nodes);
ModulePortId find_connection_block_module_chan_port(const ModuleManager& module_manager, ModulePortId find_connection_block_module_chan_port(const ModuleManager& module_manager,
const ModuleId& cb_module, const ModuleId& cb_module,

View File

@ -47,11 +47,11 @@ void build_switch_block_module_short_interc(ModuleManager& module_manager,
const e_side& chan_side, const e_side& chan_side,
const RRNodeId& cur_rr_node, const RRNodeId& cur_rr_node,
const RRNodeId& drive_rr_node, const RRNodeId& drive_rr_node,
const std::map<ModulePortId, ModuleNetId>& input_port_to_module_nets) { const std::map<ModulePortId, std::vector<ModuleNetId>>& input_port_to_module_nets) {
/* Find the name of output port */ /* Find the name of output port */
ModulePortId output_port_id = find_switch_block_module_chan_port(module_manager, sb_module, std::pair<ModulePortId, size_t> output_port_info = find_switch_block_module_chan_port(module_manager, sb_module,
rr_graph, rr_gsb, rr_graph, rr_gsb,
chan_side, cur_rr_node, OUT_PORT); chan_side, cur_rr_node, OUT_PORT);
enum e_side input_pin_side = chan_side; enum e_side input_pin_side = chan_side;
int index = -1; int index = -1;
@ -81,20 +81,17 @@ void build_switch_block_module_short_interc(ModuleManager& module_manager,
exit(1); exit(1);
} }
/* Find the name of input port */ /* 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); std::pair<ModulePortId, size_t> 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 */ /* The input port and output port must match in size */
BasicPort input_port = module_manager.module_port(sb_module, input_port_id); BasicPort input_port = module_manager.module_port(sb_module, input_port_info.first);
BasicPort output_port = module_manager.module_port(sb_module, output_port_id); BasicPort output_port = module_manager.module_port(sb_module, output_port_info.first);
VTR_ASSERT(input_port.get_width() == output_port.get_width());
/* Create a module net for this short-wire connection */ /* 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_info.first)[input_port_info.second];
ModuleNetId net = input_port_to_module_nets.at(input_port_id); /* Skip Configuring the net source, it is done before */
/* Skip Configuring the net source, it is done before */ /* Configure the net sink */
/* Configure the net sink */ module_manager.add_module_net_sink(sb_module, net, sb_module, 0, output_port_info.first, output_port_info.second);
module_manager.add_module_net_sink(sb_module, net, sb_module, 0, output_port_id, output_port.pins()[pin_id]);
}
} }
/********************************************************************* /*********************************************************************
@ -113,7 +110,7 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
const RRNodeId& cur_rr_node, const RRNodeId& cur_rr_node,
const std::vector<RRNodeId>& driver_rr_nodes, const std::vector<RRNodeId>& driver_rr_nodes,
const RRSwitchId& switch_index, const RRSwitchId& switch_index,
const std::map<ModulePortId, ModuleNetId>& input_port_to_module_nets) { const std::map<ModulePortId, std::vector<ModuleNetId>>& input_port_to_module_nets) {
/* Check current rr_node is CHANX or CHANY*/ /* 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))); 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); 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 */ /* Generate input ports that are wired to the input bus of the routing multiplexer */
std::vector<ModulePortId> sb_input_port_ids = find_switch_block_module_input_ports(module_manager, sb_module, rr_graph, rr_gsb, driver_rr_nodes); std::vector<std::pair<ModulePortId, size_t>> 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 */ /* Link input bus port to Switch Block inputs */
std::vector<CircuitPortId> mux_model_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); std::vector<CircuitPortId> mux_model_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true);
@ -154,10 +151,10 @@ void build_switch_block_mux_module(ModuleManager& module_manager,
VTR_ASSERT(mux_input_port.get_width() == sb_input_port_ids.size()); VTR_ASSERT(mux_input_port.get_width() == sb_input_port_ids.size());
for (size_t pin_id = 0; pin_id < sb_input_port_ids.size(); ++pin_id) { for (size_t pin_id = 0; pin_id < sb_input_port_ids.size(); ++pin_id) {
/* Use the exising net */ /* Use the exising net */
ModuleNetId net = input_port_to_module_nets.at(sb_input_port_ids[pin_id]); ModuleNetId net = input_port_to_module_nets.at(sb_input_port_ids[pin_id].first)[sb_input_port_ids[pin_id].second];
/* Configure the net source only if it is not yet in the source list */ /* 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)) { 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], 0); 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 */ /* 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]); 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])); 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)); 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); 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); std::pair<ModulePortId, size_t> 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); BasicPort sb_output_port = module_manager.module_port(sb_module, sb_output_port_id.first);
/* Check port size should match */ /* 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) { 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 */ /* 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 */ /* 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 */ /* Instanciate memory modules */
@ -220,7 +216,7 @@ void build_switch_block_interc_modules(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const e_side& chan_side, const e_side& chan_side,
const size_t& chan_node_id, const size_t& chan_node_id,
const std::map<ModulePortId, ModuleNetId>& input_port_to_module_nets) { const std::map<ModulePortId, std::vector<ModuleNetId>>& input_port_to_module_nets) {
std::vector<RRNodeId> driver_rr_nodes; std::vector<RRNodeId> driver_rr_nodes;
/* Get the node */ /* Get the node */
@ -346,30 +342,24 @@ void build_switch_block_module(ModuleManager& module_manager,
generate_switch_block_module_name(gsb_coordinate).c_str()); generate_switch_block_module_name(gsb_coordinate).c_str());
/* Create a cache (fast look up) for module nets whose source are input ports */ /* Create a cache (fast look up) for module nets whose source are input ports */
std::map<ModulePortId, ModuleNetId> input_port_to_module_nets; std::map<ModulePortId, std::vector<ModuleNetId>> input_port_to_module_nets;
/* Add routing channel ports at each side of the GSB */ /* Add routing channel ports at each side of the GSB */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) { for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
SideManager side_manager(side); SideManager side_manager(side);
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) { /* Count input and output port sizes */
std::string port_name = generate_sb_module_track_port_name(rr_graph.node_type(rr_gsb.get_chan_node(side_manager.get_side(), itrack)), size_t chan_input_port_size = 0;
side_manager.get_side(), itrack, size_t chan_output_port_size = 0;
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 */
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)) { switch (rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
case OUT_PORT: case OUT_PORT:
module_manager.add_port(sb_module, module_port, ModuleManager::MODULE_OUTPUT_PORT); chan_output_port_size++;
break; break;
case IN_PORT: { case IN_PORT:
ModulePortId input_port_id = module_manager.add_port(sb_module, module_port, ModuleManager::MODULE_INPUT_PORT); chan_input_port_size++;
/* 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;
break; break;
}
default: default:
VTR_LOGF_ERROR(__FILE__, __LINE__, VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid direction of chan[%d][%d]_track[%d]!\n", "Invalid direction of chan[%d][%d]_track[%d]!\n",
@ -377,6 +367,31 @@ void build_switch_block_module(ModuleManager& module_manager,
exit(1); 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 */
input_port_to_module_nets[chan_input_port_id].reserve(chan_input_port_size);
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[chan_input_port_id].push_back(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 */ /* Dump OPINs of adjacent CLBs */
for (size_t inode = 0; inode < rr_gsb.get_num_opin_nodes(side_manager.get_side()); ++inode) { for (size_t inode = 0; inode < rr_gsb.get_num_opin_nodes(side_manager.get_side()); ++inode) {
vtr::Point<size_t> port_coord(rr_graph.node_xlow(rr_gsb.get_opin_node(side_manager.get_side(), inode)), vtr::Point<size_t> port_coord(rr_graph.node_xlow(rr_gsb.get_opin_node(side_manager.get_side(), inode)),
@ -389,9 +404,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); ModulePortId input_port_id = module_manager.add_port(sb_module, module_port, ModuleManager::MODULE_INPUT_PORT);
/* Cache the input net */ /* Cache the input net */
ModuleNetId net = module_manager.create_module_net(sb_module); ModuleNetId net = create_module_source_pin_net(module_manager, sb_module, sb_module, 0, input_port_id, 0);
module_manager.add_module_net_source(sb_module, net, sb_module, 0, input_port_id, 0); input_port_to_module_nets[input_port_id].push_back(net);
input_port_to_module_nets[input_port_id] = net;
} }
} }
@ -399,7 +413,7 @@ void build_switch_block_module(ModuleManager& module_manager,
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) { for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
SideManager side_manager(side); SideManager side_manager(side);
for (size_t itrack = 0; itrack < rr_gsb.get_chan_width(side_manager.get_side()); ++itrack) { 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)) { if (OUT_PORT == rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
build_switch_block_interc_modules(module_manager, build_switch_block_interc_modules(module_manager,
sb_module, device_annotation, rr_graph, rr_gsb, sb_module, device_annotation, rr_graph, rr_gsb,

View File

@ -555,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) { 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)), 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)); module_sb.get_chan_node_direction(side_manager.get_side(), itrack));
/* Prepare SB-related port information */ /* Prepare SB-related port information */
ModulePortId sb_port_id = module_manager.find_module_port(sb_module_id, sb_port_name); ModulePortId sb_port_id = module_manager.find_module_port(sb_module_id, sb_port_name);
@ -578,7 +578,7 @@ void add_top_module_nets_connect_sb_and_cb(ModuleManager& module_manager,
BasicPort cb_port = module_manager.module_port(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 */ /* Source and sink port should match in size */
VTR_ASSERT(cb_port.get_width() == sb_port.get_width()); VTR_ASSERT(1 == cb_port.get_width());
/* Create a net for each pin */ /* Create a net for each pin */
for (size_t pin_id = 0; pin_id < cb_port.pins().size(); ++pin_id) { for (size_t pin_id = 0; pin_id < cb_port.pins().size(); ++pin_id) {
@ -587,12 +587,12 @@ void add_top_module_nets_connect_sb_and_cb(ModuleManager& module_manager,
* If sb port is an input (sink), cb port is an output (source) * 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)) { 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, sb_port.pins()[pin_id]); 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, cb_port.pins()[pin_id]); module_manager.add_module_net_sink(top_module, net, cb_module_id, cb_instance, cb_port_id, cb_port.pins()[pin_id]);
} else { } else {
VTR_ASSERT(IN_PORT == module_sb.get_chan_node_direction(side_manager.get_side(), itrack)); 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, cb_port.pins()[pin_id]); ModuleNetId net = create_module_source_pin_net(module_manager, top_module, 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]); module_manager.add_module_net_sink(top_module, net, sb_module_id, sb_instance, sb_port_id, itrack / 2);
} }
} }
} }

View File

@ -319,7 +319,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp,
const RRNodeId& chan_node = rr_gsb.get_chan_node(side_manager.get_side(), itrack); const RRNodeId& chan_node = rr_gsb.get_chan_node(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)), 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, side_manager.get_side(),
rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)); rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack));
if (true == compact_routing_hierarchy) { if (true == compact_routing_hierarchy) {
@ -327,7 +327,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp,
vtr::Point<size_t> sb_coord(rr_gsb.get_x(), rr_gsb.get_y()); vtr::Point<size_t> sb_coord(rr_gsb.get_x(), rr_gsb.get_y());
const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(sb_coord); const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(sb_coord);
port_name = generate_sb_module_track_port_name(rr_graph.node_type(unique_mirror.get_chan_node(side_manager.get_side(), itrack)), port_name = generate_sb_module_track_port_name(rr_graph.node_type(unique_mirror.get_chan_node(side_manager.get_side(), itrack)),
side_manager.get_side(), itrack, side_manager.get_side(),
unique_mirror.get_chan_node_direction(side_manager.get_side(), itrack)); unique_mirror.get_chan_node_direction(side_manager.get_side(), itrack));
} }
@ -347,9 +347,12 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp,
continue; continue;
} }
BasicPort sb_port(module_manager.module_port(sb_module, module_port).get_name(),
itrack / 2, itrack / 2);
fp << "set_disable_timing "; fp << "set_disable_timing ";
fp << sb_instance_name << "/"; fp << sb_instance_name << "/";
fp << generate_sdc_port(module_manager.module_port(sb_module, module_port)); fp << generate_sdc_port(sb_port);
fp << std::endl; fp << std::endl;
} }
} }
@ -467,7 +470,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp,
const RRNodeId& chan_node = rr_gsb.get_chan_node(side_manager.get_side(), itrack); const RRNodeId& chan_node = rr_gsb.get_chan_node(side_manager.get_side(), itrack);
std::string port_name = generate_sb_module_track_port_name(rr_graph.node_type(chan_node), std::string port_name = generate_sb_module_track_port_name(rr_graph.node_type(chan_node),
side_manager.get_side(), itrack, side_manager.get_side(),
rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)); rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack));
if (true == compact_routing_hierarchy) { if (true == compact_routing_hierarchy) {
@ -477,7 +480,7 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp,
const RRNodeId& unique_mirror_chan_node = unique_mirror.get_chan_node(side_manager.get_side(), itrack); const RRNodeId& unique_mirror_chan_node = unique_mirror.get_chan_node(side_manager.get_side(), itrack);
port_name = generate_sb_module_track_port_name(rr_graph.node_type(unique_mirror_chan_node), port_name = generate_sb_module_track_port_name(rr_graph.node_type(unique_mirror_chan_node),
side_manager.get_side(), itrack, side_manager.get_side(),
unique_mirror.get_chan_node_direction(side_manager.get_side(), itrack)); unique_mirror.get_chan_node_direction(side_manager.get_side(), itrack));
} }
@ -488,12 +491,11 @@ void print_analysis_sdc_disable_sb_unused_resources(std::fstream& fp,
AtomNetId mapped_atom_net = atom_ctx.lookup.atom_net(routing_annotation.rr_node_net(chan_node)); AtomNetId mapped_atom_net = atom_ctx.lookup.atom_net(routing_annotation.rr_node_net(chan_node));
disable_analysis_module_input_port_net_sinks(fp, module_manager, disable_analysis_module_input_pin_net_sinks(fp, module_manager, sb_module,
sb_module, sb_instance_name,
sb_instance_name, module_port, itrack / 2,
module_port, mapped_atom_net,
mapped_atom_net, mux_instance_to_net_map);
mux_instance_to_net_map);
} }
} }
} }

View File

@ -67,23 +67,23 @@ void print_pnr_sdc_constrain_sb_mux_timing(std::fstream& fp,
|| ( CHANY == rr_graph.node_type(output_rr_node) )); || ( CHANY == rr_graph.node_type(output_rr_node) ));
/* Find the module port corresponding to the output rr_node */ /* Find the module port corresponding to the output rr_node */
ModulePortId module_output_port = find_switch_block_module_chan_port(module_manager, std::pair<ModulePortId, size_t> module_output_port = find_switch_block_module_chan_port(module_manager,
sb_module, sb_module,
rr_graph, rr_graph,
rr_gsb, rr_gsb,
output_node_side, output_node_side,
output_rr_node, output_rr_node,
OUT_PORT); OUT_PORT);
/* Find the module port corresponding to the fan-in rr_nodes of the output rr_node */ /* Find the module port corresponding to the fan-in rr_nodes of the output rr_node */
std::vector<ModulePortId> module_input_ports = find_switch_block_module_input_ports(module_manager, std::vector<std::pair<ModulePortId, size_t>> module_input_ports = find_switch_block_module_input_ports(module_manager,
sb_module, sb_module,
rr_graph, rr_graph,
rr_gsb, rr_gsb,
get_rr_graph_configurable_driver_nodes(rr_graph, output_rr_node)); get_rr_graph_configurable_driver_nodes(rr_graph, output_rr_node));
/* Find timing constraints for each path (edge) */ /* Find timing constraints for each path (edge) */
std::map<ModulePortId, float> switch_delays; std::map<std::pair<ModulePortId, size_t>, float> switch_delays;
size_t edge_counter = 0; size_t edge_counter = 0;
for (const RREdgeId& edge : rr_graph.node_configurable_in_edges(output_rr_node)) { for (const RREdgeId& edge : rr_graph.node_configurable_in_edges(output_rr_node)) {
/* Get the switch delay */ /* Get the switch delay */
@ -93,28 +93,38 @@ void print_pnr_sdc_constrain_sb_mux_timing(std::fstream& fp,
} }
/* Find the starting points */ /* Find the starting points */
for (const ModulePortId& module_input_port : module_input_ports) { for (const std::pair<ModulePortId, size_t>& module_input_port : module_input_ports) {
/* If we have a zero-delay path to contrain, we will skip unless users want so */ /* If we have a zero-delay path to contrain, we will skip unless users want so */
if ( (false == constrain_zero_delay_paths) if ( (false == constrain_zero_delay_paths)
&& (0. == switch_delays[module_input_port]) ) { && (0. == switch_delays[module_input_port]) ) {
continue; continue;
} }
BasicPort src_port(module_manager.module_port(sb_module, module_input_port.first).get_name(),
module_input_port.second,
module_input_port.second);
BasicPort sink_port(module_manager.module_port(sb_module, module_output_port.first).get_name(),
module_output_port.second,
module_output_port.second);
/* Constrain a path */ /* Constrain a path */
if (false == hierarchical) { if (false == hierarchical) {
print_pnr_sdc_constrain_max_delay(fp, print_pnr_sdc_constrain_max_delay(fp,
module_path, module_path,
generate_sdc_port(module_manager.module_port(sb_module, module_input_port)), generate_sdc_port(src_port),
module_path, module_path,
generate_sdc_port(module_manager.module_port(sb_module, module_output_port)), generate_sdc_port(sink_port),
switch_delays[module_input_port] / time_unit); switch_delays[module_input_port] / time_unit);
} else { } else {
VTR_ASSERT_SAFE(true == hierarchical); VTR_ASSERT_SAFE(true == hierarchical);
print_pnr_sdc_constrain_port2port_timing(fp, print_pnr_sdc_constrain_max_delay(fp,
module_manager, std::string(),
sb_module, module_input_port, generate_sdc_port(src_port),
sb_module, module_output_port, std::string(),
switch_delays[module_input_port] / time_unit); generate_sdc_port(sink_port),
switch_delays[module_input_port] / time_unit);
} }
} }
} }

View File

@ -180,6 +180,12 @@ void RRChan::add_node(const RRGraph& rr_graph, const RRNodeId& node, const RRSeg
nodes_.push_back(node); nodes_.push_back(node);
node_segments_.push_back(node_segment); node_segments_.push_back(node_segment);
if (NUM_RR_TYPES == type_) {
type_ = rr_graph.node_type(node);
} else {
VTR_ASSERT(type_ == rr_graph.node_type(node));
}
VTR_ASSERT(valid_node_type(rr_graph, node)); VTR_ASSERT(valid_node_type(rr_graph, node));
} }

View File

@ -55,6 +55,13 @@ size_t RRGSB::get_chan_width(const e_side& side) const {
return chan_node_[side_manager.to_size_t()].get_chan_width(); return chan_node_[side_manager.to_size_t()].get_chan_width();
} }
/* Get the number of routing tracks on a side */
t_rr_type RRGSB::get_chan_type(const e_side& side) const {
SideManager side_manager(side);
VTR_ASSERT(side_manager.validate());
return chan_node_[side_manager.to_size_t()].get_type();
}
/* Get the maximum number of routing tracks on all sides */ /* Get the maximum number of routing tracks on all sides */
size_t RRGSB::get_max_chan_width() const { size_t RRGSB::get_max_chan_width() const {
size_t max_chan_width = 0; size_t max_chan_width = 0;

View File

@ -60,6 +60,9 @@ class RRGSB {
/* Get the number of routing tracks on a side */ /* Get the number of routing tracks on a side */
size_t get_chan_width(const e_side& side) const; size_t get_chan_width(const e_side& side) const;
/* Get the type of routing tracks on a side */
t_rr_type get_chan_type(const e_side& side) const;
/* Get the maximum number of routing tracks on all sides */ /* Get the maximum number of routing tracks on all sides */
size_t get_max_chan_width() const; size_t get_max_chan_width() const;