Merge branch 'refactoring' into dev
This commit is contained in:
commit
a6fd0257aa
|
@ -61,6 +61,7 @@ void build_fabric(OpenfpgaContext& openfpga_context,
|
|||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_compress_routing = cmd.option("compress_routing");
|
||||
CommandOptionId opt_duplicate_grid_pin = cmd.option("duplicate_grid_pin");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
if (true == cmd_context.option_enable(cmd, opt_compress_routing)) {
|
||||
|
@ -70,7 +71,10 @@ void build_fabric(OpenfpgaContext& openfpga_context,
|
|||
VTR_LOG("\n");
|
||||
|
||||
openfpga_context.mutable_module_graph() = build_device_module_graph(g_vpr_ctx.device(),
|
||||
const_cast<const OpenfpgaContext&>(openfpga_context));
|
||||
const_cast<const OpenfpgaContext&>(openfpga_context),
|
||||
cmd_context.option_enable(cmd, opt_compress_routing),
|
||||
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -10,6 +10,13 @@ enum e_pin2pin_interc_type {
|
|||
NUM_PIN2PIN_INTERC_TYPES
|
||||
};
|
||||
|
||||
enum e_circuit_pb_port_type {
|
||||
CIRCUIT_PB_PORT_INPUT,
|
||||
CIRCUIT_PB_PORT_OUTPUT,
|
||||
CIRCUIT_PB_PORT_CLOCK,
|
||||
NUM_CIRCUIT_PB_PORT_TYPES
|
||||
};
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "openfpga_side_manager.h"
|
||||
#include "pb_type_utils.h"
|
||||
#include "circuit_library_utils.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
#include "openfpga_naming.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
|
@ -1116,7 +1117,9 @@ std::string generate_grid_block_instance_name(const std::string& prefix,
|
|||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the module name of a physical block
|
||||
* Generate the module name of a logical block type (pb_type)
|
||||
* Since the logical block does not carry any physical attributes,
|
||||
* this logical block will have a common prefix 'logical_type'
|
||||
* To ensure a unique name for each physical block inside the graph of complex blocks
|
||||
* (pb_graph_nodes), this function trace backward to the top-level node
|
||||
* in the graph and add the name of these parents
|
||||
|
@ -1126,8 +1129,7 @@ std::string generate_grid_block_instance_name(const std::string& prefix,
|
|||
* TODO: to make sure the length of this name does not exceed the size of
|
||||
* chars in a line of a file!!!
|
||||
**********************************************************************/
|
||||
std::string generate_physical_block_module_name(const std::string& prefix,
|
||||
t_pb_type* physical_pb_type) {
|
||||
std::string generate_physical_block_module_name(t_pb_type* physical_pb_type) {
|
||||
std::string module_name(physical_pb_type->name);
|
||||
|
||||
t_pb_type* parent_pb_type = physical_pb_type;
|
||||
|
@ -1164,7 +1166,7 @@ std::string generate_physical_block_module_name(const std::string& prefix,
|
|||
}
|
||||
|
||||
/* Add the prefix */
|
||||
module_name = prefix + module_name;
|
||||
module_name = LOGICAL_MODULE_NAME_PREFIX + module_name;
|
||||
|
||||
return module_name;
|
||||
}
|
||||
|
@ -1173,37 +1175,9 @@ std::string generate_physical_block_module_name(const std::string& prefix,
|
|||
/*********************************************************************
|
||||
* Generate the instance name for physical block with a given index
|
||||
**********************************************************************/
|
||||
std::string generate_physical_block_instance_name(const std::string& prefix,
|
||||
t_pb_type* pb_type,
|
||||
std::string generate_physical_block_instance_name(t_pb_type* pb_type,
|
||||
const size_t& index) {
|
||||
std::string instance_name = generate_physical_block_module_name(prefix, pb_type);
|
||||
/* Add index to the name */
|
||||
instance_name += std::string("_");
|
||||
instance_name += std::to_string(index);
|
||||
|
||||
return instance_name;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* This function is a wrapper for the function generate_physical_block_module_name()
|
||||
* which can automatically decode the io_side and add a prefix
|
||||
**********************************************************************/
|
||||
std::string generate_grid_physical_block_module_name(const std::string& prefix,
|
||||
t_pb_type* pb_type,
|
||||
const e_side& border_side) {
|
||||
std::string module_name_prefix = generate_grid_block_prefix(prefix, border_side);
|
||||
return generate_physical_block_module_name(module_name_prefix, pb_type);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the instance name for physical block in Grid with a given index
|
||||
**********************************************************************/
|
||||
std::string generate_grid_physical_block_instance_name(const std::string& prefix,
|
||||
t_pb_type* pb_type,
|
||||
const e_side& border_side,
|
||||
const size_t& index) {
|
||||
std::string module_name_prefix = generate_grid_block_prefix(prefix, border_side);
|
||||
std::string instance_name = generate_physical_block_module_name(module_name_prefix, pb_type);
|
||||
std::string instance_name = generate_physical_block_module_name(pb_type);
|
||||
/* Add index to the name */
|
||||
instance_name += std::string("_");
|
||||
instance_name += std::to_string(index);
|
||||
|
|
|
@ -219,23 +219,11 @@ std::string generate_grid_block_instance_name(const std::string& prefix,
|
|||
const e_side& io_side,
|
||||
const vtr::Point<size_t>& grid_coord);
|
||||
|
||||
std::string generate_physical_block_module_name(const std::string& prefix,
|
||||
t_pb_type* physical_pb_type);
|
||||
std::string generate_physical_block_module_name(t_pb_type* physical_pb_type);
|
||||
|
||||
std::string generate_physical_block_instance_name(const std::string& prefix,
|
||||
t_pb_type* pb_type,
|
||||
std::string generate_physical_block_instance_name(t_pb_type* pb_type,
|
||||
const size_t& index);
|
||||
|
||||
std::string generate_grid_physical_block_module_name(const std::string& prefix,
|
||||
t_pb_type* pb_type,
|
||||
const e_side& border_side);
|
||||
|
||||
std::string generate_grid_physical_block_instance_name(const std::string& prefix,
|
||||
t_pb_type* pb_type,
|
||||
const e_side& border_side,
|
||||
const size_t& index);
|
||||
|
||||
|
||||
e_side find_grid_border_side(const vtr::Point<size_t>& device_size,
|
||||
const vtr::Point<size_t>& grid_coordinate);
|
||||
|
||||
|
|
|
@ -10,9 +10,13 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/* IO PORT */
|
||||
/* Prefix of global input, output and inout ports of FPGA fabric */
|
||||
constexpr char* GIO_INOUT_PREFIX = "gfpga_pad_";
|
||||
|
||||
/* Grid naming constant strings */
|
||||
constexpr char* GRID_MODULE_NAME_PREFIX = "grid_";
|
||||
constexpr char* LOGICAL_MODULE_NAME_PREFIX = "logical_tile_";
|
||||
|
||||
/* Memory naming constant strings */
|
||||
constexpr char* GRID_MEM_INSTANCE_PREFIX = "mem_";
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include "build_lut_modules.h"
|
||||
#include "build_wire_modules.h"
|
||||
#include "build_memory_modules.h"
|
||||
//#include "build_grid_modules.h"
|
||||
//#include "build_routing_modules.h"
|
||||
#include "build_grid_modules.h"
|
||||
#include "build_routing_modules.h"
|
||||
//#include "build_top_module.h"
|
||||
#include "build_device_module.h"
|
||||
|
||||
|
@ -27,7 +27,10 @@ namespace openfpga {
|
|||
* for a FPGA fabric
|
||||
*******************************************************************/
|
||||
ModuleManager build_device_module_graph(const DeviceContext& vpr_device_ctx,
|
||||
const OpenfpgaContext& openfpga_ctx) {
|
||||
const OpenfpgaContext& openfpga_ctx,
|
||||
const bool& compress_routing,
|
||||
const bool& duplicate_grid_pin,
|
||||
const bool& verbose) {
|
||||
vtr::ScopedStartFinishTimer timer("Build fabric module graph");
|
||||
|
||||
/* Module manager to be built */
|
||||
|
@ -67,21 +70,31 @@ ModuleManager build_device_module_graph(const DeviceContext& vpr_device_ctx,
|
|||
openfpga_ctx.arch().config_protocol.type());
|
||||
|
||||
/* Build grid and programmable block modules */
|
||||
//build_grid_modules(module_manager, arch.spice->circuit_lib, mux_lib,
|
||||
// arch.sram_inf.verilog_sram_inf_orgz->type, sram_model,
|
||||
// TRUE == vpr_setup.FPGA_SPICE_Opts.duplicate_grid_pin);
|
||||
|
||||
//if (TRUE == vpr_setup.FPGA_SPICE_Opts.compact_routing_hierarchy) {
|
||||
// build_unique_routing_modules(module_manager, L_device_rr_gsb, arch.spice->circuit_lib,
|
||||
// arch.sram_inf.verilog_sram_inf_orgz->type, sram_model,
|
||||
// vpr_setup.RoutingArch, rr_switches);
|
||||
//} else {
|
||||
// VTR_ASSERT(FALSE == vpr_setup.FPGA_SPICE_Opts.compact_routing_hierarchy);
|
||||
// build_flatten_routing_modules(module_manager, L_device_rr_gsb, arch.spice->circuit_lib,
|
||||
// arch.sram_inf.verilog_sram_inf_orgz->type, sram_model,
|
||||
// vpr_setup.RoutingArch, rr_switches);
|
||||
//}
|
||||
build_grid_modules(module_manager, vpr_device_ctx,
|
||||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.arch().circuit_lib,
|
||||
openfpga_ctx.mux_lib(),
|
||||
openfpga_ctx.arch().config_protocol.type(),
|
||||
sram_model, duplicate_grid_pin, verbose);
|
||||
|
||||
if (true == compress_routing) {
|
||||
build_unique_routing_modules(module_manager,
|
||||
vpr_device_ctx,
|
||||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.device_rr_gsb(),
|
||||
openfpga_ctx.arch().circuit_lib,
|
||||
openfpga_ctx.arch().config_protocol.type(),
|
||||
sram_model, verbose);
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == compress_routing);
|
||||
build_flatten_routing_modules(module_manager,
|
||||
vpr_device_ctx,
|
||||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.device_rr_gsb(),
|
||||
openfpga_ctx.arch().circuit_lib,
|
||||
openfpga_ctx.arch().config_protocol.type(),
|
||||
sram_model, verbose);
|
||||
}
|
||||
|
||||
/* Build FPGA fabric top-level module */
|
||||
//build_top_module(module_manager, arch.spice->circuit_lib,
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
namespace openfpga {
|
||||
|
||||
ModuleManager build_device_module_graph(const DeviceContext& vpr_device_ctx,
|
||||
const OpenfpgaContext& openfpga_ctx);
|
||||
const OpenfpgaContext& openfpga_ctx,
|
||||
const bool& compress_routing,
|
||||
const bool& duplicate_grid_pin,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ void add_grid_module_net_connect_duplicated_pb_graph_pin(ModuleManager& module_m
|
|||
*/
|
||||
size_t grid_pin_index = pb_graph_pin->pin_count_in_cluster
|
||||
+ child_instance * grid_type_descriptor->num_pins / grid_type_descriptor->capacity;
|
||||
|
||||
int pin_width = grid_type_descriptor->pin_height_offset[grid_pin_index];
|
||||
int pin_height = grid_type_descriptor->pin_height_offset[grid_pin_index];
|
||||
for (const e_side& side : grid_pin_sides) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
#ifndef BUILD_GRID_MODULES_H
|
||||
#define BUILD_GRID_MODULES_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "vpr_context.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "module_manager.h"
|
||||
#include "mux_library.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void build_grid_modules(ModuleManager& module_manager,
|
||||
const DeviceContext& device_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const CircuitModelId& sram_model,
|
||||
const bool& duplicate_grid_pin,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
|||
#ifndef BUILD_ROUTING_MODULES_H
|
||||
#define BUILD_ROUTING_MODULES_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "vpr_context.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "device_rr_gsb.h"
|
||||
#include "mux_library.h"
|
||||
#include "circuit_library.h"
|
||||
#include "module_manager.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void build_flatten_routing_modules(ModuleManager& module_manager,
|
||||
const DeviceContext& device_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const CircuitModelId& sram_model,
|
||||
const bool& verbose);
|
||||
|
||||
void build_unique_routing_modules(ModuleManager& module_manager,
|
||||
const DeviceContext& device_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const CircuitModelId& sram_model,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -81,4 +81,51 @@ std::vector<RRSwitchId> get_rr_graph_driver_switches(const RRGraph& rr_graph,
|
|||
return driver_switches;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Find the driver nodes for a node in the rr_graph
|
||||
***********************************************************************/
|
||||
std::vector<RRNodeId> get_rr_graph_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRNodeId& node) {
|
||||
std::vector<RRNodeId> driver_nodes;
|
||||
for (const RREdgeId& edge : rr_graph.node_in_edges(node)) {
|
||||
driver_nodes.push_back(rr_graph.edge_src_node(edge));
|
||||
}
|
||||
|
||||
return driver_nodes;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Find the configurable driver nodes for a node in the rr_graph
|
||||
***********************************************************************/
|
||||
std::vector<RRNodeId> get_rr_graph_configurable_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRNodeId& node) {
|
||||
std::vector<RRNodeId> driver_nodes;
|
||||
for (const RREdgeId& edge : rr_graph.node_in_edges(node)) {
|
||||
/* Bypass non-configurable edges */
|
||||
if (false == rr_graph.edge_is_configurable(edge)) {
|
||||
continue;
|
||||
}
|
||||
driver_nodes.push_back(rr_graph.edge_src_node(edge));
|
||||
}
|
||||
|
||||
return driver_nodes;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Find the configurable driver nodes for a node in the rr_graph
|
||||
***********************************************************************/
|
||||
std::vector<RRNodeId> get_rr_graph_non_configurable_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRNodeId& node) {
|
||||
std::vector<RRNodeId> driver_nodes;
|
||||
for (const RREdgeId& edge : rr_graph.node_in_edges(node)) {
|
||||
/* Bypass configurable edges */
|
||||
if (true == rr_graph.edge_is_configurable(edge)) {
|
||||
continue;
|
||||
}
|
||||
driver_nodes.push_back(rr_graph.edge_src_node(edge));
|
||||
}
|
||||
|
||||
return driver_nodes;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -26,6 +26,15 @@ vtr::Point<size_t> get_track_rr_node_end_coordinate(const RRGraph& rr_graph,
|
|||
std::vector<RRSwitchId> get_rr_graph_driver_switches(const RRGraph& rr_graph,
|
||||
const RRNodeId& node);
|
||||
|
||||
std::vector<RRNodeId> get_rr_graph_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRNodeId& node);
|
||||
|
||||
std::vector<RRNodeId> get_rr_graph_configurable_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRNodeId& node);
|
||||
|
||||
std::vector<RRNodeId> get_rr_graph_non_configurable_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRNodeId& node);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue