31 #define AAPACK_MAX_OVERUSE_LOOKAHEAD_PINS_FAC 2
32 #define AAPACK_MAX_OVERUSE_LOOKAHEAD_PINS_CONST 5
34 #define AAPACK_MAX_FEASIBLE_BLOCK_ARRAY_SIZE 30
35 #define AAPACK_MAX_NET_SINKS_IGNORE 256
36 #define AAPACK_MAX_HIGH_FANOUT_EXPLORE 10
38 #define SCALE_NUM_PATHS 1e-2
47 #define SCALE_DISTANCE_VAL 1e-4
117 static void check_for_duplicate_inputs ();
123 std::map<int, float> &gain,
t_pb *pb);
126 float beta,
int max_cluster_size,
int max_molecule_inputs,
127 int max_pb_depth,
int max_models,
142 int sibling_memory_blk);
154 int max_molecule_inputs);
160 INP int clb_index,
INP int max_nets_in_pb_type,
INP int detailed_routing_stage);
164 INP int max_cluster_size,
INP int clb_index,
165 INP int max_nets_in_pb_type,
181 int clustered_block,
int port_on_clustered_block,
182 int pin_on_clustered_block,
boolean timing_driven,
183 boolean connection_driven,
188 boolean connection_driven,
boolean global_clocks,
t_pb *pb);
191 INP int clb_index,
INP boolean *is_clock,
INP boolean global_clocks,
192 INP float alpha,
INP float beta,
INP boolean timing_driven,
200 INOUTP int *num_used_instances_type,
INOUTP int *num_instances_type,
201 INP int num_models,
INP int max_cluster_size,
202 INP int max_nets_in_pb_type,
INP int detailed_routing_stage);
211 INP boolean allow_unrelated_clustering,
212 INOUTP int *num_unrelated_clustering_attempts,
233 int num_models,
boolean global_clocks,
boolean *is_clock,
234 boolean hill_climbing_flag,
char *out_fname,
boolean timing_driven,
236 int recompute_timing_after,
float block_delay,
237 float intra_cluster_net_delay,
float inter_cluster_net_delay,
238 float aspect,
boolean allow_unrelated_clustering,
239 boolean allow_early_exit,
boolean connection_driven,
252 int i, iblk, num_molecules, blocks_since_last_analysis, num_clb, max_nets_in_pb_type,
253 cur_nets_in_pb_type, num_blocks_hill_added, max_cluster_size, cur_cluster_size,
254 max_molecule_inputs, max_pb_depth, cur_pb_depth, num_unrelated_clustering_attempts,
255 indexofcrit, savedindexofcrit ,
256 detailed_routing_stage, *hill_climbing_inputs_avail;
258 int *num_used_instances_type, *num_instances_type;
261 boolean early_exit, is_cluster_legal;
269 t_pack_molecule *istart, *next_molecule, *prev_molecule, *cur_molecule;
275 float num_paths_scaling, distance_scaling;
284 max_cluster_size = 0;
285 max_molecule_inputs = 0;
287 max_nets_in_pb_type = 0;
291 cur_molecule = molecule_head;
293 while (cur_molecule != NULL) {
299 cur_molecule = cur_molecule->
next;
310 if (cur_cluster_size > max_cluster_size) {
311 max_cluster_size = cur_cluster_size;
313 if (cur_pb_depth > max_pb_depth) {
314 max_pb_depth = cur_pb_depth;
316 if (cur_nets_in_pb_type > max_nets_in_pb_type) {
317 max_nets_in_pb_type = cur_nets_in_pb_type;
321 if (hill_climbing_flag) {
322 hill_climbing_inputs_avail = (
int *)
my_calloc(max_cluster_size + 1,
325 hill_climbing_inputs_avail = NULL;
333 check_for_duplicate_inputs ();
336 max_molecule_inputs, max_pb_depth, num_models,
337 &cluster_placement_stats, &primitives_list, molecule_head,
340 blocks_since_last_analysis = 0;
342 num_blocks_hill_added = 0;
343 num_used_instances_type = (
int*)
my_calloc(num_types,
sizeof(
int));
344 num_instances_type = (
int*)
my_calloc(num_types,
sizeof(
int));
351 inter_cluster_net_delay, arch->
models, timing_inf);
357 #ifndef PATH_COUNTING
385 crit = PACK_PATH_WEIGHT * slacks->path_criticality[inet][ipin]
397 for (inode = 0; inode <
num_tnodes; inode++) {
406 * (float)
tnode[inode].prepacked_data->normalized_total_critical_paths;
428 max_molecule_inputs);
433 max_molecule_inputs);
437 while (istart != NULL) {
438 is_cluster_legal =
FALSE;
439 savedindexofcrit = indexofcrit;
445 &clb[num_clb], num_clb, istart, aspect, num_used_instances_type,
446 num_instances_type, num_models, max_cluster_size,
447 max_nets_in_pb_type, detailed_routing_stage);
448 vpr_printf(TIO_MESSAGE_INFO,
"Complex block %d: %s, type: %s\n",
449 num_clb, clb[num_clb].name, clb[num_clb].type->
name);
453 beta, timing_driven, connection_driven, slacks);
456 if (timing_driven && !early_exit) {
457 blocks_since_last_analysis++;
461 cur_cluster_placement_stats_ptr = &cluster_placement_stats[clb[num_clb
463 num_unrelated_clustering_attempts = 0;
465 clb[num_clb - 1].pb, allow_unrelated_clustering,
466 &num_unrelated_clustering_attempts,
467 cur_cluster_placement_stats_ptr);
468 prev_molecule = istart;
469 while (next_molecule != NULL && prev_molecule != next_molecule) {
471 cur_cluster_placement_stats_ptr, next_molecule,
472 primitives_list, clb[num_clb - 1].pb, num_models,
473 max_cluster_size, num_clb - 1, max_nets_in_pb_type, detailed_routing_stage);
474 prev_molecule = next_molecule;
476 if (next_molecule != NULL) {
478 #ifdef DEBUG_FAILED_PACKING_CANDIDATES
479 vpr_printf(TIO_MESSAGE_DIRECT,
"\tNO_ROUTE:%s type %s/n",
487 #ifdef DEBUG_FAILED_PACKING_CANDIDATES
488 vpr_printf(TIO_MESSAGE_DIRECT,
"\tFAILED_CHECK:%s type %s check %d\n",
500 clb[num_clb - 1].pb, allow_unrelated_clustering,
501 &num_unrelated_clustering_attempts,
502 cur_cluster_placement_stats_ptr);
506 #ifdef DEBUG_FAILED_PACKING_CANDIDATES
507 vpr_printf(TIO_MESSAGE_DIRECT,
"\tPASSED:%s type %s\n",
516 global_clocks, alpha, beta, timing_driven,
517 connection_driven, slacks);
518 num_unrelated_clustering_attempts = 0;
520 if (timing_driven && !early_exit) {
521 blocks_since_last_analysis++;
524 clb[num_clb - 1].pb, allow_unrelated_clustering,
525 &num_unrelated_clustering_attempts,
526 cur_cluster_placement_stats_ptr);
531 if (is_cluster_legal ==
TRUE) {
532 vpr_printf(TIO_MESSAGE_INFO,
"Passed route at end.\n");
534 vpr_printf(TIO_MESSAGE_INFO,
"Failed route at end, repack cluster trying detailed routing at each stage.\n");
537 is_cluster_legal =
TRUE;
539 if (is_cluster_legal ==
TRUE) {
542 if (num_blocks_hill_added > 0 && !early_exit) {
543 blocks_since_last_analysis += num_blocks_hill_added;
549 max_molecule_inputs);
554 max_molecule_inputs);
559 num_used_instances_type[clb[num_clb - 1].type->index]--;
561 free(clb[num_clb - 1].pb);
562 free(clb[num_clb - 1].name);
563 clb[num_clb - 1].name = NULL;
564 clb[num_clb - 1].pb = NULL;
566 indexofcrit = savedindexofcrit;
579 output_blif (clb, num_clb, global_clocks, is_clock,
583 if (hill_climbing_flag) {
584 free(hill_climbing_inputs_avail);
588 for (i = 0; i < num_clb; i++) {
596 free(num_used_instances_type);
597 free(num_instances_type);
598 free(unclustered_list_head);
614 free (primitives_list);
625 int inet, iblk, ipin;
632 for (ipin = 0; ipin < port->
size; ipin++) {
635 if (is_clock[inet]) {
636 vpr_printf(TIO_MESSAGE_ERROR,
"Error in check_clocks.\n");
637 vpr_printf(TIO_MESSAGE_ERROR,
"Net %d (%s) is a clock, but also connects to a logic block input on logical_block %d (%s).\n",
639 vpr_printf(TIO_MESSAGE_ERROR,
"This would break the current clustering implementation and is electrically questionable, so clustering has been aborted.\n");
665 std::map<int, float> &gain,
t_pb *pb) {
716 float beta,
int max_cluster_size,
int max_molecule_inputs,
717 int max_pb_depth,
int max_models,
725 int i, ext_inps, ipin, driving_blk, inet;
729 int max_molecule_size;
743 for (i = 0; i <= max_molecule_inputs; i++) {
744 unclustered_list_head[i].
next = NULL;
749 cur_molecule = molecules_head;
750 for (i = 0; i < num_molecules; i++) {
751 assert(cur_molecule != NULL);
752 molecule_array[i] = cur_molecule;
753 cur_molecule = cur_molecule->
next;
755 assert(cur_molecule == NULL);
763 for (i = 0; i < num_molecules; i++) {
766 next_ptr->
next = unclustered_list_head[ext_inps].
next;
767 unclustered_list_head[ext_inps].
next = next_ptr;
770 free(molecule_array);
780 if (
vpack_net[inet].node_block[ipin] == driving_blk) {
793 max_molecule_size = 1;
794 cur_molecule = molecules_head;
795 while (cur_molecule != NULL) {
796 if (cur_molecule->
num_blocks > max_molecule_size) {
799 cur_molecule = cur_molecule->
next;
834 t_pb *memory_class_pb;
835 int sibling_memory_blk;
838 memory_class_pb = NULL;
839 sibling_memory_blk =
OPEN;
860 if (sibling_memory_blk ==
OPEN) {
861 memory_class_pb = NULL;
866 memory_class_pb, sibling_memory_blk);
871 int sibling_memory_blk) {
880 while (port || !second_pass) {
886 for (i = 0; i < cur_pb_type->
num_ports; i++) {
889 for (j = 0; j < port->
size; j++) {
891 if (memory_class_pb) {
908 if (memory_class_pb) {
927 if (memory_class_pb) {
977 prev_ptr = &unclustered_list_head[ext_inps];
978 ptr = unclustered_list_head[ext_inps].
next;
979 while (ptr != NULL) {
988 cluster_placement_stats_ptr, ilogical_blk)) {
994 if (success ==
TRUE) {
1029 int inputs_avail = 0;
1031 for (i = 0; i < cur_pb->pb_graph_node->num_input_pin_class; i++) {
1032 for (j = 0; j < cur_pb->pb_graph_node->input_pin_class_size[i]; j++) {
1033 if (cur_pb->pb_stats->input_pins_used[i][j] !=
OPEN)
1044 for (ext_inps = inputs_avail; ext_inps >= 0; ext_inps--) {
1047 if (molecule != NULL) {
1056 int max_molecule_inputs) {
1066 for (ext_inps = max_molecule_inputs; ext_inps >= 0; ext_inps--) {
1067 ptr = unclustered_list_head[ext_inps].
next;
1069 while (ptr != NULL) {
1083 int max_nets_in_pb_type) {
1160 max_nets_in_pb_type *
sizeof(
int));
1178 INP int clb_index,
INP int max_nets_in_pb_type,
INP int detailed_routing_stage) {
1179 int molecule_size, failed_location;
1186 boolean is_root_of_chain;
1195 failed_location = 0;
1200 primitives_list, clb_index)) {
1203 for (i = 0; i < molecule_size && block_pack_status ==
BLK_PASSED;
1206 (primitives_list[i] == NULL) == (molecule->logical_block_ptrs[i] == NULL));
1207 failed_location = i + 1;
1208 if (molecule->logical_block_ptrs[i] != NULL) {
1209 if(molecule->type ==
MOLECULE_FORCED_PACK && molecule->pack_pattern->is_chain && i == molecule->pack_pattern->root_block->block_id) {
1210 chain_root_pin = molecule->pack_pattern->chain_root_pin;
1211 is_root_of_chain =
TRUE;
1213 chain_root_pin = NULL;
1214 is_root_of_chain =
FALSE;
1218 molecule->logical_block_ptrs[i]->index, pb, &parent,
1219 max_models, max_cluster_size, clb_index,
1220 max_nets_in_pb_type, cluster_placement_stats_ptr, is_root_of_chain, chain_root_pin);
1246 chain_root_block = molecule->logical_block_ptrs[molecule->pack_pattern->root_block->block_id];
1248 while(cur_pb != NULL) {
1254 for (i = 0; i < molecule_size; i++) {
1255 if (molecule->logical_block_ptrs[i] != NULL) {
1258 molecule->logical_block_ptrs[i]->packed_molecules;
1259 while (cur_molecule != NULL) {
1262 cur_molecule = cur_molecule->
next;
1265 primitives_list[i]);
1271 for (i = 0; i < failed_location; i++) {
1272 if (molecule->logical_block_ptrs[i] != NULL) {
1274 molecule->logical_block_ptrs[i]->index,
1286 return block_pack_status;
1296 INP int max_cluster_size,
INP int clb_index,
1297 INP int max_nets_in_pb_type,
1301 boolean is_primitive;
1305 t_pb *pb, *parent_pb;
1315 if (pb_graph_node->parent_pb_graph_node != cb->pb_graph_node) {
1317 pb_graph_node->parent_pb_graph_node, ilogical_block, cb,
1318 &my_parent, max_models, max_cluster_size, clb_index,
1319 max_nets_in_pb_type, cluster_placement_stats_ptr, is_root_of_chain, chain_root_pin);
1320 parent_pb = my_parent;
1327 assert(parent_pb->
name == NULL);
1330 parent_pb->
mode = pb_graph_node->pb_type->parent_mode->index;
1356 assert(parent_pb->
mode == pb_graph_node->pb_type->parent_mode->index);
1363 if (pb_graph_node->pb_type
1369 i < parent_pb->pb_graph_node->pb_type->modes[parent_pb->
mode].num_pb_type_children);
1370 pb = &parent_pb->
child_pbs[i][pb_graph_node->placement_index];
1376 pb_type = pb_graph_node->pb_type;
1394 if (block_pack_status ==
BLK_PASSED && is_root_of_chain ==
TRUE) {
1396 root_port = chain_root_pin->port->model_port;
1399 if(pb_graph_node != chain_root_pin->parent_node) {
1407 return block_pack_status;
1428 while (pb != NULL) {
1456 int num_internal_connections, num_open_connections, num_stuck_connections;
1458 num_internal_connections = num_open_connections = num_stuck_connections = 0;
1469 num_internal_connections++;
1471 num_open_connections++;
1473 num_stuck_connections++;
1477 if (net_relation_to_clustered_block ==
OUTPUT) {
1486 if (num_internal_connections > 1) {
1489 - (num_internal_connections - 1)
1490 + 1 * num_stuck_connections);
1494 - num_internal_connections
1495 + 1 * num_stuck_connections);
1500 if (net_relation_to_clustered_block ==
INPUT) {
1509 if (num_internal_connections > 1) {
1512 - (num_internal_connections - 1) + 1
1513 + 1 * num_stuck_connections);
1517 - num_internal_connections + 1
1518 + 1 * num_stuck_connections);
1540 if (net_relation_to_clustered_block ==
OUTPUT
1545 #ifdef PATH_COUNTING
1547 timinggain = TIMING_GAIN_PATH_WEIGHT * slacks->path_criticality[inet][ipin]
1562 if (net_relation_to_clustered_block ==
INPUT
1569 #ifdef PATH_COUNTING
1571 timinggain = TIMING_GAIN_PATH_WEIGHT * slacks->path_criticality[inet][ipin]
1589 int clustered_block,
int port_on_clustered_block,
1590 int pin_on_clustered_block,
boolean timing_driven,
1591 boolean connection_driven,
1603 int iblk, ipin, ifirst, stored_net;
1635 if (gain_flag ==
GAIN) {
1665 if (connection_driven) {
1667 net_relation_to_clustered_block);
1670 if (timing_driven) {
1672 net_relation_to_clustered_block, slacks);
1685 boolean connection_driven,
boolean global_clocks,
t_pb *pb) {
1692 int num_input_pins, num_output_pins;
1693 int num_used_input_pins, num_used_output_pins;
1713 num_used_input_pins = 0;
1715 num_input_pins += port->
size;
1717 for (k = 0; k < port->
size; k++) {
1719 num_used_input_pins++;
1726 if (num_input_pins == 0) {
1730 num_used_output_pins = 0;
1732 num_output_pins = 0;
1735 num_output_pins += port->
size;
1736 for (k = 0; k < port->
size; k++) {
1738 num_used_output_pins++;
1747 if (connection_driven) {
1753 / (num_used_input_pins + num_used_output_pins);
1758 / (num_used_input_pins + num_used_output_pins);
1763 if (timing_driven) {
1766 + (1.0 - alpha) * (
float) cur_pb->
pb_stats->
gain[iblk];
1775 INP int clb_index,
INP boolean *is_clock,
INP boolean global_clocks,
1776 INP float alpha,
INP float beta,
INP boolean timing_driven,
1782 int new_blk, molecule_size;
1801 for (iblock = 0; iblock < molecule_size; iblock++) {
1802 if (molecule->logical_block_ptrs[iblock] == NULL) {
1805 new_blk = molecule->logical_block_ptrs[iblock]->index;
1822 for (ipin = 0; ipin < port->
size; ipin++) {
1825 if (!is_clock[inet] || !global_clocks)
1827 port->
index, ipin, timing_driven,
1828 connection_driven,
OUTPUT, slacks);
1831 port->
index, ipin, timing_driven,
1832 connection_driven,
OUTPUT, slacks);
1843 for (ipin = 0; ipin < port->
size; ipin++) {
1848 port->
index, ipin, timing_driven, connection_driven,
1863 timing_driven, connection_driven,
INPUT, slacks);
1866 timing_driven, connection_driven,
INPUT, slacks);
1883 INOUTP int *num_used_instances_type,
INOUTP int *num_instances_type,
1884 INP int num_models,
INP int max_cluster_size,
1885 INP int max_nets_in_pb_type,
INP int detailed_routing_stage) {
1893 assert(new_cluster->name == NULL);
1898 (strlen(molecule->logical_block_ptrs[molecule->root]->name) + 4) *
sizeof(char));
1899 sprintf(new_cluster->name,
"cb.%s",
1900 molecule->logical_block_ptrs[molecule->root]->name);
1901 new_cluster->nets = NULL;
1902 new_cluster->type = NULL;
1903 new_cluster->pb = NULL;
1913 if (num_used_instances_type[i] < num_instances_type[i]) {
1919 new_cluster->pb->pb_graph_node =
1920 new_cluster->type->pb_graph_head;
1922 max_nets_in_pb_type);
1923 new_cluster->pb->parent_pb = NULL;
1928 j < new_cluster->type->pb_graph_head->pb_type->num_modes
1930 new_cluster->pb->mode = j;
1933 new_cluster->pb->pb_graph_node, j);
1936 molecule, primitives_list, new_cluster->pb,
1937 num_models, max_cluster_size, clb_index,
1938 max_nets_in_pb_type, detailed_routing_stage));
1946 free(new_cluster->pb);
1951 if (count == num_types - 1) {
1952 vpr_printf(TIO_MESSAGE_ERROR,
"Can not find any logic block that can implement molecule.\n");
1954 vpr_printf(TIO_MESSAGE_ERROR,
"\tPattern %s %s\n",
1955 molecule->pack_pattern->name,
1956 molecule->logical_block_ptrs[molecule->root]->name);
1959 molecule->logical_block_ptrs[molecule->root]->name);
1966 if (aspect >= 1.0) {
1973 vpr_printf(TIO_MESSAGE_INFO,
"Not enough resources expand FPGA size to x = %d y = %d.\n",
1976 vpr_printf(TIO_MESSAGE_ERROR,
"Circuit cannot pack into architecture, architecture size (nx = %d, ny = %d) exceeds packer range.\n",
1984 num_used_instances_type[new_cluster->type->index]++;
1998 int i, j, iblk, index, inet, count;
2006 vpr_printf(TIO_MESSAGE_ERROR,
"Hill climbing not supported yet, error out.\n");
2010 if (cur_pb->pb_stats->num_feasible_blocks ==
NOT_VALID) {
2014 cur_pb->pb_stats->num_feasible_blocks = 0;
2016 if (cur_pb->pb_stats->num_marked_blocks
2018 for (i = 0; i < cur_pb->pb_stats->num_marked_blocks; i++) {
2019 iblk = cur_pb->pb_stats->marked_blocks[i];
2022 while (cur != NULL) {
2024 if (molecule->
valid) {
2033 cluster_placement_stats_ptr,
2042 cur_pb->pb_stats->gain, cur_pb);
2053 while (cur != NULL) {
2055 if (molecule->
valid) {
2064 cluster_placement_stats_ptr,
2073 cur_pb->pb_stats->gain, cur_pb);
2082 if(cur_pb->pb_stats->num_feasible_blocks == 0 && cur_pb->pb_stats->tie_break_high_fanout_net !=
OPEN) {
2085 inet = cur_pb->pb_stats->tie_break_high_fanout_net;
2091 while (cur != NULL) {
2093 if (molecule->
valid) {
2102 cluster_placement_stats_ptr,
2111 cur_pb->pb_stats->gain, cur_pb);
2119 cur_pb->pb_stats->tie_break_high_fanout_net =
OPEN;
2122 for (j = 0; j < cur_pb->pb_stats->num_feasible_blocks; j++) {
2123 if (cur_pb->pb_stats->num_feasible_blocks != 0) {
2124 cur_pb->pb_stats->num_feasible_blocks--;
2125 index = cur_pb->pb_stats->num_feasible_blocks;
2126 molecule = cur_pb->pb_stats->feasible_blocks[index];
2138 INP boolean allow_unrelated_clustering,
2139 INOUTP int *num_unrelated_clustering_attempts,
2158 if (allow_unrelated_clustering) {
2159 if (best_molecule == NULL) {
2160 if (*num_unrelated_clustering_attempts == 0) {
2163 packer_algorithm, cur_pb,
2164 cluster_placement_stats_ptr);
2165 (*num_unrelated_clustering_attempts)++;
2168 *num_unrelated_clustering_attempts = 0;
2172 return best_molecule;
2179 int i, j, i_clb, node_index, ipin, iclass;
2180 int inport, outport, clockport;
2185 for (i_clb = 0; i_clb < num_clb; i_clb++) {
2186 rr_node = clb[i_clb].pb->rr_graph;
2187 pb_type = clb[i_clb].pb->pb_graph_node->pb_type;
2190 clb[i_clb].nets = (
int*)
my_malloc(clb[i_clb].type->num_pins *
sizeof(
int));
2191 for (i = 0; i < clb[i_clb].type->num_pins; i++) {
2192 clb[i_clb].nets[i] =
OPEN;
2195 inport = outport = clockport = 0;
2198 for (i = 0; i < pb_type->
num_ports; i++) {
2202 iclass = clb[i_clb].type->pin_class[ipin];
2203 assert(clb[i_clb].type->class_inf[iclass].type ==
RECEIVER);
2213 iclass = clb[i_clb].type->pin_class[ipin];
2214 assert(clb[i_clb].type->class_inf[iclass].type ==
DRIVER);
2225 iclass = clb[i_clb].type->pin_class[ipin];
2226 assert(clb[i_clb].type->class_inf[iclass].type ==
RECEIVER);
2227 assert(clb[i_clb].type->is_global_pin[ipin]);
2244 boolean * blocks_checked;
2253 vpr_printf(TIO_MESSAGE_ERROR,
"pb %s does not contain logical block %s but logical block %s #%d links to pb.\n",
2261 assert(cur_pb->
name);
2263 if (cur_pb != clb[num_clb].pb) {
2264 vpr_printf(TIO_MESSAGE_ERROR,
"CLB %s does not match CLB contained by pb %s.\n",
2271 for (i = 0; i < num_clb; i++) {
2276 if (blocks_checked[i] ==
FALSE) {
2277 vpr_printf(TIO_MESSAGE_ERROR,
"Logical block %s #%d not found in any cluster.\n",
2283 free(blocks_checked);
2298 vpr_printf(TIO_MESSAGE_ERROR,
"pb %s contains logical block %s #%d but logical block is already contained in another pb.\n",
2304 vpr_printf(TIO_MESSAGE_ERROR,
"pb %s contains logical block %s #%d but logical block does not link to pb.\n",
2343 while (cur != NULL) {
2345 if (molecule->
valid) {
2353 assert(best != NULL);
2368 int i, ipin, iport, inet, iblk;
2369 int num_introduced_inputs_of_indirectly_related_block;
2373 num_introduced_inputs_of_indirectly_related_block = 0;
2383 while (cur != NULL) {
2385 for (ipin = 0; ipin < cur->
size; ipin++) {
2389 num_introduced_inputs_of_indirectly_related_block++;
2393 molecule); iblk++) {
2398 num_introduced_inputs_of_indirectly_related_block--;
2413 gain -= num_introduced_inputs_of_indirectly_related_block * (0.001);
2419 float base_gain_a, base_gain_b, diff;
2426 diff = base_gain_a - base_gain_b;
2526 pb_type = pb_graph_node->
pb_type;
2530 input_port = output_port = clock_port = 0;
2531 for (i = 0; i < pb_type->
num_ports; i++) {
2532 prim_port = &pb_type->
ports[i];
2535 assert(prim_port->
num_pins == 1 && clock_port == 0);
2544 for (j = 0; j < prim_port->
num_pins; j++) {
2548 &pb_graph_node->
input_pins[input_port][j], cur_pb,
2554 for (j = 0; j < prim_port->
num_pins; j++) {
2558 &pb_graph_node->
output_pins[output_port][j], cur_pb,
2573 int pin_class, output_port;
2581 boolean skip, found;
2588 assert(pin_class !=
OPEN);
2592 output_pb_graph_pin = NULL;
2599 for (i = 0; i < pb_type->
num_ports && !found; i++) {
2600 prim_port = &pb_type->
ports[i];
2611 output_pb_graph_pin =
2618 if (output_pb_graph_pin != NULL) {
2620 while (check_pb != NULL && check_pb != cur_pb) {
2623 if (check_pb != NULL) {
2688 if (i ==
vpack_net[inet].num_sinks + 1) {
2701 if (count ==
vpack_net[inet].num_sinks) {
2774 if (success && cur_pb->
child_pbs != NULL) {
2815 assert(ipin <= cur_pb->pb_graph_node->input_pin_class_size[i]);
2831 assert(ipin <= cur_pb->pb_graph_node->output_pin_class_size[i]);
2859 if (cur_pb->
name == NULL) {
2891 if (ilogical_block ==
OPEN) {
2916 fprintf(fp,
"Index \tLogical block name \tCriticality \tCritindexarray\n\n");
2922 fprintf(fp,
"\t\t");
2923 }
else if (len < 16) {
int get_max_depth_of_pb_type(t_pb_type *pb_type)
std::map< int, float > sharinggain
void set_mode_cluster_placement_stats(INP t_pb_graph_node *pb_graph_node, int mode)
#define AAPACK_MAX_FEASIBLE_BLOCK_ARRAY_SIZE
static void commit_lookahead_pins_used(t_pb *cur_pb)
t_pb_graph_pin ** clock_pins
static void try_update_lookahead_pins_used(t_pb *cur_pb)
enum e_pb_type_class class_type
FILE * my_fopen(const char *fname, const char *flag, int prompt)
#define AAPACK_MAX_HIGH_FANOUT_EXPLORE
t_pack_molecule * moleculeptr
e_net_relation_to_clustered_block
static int * critindexarray
t_model_ports * model_port
struct s_pb_type * pb_type_children
void free_cluster_legality_checker(void)
static void check_clustering(int num_clb, t_block *clb, boolean *is_clock)
int tie_break_high_fanout_net
#define AAPACK_MAX_OVERUSE_LOOKAHEAD_PINS_FAC
void heapsort(int *sort_index, float *sort_values, int nelem, int start_index)
static boolean check_lookahead_pins_used(t_pb *cur_pb)
struct s_pb_graph_node * parent_pb_graph_node
int get_max_nets_in_pb_type(const t_pb_type *pb_type)
void free_legalizer_for_cluster(INP t_block *clb, boolean free_local_rr_graph)
int * output_pin_class_size
static boolean primitive_type_and_memory_feasible(int iblk, const t_pb_type *cur_pb_type, t_pb *memory_class_pb, int sibling_memory_blk)
#define SCALE_DISTANCE_VAL
struct s_pack_molecule ** feasible_blocks
void free_pb_stats(t_pb *pb)
static t_pack_molecule * get_molecule_for_cluster(INP enum e_packer_algorithm packer_algorithm, INP t_pb *cur_pb, INP boolean allow_unrelated_clustering, INOUTP int *num_unrelated_clustering_attempts, INP t_cluster_placement_stats *cluster_placement_stats_ptr)
static void compute_and_mark_lookahead_pins_used(int ilogical_block)
int get_max_primitives_in_pb_type(t_pb_type *pb_type)
std::map< int, int > num_pins_of_net_in_pb
void restore_routing_cluster(void)
static void start_new_cluster(INP t_cluster_placement_stats *cluster_placement_stats, INP t_pb_graph_node **primitives_list, INP const t_arch *arch, INOUTP t_block *new_cluster, INP int clb_index, INP t_pack_molecule *molecule, INP float aspect, INOUTP int *num_used_instances_type, INOUTP int *num_instances_type, INP int num_models, INP int max_cluster_size, INP int max_nets_in_pb_type, INP int detailed_routing_stage)
static void update_timing_gain_values(int inet, int clustered_block, t_pb *cur_pb, enum e_net_relation_to_clustered_block net_relation_to_clustered_block, t_slack *slacks)
static void check_cluster_logical_blocks(t_pb *pb, boolean *blocks_checked)
void free_cluster_placement_stats(INOUTP t_cluster_placement_stats *cluster_placement_stats_list)
int unclustered_list_head_size
static t_pack_molecule * get_seed_logical_molecule_with_most_ext_inputs(int max_molecule_inputs)
void * my_calloc(size_t nelem, size_t size)
struct s_model_ports * next
static int * net_output_feeds_driving_block_input
struct s_linked_vptr * packed_molecules
static void revert_place_logical_block(INP int ilogical_block, INP int max_models)
static int get_net_corresponding_to_pb_graph_pin(t_pb *cur_pb, t_pb_graph_pin *pb_graph_pin)
void do_timing_analysis(t_slack *slacks, boolean is_prepacked, boolean do_lut_input_balancing, boolean is_final_analysis)
#define AAPACK_MAX_NET_SINKS_IGNORE
void print_clustering_timing_info(const char *fname)
void commit_primitive(INOUTP t_cluster_placement_stats *cluster_placement_stats, INP t_pb_graph_node *primitive)
t_pb_graph_pin ** output_pins
void reset_legalizer_for_cluster(t_block *clb)
void output_blif(t_block *clb, int num_clusters, boolean global_clocks, boolean *is_clock, const char *out_fname, boolean skip_clustering)
t_cluster_placement_stats * alloc_and_load_cluster_placement_stats(void)
#define AAPACK_MAX_OVERUSE_LOOKAHEAD_PINS_CONST
boolean getEchoEnabled(void)
static void reset_lookahead_pins_used(t_pb *cur_pb)
t_prepacked_tnode_data * prepacked_data
static struct s_molecule_link * unclustered_list_head
static void alloc_and_init_clustering(boolean global_clocks, float alpha, float beta, int max_cluster_size, int max_molecule_inputs, int max_pb_depth, int max_models, t_cluster_placement_stats **cluster_placement_stats, t_pb_graph_node ***primitives_list, t_pack_molecule *molecules_head, int num_molecules)
void alloc_and_load_grid(INOUTP int *num_instances_type)
static t_pack_molecule * get_molecule_by_num_ext_inputs(INP enum e_packer_algorithm packer_algorithm, INOUTP t_pb *cur_pb, INP int ext_inps, INP enum e_removal_policy remove_flag, INP t_cluster_placement_stats *cluster_placement_stats_ptr)
void setup_intracluster_routing_for_molecule(INP t_pack_molecule *molecule, INP t_pb_graph_node **primitive_list)
static float * block_criticality
boolean try_breadth_first_route_cluster(void)
static void check_clocks(boolean *is_clock)
void save_and_reset_routing_cluster(void)
void set_pb_graph_mode(t_pb_graph_node *pb_graph_node, int mode, int isOn)
std::map< int, float > hillgain
t_slack * alloc_and_load_pre_packing_timing_graph(float block_delay, float inter_cluster_net_delay, t_model *models, t_timing_inf timing_inf)
int ** lookahead_output_pins_used
static void free_pb_stats_recursive(t_pb *pb)
static void * my_malloc(int ibytes)
int get_array_size_of_molecule(t_pack_molecule *molecule)
void output_clustering(t_block *clb, int num_clusters, boolean global_clocks, boolean *is_clock, char *out_fname, boolean skip_clustering)
int * num_connectable_primtive_input_pins
static t_pack_molecule * get_highest_gain_molecule(INP enum e_packer_algorithm packer_algorithm, INOUTP t_pb *cur_pb, INP enum e_gain_type gain_mode, INP t_cluster_placement_stats *cluster_placement_stats_ptr)
int num_child_blocks_in_pb
static t_pack_molecule * get_most_critical_seed_molecule(int *indexofcrit)
static void alloc_and_load_pb_stats(t_pb *pb, int max_models, int max_nets_in_pb_type)
static void update_connection_gain_values(int inet, int clustered_block, t_pb *cur_pb, enum e_net_relation_to_clustered_block net_relation_to_clustered_block)
void reset_cluster_placement_stats(INOUTP t_cluster_placement_stats *cluster_placement_stats)
boolean has_valid_normalized_T_arr(int inode)
static enum e_block_pack_status try_pack_molecule(INOUTP t_cluster_placement_stats *cluster_placement_stats_ptr, INP t_pack_molecule *molecule, INOUTP t_pb_graph_node **primitives_list, INOUTP t_pb *pb, INP int max_models, INP int max_cluster_size, INP int clb_index, INP int max_nets_in_pb_type, INP int detailed_routing_stage)
struct s_pb_graph_node * parent_node
static void print_block_criticalities(const char *fname)
void reset_tried_but_unused_cluster_placements(INOUTP t_cluster_placement_stats *cluster_placement_stats)
static void add_molecule_to_pb_stats_candidates(t_pack_molecule *molecule, std::map< int, float > &gain, t_pb *pb)
boolean isEchoFileEnabled(enum e_echo_files echo_option)
void do_clustering(const t_arch *arch, t_pack_molecule *molecule_head, int num_models, boolean global_clocks, boolean *is_clock, boolean hill_climbing_flag, char *out_fname, boolean timing_driven, enum e_cluster_seed cluster_seed_type, float alpha, float beta, int recompute_timing_after, float block_delay, float intra_cluster_net_delay, float inter_cluster_net_delay, float aspect, boolean allow_unrelated_clustering, boolean allow_early_exit, boolean connection_driven, enum e_packer_algorithm packer_algorithm, t_timing_inf timing_inf)
std::map< int, float > connectiongain
boolean exists_free_primitive_for_logical_block(INOUTP t_cluster_placement_stats *cluster_placement_stats, INP int ilogical_block)
struct s_pb_graph_node *** child_pb_graph_nodes
struct s_linked_vptr * next
struct s_pb_graph_pin *** list_of_connectable_input_pin_ptrs
std::map< int, float > gain
struct s_molecule_link * next
struct s_pack_molecule * next
struct s_pb_stats t_pb_stats
static int compare_molecule_gain(const void *a, const void *b)
void print_criticality(t_slack *slacks, boolean criticality_is_normalized, const char *fname)
static t_pack_molecule * get_free_molecule_with_most_ext_inputs_for_cluster(INP enum e_packer_algorithm packer_algorithm, INOUTP t_pb *cur_pb, INP t_cluster_placement_stats *cluster_placement_stats_ptr)
struct s_pb_type * pb_type
static struct s_molecule_link * memory_pool
float ** timing_criticality
static void compute_and_mark_lookahead_pins_used_for_pin(t_pb_graph_pin *pb_graph_pin, t_pb *primitive_pb, int inet)
std::map< int, float > timinggain
static boolean is_logical_blk_in_pb(int iblk, t_pb *pb)
void print_slack(float **slack, boolean slack_is_normalized, const char *fname)
int * input_pin_class_size
void print_timing_graph(const char *fname)
e_detailed_routing_stages
static float get_molecule_gain(t_pack_molecule *molecule, std::map< int, float > &blk_gain)
struct s_type_descriptor * type_descriptors
char * getEchoFileName(enum e_echo_files echo_option)
t_logical_block ** logical_block_ptrs
static void mark_and_update_partial_gain(int inet, enum e_gain_update gain_flag, int clustered_block, int port_on_clustered_block, int pin_on_clustered_block, boolean timing_driven, boolean connection_driven, enum e_net_relation_to_clustered_block net_relation_to_clustered_block, t_slack *slacks)
int ** lookahead_input_pins_used
static void alloc_and_load_cluster_info(INP int num_clb, INOUTP t_block *clb)
struct s_pb_stats * pb_stats
int num_ext_inputs_logical_block(int iblk)
void alloc_and_load_legalizer_for_cluster(INP t_block *clb, INP int clb_index, INP const t_arch *arch)
char * my_strdup(const char *str)
void save_cluster_solution(void)
t_pb_graph_node * pb_graph_node
void free_timing_graph(t_slack *slacks)
boolean is_non_clock_global
static enum e_block_pack_status try_place_logical_block_rec(INP t_pb_graph_node *pb_graph_node, INP int ilogical_block, INP t_pb *cb, OUTP t_pb **parent, INP int max_models, INP int max_cluster_size, INP int clb_index, INP int max_nets_in_pb_type, INP t_cluster_placement_stats *cluster_placement_stats_ptr, INP boolean is_root_of_chain, INP t_pb_graph_pin *chain_root_pin)
void alloc_and_load_cluster_legality_checker(void)
static boolean primitive_feasible(int iblk, t_pb *cur_pb)
boolean get_next_primitive_list(INOUTP t_cluster_placement_stats *cluster_placement_stats, INP t_pack_molecule *molecule, INOUTP t_pb_graph_node **primitives_list, INP int clb_index)
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
static void update_cluster_stats(INP t_pack_molecule *molecule, INP int clb_index, INP boolean *is_clock, INP boolean global_clocks, INP float alpha, INP float beta, INP boolean timing_driven, INP boolean connection_driven, INP t_slack *slacks)
static void update_total_gain(float alpha, float beta, boolean timing_driven, boolean connection_driven, boolean global_clocks, t_pb *pb)