[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;
|
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
|
* 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:
|
*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
|
/* Get the submodule of connection blocks one by one, build connections
|
||||||
* between sb and cb */
|
* between sb and cb */
|
||||||
for (size_t isb = 0; isb < fabric_tile.sb_coordinates(fabric_tile_id).size();
|
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;
|
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;
|
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);
|
cb_ipin_side, grids, vpr_device_annotation, rr_graph, module_ipin_node);
|
||||||
std::string src_tile_cb_port_name = generate_tile_module_port_name(
|
std::string src_tile_cb_port_name = generate_tile_module_port_name(
|
||||||
src_cb_instance_name_in_unique_tile, src_cb_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 =
|
ModulePortId src_cb_port_id =
|
||||||
module_manager.find_module_port(tile_module, src_tile_cb_port_name);
|
module_manager.find_module_port(tile_module, src_tile_cb_port_name);
|
||||||
VTR_ASSERT(true == module_manager.valid_module_port_id(tile_module,
|
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(
|
std::string sink_tile_grid_port_name = generate_tile_module_port_name(
|
||||||
sink_grid_module_name, sink_grid_port_name);
|
sink_grid_module_name, sink_grid_port_name);
|
||||||
ModulePortId sink_grid_port_id =
|
ModulePortId sink_grid_port_id = module_manager.find_module_port(
|
||||||
module_manager.find_module_port(sink_tile_module, sink_tile_grid_port_name);
|
sink_tile_module, sink_tile_grid_port_name);
|
||||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||||
sink_tile_module, sink_grid_port_id));
|
sink_tile_module, sink_grid_port_id));
|
||||||
BasicPort sink_grid_port =
|
BasicPort sink_grid_port =
|
||||||
|
|
Loading…
Reference in New Issue