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)