start plug in tileable rr_graph builder
This commit is contained in:
parent
3eb59d201f
commit
245a379c4f
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,33 +320,54 @@ void create_rr_graph(const t_graph_type graph_type,
|
||||||
|
|
||||||
free_rr_graph();
|
free_rr_graph();
|
||||||
|
|
||||||
build_rr_graph(graph_type,
|
if (GRAPH_UNIDIR_TILEABLE != graph_type) {
|
||||||
block_types,
|
build_rr_graph(graph_type,
|
||||||
grid,
|
block_types,
|
||||||
nodes_per_chan,
|
grid,
|
||||||
det_routing_arch->switch_block_type,
|
nodes_per_chan,
|
||||||
det_routing_arch->Fs,
|
det_routing_arch->switch_block_type,
|
||||||
det_routing_arch->switchblocks,
|
det_routing_arch->Fs,
|
||||||
num_arch_switches,
|
det_routing_arch->switchblocks,
|
||||||
segment_inf,
|
num_arch_switches,
|
||||||
det_routing_arch->global_route_switch,
|
segment_inf,
|
||||||
det_routing_arch->wire_to_arch_ipin_switch,
|
det_routing_arch->global_route_switch,
|
||||||
det_routing_arch->delayless_switch,
|
det_routing_arch->wire_to_arch_ipin_switch,
|
||||||
det_routing_arch->R_minW_nmos,
|
det_routing_arch->delayless_switch,
|
||||||
det_routing_arch->R_minW_pmos,
|
det_routing_arch->R_minW_nmos,
|
||||||
base_cost_type,
|
det_routing_arch->R_minW_pmos,
|
||||||
trim_empty_channels,
|
base_cost_type,
|
||||||
trim_obs_channels,
|
trim_empty_channels,
|
||||||
directs, num_directs,
|
trim_obs_channels,
|
||||||
&det_routing_arch->wire_to_rr_ipin_switch,
|
directs, num_directs,
|
||||||
Warnings);
|
&det_routing_arch->wire_to_rr_ipin_switch,
|
||||||
|
Warnings);
|
||||||
|
|
||||||
if (clock_modeling == DEDICATED_NETWORK) {
|
if (clock_modeling == DEDICATED_NETWORK) {
|
||||||
ClockRRGraphBuilder::create_and_append_clock_rr_graph(segment_inf,
|
ClockRRGraphBuilder::create_and_append_clock_rr_graph(segment_inf,
|
||||||
det_routing_arch->R_minW_nmos,
|
det_routing_arch->R_minW_nmos,
|
||||||
det_routing_arch->R_minW_pmos,
|
det_routing_arch->R_minW_pmos,
|
||||||
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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue