[core] fixed a bug where undriven cb ports are not connected to tile
This commit is contained in:
parent
3745897ff6
commit
b8d080b08e
|
@ -743,6 +743,222 @@ static int build_tile_module_port_and_nets_between_sb_and_cb(
|
|||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* This function will a port for tile where its connection blocks
|
||||
* need to drive or to be driven by a switch block which is not in the tile
|
||||
*
|
||||
* +------------+ +------------------+
|
||||
* | Connection | | |
|
||||
* | Block |----->| Switch Block |
|
||||
* | X-direction|<-----| [x][y] |
|
||||
* | [x][y] | | |
|
||||
* +------------+ +------------------+
|
||||
*
|
||||
*******************************************************************/
|
||||
static int build_tile_module_one_port_from_cb(
|
||||
ModuleManager& module_manager, const ModuleId& tile_module,
|
||||
const ModuleId& cb_module, const std::string& chan_port_name,
|
||||
const vtr::Point<size_t>& tile_coord,
|
||||
const std::string& cb_instance_name_in_tile, const size_t& cb_instance,
|
||||
const bool& frame_view, const bool& verbose) {
|
||||
std::string cb_module_name = module_manager.module_name(cb_module);
|
||||
ModulePortId chan_port_id =
|
||||
module_manager.find_module_port(cb_module, chan_port_name);
|
||||
BasicPort chan_port = module_manager.module_port(cb_module, chan_port_id);
|
||||
ModuleManager::e_module_port_type chan_port_type =
|
||||
module_manager.port_type(cb_module, chan_port_id);
|
||||
|
||||
bool require_port_addition = false;
|
||||
for (size_t pin_id = 0; pin_id < chan_port.pins().size(); ++pin_id) {
|
||||
if (module_manager.valid_module_net_id(
|
||||
tile_module, module_manager.module_instance_port_net(
|
||||
tile_module, cb_module, cb_instance, chan_port_id,
|
||||
chan_port.pins()[pin_id]))) {
|
||||
continue;
|
||||
}
|
||||
require_port_addition = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Early exit if this port is fully connected inside the tile */
|
||||
if (!require_port_addition) {
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
BasicPort tile_chan_port(chan_port);
|
||||
tile_chan_port.set_name(generate_tile_module_port_name(
|
||||
cb_instance_name_in_tile, chan_port.get_name()));
|
||||
|
||||
/* Add new port */
|
||||
VTR_LOGV(verbose,
|
||||
"Adding ports '%s' to tile as required by the "
|
||||
"connection block '%s'...\n",
|
||||
tile_chan_port.to_verilog_string().c_str(), cb_module_name.c_str());
|
||||
/* Create a new port and a new net. FIXME: Create a proper name to
|
||||
* avoid naming conflicts */
|
||||
ModulePortId tile_module_port_id =
|
||||
module_manager.add_port(tile_module, tile_chan_port, chan_port_type);
|
||||
|
||||
if (!frame_view) {
|
||||
for (size_t pin_id = 0; pin_id < chan_port.pins().size(); ++pin_id) {
|
||||
if (module_manager.valid_module_net_id(
|
||||
tile_module, module_manager.module_instance_port_net(
|
||||
tile_module, cb_module, cb_instance, chan_port_id,
|
||||
chan_port.pins()[pin_id]))) {
|
||||
continue;
|
||||
}
|
||||
if (chan_port_type ==
|
||||
ModuleManager::e_module_port_type::MODULE_INPUT_PORT) {
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, tile_module, tile_module, 0, tile_module_port_id,
|
||||
chan_port.pins()[pin_id]);
|
||||
/* Configure the net sink */
|
||||
module_manager.add_module_net_sink(tile_module, net, cb_module,
|
||||
cb_instance, chan_port_id,
|
||||
chan_port.pins()[pin_id]);
|
||||
} else if (chan_port_type ==
|
||||
ModuleManager::e_module_port_type::MODULE_OUTPUT_PORT) {
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, tile_module, cb_module, cb_instance, chan_port_id,
|
||||
chan_port.pins()[pin_id]);
|
||||
/* Configure the net sink */
|
||||
module_manager.add_module_net_sink(tile_module, net, tile_module, 0,
|
||||
tile_module_port_id,
|
||||
chan_port.pins()[pin_id]);
|
||||
} else {
|
||||
VTR_LOG_ERROR(
|
||||
"Expect either input or output port '%s' for cb module '%s' "
|
||||
"required by tile[%lu][%lu]!\n",
|
||||
chan_port.to_verilog_string().c_str(), cb_module_name.c_str(),
|
||||
tile_coord.x(), tile_coord.y());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* This function will create ports for tile where its connection blocks
|
||||
* need to drive or to be driven by a switch block which is not in the tile
|
||||
*
|
||||
* +------------+ +------------------+
|
||||
* | Connection | | |
|
||||
* | Block |----->| Switch Block |
|
||||
* | X-direction|<-----| [x][y] |
|
||||
* | [x][y] | | |
|
||||
* +------------+ +------------------+
|
||||
*
|
||||
*******************************************************************/
|
||||
static int build_tile_module_ports_from_cb(
|
||||
ModuleManager& module_manager, const ModuleId& tile_module,
|
||||
const DeviceRRGSB& device_rr_gsb, const RRGSB& rr_gsb,
|
||||
const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id,
|
||||
const t_rr_type& cb_type,
|
||||
const std::map<t_rr_type, std::vector<size_t>>& cb_instances,
|
||||
const size_t& icb, const bool& compact_routing_hierarchy,
|
||||
const bool& frame_view, const bool& verbose) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
size_t cb_instance = cb_instances.at(cb_type)[icb];
|
||||
/* We could have two different coordinators, one is the instance, the other is
|
||||
* the module */
|
||||
vtr::Point<size_t> instance_cb_coordinate(rr_gsb.get_cb_x(cb_type),
|
||||
rr_gsb.get_cb_y(cb_type));
|
||||
vtr::Point<size_t> module_gsb_coordinate(rr_gsb.get_x(), rr_gsb.get_y());
|
||||
|
||||
/* Skip those Connection blocks that do not exist */
|
||||
if (false == rr_gsb.is_cb_exist(cb_type)) {
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Skip if the cb does not contain any configuration bits! */
|
||||
if (true == connection_block_contain_only_routing_tracks(rr_gsb, cb_type)) {
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/* If we use compact routing hierarchy, we should find the unique module of
|
||||
* CB, which is added to the top module */
|
||||
if (true == compact_routing_hierarchy) {
|
||||
vtr::Point<size_t> gsb_coord(rr_gsb.get_x(), rr_gsb.get_y());
|
||||
const RRGSB& unique_mirror =
|
||||
device_rr_gsb.get_cb_unique_module(cb_type, gsb_coord);
|
||||
module_gsb_coordinate.set_x(unique_mirror.get_x());
|
||||
module_gsb_coordinate.set_y(unique_mirror.get_y());
|
||||
}
|
||||
|
||||
/* This is the source cb that is added to the top module */
|
||||
const RRGSB& module_cb = device_rr_gsb.get_gsb(module_gsb_coordinate);
|
||||
vtr::Point<size_t> module_cb_coordinate(module_cb.get_cb_x(cb_type),
|
||||
module_cb.get_cb_y(cb_type));
|
||||
|
||||
/* Collect source-related information */
|
||||
std::string cb_module_name =
|
||||
generate_connection_block_module_name(cb_type, module_cb_coordinate);
|
||||
ModuleId cb_module = module_manager.find_module(cb_module_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(cb_module));
|
||||
|
||||
/* Find the instance name for the connection block in the context of the tile
|
||||
*/
|
||||
vtr::Point<size_t> cb_coord_in_unique_tile =
|
||||
fabric_tile.cb_coordinates(curr_fabric_tile_id, cb_type)[icb];
|
||||
std::string cb_instance_name_in_tile =
|
||||
generate_connection_block_module_name(cb_type, cb_coord_in_unique_tile);
|
||||
vtr::Point<size_t> tile_coord =
|
||||
fabric_tile.tile_coordinate(curr_fabric_tile_id);
|
||||
|
||||
/* Check any track input and output are unconnected in the tile */
|
||||
/* 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);
|
||||
|
||||
/* Check if any of the input port is driven, if not add new port */
|
||||
status = build_tile_module_one_port_from_cb(
|
||||
module_manager, tile_module, cb_module, chan_upper_input_port_name,
|
||||
tile_coord, cb_instance_name_in_tile, cb_instance, frame_view, verbose);
|
||||
if (status != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Check if any of the input port is driven, if not add new port */
|
||||
status = build_tile_module_one_port_from_cb(
|
||||
module_manager, tile_module, cb_module, chan_lower_input_port_name,
|
||||
tile_coord, cb_instance_name_in_tile, cb_instance, frame_view, verbose);
|
||||
if (status != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Check if any of the input port is driven, if not add new port */
|
||||
status = build_tile_module_one_port_from_cb(
|
||||
module_manager, tile_module, cb_module, chan_upper_output_port_name,
|
||||
tile_coord, cb_instance_name_in_tile, cb_instance, frame_view, verbose);
|
||||
if (status != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Check if any of the input port is driven, if not add new port */
|
||||
status = build_tile_module_one_port_from_cb(
|
||||
module_manager, tile_module, cb_module, chan_lower_output_port_name,
|
||||
tile_coord, cb_instance_name_in_tile, cb_instance, frame_view, verbose);
|
||||
if (status != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* This function will create nets for the unconnected pins for a programmable
|
||||
*block in a tile This function should be called after the following functions:
|
||||
|
@ -981,6 +1197,7 @@ static int build_tile_module_ports_and_nets(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the submodule of connection blocks one by one, build connections
|
||||
* between sb and cb */
|
||||
for (size_t isb = 0; isb < fabric_tile.sb_coordinates(fabric_tile_id).size();
|
||||
|
@ -1009,6 +1226,25 @@ static int build_tile_module_ports_and_nets(
|
|||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* Get the submodule of connection blocks one by one, build connections
|
||||
* between cb and pb */
|
||||
for (t_rr_type cb_type : {CHANX, CHANY}) {
|
||||
for (size_t icb = 0;
|
||||
icb < fabric_tile.cb_coordinates(fabric_tile_id, cb_type).size();
|
||||
++icb) {
|
||||
vtr::Point<size_t> cb_coord =
|
||||
fabric_tile.cb_coordinates(fabric_tile_id, cb_type)[icb];
|
||||
const RRGSB& rr_gsb = device_rr_gsb.get_gsb(cb_coord);
|
||||
|
||||
/* Build any ports missing from connection blocks */
|
||||
status_code = build_tile_module_ports_from_cb(
|
||||
module_manager, tile_module, device_rr_gsb, rr_gsb, fabric_tile,
|
||||
fabric_tile_id, cb_type, cb_instances, icb, true, frame_view, verbose);
|
||||
if (status_code != CMD_EXEC_SUCCESS) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status_code;
|
||||
}
|
||||
|
|
|
@ -594,7 +594,9 @@ static int build_top_module_tile_nets_between_cb_and_pb(
|
|||
cb_ipin_side, grids, vpr_device_annotation, rr_graph, module_ipin_node);
|
||||
std::string src_tile_cb_port_name = generate_tile_module_port_name(
|
||||
src_cb_instance_name_in_unique_tile, src_cb_port_name);
|
||||
VTR_LOGV(verbose, "Finding port '%s' from connection block in tile [%lu][%lu]\n", src_tile_cb_port_name.c_str(), src_tile_coord.x(), src_tile_coord.y());
|
||||
VTR_LOGV(
|
||||
verbose, "Finding port '%s' from connection block in tile [%lu][%lu]\n",
|
||||
src_tile_cb_port_name.c_str(), src_tile_coord.x(), src_tile_coord.y());
|
||||
ModulePortId src_cb_port_id =
|
||||
module_manager.find_module_port(tile_module, src_tile_cb_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(tile_module,
|
||||
|
@ -636,8 +638,8 @@ static int build_top_module_tile_nets_between_cb_and_pb(
|
|||
|
||||
std::string sink_tile_grid_port_name = generate_tile_module_port_name(
|
||||
sink_grid_module_name, sink_grid_port_name);
|
||||
ModulePortId sink_grid_port_id =
|
||||
module_manager.find_module_port(sink_tile_module, sink_tile_grid_port_name);
|
||||
ModulePortId sink_grid_port_id = module_manager.find_module_port(
|
||||
sink_tile_module, sink_tile_grid_port_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||
sink_tile_module, sink_grid_port_id));
|
||||
BasicPort sink_grid_port =
|
||||
|
|
Loading…
Reference in New Issue