update rr_gsb to build connection blocks
This commit is contained in:
parent
472aff5acb
commit
c9f810ceb6
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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,
|
||||
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,
|
||||
|
@ -864,16 +873,13 @@ RRGSB build_rr_switch_block(DeviceCoordinator& device_range,
|
|||
/* Grid[x+1][y+1] left side outputs pins */
|
||||
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;
|
||||
|
||||
return rr_switch_block;
|
||||
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_gsb;
|
||||
}
|
||||
|
||||
/* Rotate the Switch block and try to add to rotatable mirrors */
|
||||
|
@ -1191,7 +1268,7 @@ 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,
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue