11 #define ALLOW_SWITCH_OFF 
   16 #define ENABLE_REVERSE 0 
   43         short from_node_switch, 
short to_node_switch, 
short switch_types[2]);
 
   52         INP boolean from_is_sbox, 
INP int from_switch,
 
   53         INOUTP boolean * L_rr_edge_done,
 
   58         INP int from_track, 
INP int to_chan, 
INP int to_seg, 
INP int to_sb,
 
   61         INP int Fs_per_side, 
INP int *opin_mux_size,
 
   62         INP short *****sblock_pattern, 
INP t_ivec *** L_rr_node_indices,
 
   76         OUTP int *num_wire_muxes);
 
   82         INP int *opin_mux_size, 
INP t_ivec *** L_rr_node_indices);
 
   87         OUTP int *num_incoming_wires, 
OUTP int *num_ending_wires);
 
  113     int i, imax, freq_sum, assigned, size;
 
  114     double scale, 
max, reduce;
 
  116     result = (
int *) 
my_malloc(
sizeof(
int) * num_seg_types);
 
  117     demand = (
double *) 
my_malloc(
sizeof(
double) * num_seg_types);
 
  123     for (i = 0; i < num_seg_types; ++i) {
 
  124         scale *= segment_inf[i].length;
 
  125         freq_sum += segment_inf[i].frequency;
 
  127     reduce = scale * freq_sum;
 
  130     for (i = 0; i < num_seg_types; ++i) {
 
  132         demand[i] = scale * num_sets * segment_inf[i].frequency;
 
  133         if (use_full_seg_groups) {
 
  134             demand[i] /= segment_inf[i].length;
 
  142     while (assigned < num_sets) {
 
  145         for (i = 0; i < num_seg_types; ++i) {
 
  146             if (demand[i] > max) {
 
  153         size = (use_full_seg_groups ? segment_inf[imax].length : 1);
 
  154         demand[imax] -= reduce;
 
  155         result[imax] += size;
 
  160     if ((assigned - num_sets) > (size / 2)) {
 
  161         result[imax] -= size;
 
  177         INP boolean use_full_seg_groups, 
INP boolean is_global_graph,
 
  189     int i, cur_track, ntracks, itrack, length, j, index;
 
  190     int wire_switch, opin_switch, fac, num_sets, tmp;
 
  191     int group_start, first_track;
 
  192     int *sets_per_seg_type = NULL;
 
  203     assert(*nodes_per_chan % fac == 0);
 
  207             num_seg_types, segment_inf, use_full_seg_groups);
 
  211     for (i = 0; i < num_seg_types; ++i) {
 
  212         tmp += sets_per_seg_type[i] * fac;
 
  214     assert(use_full_seg_groups || (tmp == *nodes_per_chan));
 
  215     *nodes_per_chan = tmp;
 
  222     for (i = 0; i < num_seg_types; ++i) {
 
  223         first_track = cur_track;
 
  225         num_sets = sets_per_seg_type[i];
 
  226         ntracks = fac * num_sets;
 
  231         longline = segment_inf[i].longline;
 
  232         length = segment_inf[i].length;
 
  237         wire_switch = segment_inf[i].wire_switch;
 
  238         opin_switch = segment_inf[i].opin_switch;
 
  244         for (itrack = 0; itrack < ntracks; itrack++) {
 
  247             if ((itrack / fac) % length == 0 && (itrack % fac) == 0) {
 
  248                 group_start = cur_track;
 
  251             seg_details[cur_track].
length = length;
 
  252             seg_details[cur_track].
longline = longline;
 
  260             seg_details[cur_track].
start = (cur_track / fac) % length + 1;
 
  266                     std::min(ntracks + first_track - group_start,
 
  268             assert(0 == seg_details[cur_track].group_size % fac);
 
  269             if (0 == seg_details[cur_track].group_size) {
 
  270                 seg_details[cur_track].
group_size = length * fac;
 
  276                     length * 
sizeof(
boolean));
 
  278                     (length + 1) * 
sizeof(
boolean));
 
  279             for (j = 0; j < length; ++j) {
 
  280                 if (is_global_graph) {
 
  281                     seg_details[cur_track].
cb[j] = 
TRUE;
 
  287                         index = (index + itrack) % length;
 
  291                     if (itrack % fac == 1) {
 
  292                         index = (length - 1) - j;
 
  296                     index = j % segment_inf[i].cb_len;
 
  297                     seg_details[cur_track].
cb[j] = segment_inf[i].cb[index];
 
  300             for (j = 0; j < (length + 1); ++j) {
 
  301                 if (is_global_graph) {
 
  302                     seg_details[cur_track].
sb[j] = 
TRUE;
 
  308                         index = (index + itrack) % (length + 1);
 
  312                     if (itrack % fac == 1) {
 
  313                         index = ((length + 1) - 1) - j;
 
  317                     index = j % segment_inf[i].sb_len;
 
  318                     seg_details[cur_track].
sb[j] = segment_inf[i].sb[index];
 
  322             seg_details[cur_track].
Rmetal = segment_inf[i].Rmetal;
 
  323             seg_details[cur_track].
Cmetal = segment_inf[i].Cmetal;
 
  337             switch (segment_inf[i].directionality) {
 
  346             seg_details[cur_track].
index = i;
 
  353     free(sets_per_seg_type);
 
  364     for (i = 0; i < nodes_per_chan; i++) {
 
  365         free(seg_details[i].cb);
 
  366         free(seg_details[i].sb);
 
  378     const char *drivers_names[] = { 
"multi_buffered", 
"single" };
 
  379     const char *direction_names[] = { 
"inc_direction", 
"dec_direction",
 
  384     for (i = 0; i < nodes_per_chan; i++) {
 
  385         fprintf(fp, 
"Track: %d.\n", i);
 
  386         fprintf(fp, 
"Length: %d,  Start: %d,  Long line: %d  " 
  387                 "wire_switch: %d  opin_switch: %d.\n", seg_details[i].length,
 
  388                 seg_details[i].start, seg_details[i].longline,
 
  389                 seg_details[i].wire_switch, seg_details[i].opin_switch);
 
  391         fprintf(fp, 
"Rmetal: %g  Cmetal: %g\n", seg_details[i].Rmetal,
 
  392                 seg_details[i].Cmetal);
 
  394         fprintf(fp, 
"Direction: %s  Drivers: %s\n",
 
  395                 direction_names[seg_details[i].direction],
 
  396                 drivers_names[seg_details[i].drivers]);
 
  398         fprintf(fp, 
"cb list:  ");
 
  399         for (j = 0; j < seg_details[i].
length; j++)
 
  400             fprintf(fp, 
"%d ", seg_details[i].cb[j]);
 
  403         fprintf(fp, 
"sb list: ");
 
  404         for (j = 0; j <= seg_details[i].
length; j++)
 
  405             fprintf(fp, 
"%d ", seg_details[i].sb[j]);
 
  417         INP int chan_num, 
INP int seg_num) {
 
  419     int seg_start, length, start;
 
  422     if (
FALSE == seg_details[itrack].longline) {
 
  424         length = seg_details[itrack].length;
 
  425         start = seg_details[itrack].start;
 
  431         assert(start <= length);
 
  437         seg_start = seg_num - (seg_num + length + chan_num - start) % length;
 
  447         INP int chan_num, 
INP int seg_max) {
 
  448     int len, ofs, end, first_full;
 
  450     len = seg_details[itrack].length;
 
  451     ofs = seg_details[itrack].start;
 
  454     end = istart + len - 1;
 
  460         first_full = (len - (chan_num % len) + ofs - 1) % len + 1;
 
  461         if (first_full > 1) {
 
  463             end = first_full - 1;
 
  480         INP int Fc, 
INP boolean * L_rr_edge_done,
 
  483     int iside, num_conn, ofs, tr_i, tr_j, chan, seg;
 
  484     int to_track, to_switch, to_node, iconn;
 
  485     int is_connected_track;
 
  495     for (iside = 0; iside < 4; iside++) {
 
  498         tr_i = ((iside == 
LEFT) ? (i - 1) : i);
 
  499         tr_j = ((iside == 
BOTTOM) ? (j - 1) : j);
 
  503         chan = ((to_type == 
CHANX) ? tr_j : tr_i);
 
  504         seg = ((to_type == 
CHANX) ? tr_i : tr_j);
 
  507         if ((tr_i < 0) || (tr_i > 
nx)) {
 
  510         if ((tr_j < 0) || (tr_j > 
ny)) {
 
  513         if ((
CHANX == to_type) && (tr_i < 1)) {
 
  516         if ((
CHANY == to_type) && (tr_j < 1)) {
 
  520         is_connected_track = 
FALSE;
 
  523         for (iconn = 0; iconn < Fc; ++iconn) {
 
  524             to_track = opin_to_track_map[type->
index][ipin][ofs][iside][iconn];
 
  527             if (
OPEN == to_track || is_connected_track) {
 
  528                 is_connected_track = 
TRUE;
 
  530                         OPEN == opin_to_track_map[type-> index][ipin][ofs][iside] [0]);
 
  536                 to_switch = seg_details[to_track].wire_switch;
 
  542                 L_rr_edge_done[to_node] = 
TRUE;
 
  554         INOUTP boolean * L_rr_edge_done, 
INP int max_len,
 
  555         INP int nodes_per_chan, 
INP t_ivec *** L_rr_node_indices,
 
  556         OUTP boolean * Fc_clipped) {
 
  561     int *inc_muxes = NULL;
 
  562     int *dec_muxes = NULL;
 
  563     int num_inc_muxes, num_dec_muxes, iconn;
 
  564     int inc_inode, dec_inode;
 
  565     int inc_mux, dec_mux;
 
  566     int inc_track, dec_track;
 
  576     x = ((
CHANX == chan_type) ? seg : chan);
 
  577     y = ((
CHANX == chan_type) ? chan : seg);
 
  581             nodes_per_chan, &num_inc_muxes);
 
  583             nodes_per_chan, &num_dec_muxes);
 
  586     if (((Fc / 2) > num_inc_muxes) || ((Fc / 2) > num_dec_muxes)) {
 
  588         Fc = 2 * 
std::min(num_inc_muxes, num_dec_muxes);
 
  593     for (iconn = 0; iconn < (Fc / 2); ++iconn) {
 
  595         inc_mux = Fc_ofs[chan][seg] % num_inc_muxes;
 
  596         dec_mux = Fc_ofs[chan][seg] % num_dec_muxes;
 
  600         inc_track = inc_muxes[inc_mux];
 
  601         dec_track = dec_muxes[dec_mux];
 
  610         if (
FALSE == L_rr_edge_done[inc_inode]) {
 
  611             L_rr_edge_done[inc_inode] = 
TRUE;
 
  613                     seg_details[inc_track].opin_switch);
 
  616         if (
FALSE == L_rr_edge_done[dec_inode]) {
 
  617             L_rr_edge_done[dec_inode] = 
TRUE;
 
  619                     seg_details[dec_track].opin_switch);
 
  640     int length, ofs, start_seg;
 
  642     length = seg_details[track].length;
 
  647     ofs = seg - start_seg;
 
  650     assert(ofs < length);
 
  654         ofs = (length - 1) - ofs;
 
  657     return seg_details[track].cb[ofs];
 
  663     int chan, seg, track, start, inode;
 
  666     for (chan = 0; chan < num_chans; ++chan) {
 
  669         indices[type][chan][0].nelem = 0;
 
  670         indices[type][chan][0].list = NULL;
 
  672         for (seg = 1; seg < chan_len; ++seg) {
 
  674             indices[type][chan][seg].nelem = nodes_per_chan;
 
  675             indices[type][chan][seg].list = (
int *) 
my_malloc(
 
  676                     sizeof(
int) * nodes_per_chan);
 
  677             for (track = 0; track < nodes_per_chan; ++track) {
 
  678                 indices[type][chan][seg].list[track] = 
OPEN;
 
  683     for (chan = 0; chan < num_chans; ++chan) {
 
  684         for (seg = 1; seg < chan_len; ++seg) {
 
  686             for (track = 0; track < indices[type][chan][seg].nelem; ++track) {
 
  691                 inode = indices[type][chan][start].list[track];
 
  696                     indices[type][chan][start].list[track] = inode;
 
  700                 indices[type][chan][seg].list[track] = inode;
 
  723     for (i = 0; i <= (L_nx + 1); ++i) {
 
  726         for (j = 0; j <= (L_ny + 1); ++j) {
 
  736     for (i = 0; i <= (L_nx + 1); i++) {
 
  737         for (j = 0; j <= (L_ny + 1); j++) {
 
  748                     for (k = 0; k < tmp.
nelem; ++k) {
 
  749                         tmp.
list[k] = *index;
 
  753                 indices[
SINK][i][j] = tmp;
 
  761                     for (k = 0; k < tmp.
nelem; ++k) {
 
  762                         tmp.
list[k] = *index;
 
  766                 indices[
IPIN][i][j] = tmp;
 
  772     for (i = 0; i <= (L_nx + 1); i++) {
 
  773         for (j = 0; j <= (L_ny + 1); j++) {
 
  777                 indices[
SINK][i][j] = indices[
SINK][i][j - ofs];
 
  778                 indices[
IPIN][i][j] = indices[
IPIN][i][j - ofs];
 
  801     for (i = 0; i <= (
nx + 1); ++i) {
 
  802         for (j = 0; j <= (
ny + 1); ++j) {
 
  806                 L_rr_node_indices[
SINK][i][j].list = NULL;
 
  807                 L_rr_node_indices[
IPIN][i][j].list = NULL;
 
  810             if (L_rr_node_indices[
SINK][i][j].
list != NULL) {
 
  811                 free(L_rr_node_indices[
SINK][i][j].
list);
 
  813             if (L_rr_node_indices[
IPIN][i][j].
list != NULL) {
 
  814                 free(L_rr_node_indices[
IPIN][i][j].
list);
 
  817         free(L_rr_node_indices[
SINK][i]);
 
  818         free(L_rr_node_indices[
IPIN][i]);
 
  820     free(L_rr_node_indices[
SINK]);
 
  821     free(L_rr_node_indices[
IPIN]);
 
  823     for (i = 0; i < (
nx + 1); ++i) {
 
  824         for (j = 0; j < (
ny + 1); ++j) {
 
  825             if (L_rr_node_indices[
CHANY][i][j].
list != NULL) {
 
  826                 free(L_rr_node_indices[
CHANY][i][j].
list);
 
  829         free(L_rr_node_indices[
CHANY][i]);
 
  831     free(L_rr_node_indices[
CHANY]);
 
  833     for (i = 0; i < (
ny + 1); ++i) {
 
  834         for (j = 0; j < (
nx + 1); ++j) {
 
  835             if (L_rr_node_indices[
CHANX][i][j].
list != NULL) {
 
  836                 free(L_rr_node_indices[
CHANX][i][j].
list);
 
  839         free(L_rr_node_indices[
CHANX][i]);
 
  841     free(L_rr_node_indices[
CHANX]);
 
  843     free(L_rr_node_indices);
 
  847         t_ivec *** L_rr_node_indices) {
 
  872     assert(x >= 0 && x <= (
nx + 1));
 
  873     assert(y >= 0 && y <= (
ny + 1));
 
  878     if (
CHANX == rr_type) {
 
  885     lookup = L_rr_node_indices[rr_type][x][y];
 
  889     assert(ptc < lookup.
nelem);
 
  894         assert(ptc < type->num_class);
 
  899         assert(ptc < type->num_class);
 
  904         assert(ptc < type->num_pins);
 
  910         assert(ptc < type->num_pins);
 
  920         vpr_printf(TIO_MESSAGE_ERROR, 
"Bad rr_node passed to get_rr_node_index.\n");
 
  921         vpr_printf(TIO_MESSAGE_ERROR, 
"Request for type=%d ptc=%d at (%d, %d).\n", rr_type, ptc, x, y);
 
  926     return lookup.
list[ptc];
 
  932         enum e_rr_type chan_type, 
int chan_length, 
int wire_to_ipin_switch,
 
  938     int j, pass, iconn, phy_track, end, to_node, max_conn, ipin, side, x, y,
 
  944     end = 
get_seg_end(seg_details, track, seg, chan, chan_length);
 
  946     edge_list_head = *edge_list_ptr;
 
  949     for (j = seg; j <= end; j++) {
 
  950         if (
is_cbox(chan, j, track, seg_details, directionality)) {
 
  951             for (pass = 0; pass < 2; ++pass) {
 
  952                 if (
CHANX == chan_type) {
 
  957                     assert(
CHANY == chan_type);
 
  978                         track_to_ipin_lookup[type->
index][phy_track][off][side].
nelem;
 
  979                 for (iconn = 0; iconn < max_conn; iconn++) {
 
  981                             track_to_ipin_lookup[type->
index][phy_track][off][side].
list[iconn];
 
  984                     assert(type->
pinloc[off][side][ipin]);
 
  990                             to_node, wire_to_ipin_switch);
 
  992                 num_conn += max_conn;
 
  997     *edge_list_ptr = edge_list_head;
 
 1019         INP int chan_len, 
INP int nodes_per_chan, 
INP int *opin_mux_size,
 
 1020         INP int Fs_per_side, 
INP short *****sblock_pattern,
 
 1025         INP struct s_ivec ***switch_block_conn) {
 
 1027     int from_switch, from_end, from_sb, from_first;
 
 1030     struct s_ivec conn_tracks;
 
 1031     boolean from_is_sbox, is_behind, Fs_clipped;
 
 1032     enum e_side from_side_a, from_side_b, to_side;
 
 1035             from_seg == 
get_seg_start(seg_details, from_track, from_chan, from_seg));
 
 1037     from_switch = seg_details[from_track].wire_switch;
 
 1038     from_end = 
get_seg_end(seg_details, from_track, from_seg, from_chan,
 
 1040     from_first = from_seg - 1;
 
 1043     if (
CHANX == from_type) {
 
 1044         from_side_a = 
RIGHT;
 
 1047         assert(
CHANY == from_type);
 
 1055     if (to_type == from_type) {
 
 1058         assert((to_seg == (from_end + 1)) || (to_seg == (from_seg - 1)));
 
 1059         if (to_seg > from_end) {
 
 1065         assert((to_seg == from_chan) || (to_seg == (from_chan + 1)));
 
 1066         if (to_seg > from_chan) {
 
 1073     if (
CHANX == to_type) {
 
 1076         assert(
CHANY == to_type);
 
 1087     if (to_type == from_type) {
 
 1088         start = (is_behind ? end : start);
 
 1094     for (from_sb = start; from_sb <= end; ++from_sb) {
 
 1096         from_is_sbox = 
is_sbox(from_chan, from_seg, from_sb, from_track,
 
 1097                 seg_details, directionality);
 
 1099         if (from_sb == from_end || from_sb == from_first) {
 
 1100             from_is_sbox = 
TRUE; 
 
 1107         if (from_type == to_type) {
 
 1108             to_chan = from_chan;
 
 1113         if (from_sb < from_end) {
 
 1116                         switch_block_conn[from_side_a][to_side][from_track];
 
 1118                         L_rr_node_indices, to_chan, to_seg, to_sb, to_type,
 
 1119                         seg_details, from_is_sbox, from_switch, L_rr_edge_done,
 
 1120                         directionality, edge_list);
 
 1129                             (
boolean)(from_sb == from_first), from_track, to_chan,
 
 1130                             to_seg, to_sb, to_type, nodes_per_chan, 
nx, 
ny,
 
 1131                             from_side_a, to_side, Fs_per_side, opin_mux_size,
 
 1132                             sblock_pattern, L_rr_node_indices, seg_details,
 
 1133                             L_rr_edge_done, &Fs_clipped, edge_list);
 
 1139         if (from_sb > from_first) {
 
 1142                         switch_block_conn[from_side_b][to_side][from_track];
 
 1144                         L_rr_node_indices, to_chan, to_seg, to_sb, to_type,
 
 1145                         seg_details, from_is_sbox, from_switch, L_rr_edge_done,
 
 1146                         directionality, edge_list);
 
 1155                             (
boolean)(from_sb == from_end), from_track, to_chan, to_seg,
 
 1156                             to_sb, to_type, nodes_per_chan, 
nx, 
ny, from_side_b,
 
 1157                             to_side, Fs_per_side, opin_mux_size, sblock_pattern,
 
 1158                             L_rr_node_indices, seg_details, L_rr_edge_done,
 
 1159                             &Fs_clipped, edge_list);
 
 1171         INP boolean from_is_sbox, 
INP int from_switch,
 
 1172         INOUTP boolean * L_rr_edge_done,
 
 1175     int iconn, to_track, to_node, to_switch, num_conn, to_x, to_y, i;
 
 1177     short switch_types[2];
 
 1180     if (
CHANX == to_type) {
 
 1184         assert(
CHANY == to_type);
 
 1191     for (iconn = 0; iconn < conn_tracks.nelem; ++iconn) {
 
 1192         to_track = conn_tracks.list[iconn];
 
 1197         if (L_rr_edge_done[to_node]) {
 
 1202         to_switch = seg_details[to_track].wire_switch;
 
 1204         to_is_sbox = 
is_sbox(to_chan, to_seg, to_sb, to_track, seg_details,
 
 1210         for (i = 0; i < 2; ++i) {
 
 1212             if (
OPEN == switch_types[i]) {
 
 1220             L_rr_edge_done[to_node] = 
TRUE;
 
 1229         INP int from_track, 
INP int to_chan, 
INP int to_seg, 
INP int to_sb,
 
 1232         INP int Fs_per_side, 
INP int *opin_mux_size,
 
 1233         INP short *****sblock_pattern, 
INP t_ivec *** L_rr_node_indices,
 
 1236     int to_track, to_mux, to_node, to_x, to_y, i, max_len, num_labels;
 
 1237     int sb_x, sb_y, count;
 
 1238     int *mux_labels = NULL;
 
 1240     boolean is_fringe, is_core, is_corner, is_straight;
 
 1243     if (
CHANX == to_type) {
 
 1250         assert(
CHANY == to_type);
 
 1259     if (to_sb < to_seg) {
 
 1263     *Fs_clipped = 
FALSE;
 
 1266     is_corner = (
boolean)(((sb_x < 1) || (sb_x >= L_nx))
 
 1267             && ((sb_y < 1) || (sb_y >= L_ny)));
 
 1269             && ((sb_x < 1) || (sb_y < 1) || (sb_x >= L_nx) || (sb_y >= L_ny)));
 
 1272             || (from_side == 
LEFT && to_side == 
RIGHT)
 
 1273             || (from_side == 
TOP && to_side == 
BOTTOM)
 
 1274             || (from_side == 
BOTTOM && to_side == 
TOP));
 
 1277     if (is_end_sb && (is_core || is_corner || is_straight)) {
 
 1280                 to_dir, nodes_per_chan, &num_labels);
 
 1282         assert(is_fringe || !is_end_sb);
 
 1285                 max_len, to_dir, nodes_per_chan, &num_labels, to_type,
 
 1286                 opin_mux_size, L_rr_node_indices);
 
 1290     if (num_labels < 1) {
 
 1299     if (Fs_per_side > num_labels) {
 
 1304     to_mux = sblock_pattern[sb_x][sb_y][from_side][to_side][from_track];
 
 1305     assert(to_mux != 
UN_SET);
 
 1309     for (i = 0; i < Fs_per_side; ++i) {
 
 1311         to_track = mux_labels[(to_mux + i) % num_labels];
 
 1316         if (
FALSE == L_rr_edge_done[to_node]) {
 
 1317             L_rr_edge_done[to_node] = 
TRUE;
 
 1319                     seg_details[to_track].wire_switch);
 
 1336     int length, ofs, fac;
 
 1343     length = seg_details[track].length;
 
 1346     wire_seg = 
get_seg_start(seg_details, track, chan, wire_seg);
 
 1348     ofs = sb_seg - wire_seg + 1; 
 
 1351     assert(ofs < (length + 1));
 
 1354     if ((ofs % fac) > 0) {
 
 1358     return seg_details[track].sb[ofs];
 
 1362         short from_node_switch, 
short to_node_switch, 
short switch_types[2]) {
 
 1372     boolean forward_pass_trans;
 
 1373     boolean backward_pass_trans;
 
 1374     int used, min_switch, max_switch;
 
 1376     switch_types[0] = 
OPEN; 
 
 1377     switch_types[1] = 
OPEN;
 
 1379     forward_pass_trans = 
FALSE;
 
 1380     backward_pass_trans = 
FALSE;
 
 1384         switch_types[used] = to_node_switch;
 
 1386             forward_pass_trans = 
TRUE;
 
 1394             switch_types[used] = from_node_switch;
 
 1395             backward_pass_trans = 
TRUE;
 
 1401     if (forward_pass_trans && backward_pass_trans) {
 
 1402         min_switch = 
std::min(to_node_switch, from_node_switch);
 
 1403         max_switch = 
std::max(to_node_switch, from_node_switch);
 
 1407         switch_types[used] = min_switch;
 
 1409             switch_types[used] = max_switch;
 
 1418     int group_start, group_size;
 
 1419     int vpr_offset_for_first_phy_track;
 
 1420     int vpr_offset, phy_offset;
 
 1430     group_start = seg_details[itrack].group_start;
 
 1431     group_size = seg_details[itrack].group_size;
 
 1433     vpr_offset_for_first_phy_track = (chan_num + seg_num - 1)
 
 1434             % (group_size / fac);
 
 1435     vpr_offset = (itrack - group_start) / fac;
 
 1436     phy_offset = (vpr_offset_for_first_phy_track + vpr_offset)
 
 1437             % (group_size / fac);
 
 1438     phy_track = group_start + (fac * phy_offset) + (itrack - group_start) % fac;
 
 1445     int i, j, from_side, to_side, itrack, items;
 
 1464     items *= (L_nx + 1);
 
 1465     i_list = (
short *****) 
my_malloc(
sizeof(
short ****) * items);
 
 1466     items *= (L_ny + 1);
 
 1467     j_list = (
short ****) 
my_malloc(
sizeof(
short ***) * items);
 
 1469     from_list = (
short ***) 
my_malloc(
sizeof(
short **) * items);
 
 1471     to_list = (
short **) 
my_malloc(
sizeof(
short *) * items);
 
 1472     items *= (nodes_per_chan);
 
 1473     track_list = (
short *) 
my_malloc(
sizeof(
short) * items);
 
 1477     i_list += (L_nx + 1); 
 
 1478     for (i = 0; i < (L_nx + 1); ++i) {
 
 1481         j_list += (L_ny + 1); 
 
 1482         for (j = 0; j < (L_ny + 1); ++j) {
 
 1484             result[i][j] = from_list;
 
 1486             for (from_side = 0; from_side < 4; ++from_side) {
 
 1488                 result[i][j][from_side] = to_list;
 
 1490                 for (to_side = 0; to_side < 4; ++to_side) {
 
 1492                     result[i][j][from_side][to_side] = track_list;
 
 1493                     track_list += (nodes_per_chan); 
 
 1494                     for (itrack = 0; itrack < nodes_per_chan; itrack++) {
 
 1497                         result[i][j][from_side][to_side][itrack] = 
UN_SET;
 
 1517     free(****sblock_pattern); 
 
 1518     free(***sblock_pattern); 
 
 1519     free(**sblock_pattern); 
 
 1520     free(*sblock_pattern); 
 
 1521     free(sblock_pattern); 
 
 1527         INOUTP short *****sblock_pattern) {
 
 1533     int side_cw_incoming_wire_count, side_ccw_incoming_wire_count,
 
 1534             opp_incoming_wire_count;
 
 1535     int to_side, side, side_cw, side_ccw, side_opp, itrack;
 
 1536     int Fs_per_side, chan, seg, chan_len, sb_seg;
 
 1537     boolean is_core_sblock, is_corner_sblock, x_edge, y_edge;
 
 1538     int *incoming_wire_label[4];
 
 1539     int *wire_mux_on_track[4];
 
 1540     int num_incoming_wires[4];
 
 1541     int num_ending_wires[4];
 
 1542     int num_wire_muxes[4];
 
 1543     boolean skip, vert, pos_dir;
 
 1548         Fs_per_side = Fs / 3;
 
 1598     x_edge = (
boolean)((i < 1) || (i >= 
nx));
 
 1599     y_edge = (
boolean)((j < 1) || (j >= 
ny));
 
 1601     is_corner_sblock = (
boolean)(x_edge && y_edge);
 
 1602     is_core_sblock = (
boolean)(!x_edge && !y_edge);
 
 1605     for (side = 0; side < 4; ++side) {
 
 1607         wire_mux_on_track[side] = NULL;
 
 1608         incoming_wire_label[side] = NULL;
 
 1609         num_incoming_wires[side] = 0;
 
 1610         num_ending_wires[side] = 0;
 
 1611         num_wire_muxes[side] = 0;
 
 1646         chan = (vert ? i : j);
 
 1647         sb_seg = (vert ? j : i);
 
 1648         seg = (pos_dir ? (sb_seg + 1) : sb_seg);
 
 1649         chan_len = (vert ? 
ny : 
nx);
 
 1655                 seg_details, chan_len, dir, nodes_per_chan,
 
 1656                 &num_incoming_wires[side], &num_ending_wires[side]);
 
 1661                 chan_len, dir, nodes_per_chan, &num_wire_muxes[side]);
 
 1664     for (to_side = 0; to_side < 4; to_side++) {
 
 1666         if (0 == num_wire_muxes[to_side]) {
 
 1672         side_cw = (to_side + 1) % 4;
 
 1673         side_opp = (to_side + 2) % 4;
 
 1674         side_ccw = (to_side + 3) % 4;
 
 1687         side_cw_incoming_wire_count = 0;
 
 1688         if (incoming_wire_label[side_cw]) {
 
 1689             for (itrack = 0; itrack < nodes_per_chan; itrack++) {
 
 1691                 if (incoming_wire_label[side_cw][itrack] != 
UN_SET) {
 
 1693                     if ((is_corner_sblock || is_core_sblock)
 
 1694                             && (incoming_wire_label[side_cw][itrack]
 
 1695                                     < num_ending_wires[side_cw])) {
 
 1701                                 num_ending_wires[side_cw] == num_wire_muxes[to_side]);
 
 1702                         sblock_pattern[i][j][side_cw][to_side][itrack] =
 
 1704                                         incoming_wire_label[side_cw][itrack],
 
 1706                                         num_wire_muxes[to_side]);
 
 1712                         sblock_pattern[i][j][side_cw][to_side][itrack] =
 
 1713                                 (side_cw_incoming_wire_count * Fs_per_side)
 
 1714                                         % num_wire_muxes[to_side];
 
 1715                         side_cw_incoming_wire_count++;
 
 1721         side_ccw_incoming_wire_count = 0;
 
 1722         for (itrack = 0; itrack < nodes_per_chan; itrack++) {
 
 1725             if (incoming_wire_label[side_ccw] == NULL)
 
 1729             if (incoming_wire_label[side_ccw][itrack] != 
UN_SET) {
 
 1731                 if ((is_corner_sblock || is_core_sblock)
 
 1732                         && (incoming_wire_label[side_ccw][itrack]
 
 1733                                 < num_ending_wires[side_ccw])) {
 
 1737                             incoming_wire_label[side_ccw] [itrack] < num_wire_muxes[to_side]);
 
 1738                     sblock_pattern[i][j][side_ccw][to_side][itrack] =
 
 1740                                     incoming_wire_label[side_ccw][itrack],
 
 1741                                     switch_block_type, num_wire_muxes[to_side]);
 
 1746                     sblock_pattern[i][j][side_ccw][to_side][itrack] =
 
 1747                             ((side_ccw_incoming_wire_count
 
 1748                                     + side_cw_incoming_wire_count) * Fs_per_side)
 
 1749                                     % num_wire_muxes[to_side];
 
 1750                     side_ccw_incoming_wire_count++;
 
 1755         opp_incoming_wire_count = 0;
 
 1756         if (incoming_wire_label[side_opp]) {
 
 1757             for (itrack = 0; itrack < nodes_per_chan; itrack++) {
 
 1759                 if (incoming_wire_label[side_opp][itrack] != 
UN_SET) {
 
 1762                     if (is_core_sblock) {
 
 1763                         if (incoming_wire_label[side_opp][itrack]
 
 1764                                 < num_ending_wires[side_opp]) {
 
 1769                             sblock_pattern[i][j][side_opp][to_side][itrack] =
 
 1771                                             wire_mux_on_track[to_side],
 
 1772                                             num_wire_muxes[to_side], itrack);
 
 1775                             sblock_pattern[i][j][side_opp][to_side][itrack] =
 
 1776                                     ((side_ccw_incoming_wire_count
 
 1777                                             + side_cw_incoming_wire_count)
 
 1779                                             + opp_incoming_wire_count
 
 1780                                                     * (Fs_per_side - 1))
 
 1781                                             % num_wire_muxes[to_side];
 
 1782                             opp_incoming_wire_count++;
 
 1785                         if (incoming_wire_label[side_opp][itrack]
 
 1786                                 < num_ending_wires[side_opp]) {
 
 1787                             sblock_pattern[i][j][side_opp][to_side][itrack] =
 
 1789                                             wire_mux_on_track[to_side],
 
 1790                                             num_wire_muxes[to_side], itrack);
 
 1793                             sblock_pattern[i][j][side_opp][to_side][itrack] =
 
 1794                                     ((side_ccw_incoming_wire_count
 
 1795                                             + side_cw_incoming_wire_count)
 
 1797                                             + opp_incoming_wire_count
 
 1798                                                     * (Fs_per_side - 1))
 
 1799                                             % num_wire_muxes[to_side];
 
 1800                             opp_incoming_wire_count++;
 
 1808     for (side = 0; side < 4; ++side) {
 
 1809         if (incoming_wire_label[side]) {
 
 1810             free(incoming_wire_label[side]);
 
 1812         if (wire_mux_on_track[side]) {
 
 1813             free(wire_mux_on_track[side]);
 
 1823         INP int *opin_mux_size, 
INP t_ivec *** L_rr_node_indices) {
 
 1849     int num_labels, max_opin_mux_size, min_opin_mux_size;
 
 1850     int inode, i, j, x, y;
 
 1851     int *pre_labels, *final_labels;
 
 1853     if (chan_type == 
CHANX) {
 
 1856     } 
else if (chan_type == 
CHANY) {
 
 1860         vpr_printf(TIO_MESSAGE_ERROR, 
"Bad channel type (%d).\n", chan_type);
 
 1866             direction, nodes_per_chan, &num_labels);
 
 1870     max_opin_mux_size = 0;
 
 1871     for (i = 0; i < num_labels; ++i) {
 
 1874         if (opin_mux_size[inode] < min_opin_mux_size) {
 
 1875             min_opin_mux_size = opin_mux_size[inode];
 
 1877         if (opin_mux_size[inode] > max_opin_mux_size) {
 
 1878             max_opin_mux_size = opin_mux_size[inode];
 
 1881     if (max_opin_mux_size > (min_opin_mux_size + 1)) {
 
 1882         vpr_printf(TIO_MESSAGE_ERROR, 
"opin muxes are not balanced!\n");
 
 1883         vpr_printf(TIO_MESSAGE_ERROR, 
"max_opin_mux_size %d min_opin_mux_size %d chan_type %d x %d y %d\n",
 
 1884                 max_opin_mux_size, min_opin_mux_size, chan_type, x, y);
 
 1889     final_labels = (
int *) 
my_malloc(
sizeof(
int) * num_labels);
 
 1891     for (i = 0; i < num_labels; ++i) {
 
 1892         inode = pre_labels[i];
 
 1893         if (opin_mux_size[inode] < max_opin_mux_size) {
 
 1894             final_labels[j] = inode;
 
 1898     for (i = 0; i < num_labels; ++i) {
 
 1899         inode = pre_labels[i];
 
 1900         if (opin_mux_size[inode] >= max_opin_mux_size) {
 
 1901             final_labels[j] = inode;
 
 1912     *num_wire_muxes = num_labels;
 
 1913     return final_labels;
 
 1920         OUTP int *num_wire_muxes) {
 
 1926     int itrack, start, end, num_labels, pass;
 
 1928     boolean is_endpoint;
 
 1932     for (pass = 0; pass < 2; ++pass) {
 
 1935             labels = (
int *) 
my_malloc(
sizeof(
int) * num_labels);
 
 1940         for (itrack = 0; itrack < nodes_per_chan; ++itrack) {
 
 1941             start = 
get_seg_start(seg_details, itrack, chan_num, seg_num);
 
 1942             end = 
get_seg_end(seg_details, itrack, start, chan_num, max_len);
 
 1945             if (seg_details[itrack].direction != dir) {
 
 1950             is_endpoint = (
boolean)(seg_num == start);
 
 1952                 is_endpoint = (
boolean)(seg_num == end);
 
 1958                     labels[num_labels] = itrack;
 
 1965     *num_wire_muxes = num_labels;
 
 1973         OUTP int *num_incoming_wires, 
OUTP int *num_ending_wires) {
 
 1979     int itrack, start, end, i, num_passing, num_ending, pass;
 
 1981     boolean sbox_exists, is_endpoint;
 
 1984     labels = (
int *) 
my_malloc(nodes_per_chan * 
sizeof(
int));
 
 1985     for (i = 0; i < nodes_per_chan; ++i) {
 
 1991     for (pass = 0; pass < 2; ++pass) {
 
 1992         for (itrack = 0; itrack < nodes_per_chan; ++itrack) {
 
 1993             if (seg_details[itrack].direction == dir) {
 
 1994                 start = 
get_seg_start(seg_details, itrack, chan_num, seg_num);
 
 1995                 end = 
get_seg_end(seg_details, itrack, start, chan_num,
 
 1999                 is_endpoint = (
boolean)(seg_num == end);
 
 2001                     is_endpoint = (
boolean)(seg_num == start);
 
 2005                 sbox_exists = 
is_sbox(chan_num, seg_num, sb_seg, itrack,
 
 2012                         labels[itrack] = num_ending;
 
 2020                     if ((
FALSE == is_endpoint) && sbox_exists) {
 
 2021                         labels[itrack] = num_ending + num_passing;
 
 2030     *num_incoming_wires = num_passing + num_ending;
 
 2031     *num_ending_wires = num_ending;
 
 2042     for (i = 0; i < num_wire_muxes; i++) {
 
 2043         if (wire_mux_on_track[i] == from_track) {
 
 2048     vpr_printf(TIO_MESSAGE_ERROR, 
"Expected mux not found.\n");
 
boolean is_cbox(INP int chan, INP int seg, INP int track, INP t_seg_details *seg_details, INP enum e_directionality directionality)
FILE * my_fopen(const char *fname, const char *flag, int prompt)
struct s_class * class_inf
boolean is_sbox(INP int chan, INP int wire_seg, INP int sb_seg, INP int track, INP t_seg_details *seg_details, INP enum e_directionality directionality)
int get_seg_start(INP t_seg_details *seg_details, INP int itrack, INP int chan_num, INP int seg_num)
int get_simple_switch_block_track(INP enum e_side from_side, INP enum e_side to_side, INP int from_track, INP enum e_switch_block_type switch_block_type, INP int nodes_per_chan)
t_seg_details * alloc_and_load_seg_details(INOUTP int *nodes_per_chan, INP int max_len, INP int num_seg_types, INP t_segment_inf *segment_inf, INP boolean use_full_seg_groups, INP boolean is_global_graph, INP enum e_directionality directionality)
void load_sblock_pattern_lookup(INP int i, INP int j, INP int nodes_per_chan, INP t_seg_details *seg_details, INP int Fs, INP enum e_switch_block_type switch_block_type, INOUTP short *****sblock_pattern)
t_linked_edge * insert_in_edge_list(INP t_linked_edge *head, INP int edge, INP short iswitch)
struct s_ivec *** alloc_and_load_rr_node_indices(INP int nodes_per_chan, INP int L_nx, INP int L_ny, INOUTP int *index, INP t_seg_details *seg_details)
static int find_label_of_track(int *wire_mux_on_track, int num_wire_muxes, int from_track)
static int vpr_to_phy_track(INP int itrack, INP int chan_num, INP int seg_num, INP t_seg_details *seg_details, INP enum e_directionality directionality)
int get_bidir_opin_connections(INP int i, INP int j, INP int ipin, INP struct s_linked_edge **edge_list, INP int *****opin_to_track_map, INP int Fc, INP boolean *L_rr_edge_done, INP t_ivec ***L_rr_node_indices, INP t_seg_details *seg_details)
int get_rr_node_index(int x, int y, t_rr_type rr_type, int ptc, t_ivec ***L_rr_node_indices)
static int * label_wire_muxes_for_balance(INP int chan_num, INP int seg_num, INP t_seg_details *seg_details, INP int max_len, INP enum e_direction direction, INP int nodes_per_chan, INP int *num_wire_muxes, INP t_rr_type chan_type, INP int *opin_mux_size, INP t_ivec ***L_rr_node_indices)
int get_track_to_tracks(INP int from_chan, INP int from_seg, INP int from_track, INP t_rr_type from_type, INP int to_seg, INP t_rr_type to_type, INP int chan_len, INP int nodes_per_chan, INP int *opin_mux_size, INP int Fs_per_side, INP short *****sblock_pattern, INOUTP struct s_linked_edge **edge_list, INP t_seg_details *seg_details, INP enum e_directionality directionality, INP t_ivec ***L_rr_node_indices, INOUTP boolean *L_rr_edge_done, INP struct s_ivec ***switch_block_conn)
static int get_bidir_track_to_chan_seg(INP struct s_ivec conn_tracks, INP t_ivec ***L_rr_node_indices, INP int to_chan, INP int to_seg, INP int to_sb, INP t_rr_type to_type, INP t_seg_details *seg_details, INP boolean from_is_sbox, INP int from_switch, INOUTP boolean *L_rr_edge_done, INP enum e_directionality directionality, INOUTP struct s_linked_edge **edge_list)
static void * my_malloc(int ibytes)
int get_unidir_opin_connections(INP int chan, INP int seg, INP int Fc, INP t_rr_type chan_type, INP t_seg_details *seg_details, INOUTP t_linked_edge **edge_list_ptr, INOUTP int **Fc_ofs, INOUTP boolean *L_rr_edge_done, INP int max_len, INP int nodes_per_chan, INP t_ivec ***L_rr_node_indices, OUTP boolean *Fc_clipped)
t_linked_edge * free_edge_list_head
enum e_direction direction
static int * label_incoming_wires(INP int chan_num, INP int seg_num, INP int sb_seg, INP t_seg_details *seg_details, INP int max_len, INP enum e_direction dir, INP int nodes_per_chan, OUTP int *num_incoming_wires, OUTP int *num_ending_wires)
struct s_switch_inf * switch_inf
static int get_unidir_track_to_chan_seg(INP boolean is_end_sb, INP int from_track, INP int to_chan, INP int to_seg, INP int to_sb, INP t_rr_type to_type, INP int nodes_per_chan, INP int L_nx, INP int L_ny, INP enum e_side from_side, INP enum e_side to_side, INP int Fs_per_side, INP int *opin_mux_size, INP short *****sblock_pattern, INP t_ivec ***L_rr_node_indices, INP t_seg_details *seg_details, INOUTP boolean *L_rr_edge_done, OUTP boolean *Fs_clipped, INOUTP struct s_linked_edge **edge_list)
struct s_grid_tile ** grid
void free_sblock_pattern_lookup(INOUTP short *****sblock_pattern)
void free_seg_details(t_seg_details *seg_details, int nodes_per_chan)
static void load_chan_rr_indices(INP int nodes_per_chan, INP int chan_len, INP int num_chans, INP t_rr_type type, INP t_seg_details *seg_details, INOUTP int *index, INOUTP t_ivec ***indices)
static void get_switch_type(boolean is_from_sbox, boolean is_to_sbox, short from_node_switch, short to_node_switch, short switch_types[2])
int get_seg_end(INP t_seg_details *seg_details, INP int itrack, INP int istart, INP int chan_num, INP int seg_max)
short ***** alloc_sblock_pattern_lookup(INP int L_nx, INP int L_ny, INP int nodes_per_chan)
int get_track_to_ipins(int seg, int chan, int track, t_linked_edge **edge_list_ptr, t_ivec ***L_rr_node_indices, struct s_ivec ****track_to_ipin_lookup, t_seg_details *seg_details, enum e_rr_type chan_type, int chan_length, int wire_to_ipin_switch, enum e_directionality directionality)
static int * label_wire_muxes(INP int chan_num, INP int seg_num, INP t_seg_details *seg_details, INP int max_len, INP enum e_direction dir, INP int nodes_per_chan, OUTP int *num_wire_muxes)
void dump_seg_details(t_seg_details *seg_details, int nodes_per_chan, const char *fname)
void free_rr_node_indices(INP t_ivec ***L_rr_node_indices)
static int * get_seg_track_counts(INP int num_sets, INP int num_seg_types, INP t_segment_inf *segment_inf, INP boolean use_full_seg_groups)