diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c index 6ea99ef52..9ae14af6c 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c @@ -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: diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h index 0ea801cfd..598a1ece4 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.h @@ -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 diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c index a363a140a..ed0898f73 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c @@ -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) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c index e3e6b416f..711b6ddc0 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_rr_graph_utils.c @@ -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) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c index 8a3578f5f..a27fdabd9 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c @@ -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); }