update rr_gsb to build connection blocks

This commit is contained in:
tangxifan 2019-06-07 11:01:55 -06:00
parent 472aff5acb
commit c9f810ceb6
5 changed files with 135 additions and 50 deletions

View File

@ -33,6 +33,8 @@
#include "fpga_x2p_pbtypes_utils.h"
#include "fpga_x2p_bitstream_utils.h"
#include "fpga_x2p_mux_utils.h"
/* Determine the number of SRAM bit for a basis subckt of a multiplexer
* In general, the number of SRAM bits should be same as the number of inputs per level
* with one exception:

View File

@ -1,3 +1,5 @@
#ifndef FPGA_X2P_MUX_UTILS_H
#define FPGA_X2P_MUX_UTILS_H
int determine_num_sram_bits_mux_basis_subckt(t_spice_model* mux_spice_model,
int mux_size,
@ -82,4 +84,4 @@ t_llist* stats_spice_muxes(int num_switch,
t_det_routing_arch* routing_arch);
#endif

View File

@ -908,6 +908,7 @@ int count_num_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode,
}
/* Count the number of configuration bits of interconnection inside a pb_type in its default mode */
static
int count_num_reserved_conf_bits_pb_type_mode_interc(t_mode* cur_pb_type_mode,
enum e_sram_orgz cur_sram_orgz_type) {
int num_reserved_conf_bits = 0;
@ -2765,6 +2766,7 @@ int get_pb_graph_node_wired_lut_logical_block_index(t_pb_graph_node* cur_pb_grap
return wired_lut_lb_index;
}
static
void rec_sync_wired_lut_to_one_phy_pb(t_pb_graph_node* cur_pb_graph_node,
t_phy_pb* cur_phy_pb,
t_rr_node* op_pb_rr_graph) {

View File

@ -178,6 +178,7 @@ void alloc_and_load_rr_graph_rr_node(INOUTP t_rr_graph* local_rr_graph,
/* Returns the segment number at which the segment this track lies on *
* started. */
static
int get_rr_graph_seg_start(INP t_seg_details * seg_details, INP int itrack,
INP int chan_num, INP int seg_num) {
@ -895,6 +896,7 @@ void free_rr_graph_route_structs(t_rr_graph* local_rr_graph) { /* [0..num_rr_nod
return;
}
static
void free_rr_graph_trace_data(t_rr_graph* local_rr_graph,
t_trace *tptr) {

View File

@ -757,8 +757,9 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node,
return LL_device_rr_chan;
}
/* Build arrays for rr_nodes of each Switch Blocks
* A Switch Box subckt consists of following ports:
/* Build a General Switch Block (GSB)
* which includes:
* [I] A Switch Box subckt consists of following ports:
* 1. Channel Y [x][y] inputs
* 2. Channel X [x+1][y] inputs
* 3. Channel Y [x][y-1] outputs
@ -773,13 +774,13 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node,
* 12. Grid[x][y+1] Bottom side output pins
*
* -------------- --------------
* | | | |
* | | CBY | |
* | Grid | ChanY | Grid |
* | [x][y+1] | [x][y+1] | [x+1][y+1] |
* | | | |
* -------------- --------------
* ----------
* ChanX | Switch | ChanX
* ChanX & CBX | Switch | ChanX
* [x][y] | Box | [x+1][y]
* | [x][y] |
* ----------
@ -797,50 +798,57 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node,
* For channels chanX with DEC_DIRECTION on the left side, they should be marked as outputs
* For channels chanX with INC_DIRECTION on the right side, they should be marked as outputs
* For channels chanX with DEC_DIRECTION on the right side, they should be marked as inputs
*
* [II] A X-direction Connection Block [x][y]
* The connection block shares the same routing channel[x][y] with the Switch Block
* We just need to fill the ipin nodes at TOP and BOTTOM sides
* as well as properly fill the ipin_grid_side information
* [III] A Y-direction Connection Block [x][y+1]
* The connection block shares the same routing channel[x][y+1] with the Switch Block
* We just need to fill the ipin nodes at LEFT and RIGHT sides
* as well as properly fill the ipin_grid_side information
*/
static
RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
size_t sb_x, size_t sb_y,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices, int num_segments,
t_rr_indexed_data* LL_rr_indexed_data) {
RRGSB build_rr_gsb(DeviceCoordinator& device_range,
size_t sb_x, size_t sb_y,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices, int num_segments,
t_rr_indexed_data* LL_rr_indexed_data) {
/* Create an object to return */
RRGSB rr_switch_block;
RRGSB rr_gsb;
/* Check */
assert(sb_x <= device_range.get_x());
assert(sb_y <= device_range.get_y());
/* Coordinator initialization */
rr_switch_block.set_coordinator(sb_x, sb_y);
rr_gsb.set_coordinator(sb_x, sb_y);
/* Basic information*/
rr_switch_block.init_num_sides(4); /* Fixed number of sides */
rr_gsb.init_num_sides(4); /* Fixed number of sides */
/* Find all rr_nodes of channels */
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
for (size_t side = 0; side < rr_switch_block.get_num_sides(); ++side) {
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
/* Local variables inside this for loop */
Side side_manager(side);
DeviceCoordinator coordinator;
size_t ix = 0;
size_t iy = 0;
DeviceCoordinator coordinator = rr_gsb.get_side_block_coordinator(side_manager.get_side());
size_t ix = coordinator.get_x();
size_t iy = coordinator.get_y();
RRChan rr_chan;
int temp_num_opin_rr_nodes[2] = {0,0};
t_rr_node** temp_opin_rr_node[2] = {NULL, NULL};
enum e_side opin_grid_side[2] = {NUM_SIDES, NUM_SIDES};
enum PORTS chan_dir_to_port_dir_mapping[2] = {OUT_PORT, IN_PORT}; /* 0: INC_DIRECTION => ?; 1: DEC_DIRECTION => ? */
switch (side) {
case 0: /* TOP */
case TOP: /* TOP = 0 */
/* For the bording, we should take special care */
if (sb_y == device_range.get_y()) {
rr_switch_block.clear_one_side(side_manager.get_side());
rr_gsb.clear_one_side(side_manager.get_side());
break;
}
/* Routing channels*/
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Create a rr_chan object and check if it is unique in the graph */
rr_chan = build_one_rr_chan(CHANY, ix, iy,
@ -849,6 +857,7 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
chan_dir_to_port_dir_mapping[0] = OUT_PORT; /* INC_DIRECTION => OUT_PORT */
chan_dir_to_port_dir_mapping[1] = IN_PORT; /* DEC_DIRECTION => IN_PORT */
/* Build the Switch block: opin and opin_grid_side */
/* Include Grid[x][y+1] RIGHT side outputs pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
OPIN, sb_x, sb_y + 1, 1,
@ -862,18 +871,15 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
/* Grid[x][y+1] RIGHT side outputs pins */
opin_grid_side[0] = RIGHT;
/* Grid[x+1][y+1] left side outputs pins */
opin_grid_side[1] = LEFT;
opin_grid_side[1] = LEFT;
break;
case 1: /* RIGHT */
case RIGHT: /* RIGHT = 1 */
/* For the bording, we should take special care */
if (sb_x == device_range.get_x()) {
rr_switch_block.clear_one_side(side_manager.get_side());
rr_gsb.clear_one_side(side_manager.get_side());
break;
}
/* Routing channels*/
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Collect rr_nodes for Tracks for top: chany[x][y+1] */
/* Create a rr_chan object and check if it is unique in the graph */
@ -883,6 +889,7 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
chan_dir_to_port_dir_mapping[0] = OUT_PORT; /* INC_DIRECTION => OUT_PORT */
chan_dir_to_port_dir_mapping[1] = IN_PORT; /* DEC_DIRECTION => IN_PORT */
/* Build the Switch block: opin and opin_grid_side */
/* include Grid[x+1][y+1] Bottom side output pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
OPIN, sb_x + 1, sb_y + 1, 2,
@ -897,16 +904,13 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
/* Grid[x+1][y] TOP side outputs pins */
opin_grid_side[1] = TOP;
break;
case 2:
case BOTTOM: /* BOTTOM = 2*/
/* For the bording, we should take special care */
if (sb_y == 0) {
rr_switch_block.clear_one_side(side_manager.get_side());
rr_gsb.clear_one_side(side_manager.get_side());
break;
}
/* Routing channels*/
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Collect rr_nodes for Tracks for bottom: chany[x][y] */
/* Create a rr_chan object and check if it is unique in the graph */
@ -916,11 +920,12 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
chan_dir_to_port_dir_mapping[0] = IN_PORT; /* INC_DIRECTION => IN_PORT */
chan_dir_to_port_dir_mapping[1] = OUT_PORT; /* DEC_DIRECTION => OUT_PORT */
/* TODO: include Grid[x+1][y] Left side output pins */
/* Build the Switch block: opin and opin_grid_side */
/* include Grid[x+1][y] Left side output pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
OPIN, sb_x + 1, sb_y, 3,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
/* TODO: include Grid[x][y] Right side output pins */
/* include Grid[x][y] Right side output pins */
temp_opin_rr_node[1] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[1],
OPIN, sb_x, sb_y, 1,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
@ -930,16 +935,13 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
/* Grid[x][y] RIGHT side outputs pins */
opin_grid_side[1] = RIGHT;
break;
case 3:
case LEFT: /* LEFT = 3 */
/* For the bording, we should take special care */
if (sb_x == 0) {
rr_switch_block.clear_one_side(side_manager.get_side());
rr_gsb.clear_one_side(side_manager.get_side());
break;
}
/* Routing channels*/
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Collect rr_nodes for Tracks for left: chanx[x][y] */
/* Create a rr_chan object and check if it is unique in the graph */
@ -949,6 +951,7 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
chan_dir_to_port_dir_mapping[0] = IN_PORT; /* INC_DIRECTION => IN_PORT */
chan_dir_to_port_dir_mapping[1] = OUT_PORT; /* DEC_DIRECTION => OUT_PORT */
/* Build the Switch block: opin and opin_grid_side */
/* include Grid[x][y+1] Bottom side outputs pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
OPIN, sb_x, sb_y + 1, 2,
@ -984,23 +987,23 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
}
}
/* Fill chan_rr_nodes */
rr_switch_block.add_chan_node(side_manager.get_side(), rr_chan, rr_chan_dir);
rr_gsb.add_chan_node(side_manager.get_side(), rr_chan, rr_chan_dir);
}
/* 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) {
/* Grid[x+1][y+1] Bottom side outputs pins */
rr_switch_block.add_opin_node(temp_opin_rr_node[0][inode], side_manager.get_side(), opin_grid_side[0]);
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) {
/* Grid[x+1][y] TOP side outputs pins */
rr_switch_block.add_opin_node(temp_opin_rr_node[1][inode], side_manager.get_side(), opin_grid_side[1]);
rr_gsb.add_opin_node(temp_opin_rr_node[1][inode], side_manager.get_side(), opin_grid_side[1]);
}
/* Clean ipin_rr_nodes */
/* We do not have any IPIN for a Switch Block */
rr_switch_block.clear_ipin_nodes(side_manager.get_side());
rr_gsb.clear_ipin_nodes(side_manager.get_side());
/* Free */
temp_num_opin_rr_nodes[0] = 0;
@ -1014,9 +1017,83 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
opin_grid_side[1] = NUM_SIDES;
}
/* Build the connection block */
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
/* Local variables inside this for loop */
Side side_manager(side);
size_t ix;
size_t iy;
enum e_side chan_side;
int num_temp_ipin_rr_nodes = 0;
t_rr_node** temp_ipin_rr_node = NULL;
enum e_side ipin_rr_node_grid_side;
switch (side) {
case TOP: /* TOP = 0 */
/* For the bording, we should take special care */
/* Check if left side chan width is 0 or not */
chan_side = LEFT;
/* Build the connection block: ipin and ipin_grid_side */
/* BOTTOM side INPUT Pins of Grid[x][y+1] */
ix = rr_gsb.get_sb_x();
iy = rr_gsb.get_sb_y() + 1;
ipin_rr_node_grid_side = BOTTOM;
break;
case RIGHT: /* RIGHT = 1 */
/* For the bording, we should take special care */
/* Check if TOP side chan width is 0 or not */
chan_side = TOP;
/* Build the connection block: ipin and ipin_grid_side */
/* LEFT side INPUT Pins of Grid[x+1][y+1] */
ix = rr_gsb.get_sb_x() + 1;
iy = rr_gsb.get_sb_y() + 1;
ipin_rr_node_grid_side = LEFT;
break;
case BOTTOM: /* BOTTOM = 2*/
/* For the bording, we should take special care */
/* Check if left side chan width is 0 or not */
chan_side = LEFT;
/* Build the connection block: ipin and ipin_grid_side */
/* TOP side INPUT Pins of Grid[x][y] */
ix = rr_gsb.get_sb_x();
iy = rr_gsb.get_sb_y();
ipin_rr_node_grid_side = TOP;
break;
case LEFT: /* LEFT = 3 */
/* For the bording, we should take special care */
/* Check if left side chan width is 0 or not */
chan_side = TOP;
/* Build the connection block: ipin and ipin_grid_side */
/* RIGHT side INPUT Pins of Grid[x][y+1] */
ix = rr_gsb.get_sb_x();
iy = rr_gsb.get_sb_y() + 1;
ipin_rr_node_grid_side = RIGHT;
break;
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File:%s, [LINE%d])Invalid side index!\n",
__FILE__, __LINE__);
exit(1);
}
/* If there is no channel at this side, we skip ipin_node annotation */
if (0 == rr_gsb.get_chan_width(chan_side)) {
continue;
}
/* Collect IPIN rr_nodes*/
temp_ipin_rr_node = get_grid_side_pin_rr_nodes(&(num_temp_ipin_rr_nodes),
IPIN, ix, iy, ipin_rr_node_grid_side,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
/* Fill the ipin nodes of RRGSB */
for (int inode = 0; inode < num_temp_ipin_rr_nodes; ++inode) {
rr_gsb.add_ipin_node(temp_ipin_rr_node[inode], side_manager.get_side(), ipin_rr_node_grid_side);
}
/* Free */
num_temp_ipin_rr_nodes = 0;
my_free(temp_ipin_rr_node);
}
return rr_switch_block;
return rr_gsb;
}
/* Rotate the Switch block and try to add to rotatable mirrors */
@ -1191,10 +1268,10 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
/* For each switch block, determine the size of array */
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
RRGSB rr_sb = build_rr_switch_block(sb_range, ix, iy,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
RRGSB rr_sb = build_rr_gsb(sb_range, ix, iy,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
DeviceCoordinator sb_coordinator = rr_sb.get_sb_coordinator();
LL_drive_rr_gsb.add_rr_switch_block(sb_coordinator, rr_sb);
}