put routing module builder util function online

This commit is contained in:
tangxifan 2020-02-13 16:05:23 -07:00
parent 89086ed080
commit cf440f92d3
8 changed files with 292 additions and 15 deletions

View File

@ -52,7 +52,7 @@ void build_invbuf_module(ModuleManager& module_manager,
}
/* Report errors if there are any */
if (0 < num_err) {
VTR_LOG_ERROR("Inverter/buffer circuit model '%s' is power-gated. At least one config-enable global port is required!\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "Inverter/buffer circuit model '%s' is power-gated. At least one config-enable global port is required!\n",
circuit_lib.model_name(circuit_model).c_str());
exit(1);
}
@ -98,7 +98,7 @@ void build_passgate_module(ModuleManager& module_manager,
}
break;
default:
VTR_LOG_ERROR("Invalid topology for circuit model '%s'!\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid topology for circuit model '%s'!\n",
circuit_lib.model_name(circuit_model).c_str());
exit(1);
}

View File

@ -102,7 +102,7 @@ void add_grid_module_net_connect_pb_graph_pin(ModuleManager& module_manager,
module_manager.add_module_net_sink(grid_module, net, grid_module, 0, grid_module_port_id, grid_module_pin_id);
break;
default:
VTR_LOG_ERROR("Invalid pin-to-pin interconnection type!\n");
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid pin-to-pin interconnection type!\n");
exit(1);
}
}

View File

@ -354,7 +354,7 @@ void add_module_pb_graph_pin2pin_net(ModuleManager& module_manager,
module_manager.add_module_net_sink(pb_module, pin2pin_net, pin_pb_type_module, pin_pb_type_instance, pin_module_port_id, pin_module_pin_id);
break;
default:
VTR_LOG_ERROR("Invalid pin-to-pin interconnection type!\n");
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid pin-to-pin interconnection type!\n");
exit(1);
}
}
@ -532,7 +532,7 @@ void add_module_pb_graph_pin_interc(ModuleManager& module_manager,
break;
}
default:
VTR_LOG_ERROR("Invalid interconnection type for %s [at Architecture XML LINE%d]!\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid interconnection type for %s [at Architecture XML LINE%d]!\n",
cur_interc->name, cur_interc->line_num);
exit(1);
}
@ -620,7 +620,7 @@ void add_module_pb_graph_port_interc(ModuleManager& module_manager,
break;
}
default:
VTR_LOG_ERROR("Invalid pb port type!\n");
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid pb port type!\n");
exit(1);
}
}

View File

@ -265,10 +265,11 @@ void build_lut_module(ModuleManager& module_manager,
/* Sanitity check */
if ( true == circuit_lib.is_lut_fracturable(lut_model) ) {
if (mode_select_port_lsb != circuit_lib.port_size(lut_mode_select_sram_ports[0])) {
VTR_LOG_ERROR("(ircuit model '%s' has a unmatched tri-state map '%s' implied by mode_port size='%d'!\n",
circuit_lib.model_name(lut_model).c_str(),
tri_state_map.c_str(),
circuit_lib.port_size(lut_mode_select_sram_ports[0]));
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Circuit model '%s' has a unmatched tri-state map '%s' implied by mode_port size='%d'!\n",
circuit_lib.model_name(lut_model).c_str(),
tri_state_map.c_str(),
circuit_lib.port_size(lut_mode_select_sram_ports[0]));
exit(1);
}
}

View File

@ -585,7 +585,7 @@ void build_memory_module(ModuleManager& module_manager,
module_name, sram_model, num_mems);
break;
default:
VTR_LOG_ERROR("Invalid SRAM organization!\n");
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid SRAM organization!\n");
exit(1);
}
}
@ -636,7 +636,7 @@ void build_mux_memory_module(ModuleManager& module_manager,
*/
break;
default:
VTR_LOG_ERROR("Invalid design technology of multiplexer '%s'\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid design technology of multiplexer '%s'\n",
circuit_lib.model_name(mux_model).c_str());
exit(1);
}

View File

@ -346,7 +346,7 @@ void build_mux_branch_module(ModuleManager& module_manager,
build_rram_mux_branch_module(module_manager, circuit_lib, mux_model, module_name, mux_graph);
break;
default:
VTR_LOG_ERROR("Invalid design technology of multiplexer '%s'\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid design technology of multiplexer '%s'\n",
circuit_lib.model_name(mux_model).c_str());
exit(1);
}
@ -1262,7 +1262,7 @@ void build_rram_mux_module(ModuleManager& module_manager,
/* Error out for the conditions where we are not yet supported! */
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
/* RRAM LUT is not supported now... */
VTR_LOG_ERROR("RRAM-based LUT is not supported for circuit model '%s')!\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "RRAM-based LUT is not supported for circuit model '%s')!\n",
circuit_lib.model_name(circuit_model).c_str());
exit(1);
}
@ -1367,7 +1367,7 @@ void build_mux_module(ModuleManager& module_manager,
build_rram_mux_module(module_manager, circuit_lib, circuit_model, module_name, mux_graph);
break;
default:
VTR_LOG_ERROR("Invalid design technology of multiplexer '%s'\n",
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid design technology of multiplexer '%s'\n",
circuit_lib.model_name(circuit_model).c_str());
exit(1);
}

View File

@ -0,0 +1,213 @@
/********************************************************************
* This file includes most utilized functions that are used to build modules
* for global routing architecture of a FPGA fabric
* Covering:
* 1. Connection blocks
* 2. Switch blocks
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_log.h"
#include "vtr_assert.h"
#include "vtr_geometry.h"
#include "openfpga_naming.h"
#include "build_routing_module_utils.h"
/* begin namespace openfpga */
namespace openfpga {
/*********************************************************************
* Generate a port for a routing track of a swtich block
********************************************************************/
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) {
/* 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,
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;
}
/*********************************************************************
* Generate an input port for routing multiplexer inside the switch block
* In addition to give the Routing Resource node of the input
* Users should provide the side of input, which is different case by case:
* 1. When the input is a pin of a CLB/Logic Block, the input_side should
* be the side of the node on its grid!
* For example, the input pin is on the top side of a switch block
* but on the right side of a switch block
* +--------+
* | |
* | Grid |---+
* | | |
* +--------+ v input_pin
* +----------------+
* | Switch Block |
* +----------------+
* 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) {
/* Deposit an invalid value */
ModulePortId input_port_id = ModulePortId::INVALID();
/* Generate the input port object */
switch (rr_graph.node_type(input_rr_node)) {
/* case SOURCE: */
case OPIN: {
/* Find the coordinator (grid_x and grid_y) for the input port */
vtr::Point<size_t> input_port_coord(rr_graph.node_xlow(input_rr_node),
rr_graph.node_ylow(input_rr_node));
/* Find the side where the grid pin locates in the grid */
enum e_side grid_pin_side = rr_graph.node_side(input_rr_node);
VTR_ASSERT(NUM_SIDES != grid_pin_side);
std::string input_port_name = generate_sb_module_grid_port_name(input_side,
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));
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);
break;
}
default: /* SOURCE, IPIN, SINK are invalid*/
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid rr_node type! Should be [OPIN|CHANX|CHANY].\n");
exit(1);
}
return input_port_id;
}
/*********************************************************************
* 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,
const ModuleId& sb_module,
const RRGraph& rr_graph,
const RRGSB& rr_gsb,
const std::vector<RRNodeId>& input_rr_nodes) {
std::vector<ModulePortId> input_ports;
for (const RRNodeId& input_rr_node : input_rr_nodes) {
/* Find the side where the input locates in the Switch Block */
enum e_side input_pin_side = NUM_SIDES;
/* The input could be at any side of the switch block, find it */
int index = -1;
rr_gsb.get_node_side_and_index(rr_graph, input_rr_node, IN_PORT, input_pin_side, index);
VTR_ASSERT(NUM_SIDES != input_pin_side);
VTR_ASSERT(-1 != index);
input_ports.push_back(find_switch_block_module_input_port(module_manager, sb_module, rr_graph, rr_gsb, input_pin_side, input_rr_node));
}
return input_ports;
}
/*********************************************************************
* 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;
/* 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<size_t> 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);
/* 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));
break;
}
default: /* OPIN, SOURCE, IPIN, SINK are invalid*/
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid rr_node type! Should be [OPIN|CHANX|CHANY].\n");
exit(1);
}
return input_port_id;
}
/*********************************************************************
* Generate a port for a routing track of a swtich block
********************************************************************/
ModulePortId find_connection_block_module_ipin_port(const ModuleManager& module_manager,
const ModuleId& cb_module,
const RRGraph& rr_graph,
const RRGSB& rr_gsb,
const RRNodeId& src_rr_node) {
/* Ensure the src_rr_node is an input pin of a CLB */
VTR_ASSERT(IPIN == rr_graph.node_type(src_rr_node));
/* Create port description for input pin of a CLB */
vtr::Point<size_t> port_coord(rr_graph.node_xlow(src_rr_node), rr_graph.node_ylow(src_rr_node));
/* Search all the sides of a SB, see this drive_rr_node is an INPUT of this SB */
enum e_side cb_ipin_side = NUM_SIDES;
int cb_ipin_index = -1;
rr_gsb.get_node_side_and_index(rr_graph, src_rr_node, OUT_PORT, cb_ipin_side, cb_ipin_index);
/* We need to be sure that drive_rr_node is part of the CB */
VTR_ASSERT((-1 != cb_ipin_index)&&(NUM_SIDES != cb_ipin_side));
std::string port_name = generate_cb_module_grid_port_name(cb_ipin_side,
rr_graph.node_pin_num(rr_gsb.get_ipin_node(cb_ipin_side, cb_ipin_index)));
/* Must find a valid port id in the Switch Block module */
ModulePortId ipin_port_id = module_manager.find_module_port(cb_module, port_name);
VTR_ASSERT(true == module_manager.valid_module_port_id(cb_module, ipin_port_id));
return ipin_port_id;
}
/*********************************************************************
* Generate a list of routing track middle output ports
* for routing multiplexer inside the connection block
********************************************************************/
std::vector<ModulePortId> 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<RRNodeId>& input_rr_nodes) {
std::vector<ModulePortId> 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));
}
return input_ports;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,63 @@
#ifndef BUILD_ROUTING_MODULE_UTILS_H
#define BUILD_ROUTING_MODULE_UTILS_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <vector>
#include "rr_gsb.h"
#include "module_manager.h"
#include "vpr_types.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* 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);
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);
std::vector<ModulePortId> 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<RRNodeId>& input_rr_nodes);
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 find_connection_block_module_ipin_port(const ModuleManager& module_manager,
const ModuleId& cb_module,
const RRGraph& rr_graph,
const RRGSB& rr_gsb,
const RRNodeId& src_rr_node);
std::vector<ModulePortId> 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<RRNodeId>& input_rr_nodes);
} /* end namespace openfpga */
#endif