57 INP boolean perturb_switch_pattern,
61 INP int ****pin_to_track_map,
INP int *Fc,
INP int height,
62 INP int num_pins,
INP int nodes_per_chan);
66 INP int *****opin_to_track_map,
INP int **Fc_out,
76 OUTP boolean * Fc_clipped,
INP t_ivec *** L_rr_node_indices,
INP int delayless_switch,
85 INP struct s_ivec ****track_to_ipin_lookup,
86 INP int *****opin_to_track_map,
INP struct s_ivec ***switch_block_conn,
88 INP short *****sblock_pattern,
INP int **Fc_out,
INP int **Fc_xofs,
95 INOUTP int ****tracks_connected_to_pin,
INP int num_phys_pins,
96 INP int *pin_num_ordering,
INP int *side_ordering,
97 INP int *offset_ordering,
INP int nodes_per_chan,
INP int Fc,
101 INOUTP int ****tracks_connected_to_pin,
INP int num_phys_pins,
102 INP int *pin_num_ordering,
INP int *side_ordering,
103 INP int *offset_ordering,
INP int nodes_per_chan,
INP int Fc,
107 int ****tracks_connected_to_pin,
int nodes_per_chan,
int Fc,
111 INP int L_num_types,
INP int **Fc_in,
INP int **Fc_out,
119 INP struct s_ivec ****track_to_ipin_lookup,
120 INP struct s_ivec ***switch_block_conn,
INP int cost_index_offset,
121 INP int nodes_per_chan,
INP int *opin_mux_size,
122 INP short *****sblock_pattern,
INP int Fs_per_side,
128 INP struct s_ivec ****track_to_ipin_lookup,
129 INP struct s_ivec ***switch_block_conn,
INP int cost_index_offset,
130 INP int nodes_per_chan,
INP int *opin_mux_size,
131 INP short *****sblock_pattern,
INP int Fs_per_side,
137 t_segment_inf * segment_inf,
int num_seg_types,
int nodes_per_chan,
141 INP int num_edges,
INP boolean * L_rr_edge_done,
151 static void load_uniform_opin_switch_pattern_paired(
INP int *Fc_out,
153 INP int *pins_in_chan_seg,
154 INP int num_wire_inc_muxes,
155 INP int num_wire_dec_muxes,
156 INP int *wire_inc_muxes,
157 INP int *wire_dec_muxes,
163 OUTP boolean * Fc_clipped);
166 #if MUX_SIZE_DIST_DISPLAY
167 static void view_mux_size_distribution(
t_ivec *** L_rr_node_indices,
171 static void print_distribution(FILE * fptr,
182 INP int nodes_per_chan,
INP int global_route_switch);
187 INP int nodes_per_chan,
INP boolean is_Fc_out,
198 INP int global_route_switch,
INP int delayless_switch,
201 INP int num_directs,
INP boolean ignore_Fc_0,
OUTP int *Warnings) {
203 int nodes_per_chan, i, j;
208 int *****opin_to_track_map = NULL;
209 int *****ipin_to_track_map = NULL;
210 t_ivec ****track_to_ipin_lookup = NULL;
211 t_ivec ***switch_block_conn = NULL;
212 short *****unidir_sb_pattern = NULL;
213 boolean *L_rr_edge_done = NULL;
214 boolean is_global_graph;
216 boolean use_full_seg_groups;
217 boolean *perturb_ipins = NULL;
219 int **Fc_xofs = NULL;
220 int **Fc_yofs = NULL;
231 is_global_graph =
FALSE;
233 is_global_graph =
TRUE;
235 use_full_seg_groups =
FALSE;
237 use_full_seg_groups =
TRUE;
243 if (is_global_graph) {
248 nodes_per_chan = (is_global_graph ? 1 : chan_width);
249 assert(nodes_per_chan > 0);
251 clb_to_clb_directs = NULL;
252 if(num_directs > 0) {
257 if (is_global_graph) {
260 global_route_switch);
266 std::max(L_nx, L_ny), num_seg_types, segment_inf,
267 use_full_seg_groups, is_global_graph, directionality);
268 if ((is_global_graph ? 1 : chan_width) != nodes_per_chan) {
281 if (is_global_graph) {
282 Fc_in = (
int **)
my_malloc(
sizeof(
int) * L_num_types);
283 Fc_out = (
int **)
my_malloc(
sizeof(
int) * L_num_types);
284 for (i = 0; i < L_num_types; ++i) {
285 for (j = 0; j < types[i].num_pins; ++j) {
293 FALSE, directionality, &Fc_clipped, ignore_Fc_0);
299 TRUE, directionality, &Fc_clipped, ignore_Fc_0);
305 for (i = 1; i < L_num_types; ++i) {
308 vpr_printf(TIO_MESSAGE_INFO,
"Fc Actual Values: type = %s, Fc_out = full, Fc_in = %d.\n",
312 vpr_printf(TIO_MESSAGE_INFO,
"Fc Actual Values: type = %s, Fc_out = %d, Fc_in = %d.\n",
321 Fc_in, Fc_out, directionality);
331 memset(L_rr_edge_done, 0,
sizeof(
boolean) * num_rr_nodes);
335 Fc_xofs = (
int **)
alloc_matrix(0, L_ny, 0, L_nx,
sizeof(
int));
336 Fc_yofs = (
int **)
alloc_matrix(0, L_nx, 0, L_ny,
sizeof(
int));
337 for (i = 0; i <= L_nx; ++i) {
338 for (j = 0; j <= L_ny; ++j) {
347 if (is_global_graph) {
348 assert(nodes_per_chan == 1);
358 for (i = 0; i <= L_nx; i++) {
359 for (j = 0; j <= L_ny; j++) {
361 Fs, sb_type, unidir_sb_pattern);
369 ipin_to_track_map = (
int *****)
my_malloc(
sizeof(
int ****) * L_num_types);
371 sizeof(
struct s_ivec ***) * L_num_types);
372 for (i = 0; i < L_num_types; ++i) {
374 nodes_per_chan, Fc_in[i], &types[i], perturb_ipins[i],
377 ipin_to_track_map[i], Fc_in[i], types[i].height,
378 types[i].num_pins, nodes_per_chan);
385 opin_to_track_map = (
int *****)
my_malloc(
386 sizeof(
int ****) * L_num_types);
387 for (i = 0; i < L_num_types; ++i) {
389 nodes_per_chan, Fc_out[i], &types[i],
FALSE, directionality);
402 L_rr_edge_done, track_to_ipin_lookup, opin_to_track_map,
403 switch_block_conn, L_grid, L_nx, L_ny, Fs, unidir_sb_pattern,
405 delayless_switch, directionality, wire_to_ipin_switch, &Fc_clipped, directs, num_directs, clb_to_clb_directs);
407 #ifdef MUX_SIZE_DIST_DISPLAY
411 seg_details, seg_details);
425 wire_to_ipin_switch, base_cost_type);
432 num_seg_types, num_switches, segment_inf, global_route_switch,
433 delayless_switch, wire_to_ipin_switch, seg_details, Fc_in, Fc_out,
434 opin_to_track_map, ipin_to_track_map, track_to_ipin_lookup,
435 switch_block_conn, perturb_ipins);
447 free_matrix(Fc_out,0, L_num_types, 0,
sizeof(
int));
452 perturb_ipins = NULL;
454 if (switch_block_conn) {
456 switch_block_conn = NULL;
458 if (L_rr_edge_done) {
459 free(L_rr_edge_done);
460 L_rr_edge_done = NULL;
470 if (unidir_sb_pattern) {
472 unidir_sb_pattern = NULL;
474 if (opin_to_track_map) {
475 for (i = 0; i < L_num_types; ++i) {
476 free_matrix4(opin_to_track_map[i], 0, types[i].num_pins - 1, 0,
477 types[i].height - 1, 0, 3, 0,
sizeof(
int));
479 free(opin_to_track_map);
484 if(clb_to_clb_directs != NULL) {
485 free(clb_to_clb_directs);
490 t_segment_inf * segment_inf,
int num_seg_types,
int nodes_per_chan,
494 nodes_per_chan, wire_to_ipin_switch, base_cost_type);
506 boolean *result = NULL;
508 result = (
boolean *)
my_malloc(L_num_types *
sizeof(
boolean));
512 for (i = 1; i < L_num_types; ++i) {
515 if (Fc_in[i][0] > Fc_out[i][0]) {
516 Fc_ratio = (float) Fc_in[i][0] / (
float) Fc_out[i][0];
518 Fc_ratio = (float) Fc_out[i][0] / (
float) Fc_in[i][0];
521 if ((Fc_in[i][0] <= nodes_per_chan - 2)
522 && (fabs(Fc_ratio -
nint(Fc_ratio))
523 < (0.5 / (float) nodes_per_chan))) {
531 for (i = 0; i < L_num_types; ++i) {
541 INP int global_route_switch) {
544 assert(nodes_per_chan == 1);
557 result->
cb = (
boolean *)
my_malloc(
sizeof(
boolean) * 1);
559 result->
sb = (
boolean *)
my_malloc(
sizeof(
boolean) * 2);
571 INP int nodes_per_chan,
INP boolean is_Fc_out,
586 assert((nodes_per_chan % fac) == 0);
587 num_sets = nodes_per_chan / fac;
589 int max_pins = types[0].num_pins;
590 for (i = 1; i < L_num_types; ++i) {
591 if (types[i].num_pins > max_pins) {
592 max_pins = types[i].num_pins;
596 Result = (
int **)
alloc_matrix(0, L_num_types, 0, max_pins,
sizeof(
int));
598 for (i = 1; i < L_num_types; ++i) {
599 float *Fc = (
float *)
my_malloc(
sizeof(
float) * types[i].num_pins);
600 for (j = 0; j < types[i].num_pins; ++j) {
601 Fc[j] = types[i].Fc[j];
603 if(Fc[j] == 0 && ignore_Fc_0 ==
FALSE) {
608 if (types[i].is_Fc_frac[j]) {
609 Result[i][j] = fac *
nint(num_sets * Fc[j]);
611 Result[i][j] = (int)Fc[j];
614 if (is_Fc_out && types[i].is_Fc_full_flex[j]) {
615 Result[i][j] = nodes_per_chan;
618 Result[i][j] =
std::max(Result[i][j], fac);
619 if (Result[i][j] > nodes_per_chan) {
621 Result[i][j] = nodes_per_chan;
624 assert(Result[i][j] % fac == 0);
635 int i, itrack, ioff, iside;
637 if (track_to_pin_map[i] != NULL) {
638 for (itrack = 0; itrack < nodes_per_chan; itrack++) {
639 for (ioff = 0; ioff < types[i].
height; ioff++) {
640 for (iside = 0; iside < 4; iside++) {
641 if (track_to_pin_map[i][itrack][ioff][iside].
list
643 free(track_to_pin_map[i][itrack][ioff][iside].
list);
648 free_matrix3(track_to_pin_map[i], 0, nodes_per_chan - 1, 0,
649 types[i].height - 1, 0,
sizeof(
struct s_ivec));
652 free(track_to_pin_map);
660 free_matrix4(ipin_to_track_map[i], 0, types[i].num_pins - 1, 0,
661 types[i].height - 1, 0, 3, 0,
sizeof(
int));
663 free(ipin_to_track_map);
671 INP struct s_ivec ****track_to_ipin_lookup,
672 INP int *****opin_to_track_map,
INP struct s_ivec ***switch_block_conn,
674 INP short *****sblock_pattern,
INP int **Fc_out,
INP int **Fc_xofs,
678 INP int wire_to_ipin_switch,
OUTP boolean * Fc_clipped,
684 int *opin_mux_size = NULL;
690 for (i = 0; i <= (L_nx + 1); i++) {
691 for (j = 0; j <= (L_ny + 1); j++) {
693 delayless_switch, L_grid);
698 for (i = 0; i <= (L_nx + 1); ++i) {
699 for (j = 0; j <= (L_ny + 1); ++j) {
702 opin_to_track_map, Fc_out, L_rr_edge_done, seg_details,
703 L_grid, delayless_switch,
704 directs, num_directs, clb_to_clb_directs);
708 seg_details, Fc_xofs, Fc_yofs, L_rr_node,
709 L_rr_edge_done, &clipped, L_rr_node_indices, delayless_switch,
710 directs, num_directs, clb_to_clb_directs);
720 opin_mux_size = (
int *)
my_malloc(
sizeof(
int) * num_nodes);
721 for (i = 0; i < num_nodes; ++i) {
722 opin_mux_size[i] = L_rr_node[i].fan_in;
727 for (i = 0; i <= L_nx; i++) {
728 for (j = 0; j <= L_ny; j++) {
732 sblock_pattern, Fs / 3, seg_details, L_rr_node_indices,
733 L_rr_edge_done, L_rr_node, wire_to_ipin_switch,
739 opin_mux_size, sblock_pattern, Fs / 3, seg_details,
740 L_rr_node_indices, L_rr_edge_done, L_rr_node,
741 wire_to_ipin_switch, directionality);
750 INP int *****opin_to_track_map,
INP int **Fc_out,
755 int ipin, inode, num_edges, *Fc, ofs;
761 if (L_grid[i][j].offset > 0) {
765 type = L_grid[i][j].type;
766 Fc = Fc_out[type->
index];
768 for (ipin = 0; ipin < type->
num_pins; ++ipin) {
777 for (ofs = 0; ofs < type->
height; ++ofs) {
779 &edge_list, opin_to_track_map, Fc[ipin], L_rr_edge_done,
780 L_rr_node_indices, seg_details);
785 num_edges +=
get_opin_direct_connecions(i, j, ipin, &edge_list, L_rr_node_indices, delayless_switch, directs, num_directs, clb_to_clb_directs);
789 L_rr_edge_done, edge_list);
790 while (edge_list != NULL) {
791 next = edge_list->
next;
819 if (
rr_node[i].edges != NULL) {
822 if (
rr_node[i].switches != NULL) {
848 for (inet = 0; inet <
num_nets; inet++) {
850 (
clb_net[inet].num_sinks + 1) *
sizeof(int),
862 int inet, ipin, inode, iblk, i, j, node_block_pin, iclass;
865 for (inet = 0; inet <
num_nets; inet++) {
877 iclass = type->
pin_class[node_block_pin];
880 iclass, L_rr_node_indices);
894 int iblk, i, j, iclass, inode;
895 int class_low, class_high;
905 for (iclass = 0; iclass < type->
num_class; iclass++) {
906 if (iclass >= class_low && iclass <= class_high) {
932 int ipin, iclass, inode, pin_num, to_node, num_edges;
933 int num_class, num_pins;
938 int iport, ipb_pin, iporttype, z;
942 if (L_grid[i][j].offset > 0)
945 type = L_grid[i][j].type;
953 for (iclass = 0; iclass < num_class; iclass++) {
954 if (class_inf[iclass].type ==
DRIVER) {
957 num_edges = class_inf[iclass].
num_pins;
958 L_rr_node[inode].num_edges = num_edges;
959 L_rr_node[inode].edges = (
int *)
my_malloc(num_edges *
sizeof(
int));
960 L_rr_node[inode].switches = (
short *)
my_malloc(
961 num_edges *
sizeof(
short));
963 for (ipin = 0; ipin < class_inf[iclass].
num_pins; ipin++) {
964 pin_num = class_inf[iclass].
pinlist[ipin];
967 L_rr_node[inode].edges[ipin] = to_node;
968 L_rr_node[inode].switches[ipin] = delayless_switch;
970 ++L_rr_node[to_node].fan_in;
974 L_rr_node[inode].type =
SOURCE;
976 assert(class_inf[iclass].type ==
RECEIVER);
986 L_rr_node[inode].num_edges = 0;
987 L_rr_node[inode].edges = NULL;
988 L_rr_node[inode].switches = NULL;
991 L_rr_node[inode].type =
SINK;
995 L_rr_node[inode].capacity = class_inf[iclass].
num_pins;
996 L_rr_node[inode].occ = 0;
997 L_rr_node[inode].xlow = i;
998 L_rr_node[inode].xhigh = i;
999 L_rr_node[inode].ylow = j;
1000 L_rr_node[inode].yhigh = j + type->
height - 1;
1001 L_rr_node[inode].R = 0;
1002 L_rr_node[inode].C = 0;
1003 L_rr_node[inode].ptc_num = iclass;
1008 iporttype = iport = ipb_pin = 0;
1015 for (ipin = 0; ipin <
num_pins; ipin++) {
1016 iclass = pin_class[ipin];
1019 if (class_inf[iclass].type ==
RECEIVER) {
1023 L_rr_node[inode].num_edges = 1;
1024 L_rr_node[inode].edges = (
int *)
my_malloc(
sizeof(
int));
1025 L_rr_node[inode].switches = (
short *)
my_malloc(
sizeof(
short));
1027 L_rr_node[inode].edges[0] = to_node;
1028 L_rr_node[inode].switches[0] = delayless_switch;
1030 ++L_rr_node[to_node].fan_in;
1033 L_rr_node[inode].type =
IPIN;
1036 L_rr_node[inode].z = z;
1037 if(iporttype == 0) {
1038 L_rr_node[inode].pb_graph_pin = &pb_graph_node->
input_pins[iport][ipb_pin];
1052 assert(iporttype == 1);
1053 L_rr_node[inode].pb_graph_pin = &pb_graph_node->
clock_pins[iport][ipb_pin];
1067 assert(class_inf[iclass].type ==
DRIVER);
1072 L_rr_node[inode].z = z;
1074 L_rr_node[inode].num_edges = 0;
1075 L_rr_node[inode].edges = NULL;
1077 L_rr_node[inode].switches = NULL;
1080 L_rr_node[inode].type =
OPIN;
1082 L_rr_node[inode].pb_graph_pin = &pb_graph_node->
output_pins[iport][ipb_pin];
1098 L_rr_node[inode].capacity = 1;
1099 L_rr_node[inode].occ = 0;
1100 L_rr_node[inode].xlow = i;
1101 L_rr_node[inode].xhigh = i;
1102 L_rr_node[inode].ylow = j;
1103 L_rr_node[inode].yhigh = j + type->
height - 1;
1104 L_rr_node[inode].C = 0;
1105 L_rr_node[inode].R = 0;
1106 L_rr_node[inode].ptc_num = ipin;
1113 INP struct s_ivec ****track_to_ipin_lookup,
1114 INP struct s_ivec ***switch_block_conn,
INP int cost_index_offset,
1115 INP int nodes_per_chan,
INP int *opin_mux_size,
1116 INP short *****sblock_pattern,
INP int Fs_per_side,
1124 int itrack, istart, iend, num_edges, inode, length;
1127 for (itrack = 0; itrack < nodes_per_chan; itrack++) {
1140 L_rr_node_indices, track_to_ipin_lookup, seg_details,
CHANX,
nx,
1141 wire_to_ipin_switch, directionality);
1145 nx, nodes_per_chan, opin_mux_size, Fs_per_side,
1146 sblock_pattern, &edge_list, seg_details, directionality,
1147 L_rr_node_indices, L_rr_edge_done, switch_block_conn);
1152 CHANY,
nx, nodes_per_chan, opin_mux_size, Fs_per_side,
1153 sblock_pattern, &edge_list, seg_details, directionality,
1154 L_rr_node_indices, L_rr_edge_done, switch_block_conn);
1159 istart - 1,
CHANX,
nx, nodes_per_chan, opin_mux_size,
1160 Fs_per_side, sblock_pattern, &edge_list, seg_details,
1161 directionality, L_rr_node_indices, L_rr_edge_done,
1167 CHANX,
nx, nodes_per_chan, opin_mux_size, Fs_per_side,
1168 sblock_pattern, &edge_list, seg_details, directionality,
1169 L_rr_node_indices, L_rr_edge_done, switch_block_conn);
1174 L_rr_edge_done, edge_list);
1176 while (edge_list != NULL) {
1177 next = edge_list->
next;
1183 L_rr_node[inode].cost_index = cost_index_offset
1184 + seg_details[itrack].index;
1185 L_rr_node[inode].occ = 0;
1187 L_rr_node[inode].capacity = 1;
1189 L_rr_node[inode].xlow = istart;
1190 L_rr_node[inode].xhigh = iend;
1191 L_rr_node[inode].ylow = j;
1192 L_rr_node[inode].yhigh = j;
1194 length = iend - istart + 1;
1195 L_rr_node[inode].R = length * seg_details[itrack].Rmetal;
1196 L_rr_node[inode].C = length * seg_details[itrack].Cmetal;
1198 L_rr_node[inode].ptc_num = itrack;
1199 L_rr_node[inode].type =
CHANX;
1200 L_rr_node[inode].direction = seg_details[itrack].direction;
1201 L_rr_node[inode].drivers = seg_details[itrack].drivers;
1206 INP struct s_ivec ****track_to_ipin_lookup,
1207 INP struct s_ivec ***switch_block_conn,
INP int cost_index_offset,
1208 INP int nodes_per_chan,
INP int *opin_mux_size,
1209 INP short *****sblock_pattern,
INP int Fs_per_side,
1217 int itrack, istart, iend, num_edges, inode, length;
1220 for (itrack = 0; itrack < nodes_per_chan; itrack++) {
1233 L_rr_node_indices, track_to_ipin_lookup, seg_details,
CHANY,
ny,
1234 wire_to_ipin_switch, directionality);
1238 ny, nodes_per_chan, opin_mux_size, Fs_per_side,
1239 sblock_pattern, &edge_list, seg_details, directionality,
1240 L_rr_node_indices, L_rr_edge_done, switch_block_conn);
1245 CHANX,
ny, nodes_per_chan, opin_mux_size, Fs_per_side,
1246 sblock_pattern, &edge_list, seg_details, directionality,
1247 L_rr_node_indices, L_rr_edge_done, switch_block_conn);
1252 istart - 1,
CHANY,
ny, nodes_per_chan, opin_mux_size,
1253 Fs_per_side, sblock_pattern, &edge_list, seg_details,
1254 directionality, L_rr_node_indices, L_rr_edge_done,
1260 CHANY,
ny, nodes_per_chan, opin_mux_size, Fs_per_side,
1261 sblock_pattern, &edge_list, seg_details, directionality,
1262 L_rr_node_indices, L_rr_edge_done, switch_block_conn);
1267 L_rr_edge_done, edge_list);
1269 while (edge_list != NULL) {
1270 next = edge_list->
next;
1276 L_rr_node[inode].cost_index = cost_index_offset
1277 + seg_details[itrack].index;
1278 L_rr_node[inode].occ = 0;
1280 L_rr_node[inode].capacity = 1;
1282 L_rr_node[inode].xlow = i;
1283 L_rr_node[inode].xhigh = i;
1284 L_rr_node[inode].ylow = istart;
1285 L_rr_node[inode].yhigh = iend;
1287 length = iend - istart + 1;
1288 L_rr_node[inode].R = length * seg_details[itrack].Rmetal;
1289 L_rr_node[inode].C = length * seg_details[itrack].Cmetal;
1291 L_rr_node[inode].ptc_num = itrack;
1292 L_rr_node[inode].type =
CHANY;
1293 L_rr_node[inode].direction = seg_details[itrack].direction;
1294 L_rr_node[inode].drivers = seg_details[itrack].drivers;
1302 list_ptr = edge_list_head;
1305 vpr_printf(TIO_MESSAGE_TRACE,
"!!! Watching Node %d !!!!\n", inode);
1307 vpr_printf(TIO_MESSAGE_TRACE,
"Currently connects to:\n");
1308 while (list_ptr != NULL) {
1309 to_node = list_ptr->
edge;
1311 list_ptr = list_ptr->
next;
1317 INP int num_edges,
INOUTP boolean * L_rr_edge_done,
1331 assert(L_rr_node[inode].num_edges < 1);
1332 assert(NULL == L_rr_node[inode].edges);
1333 assert(NULL == L_rr_node[inode].switches);
1335 L_rr_node[inode].num_edges = num_edges;
1336 L_rr_node[inode].edges = (
int *)
my_malloc(num_edges *
sizeof(
int));
1337 L_rr_node[inode].switches = (
short *)
my_malloc(num_edges *
sizeof(
short));
1340 list_ptr = edge_list_head;
1341 while (list_ptr && (i < num_edges)) {
1342 L_rr_node[inode].edges[i] = list_ptr->
edge;
1343 L_rr_node[inode].switches[i] = list_ptr->
iswitch;
1345 ++L_rr_node[list_ptr->
edge].fan_in;
1350 list_ptr = list_ptr->
next;
1353 assert(list_ptr == NULL);
1354 assert(i == num_edges);
1360 INP boolean perturb_switch_pattern,
1367 int i, j, k, iside, ipin, iclass, num_phys_pins, pindex, ioff;
1368 int *pin_num_ordering, *side_ordering, *offset_ordering;
1369 int **num_done_per_dir;
1370 int ****tracks_connected_to_pin;
1378 if (Type->num_pins < 1) {
1389 for (i = 0; i < Type->num_pins; ++i) {
1390 iclass = Type->pin_class[i];
1391 if (Fc[i] > max_Fc && Type->class_inf[iclass].type == pin_type) {
1396 tracks_connected_to_pin = (
int ****)
alloc_matrix4(0, Type->num_pins - 1, 0,
1397 Type->height - 1, 0, 3, 0, max_Fc,
sizeof(
int));
1399 for (ipin = 0; ipin < Type->num_pins; ipin++) {
1400 for (ioff = 0; ioff < Type->height; ioff++) {
1401 for (iside = 0; iside < 4; iside++) {
1402 for (i = 0; i < max_Fc; ++i) {
1403 tracks_connected_to_pin[ipin][ioff][iside][i] =
OPEN;
1409 num_dir = (
int **)
alloc_matrix(0, Type->height - 1, 0, 3,
sizeof(
int));
1410 dir_list = (
int ***)
alloc_matrix3(0, Type->height - 1, 0, 3, 0,
1411 Type->num_pins - 1,
sizeof(
int));
1414 for (i = 0; i < Type->height; i++)
1415 for (j = 0; j < 4; j++)
1416 for (k = 0; k < Type->num_pins; k++)
1417 dir_list[i][j][k] = (-1);
1419 for (i = 0; i < Type->height; i++)
1420 for (j = 0; j < 4; j++)
1423 for (ipin = 0; ipin < Type->num_pins; ipin++) {
1424 iclass = Type->pin_class[ipin];
1425 if (Type->class_inf[iclass].type != pin_type)
1431 if (Type->is_global_pin[ipin])
1433 for (ioff = 0; ioff < Type->height; ioff++) {
1434 for (iside = 0; iside < 4; iside++) {
1435 if (Type->pinloc[ioff][iside][ipin] == 1) {
1436 dir_list[ioff][iside][num_dir[ioff][iside]] = ipin;
1437 num_dir[ioff][iside]++;
1444 for (ioff = 0; ioff < Type->height; ioff++) {
1445 for (iside = 0; iside < 4; iside++)
1446 num_phys_pins += num_dir[ioff][iside];
1448 num_done_per_dir = (
int **)
alloc_matrix(0, Type->height - 1, 0, 3,
1450 for (ioff = 0; ioff < Type->height; ioff++) {
1451 for (iside = 0; iside < 4; iside++) {
1452 num_done_per_dir[ioff][iside] = 0;
1455 pin_num_ordering = (
int *)
my_malloc(num_phys_pins *
sizeof(
int));
1456 side_ordering = (
int *)
my_malloc(num_phys_pins *
sizeof(
int));
1457 offset_ordering = (
int *)
my_malloc(num_phys_pins *
sizeof(
int));
1468 ioff = Type->height - 1;
1472 while (ipin < num_phys_pins) {
1475 }
else if (iside ==
RIGHT) {
1481 }
else if (iside ==
BOTTOM) {
1484 assert(iside ==
LEFT);
1485 if (ioff >= Type->height - 1) {
1493 assert(pindex < num_phys_pins);
1496 if (num_done_per_dir[ioff][iside] >= num_dir[ioff][iside])
1498 pin_num_ordering[ipin] = dir_list[ioff][iside][pindex];
1499 side_ordering[ipin] = iside;
1500 offset_ordering[ipin] = ioff;
1501 assert(Type->pinloc[ioff][iside][dir_list[ioff][iside][pindex]]);
1502 num_done_per_dir[ioff][iside]++;
1506 if (perturb_switch_pattern) {
1508 num_phys_pins, pin_num_ordering, side_ordering, offset_ordering,
1509 nodes_per_chan, max_Fc, directionality);
1512 num_phys_pins, pin_num_ordering, side_ordering, offset_ordering,
1513 nodes_per_chan, max_Fc, directionality);
1519 free_matrix(num_dir, 0, Type->height - 1, 0,
sizeof(
int));
1520 free_matrix3(dir_list, 0, Type->height - 1, 0, 3, 0,
sizeof(
int));
1521 free_matrix(num_done_per_dir, 0, Type->height - 1, 0,
sizeof(
int));
1522 free(pin_num_ordering);
1523 free(side_ordering);
1524 free(offset_ordering);
1526 return tracks_connected_to_pin;
1530 INOUTP int ****tracks_connected_to_pin,
INP int num_phys_pins,
1531 INP int *pin_num_ordering,
INP int *side_ordering,
1532 INP int *offset_ordering,
INP int nodes_per_chan,
INP int Fc,
1540 int i, j, ipin, iside, ioff, itrack, k;
1541 float f_track, fc_step;
1560 step_size = (float) nodes_per_chan / (
float) (Fc * num_phys_pins);
1569 assert((nodes_per_chan % group_size == 0) && (Fc % group_size == 0));
1571 fc_step = (float) nodes_per_chan / (
float) Fc;
1573 for (i = 0; i < num_phys_pins; i++) {
1574 ipin = pin_num_ordering[i];
1575 iside = side_ordering[i];
1576 ioff = offset_ordering[i];
1579 for (j = 0; j < (Fc / group_size); j++) {
1580 f_track = (i * step_size) + (j * fc_step);
1581 itrack = ((int) f_track) * group_size;
1584 itrack =
std::min(itrack, nodes_per_chan - group_size);
1587 for (k = 0; k < group_size; ++k) {
1588 tracks_connected_to_pin[ipin][ioff][iside][group_size * j + k] =
1596 INOUTP int ****tracks_connected_to_pin,
INP int num_phys_pins,
1597 INP int *pin_num_ordering,
INP int *side_ordering,
1598 INP int *offset_ordering,
INP int nodes_per_chan,
INP int Fc,
1612 int i, j, ipin, iside, itrack, ihalf, iconn, ioff;
1613 int Fc_dense, Fc_sparse, Fc_half[2];
1614 float f_track, spacing_dense, spacing_sparse, spacing[2];
1619 step_size = (float) nodes_per_chan / (
float) (Fc * num_phys_pins);
1621 Fc_dense = (Fc / 2) + 1;
1622 Fc_sparse = Fc - Fc_dense;
1624 spacing_dense = (float) nodes_per_chan / (
float) (2 * Fc_dense);
1625 spacing_sparse = (float) nodes_per_chan / (
float) (2 * Fc_sparse);
1627 for (i = 0; i < num_phys_pins; i++) {
1628 ipin = pin_num_ordering[i];
1629 iside = side_ordering[i];
1630 ioff = offset_ordering[i];
1633 spacing[i % 2] = spacing_dense;
1634 Fc_half[i % 2] = Fc_dense;
1635 spacing[(i + 1) % 2] = spacing_sparse;
1636 Fc_half[(i + 1) % 2] = Fc_sparse;
1638 f_track = i * step_size;
1641 for (ihalf = 0; ihalf < 2; ihalf++) {
1642 for (j = 0; j < Fc_half[ihalf]; ++j) {
1643 itrack = (int) f_track;
1648 itrack = itrack % nodes_per_chan;
1649 tracks_connected_to_pin[ipin][ioff][iside][iconn] = itrack;
1651 f_track += spacing[ihalf];
1659 int ****tracks_connected_to_pin,
int nodes_per_chan,
int Fc,
1664 int iconn, iside, itrack, ipin, ioff;
1665 int *num_conns_to_track;
1667 assert(nodes_per_chan > 0);
1669 num_conns_to_track = (
int *)
my_calloc(nodes_per_chan,
sizeof(
int));
1671 for (ipin = 0; ipin < type->
num_pins; ipin++) {
1672 for (ioff = 0; ioff < type->
height; ioff++) {
1673 for (iside = 0; iside < 4; iside++) {
1674 if (tracks_connected_to_pin[ipin][ioff][iside][0] !=
OPEN) {
1675 for (iconn = 0; iconn < Fc; iconn++) {
1677 tracks_connected_to_pin[ipin][ioff][iside][iconn];
1678 num_conns_to_track[itrack]++;
1685 for (itrack = 0; itrack < nodes_per_chan; itrack++) {
1686 if (num_conns_to_track[itrack] <= 0) {
1687 vpr_printf(TIO_MESSAGE_ERROR,
"check_all_tracks_reach_pins: Track %d does not connect to any CLB %ss.\n",
1688 itrack, (ipin_or_opin ==
DRIVER ?
"OPIN" :
"IPIN"));
1692 free(num_conns_to_track);
1700 INP int height,
INP int num_pins,
INP int nodes_per_chan) {
1701 int ipin, iside, itrack, iconn, ioff, pin_counter;
1702 struct s_ivec ***track_to_pin_lookup;
1722 nodes_per_chan - 1, 0, height - 1, 0, 3,
sizeof(
struct s_ivec));
1723 for (itrack = 0; itrack < nodes_per_chan; itrack++) {
1724 for (ioff = 0; ioff < height; ioff++) {
1725 for (iside = 0; iside < 4; iside++) {
1726 track_to_pin_lookup[itrack][ioff][iside].
nelem = 0;
1727 track_to_pin_lookup[itrack][ioff][iside].
list = NULL;
1733 for (ipin = 0; ipin < num_pins; ipin++) {
1734 for (ioff = 0; ioff < height; ioff++) {
1735 for (iside = 0; iside < 4; iside++) {
1736 if (pin_to_track_map[ipin][ioff][iside][0] ==
OPEN)
1739 for (iconn = 0; iconn < Fc[ipin]; iconn++) {
1740 itrack = pin_to_track_map[ipin][ioff][iside][iconn];
1741 track_to_pin_lookup[itrack][ioff][iside].
nelem++;
1748 for (itrack = 0; itrack < nodes_per_chan; itrack++) {
1749 for (ioff = 0; ioff < height; ioff++) {
1750 for (iside = 0; iside < 4; iside++) {
1751 track_to_pin_lookup[itrack][ioff][iside].
list = NULL;
1752 if (track_to_pin_lookup[itrack][ioff][iside].
nelem != 0) {
1753 track_to_pin_lookup[itrack][ioff][iside].
list =
1755 track_to_pin_lookup[itrack][ioff][iside].
nelem
1757 track_to_pin_lookup[itrack][ioff][iside].
nelem = 0;
1764 for (ipin = 0; ipin < num_pins; ipin++) {
1765 for (ioff = 0; ioff < height; ioff++) {
1766 for (iside = 0; iside < 4; iside++) {
1767 if (pin_to_track_map[ipin][ioff][iside][0] ==
OPEN)
1770 for (iconn = 0; iconn < Fc[ipin]; iconn++) {
1771 itrack = pin_to_track_map[ipin][ioff][iside][iconn];
1773 track_to_pin_lookup[itrack][ioff][iside].
nelem;
1774 track_to_pin_lookup[itrack][ioff][iside].
list[pin_counter] =
1776 track_to_pin_lookup[itrack][ioff][iside].
nelem++;
1782 return track_to_pin_lookup;
1816 static const char *
name_type[] = {
"SOURCE",
"SINK",
"IPIN",
"OPIN",
1817 "CHANX",
"CHANY",
"INTRA_CLUSTER_EDGE" };
1818 static const char *direction_name[] = {
"OPEN",
"INC_DIRECTION",
1819 "DEC_DIRECTION",
"BI_DIRECTION" };
1820 static const char *drivers_name[] = {
"OPEN",
"MULTI_BUFFER",
"SINGLE" };
1825 rr_type = L_rr_node[inode].
type;
1828 assert((
int)rr_type < (
int)(
sizeof(name_type) /
sizeof(
char *)));
1830 (L_rr_node[inode].direction + 1) < (
int)(
sizeof(direction_name) /
sizeof(
char *)));
1832 (L_rr_node[inode].drivers + 1) < (
int)(
sizeof(drivers_name) /
sizeof(
char *)));
1834 fprintf(fp,
"Node: %d %s ", inode, name_type[rr_type]);
1835 if ((L_rr_node[inode].xlow == L_rr_node[inode].xhigh)
1836 && (L_rr_node[inode].ylow == L_rr_node[inode].yhigh)) {
1837 fprintf(fp,
"(%d, %d) ", L_rr_node[inode].xlow, L_rr_node[inode].ylow);
1839 fprintf(fp,
"(%d, %d) to (%d, %d) ", L_rr_node[inode].xlow,
1840 L_rr_node[inode].ylow, L_rr_node[inode].xhigh,
1841 L_rr_node[inode].yhigh);
1843 fprintf(fp,
"Ptc_num: %d ", L_rr_node[inode].ptc_num);
1844 fprintf(fp,
"Direction: %s ",
1845 direction_name[L_rr_node[inode].direction + 1]);
1846 fprintf(fp,
"Drivers: %s ", drivers_name[L_rr_node[inode].drivers + 1]);
1849 fprintf(fp,
"%d edge(s):", L_rr_node[inode].num_edges);
1850 for (iconn = 0; iconn < L_rr_node[inode].
num_edges; iconn++)
1851 fprintf(fp,
" %d", L_rr_node[inode].edges[iconn]);
1854 fprintf(fp,
"Switch types:");
1855 for (iconn = 0; iconn < L_rr_node[inode].
num_edges; iconn++)
1856 fprintf(fp,
" %d", L_rr_node[inode].switches[iconn]);
1859 fprintf(fp,
"Occ: %d Capacity: %d\n", L_rr_node[inode].occ,
1860 L_rr_node[inode].capacity);
1862 fprintf(fp,
"R: %g C: %g\n", L_rr_node[inode].R, L_rr_node[inode].C);
1864 fprintf(fp,
"Cost_index: %d\n", L_rr_node[inode].cost_index);
1870 fprintf(fp,
"Index: %d\n", index);
1872 fprintf(fp,
"ortho_cost_index: %d ",
1874 fprintf(fp,
"base_cost: %g ",
rr_indexed_data[index].saved_base_cost);
1875 fprintf(fp,
"saved_base_cost: %g\n",
1891 OUTP boolean * Fc_clipped,
INP t_ivec *** L_rr_node_indices,
INP int delayless_switch,
1898 int ipin, iclass, ofs, chan, seg, max_len, inode, max_Fc = -1;
1902 boolean clipped, vert, pos_dir;
1906 *Fc_clipped =
FALSE;
1909 if (L_grid[i][j].offset > 0) {
1913 type = L_grid[i][j].type;
1921 if (type->
index > 0) {
1923 for (ipin = 0; ipin < type->
num_pins; ++ipin) {
1926 max_Fc = Fc_out[type->
index][ipin];
1932 for (ipin = 0; ipin < type->
num_pins; ++ipin) {
1944 if(Fc_out[type->
index][ipin] != 0) {
1945 for (ofs = 0; ofs < type->
height; ++ofs) {
1946 for (side = (
enum e_side)0; side < 4; side = (
enum e_side)(side + 1)) {
1948 if (0 == type->
pinloc[ofs][side][ipin]) {
1957 chan = (vert ? (j + ofs) : i);
1958 seg = (vert ? i : (j + ofs));
1959 max_len = (vert ?
nx :
ny);
1960 Fc_ofs = (vert ? Fc_xofs : Fc_yofs);
1961 if (
FALSE == pos_dir) {
1972 if (seg > (vert ?
nx :
ny)) {
1975 if (chan > (vert ? ny :
nx)) {
1981 max_Fc, chan_type, seg_details, &edge_list,
1982 Fc_ofs, L_rr_edge_done, max_len, nodes_per_chan,
1983 L_rr_node_indices, &clipped);
1992 num_edges +=
get_opin_direct_connecions(i, j, ipin, &edge_list, L_rr_node_indices, delayless_switch, directs, num_directs, clb_to_clb_directs);
1997 L_rr_edge_done, edge_list);
1998 while (edge_list != NULL) {
1999 next = edge_list->
next;
2007 load_uniform_opin_switch_pattern_paired(
INP int *Fc_out,
2009 INP int *pins_in_chan_seg,
2010 INP int num_wire_inc_muxes,
2011 INP int num_wire_dec_muxes,
2012 INP int *wire_inc_muxes,
2013 INP int *wire_dec_muxes,
2015 INOUTP boolean * L_rr_edge_done,
2017 OUTP boolean * Fc_clipped)
2050 int ipin, iconn, num_edges, init_mux;
2051 int from_node, to_node, to_track;
2055 int k, num_wire_muxes, Fc_output_per_side, CurFc;
2056 int count_inc, count_dec;
2059 *Fc_clipped =
FALSE;
2061 count_inc = count_dec = 0;
2063 for (ipin = 0; ipin < num_pins; ipin++)
2065 from_node = pins_in_chan_seg[ipin];
2066 xlow = L_rr_node[from_node].xlow;
2067 ylow = L_rr_node[from_node].ylow;
2073 for (k = 0; k < 2; ++k)
2077 num_wire_muxes = num_wire_inc_muxes;
2078 wire_muxes = wire_inc_muxes;
2082 num_wire_muxes = num_wire_dec_muxes;
2083 wire_muxes = wire_dec_muxes;
2087 assert(Fc_out[type->
index] % 2 == 0);
2088 Fc_output_per_side = Fc_out[type->
index] / 2;
2092 CurFc = Fc_output_per_side;
2093 if (Fc_output_per_side > num_wire_muxes)
2096 CurFc = num_wire_muxes;
2101 init_mux = (count_inc) % num_wire_muxes;
2106 init_mux = (count_dec) % num_wire_muxes;
2110 for (iconn = 0; iconn < CurFc; iconn++)
2115 wire_muxes[(init_mux +
2116 iconn) % num_wire_muxes];
2118 L_rr_node[to_node].num_opin_drivers++;
2119 to_track = L_rr_node[to_node].ptc_num;
2121 if (
FALSE == L_rr_edge_done[to_node])
2125 L_rr_edge_done[to_node] =
TRUE;
2139 vpr_printf(TIO_MESSAGE_ERROR,
"opin %d at (%d,%d) does not connect to any tracks.\n",
2140 L_rr_node[from_node].ptc_num, L_rr_node[from_node].xlow, L_rr_node[from_node].ylow);
2145 L_rr_edge_done, edge_list);
2150 #if MUX_SIZE_DIST_DISPLAY
2161 view_mux_size_distribution(
t_ivec *** L_rr_node_indices,
2167 int i, j, itrack, seg_num, chan_num, max_len;
2168 int start, end, inode, max_value, min_value;
2169 int array_count, k, num_muxes;
2170 short direction, side;
2171 float *percent_range_array;
2172 float percent_range, percent_range_sum, avg_percent_range;
2173 float std_dev_percent_range, deviation_f;
2174 int range, *range_array, global_max_range;
2175 float avg_range, range_sum, std_dev_range;
2177 t_mux *new_mux, *sblock_mux_list_head, *current, *next;
2180 FILE *dump_file_per_sblock, *dump_file;
2186 dump_file =
my_fopen(
"mux_size_dump.txt",
"w", 0);
2187 dump_file_per_sblock =
my_fopen(
"mux_size_per_sblock_dump.txt",
"w", 0);
2190 sblock_mux_list_head = NULL;
2191 percent_range_array =
2193 range_array = (
int *)
my_malloc((
nx - 1) * (
ny - 1) *
sizeof(
int));
2195 percent_range_sum = 0.0;
2197 global_max_range = 0;
2208 for (j = (
ny - 1); j > 0; j--)
2210 for (i = 1; i <
nx; i++)
2213 for (side = 0; side < 4; side++)
2221 seg_details = seg_details_x;
2229 seg_details = seg_details_x;
2237 seg_details = seg_details_y;
2245 seg_details = seg_details_y;
2253 assert(nodes_per_chan > 0);
2254 for (itrack = 0; itrack < nodes_per_chan; itrack++)
2261 start, chan_num, max_len);
2263 if ((seg_details[itrack].direction ==
2264 direction) && (((start == seg_num)
2267 || ((end == seg_num)
2282 assert((side ==
TOP) || (side ==
BOTTOM));
2297 new_mux->
next = NULL;
2300 if (sblock_mux_list_head == NULL)
2303 sblock_mux_list_head =
2306 else if (sblock_mux_list_head->
2307 size < new_mux->size)
2311 sblock_mux_list_head;
2312 sblock_mux_list_head =
2319 sblock_mux_list_head;
2320 next = current->
next;
2322 while ((next != NULL)
2350 current = sblock_mux_list_head;
2353 fprintf(dump_file_per_sblock,
2354 "sblock at (%d, %d) has mux sizes: {", i, j);
2357 if (current != NULL)
2359 max_value = min_value = current->
size;
2361 while (current != NULL)
2363 if (max_value < current->size)
2364 max_value = current->
size;
2365 if (min_value > current->
size)
2366 min_value = current->
size;
2369 fprintf(dump_file_per_sblock,
"%d ",
2371 fprintf(dump_file,
"%d\n", current->
size);
2374 current = current->
next;
2378 fprintf(dump_file_per_sblock,
"}\n\tmax: %d\tmin:%d",
2379 max_value, min_value);
2382 range = max_value - min_value;
2383 percent_range = ((float)range) / ((float)min_value);
2385 if (global_max_range < range)
2386 global_max_range = range;
2389 fprintf(dump_file_per_sblock,
2390 "\t\trange: %d\t\tpercent range:%.2f\n",
2391 range, percent_range);
2394 percent_range_array[array_count] = percent_range;
2395 range_array[array_count] = range;
2397 percent_range_sum += percent_range;
2406 distr_current = distr_list;
2407 while (distr_current != NULL
2408 && distr_current->
mux_count != num_muxes)
2410 distr_current = distr_current->
next;
2413 if (distr_current == NULL)
2420 new_distribution->
mux_count = num_muxes;
2421 new_distribution->
max_index = max_value;
2422 new_distribution->
distr =
2423 (
int *)
my_calloc(max_value + 1,
sizeof(
int));
2426 current = sblock_mux_list_head;
2427 while (current != NULL)
2429 assert(current->
size <=
2431 new_distribution->
distr[current->
size]++;
2432 current = current->
next;
2436 new_distribution->
next = distr_list;
2437 distr_list = new_distribution;
2442 current = sblock_mux_list_head;
2444 while (current != NULL)
2450 distr_current->
distr =
2459 1); k <= current->size; k++)
2460 distr_current->
distr[k] = 0;
2464 distr_current->
distr[current->
2469 distr_current->
distr[current->
2472 current = current->
next;
2477 current = sblock_mux_list_head;
2478 while (current != NULL)
2480 next = current->
next;
2484 sblock_mux_list_head = NULL;
2488 avg_percent_range = (float)percent_range_sum / array_count;
2489 avg_range = (float)range_sum / array_count;
2491 percent_range_sum = 0.0;
2493 for (k = 0; k < array_count; k++)
2495 deviation_f = (percent_range_array[k] - avg_percent_range);
2496 percent_range_sum += deviation_f * deviation_f;
2498 deviation_f = ((float)range_array[k] - avg_range);
2499 range_sum += deviation_f * deviation_f;
2501 std_dev_percent_range =
2502 sqrt(percent_range_sum / ((
float)array_count - 1.0));
2503 std_dev_range = sqrt(range_sum / ((
float)array_count - 1.0));
2504 vpr_printf(TIO_MESSAGE_INFO,
"==== MUX size statistics ====\n");
2505 vpr_printf(TIO_MESSAGE_INFO,
"Max range of mux size within a sblock: %d\n", global_max_range);
2506 vpr_printf(TIO_MESSAGE_INFO,
"Average range of mux size within a sblock: %.2f\n", avg_range);
2507 vpr_printf(TIO_MESSAGE_INFO,
"Std dev of range of mux size within a sblock: %.2f\n", std_dev_range);
2508 vpr_printf(TIO_MESSAGE_INFO,
"Average percent range of mux size within a sblock: %.2f%%\n", avg_percent_range * 100.0);
2509 vpr_printf(TIO_MESSAGE_INFO,
"Std dev of percent range of mux size within a sblock: %.2f%%\n", std_dev_percent_range * 100.0);
2511 vpr_printf(TIO_MESSAGE_INFO,
" -- Detailed MUX size distribution by sblock type -- \n");
2512 distr_current = distr_list;
2513 while (distr_current != NULL)
2515 print_distribution(stdout, distr_current);
2518 distr_next = distr_current->
next;
2520 free(distr_current->
distr);
2521 free(distr_current);
2523 distr_current = distr_next;
2526 free(percent_range_array);
2529 fclose(dump_file_per_sblock);
2535 print_distribution(FILE * fptr,
2543 distr = distr_struct->
distr;
2545 "For Sblocks containing %d MUXes, the MUX size distribution is:\n",
2547 fprintf(fptr,
"\t\t\tSize\t\t\tFrequency (percent)\n");
2550 for (k = 0; k <= distr_struct->
max_index; k++)
2554 for (k = 0; k <= distr_struct->
max_index; k++)
2556 if (zeros && (distr[k] == 0))
2563 fprintf(fptr,
"\t\t\t%d\t\t\t%d (%.2f%%)\n", k, distr[k],
2564 (
float)distr[k] / sum * 100.0);
2567 fprintf(fptr,
"\nEnd of this Sblock MUX size distribution.\n");
2580 char *pb_type_name, *port_name;
2581 int start_pin_index, end_pin_index;
2586 pb_type_name = NULL;
2589 for(i = 0; i < num_directs; i++) {
2590 pb_type_name = (
char*)
my_malloc((strlen(directs[i].from_pin) + strlen(directs[i].to_pin)) *
sizeof(
char));
2591 port_name = (
char*)
my_malloc((strlen(directs[i].from_pin) + strlen(directs[i].to_pin)) *
sizeof(
char));
2595 parse_direct_pin_name(directs[i].from_pin, directs[i].line, &start_pin_index, &end_pin_index, pb_type_name, port_name);
2603 assert(j < num_types);
2607 for(j = 0; j < pb_type->
num_ports; j++) {
2608 if(strcmp(pb_type->
ports[j].
name, port_name) == 0) {
2612 assert(j < pb_type->num_ports);
2614 if(start_pin_index ==
OPEN) {
2615 assert(start_pin_index == end_pin_index);
2616 start_pin_index = 0;
2624 parse_direct_pin_name(directs[i].to_pin, directs[i].line, &start_pin_index, &end_pin_index, pb_type_name, port_name);
2632 assert(j < num_types);
2636 for(j = 0; j < pb_type->
num_ports; j++) {
2637 if(strcmp(pb_type->
ports[j].
name, port_name) == 0) {
2641 assert(j < pb_type->num_ports);
2643 if(start_pin_index ==
OPEN) {
2644 assert(start_pin_index == end_pin_index);
2645 start_pin_index = 0;
2652 if(abs(clb_to_clb_directs[i].from_clb_pin_start_index - clb_to_clb_directs[i].from_clb_pin_end_index) != abs(clb_to_clb_directs[i].to_clb_pin_start_index - clb_to_clb_directs[i].to_clb_pin_end_index)) {
2653 vpr_printf(TIO_MESSAGE_ERROR,
"[LINE %d] Range mismatch from %s to %s.\n", directs[i].line, directs[i].from_pin, directs[i].to_pin);
2660 return clb_to_clb_directs;
2670 int max_index, min_index, offset, swap;
2674 edge_list_head = *edge_list_ptr;
2678 for(i = 0; i < num_directs; i++) {
2680 if(clb_to_clb_directs[i].from_clb_type == type) {
2682 if(clb_to_clb_directs[i].from_clb_pin_start_index > clb_to_clb_directs[i].from_clb_pin_end_index) {
2684 max_index = clb_to_clb_directs[i].from_clb_pin_start_index;
2685 min_index = clb_to_clb_directs[i].from_clb_pin_end_index;
2688 min_index = clb_to_clb_directs[i].from_clb_pin_start_index;
2689 max_index = clb_to_clb_directs[i].from_clb_pin_end_index;
2691 if(max_index >= opin && min_index <= opin) {
2692 offset = opin - min_index;
2694 if(x + directs[i].x_offset < nx + 1 &&
2695 x + directs[i].x_offset > 0 &&
2696 y + directs[i].y_offset <
ny + 1 &&
2697 y + directs[i].y_offset > 0) {
2699 if(clb_to_clb_directs[i].to_clb_pin_start_index > clb_to_clb_directs[i].to_clb_pin_end_index) {
2701 ipin = clb_to_clb_directs[i].to_clb_pin_end_index + offset;
2703 ipin = clb_to_clb_directs[i].to_clb_pin_start_index - offset;
2707 ipin = clb_to_clb_directs[i].to_clb_pin_end_index - offset;
2709 ipin = clb_to_clb_directs[i].to_clb_pin_start_index + offset;
2713 grid_ofs =
grid[x + directs[i].x_offset][y + directs[i].y_offset].
offset;
2714 inode =
get_rr_node_index(x + directs[i].x_offset, y + directs[i].y_offset - grid_ofs,
IPIN, ipin, L_rr_node_indices);
2721 *edge_list_ptr = edge_list_head;
void print_rr_indexed_data(FILE *fp, int index)
static void build_rr_sinks_sources(INP int i, INP int j, INP t_rr_node *L_rr_node, INP t_ivec ***L_rr_node_indices, INP int delayless_switch, INP struct s_grid_tile **L_grid)
t_pb_graph_pin ** clock_pins
FILE * my_fopen(const char *fname, const char *flag, int prompt)
void ** alloc_matrix(int nrmin, int nrmax, int ncmin, int ncmax, size_t elsize)
void free_matrix4(void *vptr, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, int nemin, size_t elsize)
void get_blk_pin_from_port_pin(int blk_type_index, int port, int port_pin, int *blk_pin)
int from_clb_pin_end_index
struct s_clb_to_clb_directs t_clb_to_clb_directs
void get_class_range_for_block(INP int iblk, OUTP int *class_low, OUTP int *class_high)
static void build_rr_ychan(INP int i, INP int j, INP struct s_ivec ****track_to_ipin_lookup, INP struct s_ivec ***switch_block_conn, INP int cost_index_offset, INP int nodes_per_chan, INP int *opin_mux_size, INP short *****sblock_pattern, INP int Fs_per_side, INP t_seg_details *seg_details, INP t_ivec ***L_rr_node_indices, INP boolean *L_rr_edge_done, INOUTP t_rr_node *L_rr_node, INP int wire_to_ipin_switch, INP enum e_directionality directionality)
struct s_class * class_inf
void free_matrix(void *vptr, int nrmin, int nrmax, int ncmin, size_t elsize)
t_rr_indexed_data * rr_indexed_data
void free_matrix3(void *vptr, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, size_t elsize)
static t_seg_details * alloc_and_load_global_route_seg_details(INP int nodes_per_chan, INP int global_route_switch)
int get_seg_start(INP t_seg_details *seg_details, INP int itrack, INP int chan_num, INP int seg_num)
enum e_graph_type t_graph_type
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 check_rr_graph(INP t_graph_type graph_type, INP t_type_ptr types, INP int L_nx, INP int L_ny, INP int nodes_per_chan, INP int Fs, INP int num_seg_types, INP int num_switches, INP t_segment_inf *segment_inf, INP int global_route_switch, INP int delayless_switch, INP int wire_to_ipin_switch, t_seg_details *seg_details, int **Fc_in, int **Fc_out, int *****opin_to_track_map, int *****ipin_to_track_map, t_ivec ****track_to_ipin_lookup, t_ivec ***switch_block_conn, boolean *perturb_ipins)
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)
void * my_chunk_malloc(size_t size, t_chunk *chunk_info)
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)
void * my_calloc(size_t nelem, size_t size)
static void free_type_pin_to_track_map(int *****ipin_to_track_map, t_type_ptr types)
int to_clb_pin_start_index
struct s_mux_size_distribution t_mux_size_distribution
t_pb_graph_pin ** output_pins
struct s_linked_vptr * chunk_ptr_head
static int **** alloc_and_load_pin_to_track_map(INP enum e_pin_type pin_type, INP int nodes_per_chan, INP int *Fc, INP t_type_ptr Type, INP boolean perturb_switch_pattern, INP enum e_directionality directionality)
static void build_bidir_rr_opins(INP int i, INP int j, INOUTP t_rr_node *L_rr_node, INP t_ivec ***L_rr_node_indices, INP int *****opin_to_track_map, INP int **Fc_out, INP boolean *L_rr_edge_done, INP t_seg_details *seg_details, INP struct s_grid_tile **L_grid, INP int delayless_switch, INP t_direct_inf *directs, INP int num_directs, INP t_clb_to_clb_directs *clb_to_clb_directs)
boolean getEchoEnabled(void)
void load_net_rr_terminals(t_ivec ***L_rr_node_indices)
static void load_uniform_switch_pattern(INP t_type_ptr type, INOUTP int ****tracks_connected_to_pin, INP int num_phys_pins, INP int *pin_num_ordering, INP int *side_ordering, INP int *offset_ordering, INP int nodes_per_chan, INP int Fc, INP enum e_directionality directionality)
static const char * name_type[]
static void rr_graph_externals(t_timing_inf timing_inf, t_segment_inf *segment_inf, int num_seg_types, int nodes_per_chan, int wire_to_ipin_switch, enum e_base_cost_type base_cost_type)
static void free_type_track_to_ipin_map(struct s_ivec ****track_to_pin_map, t_type_ptr types, int nodes_per_chan)
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)
struct s_ivec *** alloc_and_load_switch_block_conn(INP int nodes_per_chan, INP enum e_switch_block_type switch_block_type, INP int Fs)
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)
struct s_mux_size_distribution * next
static int ** alloc_and_load_actual_fc(INP int L_num_types, INP t_type_ptr types, INP int nodes_per_chan, INP boolean is_Fc_out, INP enum e_directionality directionality, OUTP boolean *Fc_clipped, INP boolean ignore_Fc_0)
t_type_descriptor * from_clb_type
static void build_unidir_rr_opins(INP int i, INP int j, INP struct s_grid_tile **L_grid, INP int **Fc_out, INP int nodes_per_chan, INP t_seg_details *seg_details, INOUTP int **Fc_xofs, INOUTP int **Fc_yofs, INOUTP t_rr_node *L_rr_node, INOUTP boolean *L_rr_edge_done, OUTP boolean *Fc_clipped, INP t_ivec ***L_rr_node_indices, INP int delayless_switch, INP t_direct_inf *directs, INP int num_directs, INP t_clb_to_clb_directs *clb_to_clb_directs)
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)
void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types, INP t_type_ptr types, INP int L_nx, INP int L_ny, INP struct s_grid_tile **L_grid, INP int chan_width, INP struct s_chan_width_dist *chan_capacity_inf, INP enum e_switch_block_type sb_type, INP int Fs, INP int num_seg_types, INP int num_switches, INP t_segment_inf *segment_inf, INP int global_route_switch, INP int delayless_switch, INP t_timing_inf timing_inf, INP int wire_to_ipin_switch, INP enum e_base_cost_type base_cost_type, INP t_direct_inf *directs, INP int num_directs, INP boolean ignore_Fc_0, OUTP int *Warnings)
static void alloc_and_load_rr_clb_source(t_ivec ***L_rr_node_indices)
static void build_rr_xchan(INP int i, INP int j, INP struct s_ivec ****track_to_ipin_lookup, INP struct s_ivec ***switch_block_conn, INP int cost_index_offset, INP int nodes_per_chan, INP int *opin_mux_size, INP short *****sblock_pattern, INP int Fs_per_side, INP t_seg_details *seg_details, INP t_ivec ***L_rr_node_indices, INP boolean *L_rr_edge_done, INOUTP t_rr_node *L_rr_node, INP int wire_to_ipin_switch, INP enum e_directionality directionality)
void alloc_and_load_rr_indexed_data(INP t_segment_inf *segment_inf, INP int num_segment, INP t_ivec ***L_rr_node_indices, INP int nodes_per_chan, int wire_to_ipin_switch, enum e_base_cost_type base_cost_type)
static t_clb_to_clb_directs * alloc_and_load_clb_to_clb_directs(INP t_direct_inf *directs, INP int num_directs)
enum e_direction direction
void print_rr_node(FILE *fp, t_rr_node *L_rr_node, int inode)
void dump_rr_graph(INP const char *file_name)
boolean isEchoFileEnabled(enum e_echo_files echo_option)
void add_rr_graph_C_from_switches(float C_ipin_cblock)
void parse_direct_pin_name(char *src_string, int line, int *start_pin_index, int *end_pin_index, char *pb_type_name, char *port_name)
struct s_grid_tile ** grid
static void alloc_net_rr_terminals(void)
void **** alloc_matrix4(int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, int nemin, int nemax, size_t elsize)
void free_sblock_pattern_lookup(INOUTP short *****sblock_pattern)
static int get_opin_direct_connecions(int x, int y, int opin, INOUTP t_linked_edge **edge_list_ptr, INP t_ivec ***L_rr_node_indices, INP int delayless_switch, INP t_direct_inf *directs, INP int num_directs, INP t_clb_to_clb_directs *clb_to_clb_directs)
t_ivec *** rr_node_indices
void free_seg_details(t_seg_details *seg_details, int nodes_per_chan)
static void alloc_and_load_rr_graph(INP int num_nodes, INP t_rr_node *L_rr_node, INP int num_seg_types, INP t_seg_details *seg_details, INP boolean *L_rr_edge_done, INP struct s_ivec ****track_to_ipin_lookup, INP int *****opin_to_track_map, INP struct s_ivec ***switch_block_conn, INP struct s_grid_tile **L_grid, INP int L_nx, INP int L_ny, INP int Fs, INP short *****sblock_pattern, INP int **Fc_out, INP int **Fc_xofs, INP int **Fc_yofs, INP t_ivec ***L_rr_node_indices, INP int nodes_per_chan, INP enum e_switch_block_type sb_type, INP int delayless_switch, INP enum e_directionality directionality, INP int wire_to_ipin_switch, OUTP boolean *Fc_clipped, INP t_direct_inf *directs, INP int num_directs, INP t_clb_to_clb_directs *clb_to_clb_directs)
struct s_pb_type * pb_type
static void * my_realloc(void *memblk, int ibytes)
int get_seg_end(INP t_seg_details *seg_details, INP int itrack, INP int istart, INP int chan_num, INP int seg_max)
static boolean * alloc_and_load_perturb_ipins(INP int nodes_per_chan, INP int L_num_types, INP int **Fc_in, INP int **Fc_out, INP enum e_directionality directionality)
short ***** alloc_sblock_pattern_lookup(INP int L_nx, INP int L_ny, INP int nodes_per_chan)
t_pb_graph_node * pb_graph_head
static void check_all_tracks_reach_pins(t_type_ptr type, int ****tracks_connected_to_pin, int nodes_per_chan, int Fc, enum e_pin_type ipin_or_opin)
struct s_type_descriptor * type_descriptors
char * getEchoFileName(enum e_echo_files echo_option)
t_type_descriptor * to_clb_type
void free_switch_block_conn(struct s_ivec ***switch_block_conn, int nodes_per_chan)
void free_chunk_memory(t_chunk *chunk_info)
static void load_perturbed_switch_pattern(INP t_type_ptr type, INOUTP int ****tracks_connected_to_pin, INP int num_phys_pins, INP int *pin_num_ordering, INP int *side_ordering, INP int *offset_ordering, INP int nodes_per_chan, INP int Fc, INP enum e_directionality directionality)
void watch_edges(int inode, t_linked_edge *edge_list_head)
void *** alloc_matrix3(int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, size_t elsize)
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)
void dump_seg_details(t_seg_details *seg_details, int nodes_per_chan, const char *fname)
static struct s_ivec *** alloc_and_load_track_to_pin_lookup(INP int ****pin_to_track_map, INP int *Fc, INP int height, INP int num_pins, INP int nodes_per_chan)
struct s_linked_edge * next
t_pb_graph_pin ** input_pins
void free_rr_node_indices(INP t_ivec ***L_rr_node_indices)
int from_clb_pin_start_index
void alloc_and_load_edges_and_switches(INP t_rr_node *L_rr_node, INP int inode, INP int num_edges, INP boolean *L_rr_edge_done, INP t_linked_edge *edge_list_head)