Merge branch 'refactoring' into dev
This commit is contained in:
commit
2f38b5cbc2
|
@ -257,10 +257,25 @@ RRGSB build_rr_gsb(const DeviceContext& vpr_device_ctx,
|
|||
/* Fill opin_rr_nodes */
|
||||
/* Copy from temp_opin_rr_node to opin_rr_node */
|
||||
for (const RRNodeId& inode : temp_opin_rr_nodes[0]) {
|
||||
/* Skip those has no configurable outgoing, they should NOT appear in the GSB connection
|
||||
* This is for those grid output pins used by direct connections
|
||||
*/
|
||||
if (0 == std::distance(vpr_device_ctx.rr_graph.node_configurable_out_edges(inode).begin(),
|
||||
vpr_device_ctx.rr_graph.node_configurable_out_edges(inode).end())) {
|
||||
continue;
|
||||
}
|
||||
/* Grid[x+1][y+1] Bottom side outputs pins */
|
||||
rr_gsb.add_opin_node(inode, side_manager.get_side());
|
||||
}
|
||||
for (const RRNodeId& inode : temp_opin_rr_nodes[1]) {
|
||||
/* Skip those has no configurable outgoing, they should NOT appear in the GSB connection
|
||||
* This is for those grid output pins used by direct connections
|
||||
*/
|
||||
if (0 == std::distance(vpr_device_ctx.rr_graph.node_configurable_out_edges(inode).begin(),
|
||||
vpr_device_ctx.rr_graph.node_configurable_out_edges(inode).end())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Grid[x+1][y] TOP side outputs pins */
|
||||
rr_gsb.add_opin_node(inode, side_manager.get_side());
|
||||
}
|
||||
|
@ -372,12 +387,12 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx,
|
|||
/* For each switch block, determine the size of array */
|
||||
for (size_t ix = 0; ix < gsb_range.x(); ++ix) {
|
||||
for (size_t iy = 0; iy < gsb_range.y(); ++iy) {
|
||||
/* Here we give the builder the fringe coordinates so that it can handle the GSBs at the borderside correctly */
|
||||
/* Here we give the builder the fringe coordinates so that it can handle the GSBs at the borderside correctly
|
||||
* sort drive_rr_nodes should be called if required by users
|
||||
*/
|
||||
const RRGSB& rr_gsb = build_rr_gsb(vpr_device_ctx,
|
||||
vtr::Point<size_t>(vpr_device_ctx.grid.width() - 2, vpr_device_ctx.grid.height() - 2),
|
||||
vtr::Point<size_t>(ix, iy));
|
||||
/* TODO: sort drive_rr_nodes should be done when building the tileable rr_graph */
|
||||
//sort_rr_gsb_drive_rr_nodes(rr_gsb);
|
||||
|
||||
/* Add to device_rr_gsb */
|
||||
vtr::Point<size_t> gsb_coordinate = rr_gsb.get_sb_coordinate();
|
||||
|
@ -394,6 +409,27 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx,
|
|||
gsb_range.x() * gsb_range.y());
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Sort all the incoming edges for each channel node which are
|
||||
* output ports of the GSB
|
||||
*******************************************************************/
|
||||
void sort_device_rr_gsb_chan_node_in_edges(const RRGraph& rr_graph,
|
||||
DeviceRRGSB& device_rr_gsb) {
|
||||
vtr::ScopedStartFinishTimer timer("Sort incoming edges for each routing track output node of General Switch Block(GSB)");
|
||||
|
||||
/* Note that the GSB array is smaller than the grids by 1 column and 1 row!!! */
|
||||
vtr::Point<size_t> gsb_range = device_rr_gsb.get_gsb_range();
|
||||
|
||||
/* For each switch block, determine the size of array */
|
||||
for (size_t ix = 0; ix < gsb_range.x(); ++ix) {
|
||||
for (size_t iy = 0; iy < gsb_range.y(); ++iy) {
|
||||
vtr::Point<size_t> gsb_coordinate(ix, iy);
|
||||
RRGSB& rr_gsb = device_rr_gsb.get_mutable_gsb(gsb_coordinate);
|
||||
rr_gsb.sort_chan_node_in_edges(rr_graph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Build the link between rr_graph switches to their physical circuit models
|
||||
* The binding is done based on the name of rr_switches defined in the
|
||||
|
|
|
@ -19,6 +19,9 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx,
|
|||
DeviceRRGSB& device_rr_gsb,
|
||||
const bool& verbose_output);
|
||||
|
||||
void sort_device_rr_gsb_chan_node_in_edges(const RRGraph& rr_graph,
|
||||
DeviceRRGSB& device_rr_gsb);
|
||||
|
||||
void annotate_rr_graph_circuit_models(const DeviceContext& vpr_device_ctx,
|
||||
const Arch& openfpga_arch,
|
||||
VprDeviceAnnotation& vpr_device_annotation,
|
||||
|
|
|
@ -28,13 +28,13 @@ vtr::Point<size_t> DeviceRRGSB::get_gsb_range() const {
|
|||
}
|
||||
|
||||
/* Get a rr switch block in the array with a coordinate */
|
||||
const RRGSB DeviceRRGSB::get_gsb(const vtr::Point<size_t>& coordinate) const {
|
||||
const RRGSB& DeviceRRGSB::get_gsb(const vtr::Point<size_t>& coordinate) const {
|
||||
VTR_ASSERT(validate_coordinate(coordinate));
|
||||
return rr_gsb_[coordinate.x()][coordinate.y()];
|
||||
}
|
||||
|
||||
/* Get a rr switch block in the array with a coordinate */
|
||||
const RRGSB DeviceRRGSB::get_gsb(const size_t& x, const size_t& y) const {
|
||||
const RRGSB& DeviceRRGSB::get_gsb(const size_t& x, const size_t& y) const {
|
||||
vtr::Point<size_t> coordinate(x, y);
|
||||
return get_gsb(coordinate);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ size_t DeviceRRGSB::get_num_gsb_unique_module() const {
|
|||
}
|
||||
|
||||
/* Get a rr switch block which a unique mirror */
|
||||
const RRGSB DeviceRRGSB::get_sb_unique_module(const size_t& index) const {
|
||||
const RRGSB& DeviceRRGSB::get_sb_unique_module(const size_t& index) const {
|
||||
VTR_ASSERT (validate_sb_unique_module_index(index));
|
||||
|
||||
return rr_gsb_[sb_unique_module_[index].x()][sb_unique_module_[index].y()];
|
||||
|
@ -130,7 +130,7 @@ const RRGSB& DeviceRRGSB::get_cb_unique_module(const t_rr_type& cb_type, const v
|
|||
}
|
||||
|
||||
/* Give a coordinate of a rr switch block, and return its unique mirror */
|
||||
const RRGSB DeviceRRGSB::get_sb_unique_module(const vtr::Point<size_t>& coordinate) const {
|
||||
const RRGSB& DeviceRRGSB::get_sb_unique_module(const vtr::Point<size_t>& coordinate) const {
|
||||
VTR_ASSERT(validate_coordinate(coordinate));
|
||||
size_t sb_unique_module_id = sb_unique_module_id_[coordinate.x()][coordinate.y()];
|
||||
return get_sb_unique_module(sb_unique_module_id);
|
||||
|
@ -193,6 +193,18 @@ void DeviceRRGSB::add_rr_gsb(const vtr::Point<size_t>& coordinate,
|
|||
rr_gsb_[coordinate.x()][coordinate.y()] = rr_gsb;
|
||||
}
|
||||
|
||||
/* Get a rr switch block in the array with a coordinate */
|
||||
RRGSB& DeviceRRGSB::get_mutable_gsb(const vtr::Point<size_t>& coordinate) {
|
||||
VTR_ASSERT(validate_coordinate(coordinate));
|
||||
return rr_gsb_[coordinate.x()][coordinate.y()];
|
||||
}
|
||||
|
||||
/* Get a rr switch block in the array with a coordinate */
|
||||
RRGSB& DeviceRRGSB::get_mutable_gsb(const size_t& x, const size_t& y) {
|
||||
vtr::Point<size_t> coordinate(x, y);
|
||||
return get_mutable_gsb(coordinate);
|
||||
}
|
||||
|
||||
/* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
||||
void DeviceRRGSB::build_cb_unique_module(const RRGraph& rr_graph, const t_rr_type& cb_type) {
|
||||
/* Make sure a clean start */
|
||||
|
|
|
@ -28,12 +28,12 @@ class DeviceRRGSB {
|
|||
public: /* Contructors */
|
||||
public: /* Accessors */
|
||||
vtr::Point<size_t> get_gsb_range() const; /* get the max coordinate of the switch block array */
|
||||
const RRGSB get_gsb(const vtr::Point<size_t>& coordinate) const; /* Get a rr switch block in the array with a coordinate */
|
||||
const RRGSB get_gsb(const size_t& x, const size_t& y) const; /* Get a rr switch block in the array with a coordinate */
|
||||
const RRGSB& get_gsb(const vtr::Point<size_t>& coordinate) const; /* Get a rr switch block in the array with a coordinate */
|
||||
const RRGSB& get_gsb(const size_t& x, const size_t& y) const; /* Get a rr switch block in the array with a coordinate */
|
||||
size_t get_num_gsb_unique_module() const; /* get the number of unique mirrors of GSB */
|
||||
size_t get_num_sb_unique_module() const; /* get the number of unique mirrors of switch blocks */
|
||||
const RRGSB get_sb_unique_module(const size_t& index) const; /* Get a rr switch block which a unique mirror */
|
||||
const RRGSB get_sb_unique_module(const vtr::Point<size_t>& coordinate) const; /* Get a rr switch block which a unique mirror */
|
||||
const RRGSB& get_sb_unique_module(const size_t& index) const; /* Get a rr switch block which a unique mirror */
|
||||
const RRGSB& get_sb_unique_module(const vtr::Point<size_t>& coordinate) const; /* Get a rr switch block which a unique mirror */
|
||||
const RRGSB& get_cb_unique_module(const t_rr_type& cb_type, const size_t& index) const; /* Get a rr switch block which a unique mirror */
|
||||
const RRGSB& get_cb_unique_module(const t_rr_type& cb_type, const vtr::Point<size_t>& coordinate) const;
|
||||
size_t get_num_cb_unique_module(const t_rr_type& cb_type) const; /* get the number of unique mirrors of CBs */
|
||||
|
@ -43,6 +43,8 @@ class DeviceRRGSB {
|
|||
void reserve_sb_unique_submodule_id(const vtr::Point<size_t>& coordinate); /* Pre-allocate the rr_sb_unique_module_id matrix that the device requires */
|
||||
void resize_upon_need(const vtr::Point<size_t>& coordinate); /* Resize the rr_switch_block array if needed */
|
||||
void add_rr_gsb(const vtr::Point<size_t>& coordinate, const RRGSB& rr_gsb); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
||||
RRGSB& get_mutable_gsb(const vtr::Point<size_t>& coordinate); /* Get a rr switch block in the array with a coordinate */
|
||||
RRGSB& get_mutable_gsb(const size_t& x, const size_t& y); /* Get a rr switch block in the array with a coordinate */
|
||||
void build_unique_module(const RRGraph& rr_graph); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
||||
void clear(); /* clean the content */
|
||||
private: /* Internal cleaners */
|
||||
|
|
|
@ -65,6 +65,7 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture");
|
||||
|
||||
CommandOptionId opt_activity_file = cmd.option("activity_file");
|
||||
CommandOptionId opt_sort_edge = cmd.option("sort_gsb_chan_node_in_edges");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* Annotate pb_type graphs
|
||||
|
@ -111,6 +112,11 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
openfpga_ctx.mutable_device_rr_gsb(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
if (true == cmd_context.option_enable(cmd, opt_sort_edge)) {
|
||||
sort_device_rr_gsb_chan_node_in_edges(g_vpr_ctx.device().rr_graph,
|
||||
openfpga_ctx.mutable_device_rr_gsb());
|
||||
}
|
||||
|
||||
/* Build multiplexer library */
|
||||
openfpga_ctx.mutable_mux_lib() = build_device_mux_library(g_vpr_ctx.device(),
|
||||
const_cast<const OpenfpgaContext&>(openfpga_ctx));
|
||||
|
|
|
@ -78,6 +78,9 @@ ShellCommandId add_openfpga_link_arch_command(openfpga::Shell<OpenfpgaContext>&
|
|||
CommandOptionId opt_act_file = shell_cmd.add_option("activity_file", true, "file path to the signal activity");
|
||||
shell_cmd.set_option_require_value(opt_act_file, openfpga::OPT_STRING);
|
||||
|
||||
/* Add an option '--sort_gsb_chan_node_in_edges'*/
|
||||
shell_cmd.add_option("sort_gsb_chan_node_in_edges", false, "Sort all the incoming edges for each routing track output node in General Switch Blocks (GSBs)");
|
||||
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd.add_option("verbose", false, "Show verbose outputs");
|
||||
|
||||
|
|
|
@ -238,12 +238,6 @@ void build_primitive_block_module(ModuleManager& module_manager,
|
|||
std::string memory_module_name = generate_memory_module_name(circuit_lib, primitive_model, sram_model, std::string(MEMORY_MODULE_POSTFIX));
|
||||
ModuleId memory_module = module_manager.find_module(memory_module_name);
|
||||
|
||||
/* Vectors to record all the memory modules have been added
|
||||
* They are used to add module nets of configuration bus
|
||||
*/
|
||||
std::vector<ModuleId> memory_modules;
|
||||
std::vector<size_t> memory_instances;
|
||||
|
||||
/* If there is no memory module required, we can skip the assocated net addition */
|
||||
if (ModuleId::INVALID() != memory_module) {
|
||||
size_t memory_instance_id = module_manager.num_instance(primitive_module, memory_module);
|
||||
|
@ -263,7 +257,7 @@ void build_primitive_block_module(ModuleManager& module_manager,
|
|||
/* Add all the nets to connect configuration ports from memory module to primitive modules
|
||||
* This is a one-shot addition that covers all the memory modules in this primitive module!
|
||||
*/
|
||||
if (false == memory_modules.empty()) {
|
||||
if (0 < module_manager.configurable_children(primitive_module).size()) {
|
||||
add_module_nets_memory_config_bus(module_manager, primitive_module,
|
||||
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
|
||||
}
|
||||
|
@ -878,7 +872,7 @@ void rec_build_logical_tile_modules(ModuleManager& module_manager,
|
|||
/* Add module nets to connect memory cells inside
|
||||
* This is a one-shot addition that covers all the memory modules in this pb module!
|
||||
*/
|
||||
if (false == memory_modules.empty()) {
|
||||
if (0 < module_manager.configurable_children(pb_module).size()) {
|
||||
add_module_nets_memory_config_bus(module_manager, pb_module,
|
||||
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "openfpga_reserved_words.h"
|
||||
#include "openfpga_naming.h"
|
||||
|
||||
#include "rr_gsb_utils.h"
|
||||
#include "openfpga_rr_graph_utils.h"
|
||||
#include "module_manager_utils.h"
|
||||
#include "build_module_graph_utils.h"
|
||||
|
@ -227,7 +228,7 @@ void build_switch_block_interc_modules(ModuleManager& module_manager,
|
|||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
if (false == rr_gsb.is_sb_node_passing_wire(rr_graph, chan_side, chan_node_id)) {
|
||||
driver_rr_nodes = get_rr_graph_configurable_driver_nodes(rr_graph, cur_rr_node);
|
||||
driver_rr_nodes = get_rr_gsb_chan_node_configurable_driver_nodes(rr_graph, rr_gsb, chan_side, chan_node_id);
|
||||
/* Special: if there are zero-driver nodes. We skip here */
|
||||
if (0 == driver_rr_nodes.size()) {
|
||||
return;
|
||||
|
|
|
@ -114,7 +114,7 @@ void build_switch_block_interc_bitstream(BitstreamManager& bitstream_manager,
|
|||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
if (false == rr_gsb.is_sb_node_passing_wire(rr_graph, chan_side, chan_node_id)) {
|
||||
driver_rr_nodes = get_rr_graph_configurable_driver_nodes(rr_graph, cur_rr_node);
|
||||
driver_rr_nodes = get_rr_gsb_chan_node_configurable_driver_nodes(rr_graph, rr_gsb, chan_side, chan_node_id);
|
||||
/* Special: if there are zero-driver nodes. We skip here */
|
||||
if (0 == driver_rr_nodes.size()) {
|
||||
return;
|
||||
|
|
|
@ -32,11 +32,25 @@ namespace openfpga {
|
|||
*******************************************************************/
|
||||
static
|
||||
std::string generate_verilog_undriven_local_wire_name(const ModuleManager& module_manager,
|
||||
const ModuleId& module,
|
||||
const ModulePortId& module_port_id) {
|
||||
return module_manager.module_port(module, module_port_id).get_name();
|
||||
const ModuleId& parent,
|
||||
const ModuleId& child,
|
||||
const size_t& instance_id,
|
||||
const ModulePortId& child_port_id) {
|
||||
std::string wire_name;
|
||||
if (!module_manager.instance_name(parent, child, instance_id).empty()) {
|
||||
wire_name = module_manager.instance_name(parent, child, instance_id);
|
||||
} else {
|
||||
wire_name = module_manager.module_name(parent) + std::string("_") + std::to_string(instance_id);
|
||||
wire_name += std::string("_");
|
||||
}
|
||||
|
||||
wire_name += std::string("_undriven_");
|
||||
wire_name += module_manager.module_port(child, child_port_id).get_name();
|
||||
|
||||
return wire_name;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Name a net for a local wire for a verilog module
|
||||
* 1. If this is a local wire, name it after the <src_module_name>_<instance_id>_<src_port_name>
|
||||
|
@ -176,7 +190,7 @@ std::map<std::string, std::vector<BasicPort>> find_verilog_module_local_wires(co
|
|||
}
|
||||
/* Reach here, we need a local wire, we will create a port only for the undriven pins of the port! */
|
||||
BasicPort instance_port;
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, child, child_port_id));
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, module_id, child, instance, child_port_id));
|
||||
/* We give the same port name as child module, this case happens to global ports */
|
||||
instance_port.set_width(*std::min_element(undriven_pins.begin(), undriven_pins.end()),
|
||||
*std::max_element(undriven_pins.begin(), undriven_pins.end()));
|
||||
|
@ -413,7 +427,7 @@ void write_verilog_instance_to_file(std::fstream& fp,
|
|||
BasicPort instance_port;
|
||||
if (ModuleNetId::INVALID() == net) {
|
||||
/* We give the same port name as child module, this case happens to global ports */
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, child_module, child_port_id));
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, parent_module, child_module, instance_id, child_port_id));
|
||||
instance_port.set_width(child_pin, child_pin);
|
||||
} else {
|
||||
/* Find the name for this child port */
|
||||
|
|
|
@ -36,4 +36,23 @@ bool connection_block_contain_only_routing_tracks(const RRGSB& rr_gsb,
|
|||
return routing_track_only;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Find the configurable driver nodes for a node in the rr_graph
|
||||
***********************************************************************/
|
||||
std::vector<RRNodeId> get_rr_gsb_chan_node_configurable_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRGSB& rr_gsb,
|
||||
const e_side& chan_side,
|
||||
const size_t& track_id) {
|
||||
std::vector<RRNodeId> driver_nodes;
|
||||
for (const RREdgeId& edge : rr_gsb.get_chan_node_in_edges(rr_graph, chan_side, track_id)) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -18,6 +18,11 @@ namespace openfpga {
|
|||
bool connection_block_contain_only_routing_tracks(const RRGSB& rr_gsb,
|
||||
const t_rr_type& cb_type);
|
||||
|
||||
std::vector<RRNodeId> get_rr_gsb_chan_node_configurable_driver_nodes(const RRGraph& rr_graph,
|
||||
const RRGSB& rr_gsb,
|
||||
const e_side& chan_side,
|
||||
const size_t& track_id);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,7 @@ read_openfpga_arch -f ./test_openfpga_arch/k6_frac_N10_40nm_openfpga.xml
|
|||
#write_openfpga_arch -f ./arch_echo.xml
|
||||
|
||||
# Annotate the OpenFPGA architecture to VPR data base
|
||||
link_openfpga_arch --activity_file ./test_blif/and.act #--verbose
|
||||
link_openfpga_arch --activity_file ./test_blif/and.act --sort_gsb_chan_node_in_edges #--verbose
|
||||
|
||||
# Check and correct any naming conflicts in the BLIF netlist
|
||||
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
|
||||
|
|
|
@ -499,6 +499,11 @@
|
|||
<cb type="pattern">1 1 1 1</cb>
|
||||
</segment>
|
||||
</segmentlist>
|
||||
|
||||
<directlist>
|
||||
<direct name="adder_carry" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
|
||||
</directlist>
|
||||
|
||||
<!--switch_segment_patterns>
|
||||
<pattern type="unbuf_sb" seg_length="1" seg_type="unidir" pattern_length="2">
|
||||
<unbuf_mux name="1"/>
|
||||
|
|
|
@ -499,6 +499,10 @@
|
|||
<cb type="pattern">1 1 1 1</cb>
|
||||
</segment>
|
||||
</segmentlist>
|
||||
|
||||
<directlist>
|
||||
<direct name="adder_carry" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
|
||||
</directlist>
|
||||
<!--switch_segment_patterns>
|
||||
<pattern type="unbuf_sb" seg_length="1" seg_type="unidir" pattern_length="2">
|
||||
<unbuf_mux name="1"/>
|
||||
|
|
|
@ -141,6 +141,36 @@ RRNodeId RRGSB::get_chan_node(const e_side& side, const size_t& track_id) const
|
|||
return chan_node_[side_manager.to_size_t()].get_node(track_id);
|
||||
}
|
||||
|
||||
std::vector<RREdgeId> RRGSB::get_chan_node_in_edges(const RRGraph& rr_graph,
|
||||
const e_side& side,
|
||||
const size_t& track_id) const {
|
||||
SideManager side_manager(side);
|
||||
VTR_ASSERT(side_manager.validate());
|
||||
|
||||
/* Ensure the side is valid in the context of this switch block */
|
||||
VTR_ASSERT( validate_side(side) );
|
||||
|
||||
/* Ensure the track is valid in the context of this switch block at a specific side */
|
||||
VTR_ASSERT( validate_track_id(side, track_id) );
|
||||
|
||||
/* The chan node must be an output port for the GSB, we allow users to access input edges*/
|
||||
VTR_ASSERT(OUT_PORT == get_chan_node_direction(side, track_id));
|
||||
|
||||
/* if sorted, we give sorted edges
|
||||
* if not sorted, we give the empty vector
|
||||
*/
|
||||
if (0 == chan_node_in_edges_.size()) {
|
||||
std::vector<RREdgeId> unsorted_edges;
|
||||
for (const RREdgeId& edge : rr_graph.node_in_edges(get_chan_node(side, track_id))) {
|
||||
unsorted_edges.push_back(edge);
|
||||
}
|
||||
|
||||
return unsorted_edges;
|
||||
}
|
||||
|
||||
return chan_node_in_edges_[side_manager.to_size_t()][track_id];
|
||||
}
|
||||
|
||||
/* get the segment id of a channel rr_node */
|
||||
RRSegmentId RRGSB::get_chan_node_segment(const e_side& side, const size_t& track_id) const {
|
||||
SideManager side_manager(side);
|
||||
|
@ -929,15 +959,9 @@ bool RRGSB::is_sb_node_mirror(const RRGraph& rr_graph,
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector<RREdgeId> node_in_edges;
|
||||
for (const RREdgeId& edge : rr_graph.node_in_edges(node)) {
|
||||
node_in_edges.push_back(edge);
|
||||
}
|
||||
|
||||
std::vector<RREdgeId> cand_node_in_edges;
|
||||
for (const RREdgeId& edge : rr_graph.node_in_edges(cand_node)) {
|
||||
cand_node_in_edges.push_back(edge);
|
||||
}
|
||||
/* Use unsorted/sorted edges */
|
||||
std::vector<RREdgeId> node_in_edges = get_chan_node_in_edges(rr_graph, node_side, track_id);
|
||||
std::vector<RREdgeId> cand_node_in_edges = cand. get_chan_node_in_edges(rr_graph, node_side, track_id);
|
||||
VTR_ASSERT(node_in_edges.size() == cand_node_in_edges.size());
|
||||
|
||||
for (size_t iedge = 0; iedge < node_in_edges.size(); ++iedge) {
|
||||
|
|
|
@ -83,6 +83,11 @@ class RRGSB {
|
|||
/* get a rr_node at a given side and track_id */
|
||||
RRNodeId get_chan_node(const e_side& side, const size_t& track_id) const;
|
||||
|
||||
/* get all the sorted incoming edges for a rr_node at a given side and track_id */
|
||||
std::vector<RREdgeId> get_chan_node_in_edges(const RRGraph& rr_graph,
|
||||
const e_side& side,
|
||||
const size_t& track_id) const;
|
||||
|
||||
/* get the segment id of a channel rr_node */
|
||||
RRSegmentId get_chan_node_segment(const e_side& side, const size_t& track_id) const;
|
||||
|
||||
|
|
|
@ -1032,10 +1032,18 @@ RRGSB build_rr_gsb(DeviceCoordinator& device_range,
|
|||
/* Fill opin_rr_nodes */
|
||||
/* Copy from temp_opin_rr_node to opin_rr_node */
|
||||
for (int inode = 0; inode < temp_num_opin_rr_nodes[0]; ++inode) {
|
||||
/* Skip Fc = 0 pins, they should NOT appear in the GSB connection */
|
||||
if (0. == grid[temp_opin_rr_node[0][inode]->xlow][temp_opin_rr_node[0][inode]->ylow].type->Fc[temp_opin_rr_node[0][inode]->ptc_num]) {
|
||||
continue;
|
||||
}
|
||||
/* Grid[x+1][y+1] Bottom side outputs pins */
|
||||
rr_gsb.add_opin_node(temp_opin_rr_node[0][inode], side_manager.get_side(), opin_grid_side[0]);
|
||||
}
|
||||
for (int inode = 0; inode < temp_num_opin_rr_nodes[1]; ++inode) {
|
||||
/* Skip Fc = 0 pins, they should NOT appear in the GSB connection */
|
||||
if (0. == grid[temp_opin_rr_node[1][inode]->xlow][temp_opin_rr_node[1][inode]->ylow].type->Fc[temp_opin_rr_node[1][inode]->ptc_num]) {
|
||||
continue;
|
||||
}
|
||||
/* Grid[x+1][y] TOP side outputs pins */
|
||||
rr_gsb.add_opin_node(temp_opin_rr_node[1][inode], side_manager.get_side(), opin_grid_side[1]);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,21 @@
|
|||
*******************************************************************/
|
||||
static
|
||||
std::string generate_verilog_undriven_local_wire_name(const ModuleManager& module_manager,
|
||||
const ModuleId& module,
|
||||
const ModulePortId& module_port_id) {
|
||||
return module_manager.module_port(module, module_port_id).get_name();
|
||||
const ModuleId& parent,
|
||||
const ModuleId& child,
|
||||
const size_t& instance_id,
|
||||
const ModulePortId& child_port_id) {
|
||||
std::string wire_name;
|
||||
if (!module_manager.instance_name(parent, child, instance_id).empty()) {
|
||||
wire_name = module_manager.instance_name(parent, child, instance_id);
|
||||
} else {
|
||||
wire_name = module_manager.module_name(parent) + std::string("_") + std::to_string(instance_id);
|
||||
wire_name += std::string("_");
|
||||
}
|
||||
|
||||
wire_name += module_manager.module_port(child, child_port_id).get_name();
|
||||
|
||||
return wire_name;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -164,7 +176,7 @@ std::map<std::string, std::vector<BasicPort>> find_verilog_module_local_wires(co
|
|||
}
|
||||
/* Reach here, we need a local wire, we will create a port only for the undriven pins of the port! */
|
||||
BasicPort instance_port;
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, child, child_port_id));
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, module_id, child, instance, child_port_id));
|
||||
/* We give the same port name as child module, this case happens to global ports */
|
||||
instance_port.set_width(*std::min_element(undriven_pins.begin(), undriven_pins.end()),
|
||||
*std::max_element(undriven_pins.begin(), undriven_pins.end()));
|
||||
|
@ -401,7 +413,7 @@ void write_verilog_instance_to_file(std::fstream& fp,
|
|||
BasicPort instance_port;
|
||||
if (ModuleNetId::INVALID() == net) {
|
||||
/* We give the same port name as child module, this case happens to global ports */
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, child_module, child_port_id));
|
||||
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, parent_module, child_module, instance_id, child_port_id));
|
||||
instance_port.set_width(child_pin, child_pin);
|
||||
} else {
|
||||
/* Find the name for this child port */
|
||||
|
|
Loading…
Reference in New Issue