29 INP char *pattern_name,
INOUTP int *ncount);
42 INP int curr_pattern_index,
INP int *L_num_blocks,
INP boolean make_root_of_chain);
54 INP int logical_block_index,
94 for (i = 0; i < ncount; i++) {
98 if (expansion_edge == NULL) {
102 list_of_packing_patterns[i].
base_cost = 0;
104 list_of_packing_patterns, i, NULL, NULL, &L_num_blocks);
105 list_of_packing_patterns[i].
num_blocks = L_num_blocks;
110 for(k = 0; k < L_num_blocks; k++) {
112 if(list_of_packing_patterns[i].is_chain && list_of_packing_patterns[i].root_block->block_id != k) {
122 *num_packing_patterns = ncount;
124 return list_of_packing_patterns;
131 INP char *pattern_name,
INOUTP int *ncount) {
135 if (hash_value->
count == 1) {
136 assert(*ncount == hash_value->
index);
139 return hash_value->
index;
157 if (pb_graph_node == NULL) {
161 pb_graph_node->temp_scratch_pad = NULL;
163 for (i = 0; i < pb_graph_node->num_input_ports; i++) {
164 for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
166 for (k = 0; k < pb_graph_node->input_pins[i][j].num_output_edges;
170 < pb_graph_node->input_pins[i][j].output_edges[k]->num_pack_patterns;
175 pb_graph_node->input_pins[i][j].output_edges[k]->pack_pattern_names[m],
177 if (pb_graph_node->input_pins[i][j].output_edges[k]->pack_pattern_indices
179 pb_graph_node->input_pins[i][j].output_edges[k]->pack_pattern_indices = (
int*)
181 pb_graph_node->input_pins[i][j].output_edges[k]->num_pack_patterns
184 pb_graph_node->input_pins[i][j].output_edges[k]->pack_pattern_indices[m] =
188 if (hasPattern ==
TRUE) {
195 for (i = 0; i < pb_graph_node->num_output_ports; i++) {
196 for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
198 for (k = 0; k < pb_graph_node->output_pins[i][j].num_output_edges;
202 < pb_graph_node->output_pins[i][j].output_edges[k]->num_pack_patterns;
207 pb_graph_node->output_pins[i][j].output_edges[k]->pack_pattern_names[m],
209 if (pb_graph_node->output_pins[i][j].output_edges[k]->pack_pattern_indices
211 pb_graph_node->output_pins[i][j].output_edges[k]->pack_pattern_indices = (
int*)
213 pb_graph_node->output_pins[i][j].output_edges[k]->num_pack_patterns
216 pb_graph_node->output_pins[i][j].output_edges[k]->pack_pattern_indices[m] =
220 if (hasPattern ==
TRUE) {
227 for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
228 for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
230 for (k = 0; k < pb_graph_node->clock_pins[i][j].num_output_edges;
234 < pb_graph_node->clock_pins[i][j].output_edges[k]->num_pack_patterns;
239 pb_graph_node->clock_pins[i][j].output_edges[k]->pack_pattern_names[m],
241 if (pb_graph_node->clock_pins[i][j].output_edges[k]->pack_pattern_indices
243 pb_graph_node->clock_pins[i][j].output_edges[k]->pack_pattern_indices = (
int*)
245 pb_graph_node->clock_pins[i][j].output_edges[k]->num_pack_patterns
248 pb_graph_node->clock_pins[i][j].output_edges[k]->pack_pattern_indices[m] =
252 if (hasPattern ==
TRUE) {
259 for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
260 for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
264 < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
267 &pb_graph_node->child_pb_graph_nodes[i][j][k], nhash,
278 if (pb_graph_pin->num_output_edges == 1 && pb_graph_pin->output_edges[0]->num_pack_patterns == 0 && pb_graph_pin->output_edges[0]->infer_pattern ==
FALSE) {
279 pb_graph_pin->output_edges[0]->infer_pattern =
TRUE;
280 if (pb_graph_pin->output_edges[0]->num_output_pins == 1) {
286 if (pb_graph_pin->num_input_edges == 1 && pb_graph_pin->input_edges[0]->num_pack_patterns == 0 && pb_graph_pin->input_edges[0]->infer_pattern ==
FALSE) {
287 pb_graph_pin->input_edges[0]->infer_pattern =
TRUE;
288 if (pb_graph_pin->input_edges[0]->num_input_pins == 1) {
302 struct s_hash *curr_pattern;
308 while (curr_pattern != NULL) {
309 assert(nlist[curr_pattern->
index].
name == NULL);
320 int i, j, num_pack_pattern_blocks;
322 if (list_of_pack_patterns != NULL) {
323 for (i = 0; i < num_packing_patterns; i++) {
324 num_pack_pattern_blocks = list_of_pack_patterns[i].num_blocks;
326 free(list_of_pack_patterns[i].
name);
327 free(list_of_pack_patterns[i].is_block_optional);
329 for (j = 0; j < num_pack_pattern_blocks; j++) {
330 free(pattern_block_list[j]);
332 free(pattern_block_list);
334 free(list_of_pack_patterns);
349 if (pb_graph_node == NULL) {
353 for (i = 0; i < pb_graph_node->num_input_ports; i++) {
354 for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
355 for (k = 0; k < pb_graph_node->input_pins[i][j].num_output_edges;
359 < pb_graph_node->input_pins[i][j].output_edges[k]->num_pack_patterns;
361 if (pb_graph_node->input_pins[i][j].output_edges[k]->pack_pattern_indices[m]
370 for (i = 0; i < pb_graph_node->num_output_ports; i++) {
371 for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
372 for (k = 0; k < pb_graph_node->output_pins[i][j].num_output_edges;
376 < pb_graph_node->output_pins[i][j].output_edges[k]->num_pack_patterns;
378 if (pb_graph_node->output_pins[i][j].output_edges[k]->pack_pattern_indices[m]
387 for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
388 for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
389 for (k = 0; k < pb_graph_node->clock_pins[i][j].num_output_edges;
393 < pb_graph_node->clock_pins[i][j].output_edges[k]->num_pack_patterns;
395 if (pb_graph_node->clock_pins[i][j].output_edges[k]->pack_pattern_indices[m]
397 return pb_graph_node->clock_pins[i][j].output_edges[k];
404 for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
405 for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
409 < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
412 &pb_graph_node->child_pb_graph_nodes[i][j][k]);
429 INP int curr_pattern_index,
INP int *L_num_blocks,
INOUTP boolean make_root_of_chain) {
431 int iport, ipin, iedge;
436 found = expansion_edge->infer_pattern;
437 for (i = 0; !found && i < expansion_edge->num_pack_patterns; i++) {
438 if (expansion_edge->pack_pattern_indices[i] == curr_pattern_index) {
447 for (i = 0; i < expansion_edge->num_output_pins; i++) {
448 if (expansion_edge->output_pins[i]->parent_node->pb_type->num_modes
450 destination_pb_graph_node =
452 assert(found ==
FALSE);
460 != curr_pattern_index) {
462 list_of_packing_patterns[curr_pattern_index].base_cost +=
464 destination_block->
block_id = *L_num_blocks;
467 (
void *) destination_block;
483 list_of_packing_patterns,
485 &destination_pb_graph_node->
input_pins[iport][ipin],
486 destination_block, L_num_blocks);
503 list_of_packing_patterns,
504 curr_pattern_index, L_num_blocks,
FALSE);
521 list_of_packing_patterns,
523 &destination_pb_graph_node->
clock_pins[iport][ipin],
524 destination_block, L_num_blocks);
530 == curr_pattern_index) {
531 if(make_root_of_chain ==
TRUE) {
532 list_of_packing_patterns[curr_pattern_index].chain_root_pin = expansion_edge->output_pins[i];
533 list_of_packing_patterns[curr_pattern_index].root_block = destination_block;
537 for (j = 0; j < expansion_edge->output_pins[i]->num_output_edges;
539 if (expansion_edge->output_pins[i]->output_edges[j]->infer_pattern
542 expansion_edge->output_pins[i]->output_edges[j],
543 list_of_packing_patterns, curr_pattern_index,
544 L_num_blocks, make_root_of_chain);
548 < expansion_edge->output_pins[i]->output_edges[j]->num_pack_patterns;
550 if (expansion_edge->output_pins[i]->output_edges[j]->pack_pattern_indices[k]
551 == curr_pattern_index) {
552 assert(found ==
FALSE);
556 expansion_edge->output_pins[i]->output_edges[j],
557 list_of_packing_patterns,
558 curr_pattern_index, L_num_blocks, make_root_of_chain);
578 int iport, ipin, iedge;
584 found = expansion_edge->infer_pattern;
585 for (i = 0; !found && i < expansion_edge->num_pack_patterns; i++) {
586 if (expansion_edge->pack_pattern_indices[i] == curr_pattern_index) {
595 for (i = 0; i < expansion_edge->num_input_pins; i++) {
596 if (expansion_edge->input_pins[i]->parent_node->pb_type->num_modes
599 assert(found ==
FALSE);
607 if (source_block == NULL
610 source_block->
block_id = *L_num_blocks;
612 list_of_packing_patterns[curr_pattern_index].base_cost +=
618 if (list_of_packing_patterns[curr_pattern_index].root_block
620 list_of_packing_patterns[curr_pattern_index].root_block =
635 list_of_packing_patterns,
637 &source_pb_graph_node->
input_pins[iport][ipin],
638 source_block, L_num_blocks);
653 list_of_packing_patterns,
654 curr_pattern_index, L_num_blocks,
FALSE);
669 list_of_packing_patterns,
671 &source_pb_graph_node->
clock_pins[iport][ipin],
672 source_block, L_num_blocks);
677 if (destination_pin != NULL) {
684 pack_pattern_connection->
from_block = source_block;
686 expansion_edge->input_pins[i];
687 pack_pattern_connection->
to_block = destination_block;
688 pack_pattern_connection->
to_pin = destination_pin;
690 source_block->
connections = pack_pattern_connection;
694 pack_pattern_connection->
from_block = source_block;
696 expansion_edge->input_pins[i];
697 pack_pattern_connection->
to_block = destination_block;
698 pack_pattern_connection->
to_pin = destination_pin;
699 pack_pattern_connection->
next = destination_block->connections;
700 destination_block->connections = pack_pattern_connection;
702 if (source_block == destination_block) {
703 vpr_printf(TIO_MESSAGE_ERROR,
"Invalid packing pattern defined. Source and destination block are the same (%s).\n",
708 if(expansion_edge->input_pins[i]->num_input_edges == 0) {
709 if(expansion_edge->input_pins[i]->parent_node->pb_type->parent_mode == NULL) {
711 list_of_packing_patterns[curr_pattern_index].is_chain =
TRUE;
714 list_of_packing_patterns,
715 curr_pattern_index, L_num_blocks,
TRUE);
718 for (j = 0; j < expansion_edge->input_pins[i]->num_input_edges;
720 if (expansion_edge->input_pins[i]->input_edges[j]->infer_pattern
723 expansion_edge->input_pins[i]->input_edges[j],
724 list_of_packing_patterns, curr_pattern_index,
725 destination_pin, destination_block, L_num_blocks);
729 < expansion_edge->input_pins[i]->input_edges[j]->num_pack_patterns;
731 if (expansion_edge->input_pins[i]->input_edges[j]->pack_pattern_indices[k]
732 == curr_pattern_index) {
733 assert(found ==
FALSE);
737 expansion_edge->input_pins[i]->input_edges[j],
738 list_of_packing_patterns,
739 curr_pattern_index, destination_pin,
740 destination_block, L_num_blocks);
758 INP int num_packing_patterns,
OUTP int *num_pack_molecule) {
759 int i, j, best_pattern;
764 is_used = (
boolean*)
my_calloc(num_packing_patterns,
sizeof(
boolean));
766 cur_molecule = list_of_molecules_head = NULL;
771 for (i = 0; i < num_packing_patterns; i++) {
773 for(j = 1; j < num_packing_patterns; j++) {
774 if(is_used[best_pattern]) {
776 }
else if (is_used[j] ==
FALSE &&
compare_pack_pattern(&list_of_pack_patterns[j], &list_of_pack_patterns[best_pattern]) == 1) {
780 assert(is_used[best_pattern] ==
FALSE);
781 is_used[best_pattern] =
TRUE;
784 if (cur_molecule != NULL) {
785 cur_molecule->
next = list_of_molecules_head;
790 list_of_molecules_head = cur_molecule;
814 cur_molecule->
root = 0;
821 cur_molecule->
next = list_of_molecules_head;
823 list_of_molecules_head = cur_molecule;
833 list_of_pack_patterns, num_packing_patterns,
834 list_of_molecules_head);
837 return list_of_molecules_head;
843 if (pattern_block->block_id ==
OPEN) {
847 pattern_block_list[pattern_block->block_id] = pattern_block;
848 pattern_block->block_id =
OPEN;
849 connection = pattern_block->connections;
853 next = connection->
next;
869 INP int block_index) {
877 molecule->
pack_pattern = &list_of_pack_patterns[pack_pattern_index];
880 molecule->
num_blocks = list_of_pack_patterns[pack_pattern_index].num_blocks;
882 list_of_pack_patterns[pack_pattern_index].root_block->block_id;
885 if(list_of_pack_patterns[pack_pattern_index].is_chain ==
TRUE) {
895 assert(list_of_pack_patterns[pack_pattern_index].is_block_optional[i] ==
TRUE);
899 molecule_linked_list->
data_vptr = (
void *) molecule;
900 molecule_linked_list->
next =
903 molecule_linked_list;
920 INP int logical_block_index,
922 int iport, ipin, inet;
925 boolean *is_block_optional;
927 is_block_optional = molecule->pack_pattern->is_block_optional;
928 is_optional = is_block_optional[current_pattern_block->block_id];
931 if (molecule->logical_block_ptrs[current_pattern_block->block_id] != NULL) {
932 if (molecule->logical_block_ptrs[current_pattern_block->block_id]
937 molecule->num_ext_inputs--;
944 if(
logical_block[logical_block_index].packed_molecules != NULL) {
950 current_pattern_block->pb_type)) {
954 molecule->logical_block_ptrs[current_pattern_block->block_id] =
956 molecule->num_ext_inputs +=
959 cur_pack_pattern_connection = current_pattern_block->connections;
960 while (cur_pack_pattern_connection != NULL && success ==
TRUE) {
962 == current_pattern_block) {
972 success = is_block_optional[cur_pack_pattern_connection->
to_block->
block_id];
976 cur_pack_pattern_connection->
to_block);
980 cur_pack_pattern_connection->
to_block == current_pattern_block);
1000 cur_pack_pattern_connection = cur_pack_pattern_connection->
next;
1003 success = is_optional;
1017 fprintf(fp,
"# of pack patterns %d\n", num_pack_patterns);
1019 for (i = 0; i < num_pack_patterns; i++) {
1020 fprintf(fp,
"pack pattern index %d block count %d name %s root %s\n",
1021 list_of_pack_patterns[i].index,
1023 list_of_pack_patterns[i].name,
1024 list_of_pack_patterns[i].root_block->pb_type->name);
1027 list_of_molecules_current = list_of_molecules;
1028 while (list_of_molecules_current != NULL) {
1030 fprintf(fp,
"\nmolecule type: atom\n");
1031 fprintf(fp,
"\tpattern index %d: logical block [%d] name %s\n", i,
1035 fprintf(fp,
"\nmolecule type: %s\n",
1040 fprintf(fp,
"\tpattern index %d: empty \n", i);
1042 fprintf(fp,
"\tpattern index %d: logical block [%d] name %s",
1047 fprintf(fp,
" root node\n");
1056 list_of_molecules_current = list_of_molecules_current->
next;
1065 float cost, best_cost;
1075 if(best_cost ==
UNDEFINED || best_cost > cost) {
1086 float cur_cost, best_cost;
1091 if(curr_pb_graph_node == NULL) {
1095 if(curr_pb_graph_node->pb_type->blif_model != NULL) {
1098 if(best_cost ==
UNDEFINED || best_cost > cur_cost) {
1099 best_cost = cur_cost;
1100 best = curr_pb_graph_node;
1104 for(i = 0; i < curr_pb_graph_node->pb_type->num_modes; i++) {
1105 for(j = 0; j < curr_pb_graph_node->pb_type->modes[i].num_pb_type_children; j++) {
1109 if(best == NULL || best_cost > *cost) {
1125 float base_gain_a, base_gain_b, diff;
1136 diff = base_gain_a - base_gain_b;
1156 int new_index =
OPEN;
1160 int driver_net, driver_block;
1162 assert(list_of_pack_pattern->is_chain ==
TRUE);
1163 root_ipin = list_of_pack_pattern->chain_root_pin;
1173 if(driver_net ==
OPEN) {
1185 if(new_index ==
OPEN) {
boolean primitive_type_feasible(int iblk, const t_pb_type *cur_pb_type)
struct s_hash ** alloc_hash_table(void)
t_pb_graph_pin ** clock_pins
struct s_hash_iterator start_hash_table_iterator(void)
FILE * my_fopen(const char *fname, const char *flag, int prompt)
t_model_ports * model_port
const t_pb_type * pb_type
static int add_pattern_name_to_hash(INOUTP struct s_hash **nhash, INP char *pattern_name, INOUTP int *ncount)
boolean * is_block_optional
t_pb_graph_pin ** output_pins
t_pack_pattern_block * from_block
struct s_pb_graph_edge ** output_edges
int hash_value(char *name)
void * my_calloc(size_t nelem, size_t size)
struct s_linked_vptr * packed_molecules
t_pb_graph_pin ** output_pins
t_pack_pattern_block * to_block
boolean getEchoEnabled(void)
static int find_new_root_atom_for_chain(INP int block_index, INP t_pack_patterns *list_of_pack_pattern)
t_pack_patterns * pack_pattern
static void print_pack_molecules(INP const char *fname, INP t_pack_patterns *list_of_pack_patterns, INP int num_pack_patterns, INP t_pack_molecule *list_of_molecules)
static t_pb_graph_node * get_expected_lowest_cost_primitive_for_logical_block_in_pb_graph_node(INP int ilogical_block, INP t_pb_graph_node *curr_pb_graph_node, OUTP float *cost)
void free_hash_table(struct s_hash **hash_table)
struct s_pb_graph_edge ** input_edges
float compute_primitive_base_cost(INP t_pb_graph_node *primitive)
void free_list_of_pack_patterns(INP t_pack_patterns *list_of_pack_patterns, INP int num_packing_patterns)
static void * my_malloc(int ibytes)
t_pb_graph_pin * from_pin
struct s_pb_graph_node * parent_node
static int compare_pack_pattern(const t_pack_patterns *pattern_a, const t_pack_patterns *pattern_b)
static void discover_pattern_names_in_pb_graph_node(INOUTP t_pb_graph_node *pb_graph_node, INOUTP struct s_hash **nhash, INOUTP int *ncount)
struct s_pack_pattern_connections * next
boolean isEchoFileEnabled(enum e_echo_files echo_option)
t_pack_patterns * alloc_and_load_pack_patterns(OUTP int *num_packing_patterns)
struct s_linked_vptr * next
struct s_pack_pattern_connections * connections
struct s_pack_molecule * next
static t_pack_patterns * alloc_and_init_pattern_list_from_hash(INP int ncount, INOUTP struct s_hash **nhash)
static void forward_expand_pack_pattern_from_edge(INP t_pb_graph_edge *expansion_edge, INOUTP t_pack_patterns *list_of_packing_patterns, INP int curr_pattern_index, INP int *L_num_blocks, INP boolean make_root_of_chain)
struct s_pb_type * pb_type
t_pb_graph_pin ** input_pins
t_pack_molecule * alloc_and_load_pack_molecules(INP t_pack_patterns *list_of_pack_patterns, INP int num_packing_patterns, OUTP int *num_pack_molecule)
struct s_hash * get_next_hash(struct s_hash **hash_table, struct s_hash_iterator *hash_iterator)
enum e_pack_pattern_molecule_type type
static t_pack_molecule * try_create_molecule(INP t_pack_patterns *list_of_pack_patterns, INP int pack_pattern_index, INP int block_index)
static void forward_infer_pattern(INOUTP t_pb_graph_pin *pb_graph_pin)
struct s_type_descriptor * type_descriptors
char * getEchoFileName(enum e_echo_files echo_option)
t_logical_block ** logical_block_ptrs
static void backward_infer_pattern(INOUTP t_pb_graph_pin *pb_graph_pin)
char * my_strdup(const char *str)
static t_pb_graph_node * get_expected_lowest_cost_primitive_for_logical_block(INP int ilogical_block)
static void backward_expand_pack_pattern_from_edge(INP t_pb_graph_edge *expansion_edge, INOUTP t_pack_patterns *list_of_packing_patterns, INP int curr_pattern_index, INP t_pb_graph_pin *destination_pin, INP t_pack_pattern_block *destination_block, INP int *L_num_blocks)
t_pack_pattern_block * root_block
struct s_hash * insert_in_hash_table(struct s_hash **hash_table, char *name, int next_free_index)
static void free_pack_pattern(INOUTP t_pack_pattern_block *pattern_block, INOUTP t_pack_pattern_block **pattern_block_list)
static t_pb_graph_edge * find_expansion_edge_of_pattern(INP int pattern_index, INP t_pb_graph_node *pb_graph_node)
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
t_pb_graph_node * expected_lowest_cost_primitive
static boolean try_expand_molecule(INOUTP t_pack_molecule *molecule, INP int logical_block_index, INP t_pack_pattern_block *current_pattern_block)
t_model_chain_pattern * chain_pattern