start plug in tileable rr_graph builder

This commit is contained in:
tangxifan 2020-03-06 16:03:00 -07:00
parent 3eb59d201f
commit 245a379c4f
5 changed files with 153 additions and 26 deletions

View File

@ -148,6 +148,11 @@ struct DeviceContext : public Context {
/* RRGraph object */ /* RRGraph object */
RRGraph rr_graph; RRGraph rr_graph;
/* Track ids for each rr_node in the rr_graph.
* This is used by drawer for tileable routing resource graph
*/
std::map<RRNodeId, std::vector<size_t>> rr_node_track_ids;
/* Structures to define the routing architecture of the FPGA. */ /* Structures to define the routing architecture of the FPGA. */
std::vector<t_rr_node> rr_nodes; /* autogenerated in build_rr_graph */ std::vector<t_rr_node> rr_nodes; /* autogenerated in build_rr_graph */

View File

@ -1004,6 +1004,12 @@ struct t_det_routing_arch {
enum e_switch_block_type switch_block_type; enum e_switch_block_type switch_block_type;
std::vector<t_switchblock_inf> switchblocks; std::vector<t_switchblock_inf> switchblocks;
/* Xifan Tang: subtype of switch blocks.
* Sub type and Fs are applied to pass tracks
*/
int subFs;
enum e_switch_block_type switch_block_subtype;
short global_route_switch; short global_route_switch;
short delayless_switch; short delayless_switch;
int wire_to_arch_ipin_switch; int wire_to_arch_ipin_switch;

View File

@ -41,6 +41,8 @@
#include "rr_graph_obj_util.h" #include "rr_graph_obj_util.h"
#include "check_rr_graph_obj.h" #include "check_rr_graph_obj.h"
#include "tileable_rr_graph_builder.h"
#include "clb2clb_directs.h" #include "clb2clb_directs.h"
//#define VERBOSE //#define VERBOSE
@ -318,6 +320,7 @@ void create_rr_graph(const t_graph_type graph_type,
free_rr_graph(); free_rr_graph();
if (GRAPH_UNIDIR_TILEABLE != graph_type) {
build_rr_graph(graph_type, build_rr_graph(graph_type,
block_types, block_types,
grid, grid,
@ -346,6 +349,26 @@ void create_rr_graph(const t_graph_type graph_type,
det_routing_arch->wire_to_rr_ipin_switch, det_routing_arch->wire_to_rr_ipin_switch,
base_cost_type); base_cost_type);
} }
} else {
/* We do not support dedicated network for clocks in tileable rr_graph generation */
openfpga::build_tileable_unidir_rr_graph(block_types,
grid,
nodes_per_chan,
det_routing_arch->switch_block_type,
det_routing_arch->Fs,
det_routing_arch->switch_block_subtype,
det_routing_arch->subFs,
segment_inf,
det_routing_arch->wire_to_arch_ipin_switch,
det_routing_arch->delayless_switch,
det_routing_arch->R_minW_nmos,
det_routing_arch->R_minW_pmos,
base_cost_type,
directs, num_directs,
&det_routing_arch->wire_to_rr_ipin_switch,
false, /* Do not allow passing tracks to be wired to the same routing channels */
Warnings);
}
/* Xifan Tang - Create rr_graph object: load rr_nodes to the object */ /* Xifan Tang - Create rr_graph object: load rr_nodes to the object */
//convert_rr_graph(segment_inf); //convert_rr_graph(segment_inf);

View File

@ -266,6 +266,9 @@ void build_tileable_unidir_rr_graph(const std::vector<t_physical_tile_type>& typ
/* Save the channel widths for the newly constructed graph */ /* Save the channel widths for the newly constructed graph */
device_ctx.chan_width = chan_width; device_ctx.chan_width = chan_width;
/* Save the track ids for tileable routing resource graph */
device_ctx.rr_node_track_ids = rr_node_track_ids;
/************************************************************************ /************************************************************************
* Allocate external data structures * Allocate external data structures
* a. cost_index * a. cost_index

View File

@ -1316,4 +1316,94 @@ t_pin2track_map build_gsb_opin_to_track_map(const RRGraph& rr_graph,
return opin2track_map; return opin2track_map;
} }
/************************************************************************
* Add all direct clb-pin-to-clb-pin edges to given opin
***********************************************************************/
void build_direct_connections_for_one_gsb(RRGraph& rr_graph,
const DeviceGrid& grids,
const vtr::Point<size_t>& from_grid_coordinate,
const RRSwitchId& delayless_switch,
const std::vector<t_direct_inf>& directs,
const std::vector<t_clb_to_clb_directs>& clb_to_clb_directs) {
VTR_ASSERT(directs.size() == clb_to_clb_directs.size());
const t_grid_tile& from_grid = grids[from_grid_coordinate.x()][from_grid_coordinate.y()];
t_physical_tile_type_ptr grid_type = from_grid.type;
/* Iterate through all direct connections */
for (size_t i = 0; i < directs.size(); ++i) {
/* Bypass unmatched direct clb-to-clb connections */
if (grid_type != clb_to_clb_directs[i].from_clb_type) {
continue;
}
/* This opin is specified to connect directly to an ipin,
* now compute which ipin to connect to
*/
vtr::Point<size_t> to_grid_coordinate(from_grid_coordinate.x() + directs[i].x_offset,
from_grid_coordinate.y() + directs[i].y_offset);
/* Bypass unmatched direct clb-to-clb connections */
t_physical_tile_type_ptr to_grid_type = grids[to_grid_coordinate.x()][to_grid_coordinate.y()].type;
/* Check if to_grid if the same grid */
if (to_grid_type != clb_to_clb_directs[i].to_clb_type) {
continue;
}
bool swap;
int max_index, min_index;
/* Compute index of opin with regards to given pins */
if ( clb_to_clb_directs[i].from_clb_pin_start_index
> clb_to_clb_directs[i].from_clb_pin_end_index) {
swap = true;
max_index = clb_to_clb_directs[i].from_clb_pin_start_index;
min_index = clb_to_clb_directs[i].from_clb_pin_end_index;
} else {
swap = false;
min_index = clb_to_clb_directs[i].from_clb_pin_start_index;
max_index = clb_to_clb_directs[i].from_clb_pin_end_index;
}
/* get every opin in the range */
for (int opin = min_index; opin <= max_index; ++opin) {
int offset = opin - min_index;
if ( (to_grid_coordinate.x() < grids.width() - 1)
&& (to_grid_coordinate.y() < grids.height() - 1) ) {
int ipin = OPEN;
if ( clb_to_clb_directs[i].to_clb_pin_start_index
> clb_to_clb_directs[i].to_clb_pin_end_index) {
if (true == swap) {
ipin = clb_to_clb_directs[i].to_clb_pin_end_index + offset;
} else {
ipin = clb_to_clb_directs[i].to_clb_pin_start_index - offset;
}
} else {
if(true == swap) {
ipin = clb_to_clb_directs[i].to_clb_pin_end_index - offset;
} else {
ipin = clb_to_clb_directs[i].to_clb_pin_start_index + offset;
}
}
/* Get the pin index in the rr_graph */
int from_grid_width_ofs = from_grid.width_offset;
int from_grid_height_ofs = from_grid.height_offset;
int to_grid_width_ofs = grids[to_grid_coordinate.x()][to_grid_coordinate.y()].width_offset;
int to_grid_height_ofs = grids[to_grid_coordinate.x()][to_grid_coordinate.y()].height_offset;
const RRNodeId& opin_node_id = rr_graph.find_node(from_grid_coordinate.x() - from_grid_width_ofs,
from_grid_coordinate.y() - from_grid_height_ofs,
OPIN, opin);
const RRNodeId& ipin_node_id = rr_graph.find_node(to_grid_coordinate.x() - to_grid_width_ofs,
to_grid_coordinate.y() - to_grid_height_ofs,
IPIN, ipin);
/* add edges to the opin_node */
rr_graph.create_edge(opin_node_id, ipin_node_id,
delayless_switch);
}
}
}
}
} /* end namespace openfpga */ } /* end namespace openfpga */