VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
vpr_utils.h File Reference
#include "util.h"
+ Include dependency graph for vpr_utils.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void print_tabs (FILE *fpout, int num_tab)
 
boolean is_opin (int ipin, t_type_ptr type)
 
void get_class_range_for_block (INP int iblk, OUTP int *class_low, OUTP int *class_high)
 
void sync_grid_to_blocks (INP int L_num_blocks, INP const struct s_block block_list[], INP int L_nx, INP int L_ny, INOUTP struct s_grid_tile **L_grid)
 
int get_max_primitives_in_pb_type (t_pb_type *pb_type)
 
int get_max_depth_of_pb_type (t_pb_type *pb_type)
 
int get_max_nets_in_pb_type (const t_pb_type *pb_type)
 
boolean primitive_type_feasible (int iblk, const t_pb_type *cur_pb_type)
 
t_pb_graph_pinget_pb_graph_node_pin_from_model_port_pin (t_model_ports *model_port, int model_pin, t_pb_graph_node *pb_graph_node)
 
t_pb_graph_pinget_pb_graph_node_pin_from_vpack_net (int inet, int ipin)
 
t_pb_graph_pinget_pb_graph_node_pin_from_clb_net (int inet, int ipin)
 
t_pb_graph_pinget_pb_graph_node_pin_from_block_pin (int iblock, int ipin)
 
float compute_primitive_base_cost (INP t_pb_graph_node *primitive)
 
int num_ext_inputs_logical_block (int iblk)
 
int ** alloc_and_load_net_pin_index ()
 
void get_port_pin_from_blk_pin (int blk_type_index, int blk_pin, int *port, int *port_pin)
 
void free_port_pin_from_blk_pin (void)
 
void get_blk_pin_from_port_pin (int blk_type_index, int port, int port_pin, int *blk_pin)
 
void free_blk_pin_from_port_pin (void)
 
void alloc_and_load_idirect_from_blk_pin (t_direct_inf *directs, int num_directs, int ***idirect_from_blk_pin, int ***direct_type_from_blk_pin)
 
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)
 
void free_cb (t_pb *pb)
 
void free_pb_stats (t_pb *pb)
 
void free_pb (t_pb *pb)
 

Function Documentation

void alloc_and_load_idirect_from_blk_pin ( t_direct_inf directs,
int  num_directs,
int ***  idirect_from_blk_pin,
int ***  direct_type_from_blk_pin 
)

Definition at line 1073 of file vpr_utils.c.

1074  {
1075 
1076  /* Allocates and loads idirect_from_blk_pin and direct_type_from_blk_pin arrays. *
1077  * *
1078  * For a bus (multiple bits) direct connection, all the pins in the bus are marked. *
1079  * *
1080  * idirect_from_blk_pin array allow us to quickly find pins that could be in a *
1081  * direct connection. Values stored is the index of the possible direct connection *
1082  * as specified in the arch file, OPEN (-1) is stored for pins that could not be *
1083  * part of a direct chain conneciton. *
1084  * *
1085  * direct_type_from_blk_pin array stores the value SOURCE if the pin is the *
1086  * from_pin, SINK if the pin is the to_pin in the direct connection as specified in *
1087  * the arch file, OPEN (-1) is stored for pins that could not be part of a direct *
1088  * chain conneciton. *
1089  * *
1090  * Stores the pointers to the two 2D arrays in the addresses passed in. *
1091  * *
1092  * The two arrays are freed by the caller(s). */
1093 
1094  int itype, iblk_pin, idirect, num_type_pins;
1095  int ** temp_idirect_from_blk_pin, ** temp_direct_type_from_blk_pin;
1096 
1097  char to_pb_type_name[MAX_STRING_LEN+1], to_port_name[MAX_STRING_LEN+1],
1098  from_pb_type_name[MAX_STRING_LEN+1], from_port_name[MAX_STRING_LEN+1];
1099  int to_start_pin_index = -1, to_end_pin_index = -1;
1100  int from_start_pin_index = -1, from_end_pin_index = -1;
1101 
1102  /* Allocate and initialize the values to OPEN (-1). */
1103  temp_idirect_from_blk_pin = (int **) my_malloc(num_types * sizeof(int *));
1104  temp_direct_type_from_blk_pin = (int **) my_malloc(num_types * sizeof(int *));
1105  for (itype = 1; itype < num_types; itype++) {
1106 
1107  num_type_pins = type_descriptors[itype].num_pins;
1108 
1109  temp_idirect_from_blk_pin[itype] = (int *) my_malloc(num_type_pins * sizeof(int));
1110  temp_direct_type_from_blk_pin[itype] = (int *) my_malloc(num_type_pins * sizeof(int));
1111 
1112  /* Initialize values to OPEN */
1113  for (iblk_pin = 0; iblk_pin < num_type_pins; iblk_pin++) {
1114  temp_idirect_from_blk_pin[itype][iblk_pin] = OPEN;
1115  temp_direct_type_from_blk_pin[itype][iblk_pin] = OPEN;
1116  }
1117  }
1118 
1119  /* Load the values */
1120  // Go through directs and find pins with possible direct connections
1121  for (idirect = 0; idirect < num_directs; idirect++) {
1122 
1123  // Parse out the pb_type and port name, possibly pin_indices from from_pin
1124  parse_direct_pin_name(directs[idirect].from_pin, directs[idirect].line,
1125  &from_end_pin_index, &from_start_pin_index, from_pb_type_name, from_port_name);
1126 
1127  // Parse out the pb_type and port name, possibly pin_indices from to_pin
1128  parse_direct_pin_name(directs[idirect].to_pin, directs[idirect].line,
1129  &to_end_pin_index, &to_start_pin_index, to_pb_type_name, to_port_name);
1130 
1131 
1132  /* Now I have all the data that I need, I could go through all the block pins *
1133  * in all the blocks to find all the pins that could have possible direct *
1134  * connections. Mark all down all those pins with the idirect the pins belong *
1135  * to and whether it is a source or a sink of the direct connection. */
1136 
1137  // Find blocks with the same name as from_pb_type_name and from_port_name
1138  mark_direct_of_ports (idirect, SOURCE, from_pb_type_name, from_port_name,
1139  from_end_pin_index, from_start_pin_index, directs[idirect].from_pin,
1140  directs[idirect].line,
1141  temp_idirect_from_blk_pin, temp_direct_type_from_blk_pin);
1142 
1143  // Then, find blocks with the same name as to_pb_type_name and from_port_name
1144  mark_direct_of_ports (idirect, SINK, to_pb_type_name, to_port_name,
1145  to_end_pin_index, to_start_pin_index, directs[idirect].to_pin,
1146  directs[idirect].line,
1147  temp_idirect_from_blk_pin, temp_direct_type_from_blk_pin);
1148 
1149  } // Finish going through all the directs
1150 
1151  /* Returns the pointer to the 2D arrays by reference. */
1152  *idirect_from_blk_pin = temp_idirect_from_blk_pin;
1153  *direct_type_from_blk_pin = temp_direct_type_from_blk_pin;
1154 
1155 }
static void mark_direct_of_ports(int idirect, int direct_type, char *pb_type_name, char *port_name, int end_pin_index, int start_pin_index, char *src_string, int line, int **idirect_from_blk_pin, int **direct_type_from_blk_pin)
Definition: vpr_utils.c:1023
static void * my_malloc(int ibytes)
Definition: graphics.c:499
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)
Definition: vpr_utils.c:925
#define MAX_STRING_LEN
Definition: vpr_utils.c:18
int num_types
Definition: globals.c:37
Definition: slre.c:50
struct s_type_descriptor * type_descriptors
Definition: globals.c:38

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int** alloc_and_load_net_pin_index ( )

Definition at line 651 of file vpr_utils.c.

651  {
652 
653  /* Allocates and loads net_pin_index array, this array allows us to quickly *
654  * find what pin on the net a block pin corresponds to. Returns the pointer *
655  * to the 2D net_pin_index array. */
656 
657  int inet, netpin, blk, iblk, ipin, itype, **temp_net_pin_index, max_pins_per_clb = 0;
658  t_type_ptr type;
659 
660  /* Compute required size. */
661  for (itype = 0; itype < num_types; itype++)
662  max_pins_per_clb = std::max(max_pins_per_clb, type_descriptors[itype].num_pins);
663 
664  /* Allocate for maximum size. */
665  temp_net_pin_index = (int **) alloc_matrix(0, num_blocks - 1, 0,
666  max_pins_per_clb - 1, sizeof(int));
667 
668  /* Initialize values to OPEN */
669  for (iblk = 0; iblk < num_blocks; iblk++) {
670  type = block[iblk].type;
671  for (ipin = 0; ipin < type->num_pins; ipin++) {
672  temp_net_pin_index[iblk][ipin] = OPEN;
673  }
674  }
675 
676  /* Load the values */
677  for (inet = 0; inet < num_nets; inet++) {
678  if (clb_net[inet].is_global)
679  continue;
680  for (netpin = 0; netpin <= clb_net[inet].num_sinks; netpin++) {
681  blk = clb_net[inet].node_block[netpin];
682  temp_net_pin_index[blk][clb_net[inet].node_block_pin[netpin]] = netpin;
683  }
684  }
685 
686  /* Returns the pointers to the 2D array. */
687  return temp_net_pin_index;
688 }
int * node_block_pin
Definition: vpr_types.h:509
void ** alloc_matrix(int nrmin, int nrmax, int ncmin, int ncmax, size_t elsize)
Definition: util.c:551
int num_nets
Definition: globals.c:27
int * node_block
Definition: vpr_types.h:507
t_type_ptr type
Definition: vpr_types.h:561
int num_blocks
Definition: globals.c:30
boolean * is_global
#define max(a, b)
Definition: graphics.c:171
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
int num_types
Definition: globals.c:37
Definition: slre.c:50
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
int num_sinks
Definition: vpr_types.h:506

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float compute_primitive_base_cost ( INP t_pb_graph_node primitive)

Determine cost for using primitive within a complex block, should use primitives of low cost before selecting primitives of high cost For now, assume primitives that have a lot of pins are scarcer than those without so use primitives with less pins before those with more

Definition at line 452 of file vpr_utils.c.

452  {
453  return (primitive->pb_type->num_input_pins
454  + primitive->pb_type->num_output_pins
455  + primitive->pb_type->num_clock_pins);
456 }

+ Here is the caller graph for this function:

void free_blk_pin_from_port_pin ( void  )

Definition at line 840 of file vpr_utils.c.

840  {
841 
842  /* Frees the f_blk_pin_from_port_pin array. *
843  * *
844  * This function is called when the arrays are freed in *
845  * free_placement_structs() */
846 
847  int itype, iport, num_ports;
848 
849  if (f_blk_pin_from_port_pin != NULL) {
850 
851  for (itype = 1; itype < num_types; itype++) {
852  num_ports = type_descriptors[itype].pb_type->num_ports;
853  for (iport = 0; iport < num_ports; iport++) {
854  free(f_blk_pin_from_port_pin[itype][iport]);
855  }
856  free(f_blk_pin_from_port_pin[itype]);
857  }
859 
861  }
862 
863 }
static int *** f_blk_pin_from_port_pin
Definition: vpr_utils.c:41
struct s_pb_type * pb_type
int num_types
Definition: globals.c:37
struct s_type_descriptor * type_descriptors
Definition: globals.c:38

+ Here is the caller graph for this function:

void free_cb ( t_pb pb)

Definition at line 508 of file vpr_utils.c.

508  {
509  const t_pb_type * pb_type;
510  int i, total_nodes;
511 
512  pb_type = pb->pb_graph_node->pb_type;
513 
514  total_nodes = pb->pb_graph_node->total_pb_pins + pb_type->num_input_pins
515  + pb_type->num_output_pins + pb_type->num_clock_pins;
516 
517  for (i = 0; i < total_nodes; i++) {
518  if (pb->rr_graph[i].edges != NULL) {
519  free(pb->rr_graph[i].edges);
520  }
521  if (pb->rr_graph[i].switches != NULL) {
522  free(pb->rr_graph[i].switches);
523  }
524  }
525  free(pb->rr_graph);
526  free_pb(pb);
527 }
int * edges
Definition: vpr_types.h:903
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
struct s_pb_type * pb_type
short * switches
Definition: vpr_types.h:904
void free_pb(t_pb *pb)
Definition: vpr_utils.c:529
int num_output_pins
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
int num_input_pins
int num_clock_pins

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void free_pb ( t_pb pb)

Definition at line 529 of file vpr_utils.c.

529  {
530  const t_pb_type * pb_type;
531  int i, j, mode;
532  struct s_linked_vptr *revalid_molecule;
533  t_pack_molecule *cur_molecule;
534 
535  pb_type = pb->pb_graph_node->pb_type;
536 
537  if (pb_type->blif_model == NULL) {
538  mode = pb->mode;
539  for (i = 0;
540  i < pb_type->modes[mode].num_pb_type_children
541  && pb->child_pbs != NULL; i++) {
542  for (j = 0;
543  j < pb_type->modes[mode].pb_type_children[i].num_pb
544  && pb->child_pbs[i] != NULL; j++) {
545  if (pb->child_pbs[i][j].name != NULL || pb->child_pbs[i][j].child_pbs != NULL) {
546  free_pb(&pb->child_pbs[i][j]);
547  }
548  }
549  if (pb->child_pbs[i])
550  free(pb->child_pbs[i]);
551  }
552  if (pb->child_pbs)
553  free(pb->child_pbs);
554  pb->child_pbs = NULL;
555 
556  if (pb->local_nets != NULL) {
557  for (i = 0; i < pb->num_local_nets; i++) {
558  free(pb->local_nets[i].node_block);
559  free(pb->local_nets[i].node_block_port);
560  free(pb->local_nets[i].node_block_pin);
561  if (pb->local_nets[i].name != NULL) {
562  free(pb->local_nets[i].name);
563  }
564  }
565  free(pb->local_nets);
566  pb->local_nets = NULL;
567  }
568 
569  if (pb->rr_node_to_pb_mapping != NULL) {
570  free(pb->rr_node_to_pb_mapping);
571  pb->rr_node_to_pb_mapping = NULL;
572  }
573 
574  if (pb->name)
575  free(pb->name);
576  pb->name = NULL;
577  } else {
578  /* Primitive */
579  if (pb->name)
580  free(pb->name);
581  pb->name = NULL;
582  if (pb->lut_pin_remap) {
583  free(pb->lut_pin_remap);
584  }
585  pb->lut_pin_remap = NULL;
586  if (pb->logical_block != OPEN && logical_block != NULL) {
588  logical_block[pb->logical_block].pb = NULL;
589  /* If any molecules were marked invalid because of this logic block getting packed, mark them valid */
590  revalid_molecule = logical_block[pb->logical_block].packed_molecules;
591  while (revalid_molecule != NULL) {
592  cur_molecule = (t_pack_molecule*)revalid_molecule->data_vptr;
593  if (cur_molecule->valid == FALSE) {
594  for (i = 0; i < get_array_size_of_molecule(cur_molecule); i++) {
595  if (cur_molecule->logical_block_ptrs[i] != NULL) {
596  if (cur_molecule->logical_block_ptrs[i]->clb_index != OPEN) {
597  break;
598  }
599  }
600  }
601  /* All logical blocks are open for this molecule, place back in queue */
602  if (i == get_array_size_of_molecule(cur_molecule)) {
603  cur_molecule->valid = TRUE;
604  }
605  }
606  revalid_molecule = revalid_molecule->next;
607  }
608  }
609  pb->logical_block = OPEN;
610  }
611  free_pb_stats(pb);
612 }
int * node_block_pin
Definition: vpr_types.h:509
char * name
Definition: vpr_types.h:179
struct s_pb ** child_pbs
Definition: vpr_types.h:185
struct s_pb_type * pb_type_children
t_mode * modes
int num_local_nets
Definition: vpr_types.h:193
void free_pb_stats(t_pb *pb)
Definition: vpr_utils.c:614
int * lut_pin_remap
Definition: vpr_types.h:197
int * node_block
Definition: vpr_types.h:507
struct s_linked_vptr * packed_molecules
Definition: vpr_types.h:228
char * blif_model
char * name
Definition: vpr_types.h:505
struct s_pb ** rr_node_to_pb_mapping
Definition: vpr_types.h:189
Definition: util.h:12
int get_array_size_of_molecule(t_pack_molecule *molecule)
#define NO_CLUSTER
Definition: vpr_types.h:98
int logical_block
Definition: vpr_types.h:181
struct s_net * local_nets
Definition: vpr_types.h:192
struct s_linked_vptr * next
Definition: util.h:36
int num_pb_type_children
void * data_vptr
Definition: util.h:35
struct s_pb_type * pb_type
Definition: slre.c:50
t_logical_block ** logical_block_ptrs
Definition: vpr_types.h:248
void free_pb(t_pb *pb)
Definition: vpr_utils.c:529
int mode
Definition: vpr_types.h:183
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
boolean valid
Definition: vpr_types.h:249
int * node_block_port
Definition: vpr_types.h:508
struct s_logical_block * logical_block
Definition: globals.c:20
Definition: util.h:12

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void free_pb_stats ( t_pb pb)

Definition at line 614 of file vpr_utils.c.

614  {
615  int i;
616  t_pb_graph_node *pb_graph_node = pb->pb_graph_node;
617 
618  if(pb->pb_stats == NULL) {
619  return;
620  }
621 
622  pb->pb_stats->gain.clear();
623  pb->pb_stats->timinggain.clear();
624  pb->pb_stats->sharinggain.clear();
625  pb->pb_stats->hillgain.clear();
626  pb->pb_stats->connectiongain.clear();
627  pb->pb_stats->num_pins_of_net_in_pb.clear();
628 
629  if(pb->pb_stats->marked_blocks != NULL) {
630  for (i = 0; i < pb_graph_node->num_input_pin_class; i++) {
631  free(pb->pb_stats->input_pins_used[i]);
632  free(pb->pb_stats->lookahead_input_pins_used[i]);
633  }
634  free(pb->pb_stats->input_pins_used);
636  for (i = 0; i < pb_graph_node->num_output_pin_class; i++) {
637  free(pb->pb_stats->output_pins_used[i]);
638  free(pb->pb_stats->lookahead_output_pins_used[i]);
639  }
640  free(pb->pb_stats->output_pins_used);
642  free(pb->pb_stats->feasible_blocks);
643  free(pb->pb_stats->marked_nets);
644  free(pb->pb_stats->marked_blocks);
645  }
646  pb->pb_stats->marked_blocks = NULL;
647  delete pb->pb_stats;
648  pb->pb_stats = NULL;
649 }
std::map< int, float > sharinggain
Definition: vpr_types.h:134
int ** output_pins_used
Definition: vpr_types.h:159
struct s_pack_molecule ** feasible_blocks
Definition: vpr_types.h:167
std::map< int, int > num_pins_of_net_in_pb
Definition: vpr_types.h:155
int ** input_pins_used
Definition: vpr_types.h:158
std::map< int, float > hillgain
Definition: vpr_types.h:142
int ** lookahead_output_pins_used
Definition: vpr_types.h:162
std::map< int, float > connectiongain
Definition: vpr_types.h:132
std::map< int, float > gain
Definition: vpr_types.h:128
std::map< int, float > timinggain
Definition: vpr_types.h:130
int * marked_nets
Definition: vpr_types.h:147
int ** lookahead_input_pins_used
Definition: vpr_types.h:161
struct s_pb_stats * pb_stats
Definition: vpr_types.h:190
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
int * marked_blocks
Definition: vpr_types.h:147

+ Here is the caller graph for this function:

void free_port_pin_from_blk_pin ( void  )

Definition at line 736 of file vpr_utils.c.

736  {
737 
738  /* Frees the f_port_from_blk_pin and f_port_pin_from_blk_pin arrays. *
739  * *
740  * This function is called when the file-scope arrays are corrupted. *
741  * Otherwise, the arrays are freed in free_placement_structs() */
742 
743  int itype;
744 
745  if (f_port_from_blk_pin != NULL) {
746  for (itype = 1; itype < num_types; itype++) {
747  free(f_port_from_blk_pin[itype]);
748  }
749  free(f_port_from_blk_pin);
750 
751  f_port_from_blk_pin = NULL;
752  }
753 
754  if (f_port_pin_from_blk_pin != NULL) {
755  for (itype = 1; itype < num_types; itype++) {
756  free(f_port_pin_from_blk_pin[itype]);
757  }
759 
761  }
762 
763 }
static int ** f_port_from_blk_pin
Definition: vpr_utils.c:31
int num_types
Definition: globals.c:37
static int ** f_port_pin_from_blk_pin
Definition: vpr_utils.c:36

+ Here is the caller graph for this function:

void get_blk_pin_from_port_pin ( int  blk_type_index,
int  port,
int  port_pin,
int *  blk_pin 
)

Definition at line 818 of file vpr_utils.c.

819  {
820 
821  /* This mapping is needed since there are two different netlist *
822  * conventions - in the cluster level, ports and port pins are used *
823  * while in the post-pack level, block pins are used. The reason block *
824  * type is used instead of blocks is to save memories. *
825  * *
826  * f_port_pin_to_block_pin array allows us to quickly find what block *
827  * pin a port pin corresponds to. *
828  * [0...num_types-1][0...num_ports-1][0...num_port_pins-1] */
829 
830  /* If the array is not allocated and loaded, allocate it. */
831  if (f_blk_pin_from_port_pin == NULL) {
833  }
834 
835  /* Return the port and port_pin for the pin. */
836  *blk_pin = f_blk_pin_from_port_pin[blk_type_index][port][port_pin];
837 
838 }
static int *** f_blk_pin_from_port_pin
Definition: vpr_utils.c:41
static void alloc_and_load_blk_pin_from_port_pin(void)
Definition: vpr_utils.c:865

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void get_class_range_for_block ( INP int  iblk,
OUTP int *  class_low,
OUTP int *  class_high 
)

Definition at line 162 of file vpr_utils.c.

163  {
164  /* Assumes that the placement has been done so each block has a set of pins allocated to it */
165  t_type_ptr type;
166 
167  type = block[iblk].type;
168  assert(type->num_class % type->capacity == 0);
169  *class_low = block[iblk].z * (type->num_class / type->capacity);
170  *class_high = (block[iblk].z + 1) * (type->num_class / type->capacity) - 1;
171 }
t_type_ptr type
Definition: vpr_types.h:561
struct s_block * block
Definition: globals.c:31
int z
Definition: vpr_types.h:565

+ Here is the caller graph for this function:

int get_max_depth_of_pb_type ( t_pb_type pb_type)

Definition at line 222 of file vpr_utils.c.

222  {
223  int i, j;
224  int max_depth, temp_depth;
225  max_depth = pb_type->depth;
226  for (i = 0; i < pb_type->num_modes; i++) {
227  for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
228  temp_depth = get_max_depth_of_pb_type(
229  &pb_type->modes[i].pb_type_children[j]);
230  if (temp_depth > max_depth) {
231  max_depth = temp_depth;
232  }
233  }
234  }
235  return max_depth;
236 }
int get_max_depth_of_pb_type(t_pb_type *pb_type)
Definition: vpr_utils.c:222
struct s_pb_type * pb_type_children
t_mode * modes
int num_pb_type_children

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int get_max_nets_in_pb_type ( const t_pb_type pb_type)

Definition at line 196 of file vpr_utils.c.

196  {
197  int i, j;
198  int max_nets, temp_nets;
199  if (pb_type->modes == 0) {
200  max_nets = pb_type->num_output_pins;
201  } else {
202  max_nets = 0;
203  for (i = 0; i < pb_type->num_modes; i++) {
204  temp_nets = 0;
205  for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
206  temp_nets += pb_type->modes[i].pb_type_children[j].num_pb
208  &pb_type->modes[i].pb_type_children[j]);
209  }
210  if (temp_nets > max_nets) {
211  max_nets = temp_nets;
212  }
213  }
214  }
215  if (pb_type->parent_mode == NULL) {
216  max_nets += pb_type->num_input_pins + pb_type->num_output_pins
217  + pb_type->num_clock_pins;
218  }
219  return max_nets;
220 }
struct s_pb_type * pb_type_children
int get_max_nets_in_pb_type(const t_pb_type *pb_type)
Definition: vpr_utils.c:196
t_mode * modes
t_mode * parent_mode
int num_pb_type_children
int num_output_pins
int num_input_pins
int num_clock_pins

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int get_max_primitives_in_pb_type ( t_pb_type pb_type)

Definition at line 173 of file vpr_utils.c.

173  {
174  int i, j;
175  int max_size, temp_size;
176  if (pb_type->modes == 0) {
177  max_size = 1;
178  } else {
179  max_size = 0;
180  temp_size = 0;
181  for (i = 0; i < pb_type->num_modes; i++) {
182  for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
183  temp_size += pb_type->modes[i].pb_type_children[j].num_pb
185  &pb_type->modes[i].pb_type_children[j]);
186  }
187  if (temp_size > max_size) {
188  max_size = temp_size;
189  }
190  }
191  }
192  return max_size;
193 }
struct s_pb_type * pb_type_children
t_mode * modes
int get_max_primitives_in_pb_type(t_pb_type *pb_type)
Definition: vpr_utils.c:173
int num_pb_type_children

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

t_pb_graph_pin* get_pb_graph_node_pin_from_block_pin ( int  iblock,
int  ipin 
)

Definition at line 403 of file vpr_utils.c.

403  {
404  int i, count;
405  const t_pb_type *pb_type;
406  t_pb_graph_node *pb_graph_node;
407 
408  pb_graph_node = block[iblock].pb->pb_graph_node;
409  pb_type = pb_graph_node->pb_type;
410 
411  /* If this is post-placed, then the ipin may have been shuffled up by the z * num_pins,
412  bring it back down to 0..num_pins-1 range for easier analysis */
413  ipin %= (pb_type->num_input_pins + pb_type->num_output_pins + pb_type->num_clock_pins);
414 
415  if(ipin < pb_type->num_input_pins) {
416  count = ipin;
417  for(i = 0; i < pb_graph_node->num_input_ports; i++) {
418  if(count - pb_graph_node->num_input_pins[i] >= 0) {
419  count -= pb_graph_node->num_input_pins[i];
420  } else {
421  return &pb_graph_node->input_pins[i][count];
422  }
423  }
424  } else if (ipin < pb_type->num_input_pins + pb_type->num_output_pins) {
425  count = ipin - pb_type->num_input_pins;
426  for(i = 0; i < pb_graph_node->num_output_ports; i++) {
427  if(count - pb_graph_node->num_output_pins[i] >= 0) {
428  count -= pb_graph_node->num_output_pins[i];
429  } else {
430  return &pb_graph_node->output_pins[i][count];
431  }
432  }
433  } else {
434  count = ipin - pb_type->num_input_pins - pb_type->num_output_pins;
435  for(i = 0; i < pb_graph_node->num_clock_ports; i++) {
436  if(count - pb_graph_node->num_clock_pins[i] >= 0) {
437  count -= pb_graph_node->num_clock_pins[i];
438  } else {
439  return &pb_graph_node->clock_pins[i][count];
440  }
441  }
442  }
443  assert(0);
444  return NULL;
445 }
t_pb_graph_pin ** clock_pins
t_pb_graph_pin ** output_pins
struct s_block * block
Definition: globals.c:31
struct s_pb_type * pb_type
t_pb * pb
Definition: vpr_types.h:567
int num_output_pins
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
int num_input_pins
t_pb_graph_pin ** input_pins
int num_clock_pins

+ Here is the caller graph for this function:

t_pb_graph_pin* get_pb_graph_node_pin_from_clb_net ( int  inet,
int  ipin 
)

Definition at line 391 of file vpr_utils.c.

391  {
392  int iblock, target_pin;
393  t_pb_graph_node *pb_graph_node;
394 
395  iblock = clb_net[inet].node_block[ipin];
396  pb_graph_node = block[iblock].pb->pb_graph_node;
397 
398  target_pin = clb_net[inet].node_block_pin[ipin];
399 
400  return get_pb_graph_node_pin_from_block_pin(iblock, target_pin);
401 }
int * node_block_pin
Definition: vpr_types.h:509
int * node_block
Definition: vpr_types.h:507
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
t_pb * pb
Definition: vpr_types.h:567
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
t_pb_graph_pin * get_pb_graph_node_pin_from_block_pin(int iblock, int ipin)
Definition: vpr_utils.c:403

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin ( t_model_ports model_port,
int  model_pin,
t_pb_graph_node pb_graph_node 
)

Return pb_graph_node pin from model port and pin NULL if not found

Definition at line 303 of file vpr_utils.c.

303  {
304  int i;
305 
306  if(model_port->dir == IN_PORT) {
307  if(model_port->is_clock == FALSE) {
308  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
309  if (pb_graph_node->input_pins[i][0].port->model_port == model_port) {
310  if(pb_graph_node->num_input_pins[i] > model_pin) {
311  return &pb_graph_node->input_pins[i][model_pin];
312  } else {
313  return NULL;
314  }
315  }
316  }
317  } else {
318  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
319  if (pb_graph_node->clock_pins[i][0].port->model_port == model_port) {
320  if(pb_graph_node->num_clock_pins[i] > model_pin) {
321  return &pb_graph_node->clock_pins[i][model_pin];
322  } else {
323  return NULL;
324  }
325  }
326  }
327  }
328  } else {
329  assert(model_port->dir == OUT_PORT);
330  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
331  if (pb_graph_node->output_pins[i][0].port->model_port == model_port) {
332  if(pb_graph_node->num_output_pins[i] > model_pin) {
333  return &pb_graph_node->output_pins[i][model_pin];
334  } else {
335  return NULL;
336  }
337  }
338  }
339  }
340  return NULL;
341 }
t_pb_graph_pin ** clock_pins
t_model_ports * model_port
enum PORTS dir
Definition: logic_types.h:22
t_pb_graph_pin ** output_pins
boolean is_clock
Definition: logic_types.h:26
Definition: util.h:12
t_pb_graph_pin ** input_pins

+ Here is the caller graph for this function:

t_pb_graph_pin* get_pb_graph_node_pin_from_vpack_net ( int  inet,
int  ipin 
)

Definition at line 343 of file vpr_utils.c.

343  {
344  int ilogical_block;
345  t_model_ports *port;
346 
347  ilogical_block = vpack_net[inet].node_block[ipin];
348 
349  assert(ilogical_block != OPEN);
350  if(logical_block[ilogical_block].pb == NULL) {
351  /* This net has not been packed yet thus pb_graph_pin does not exist */
352  return NULL;
353  }
354 
355  if(ipin > 0) {
356  port = logical_block[ilogical_block].model->inputs;
357  if(vpack_net[inet].is_global) {
358  while(port != NULL) {
359  if(port->is_clock) {
360  if(port->index == vpack_net[inet].node_block_port[ipin]) {
361  break;
362  }
363  }
364  port = port->next;
365  }
366  } else {
367  while(port != NULL) {
368  if(!port->is_clock) {
369  if(port->index == vpack_net[inet].node_block_port[ipin]) {
370  break;
371  }
372  }
373  port = port->next;
374  }
375  }
376  } else {
377  /* This is an output pin */
378  port = logical_block[ilogical_block].model->outputs;
379  while(port != NULL) {
380  if(port->index == vpack_net[inet].node_block_port[ipin]) {
381  break;
382  }
383  port = port->next;
384  }
385  }
386 
387  assert(port != NULL);
388  return get_pb_graph_node_pin_from_model_port_pin(port, vpack_net[inet].node_block_pin[ipin], logical_block[ilogical_block].pb->pb_graph_node);
389 }
t_pb_graph_pin * get_pb_graph_node_pin_from_model_port_pin(t_model_ports *model_port, int model_pin, t_pb_graph_node *pb_graph_node)
Definition: vpr_utils.c:303
struct s_model_ports * next
Definition: logic_types.h:28
int * node_block
Definition: vpr_types.h:507
boolean is_clock
Definition: logic_types.h:26
boolean * is_global
t_model_ports * inputs
Definition: logic_types.h:35
t_model_ports * outputs
Definition: logic_types.h:36
Definition: slre.c:50
struct s_net * vpack_net
Definition: globals.c:19
t_model * model
Definition: vpr_types.h:209
int * node_block_port
Definition: vpr_types.h:508
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void get_port_pin_from_blk_pin ( int  blk_type_index,
int  blk_pin,
int *  port,
int *  port_pin 
)

Definition at line 701 of file vpr_utils.c.

702  {
703 
704  /* These two mappings are needed since there are two different netlist *
705  * conventions - in the cluster level, ports and port pins are used *
706  * while in the post-pack level, block pins are used. The reason block *
707  * type is used instead of blocks is that the mapping is the same for *
708  * blocks belonging to the same block type. *
709  * *
710  * f_port_from_blk_pin array allow us to quickly find what port a *
711  * block pin corresponds to. *
712  * [0...num_types-1][0...blk_pin_count-1] *
713  * *
714  * f_port_pin_from_blk_pin array allow us to quickly find what port *
715  * pin a block pin corresponds to. *
716  * [0...num_types-1][0...blk_pin_count-1] */
717 
718  /* If either one of the arrays is not allocated and loaded, it is *
719  * corrupted, so free both of them. */
720  if ((f_port_from_blk_pin == NULL && f_port_pin_from_blk_pin != NULL)
721  || (f_port_from_blk_pin != NULL && f_port_pin_from_blk_pin == NULL)){
723  }
724 
725  /* If the arrays are not allocated and loaded, allocate it. */
726  if (f_port_from_blk_pin == NULL && f_port_pin_from_blk_pin == NULL) {
728  }
729 
730  /* Return the port and port_pin for the pin. */
731  *port = f_port_from_blk_pin[blk_type_index][blk_pin];
732  *port_pin = f_port_pin_from_blk_pin[blk_type_index][blk_pin];
733 
734 }
void free_port_pin_from_blk_pin(void)
Definition: vpr_utils.c:736
static void alloc_and_load_port_pin_from_blk_pin(void)
Definition: vpr_utils.c:765
static int ** f_port_from_blk_pin
Definition: vpr_utils.c:31
static int ** f_port_pin_from_blk_pin
Definition: vpr_utils.c:36

+ Here is the call graph for this function:

boolean is_opin ( int  ipin,
t_type_ptr  type 
)

Definition at line 148 of file vpr_utils.c.

148  {
149 
150  /* Returns TRUE if this clb pin is an output, FALSE otherwise. */
151 
152  int iclass;
153 
154  iclass = type->pin_class[ipin];
155 
156  if (type->class_inf[iclass].type == DRIVER)
157  return (TRUE);
158  else
159  return (FALSE);
160 }
struct s_class * class_inf
Definition: util.h:12
enum e_pin_type type
Definition: util.h:12

+ Here is the caller graph for this function:

int num_ext_inputs_logical_block ( int  iblk)

Definition at line 458 of file vpr_utils.c.

458  {
459 
460  /* Returns the number of input pins on this logical_block that must be hooked *
461  * up through external interconnect. That is, the number of input *
462  * pins used - the number which connect (internally) to the outputs. */
463 
464  int ext_inps, output_net, ipin, opin;
465 
466  t_model_ports *port, *out_port;
467 
468  /* TODO: process to get ext_inps is slow, should cache in lookup table */
469  ext_inps = 0;
470  port = logical_block[iblk].model->inputs;
471  while (port) {
472  if (port->is_clock == FALSE) {
473  for (ipin = 0; ipin < port->size; ipin++) {
474  if (logical_block[iblk].input_nets[port->index][ipin] != OPEN) {
475  ext_inps++;
476  }
477  out_port = logical_block[iblk].model->outputs;
478  while (out_port) {
479  for (opin = 0; opin < out_port->size; opin++) {
480  output_net =
481  logical_block[iblk].output_nets[out_port->index][opin];
482  if (output_net == OPEN)
483  continue;
484  /* TODO: I could speed things up a bit by computing the number of inputs *
485  * and number of external inputs for each logic logical_block at the start of *
486  * clustering and storing them in arrays. Look into if speed is a *
487  * problem. */
488 
489  if (logical_block[iblk].input_nets[port->index][ipin]
490  == output_net) {
491  ext_inps--;
492  break;
493  }
494  }
495  out_port = out_port->next;
496  }
497  }
498  }
499  port = port->next;
500  }
501 
502  assert(ext_inps >= 0);
503 
504  return (ext_inps);
505 }
struct s_model_ports * next
Definition: logic_types.h:28
boolean is_clock
Definition: logic_types.h:26
Definition: util.h:12
t_model_ports * inputs
Definition: logic_types.h:35
t_model_ports * outputs
Definition: logic_types.h:36
Definition: slre.c:50
t_model * model
Definition: vpr_types.h:209
int ** output_nets
Definition: vpr_types.h:212
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the caller graph for this function:

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 
)

Definition at line 925 of file vpr_utils.c.

926  {
927 
928  /* Parses out the pb_type_name and port_name from the direct passed in. *
929  * If the start_pin_index and end_pin_index is specified, parse them too. *
930  * Return the values parsed by reference. */
931 
932  char source_string[MAX_STRING_LEN+1];
933  char * find_format = NULL;
934  int ichar, match_count;
935 
936  // parse out the pb_type and port name, possibly pin_indices
937  find_format = strstr(src_string,"[");
938  if (find_format == NULL) {
939  /* Format "pb_type_name.port_name" */
940  *start_pin_index = *end_pin_index = -1;
941 
942  strcpy (source_string, src_string);
943  for (ichar = 0; ichar < (int)(strlen(source_string)); ichar++) {
944  if (source_string[ichar] == '.')
945  source_string[ichar] = ' ';
946  }
947 
948  match_count = sscanf(source_string, "%s %s", pb_type_name, port_name);
949  if (match_count != 2){
950  vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Invalid pin - %s, "
951  "name should be in the format \"pb_type_name\".\"port_name\" or "
952  "\"pb_type_name\".\"port_name [end_pin_index:start_pin_index]\". "
953  " The end_pin_index and start_pin_index can be the same.\n", line,
954  src_string);
955  exit(1);
956  }
957  } else {
958  /* Format "pb_type_name.port_name [end_pin_index:start_pin_index]" */
959  strcpy (source_string, src_string);
960  for (ichar = 0; ichar < (int)(strlen(source_string)); ichar++) {
961  if (source_string[ichar] == '.')
962  source_string[ichar] = ' ';
963  }
964 
965  match_count = sscanf(source_string, "%s %s [%d:%d]",
966  pb_type_name, port_name,
967  end_pin_index, start_pin_index);
968  if (match_count != 4){
969  vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Invalid pin - %s, "
970  "name should be in the format \"pb_type_name\".\"port_name\" or "
971  "\"pb_type_name\".\"port_name [end_pin_index:start_pin_index]\". "
972  " The end_pin_index and start_pin_index can be the same.\n", line,
973  src_string);
974  exit(1);
975  }
976  if (*end_pin_index < 0 || *start_pin_index < 0) {
977  vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Invalid pin - %s, "
978  "the pin_index [end_pin_index:start_pin_index] should not "
979  "be a negative value.\n", line, src_string);
980  exit(1);
981  }
982  if ( *end_pin_index < *start_pin_index) {
983  vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Invalid from_pin - %s, "
984  "the end_pin_index in [end_pin_index:start_pin_index] should "
985  "not be less than start_pin_index.\n", line, src_string);
986  exit(1);
987  }
988  }
989 }
#define MAX_STRING_LEN
Definition: vpr_utils.c:18
messagelogger vpr_printf
Definition: util.c:17

+ Here is the caller graph for this function:

boolean primitive_type_feasible ( int  iblk,
const t_pb_type cur_pb_type 
)

given a primitive type and a logical block, is the mapping legal

Definition at line 241 of file vpr_utils.c.

241  {
242  t_model_ports *port;
243  int i, j;
244  boolean second_pass;
245 
246  if (cur_pb_type == NULL) {
247  return FALSE;
248  }
249 
250  /* check if ports are big enough */
251  port = logical_block[iblk].model->inputs;
252  second_pass = FALSE;
253  while (port || !second_pass) {
254  /* TODO: This is slow if the number of ports are large, fix if becomes a problem */
255  if (!port) {
256  second_pass = TRUE;
257  port = logical_block[iblk].model->outputs;
258  }
259  for (i = 0; i < cur_pb_type->num_ports; i++) {
260  if (cur_pb_type->ports[i].model_port == port) {
261  for (j = cur_pb_type->ports[i].num_pins; j < port->size; j++) {
262  if (port->dir == IN_PORT && !port->is_clock) {
263  if (logical_block[iblk].input_nets[port->index][j]
264  != OPEN) {
265  return FALSE;
266  }
267  } else if (port->dir == OUT_PORT) {
268  if (logical_block[iblk].output_nets[port->index][j]
269  != OPEN) {
270  return FALSE;
271  }
272  } else {
273  assert(port->dir == IN_PORT && port->is_clock);
274  assert(j == 0);
275  if (logical_block[iblk].clock_net != OPEN) {
276  return FALSE;
277  }
278  }
279  }
280  break;
281  }
282  }
283  if (i == cur_pb_type->num_ports) {
284  if ((logical_block[iblk].model->inputs != NULL && !second_pass)
285  || (logical_block[iblk].model->outputs != NULL
286  && second_pass)) {
287  /* physical port not found */
288  return FALSE;
289  }
290  }
291  if (port) {
292  port = port->next;
293  }
294  }
295  return TRUE;
296 }
int num_pins
t_model_ports * model_port
enum PORTS dir
Definition: logic_types.h:22
struct s_model_ports * next
Definition: logic_types.h:28
boolean is_clock
Definition: logic_types.h:26
Definition: util.h:12
t_model_ports * inputs
Definition: logic_types.h:35
t_model_ports * outputs
Definition: logic_types.h:36
static char * model
Definition: read_blif.c:45
t_port * ports
Definition: slre.c:50
t_model * model
Definition: vpr_types.h:209
struct s_logical_block * logical_block
Definition: globals.c:20
Definition: util.h:12

+ Here is the caller graph for this function:

void print_tabs ( FILE *  fpout,
int  num_tab 
)

print tabs given number of tabs to file

Definition at line 76 of file vpr_utils.c.

76  {
77  int i;
78  for (i = 0; i < num_tab; i++) {
79  fprintf(fpout, "\t");
80  }
81 }
void sync_grid_to_blocks ( INP int  L_num_blocks,
INP const struct s_block  block_list[],
INP int  L_nx,
INP int  L_ny,
INOUTP struct s_grid_tile **  L_grid 
)

Definition at line 84 of file vpr_utils.c.

86  {
87  int i, j, k;
88 
89  /* Reset usage and allocate blocks list if needed */
90  for (j = 0; j <= (L_ny + 1); ++j) {
91  for (i = 0; i <= (L_nx + 1); ++i) {
92  L_grid[i][j].usage = 0;
93  if (L_grid[i][j].type) {
94  /* If already allocated, leave it since size doesn't change */
95  if (NULL == L_grid[i][j].blocks) {
96  L_grid[i][j].blocks = (int *) my_malloc(
97  sizeof(int) * L_grid[i][j].type->capacity);
98 
99  /* Set them as unconnected */
100  for (k = 0; k < L_grid[i][j].type->capacity; ++k) {
101  L_grid[i][j].blocks[k] = OPEN;
102  }
103  }
104  }
105  }
106  }
107 
108  /* Go through each block */
109  for (i = 0; i < L_num_blocks; ++i) {
110  /* Check range of block coords */
111  if (block[i].x < 0 || block[i].x > (L_nx + 1) || block[i].y < 0
112  || (block[i].y + block[i].type->height - 1) > (L_ny + 1)
113  || block[i].z < 0 || block[i].z > (block[i].type->capacity)) {
114  vpr_printf(TIO_MESSAGE_ERROR, "Block %d is at invalid location (%d, %d, %d).\n",
115  i, block[i].x, block[i].y, block[i].z);
116  exit(1);
117  }
118 
119  /* Check types match */
120  if (block[i].type != L_grid[block[i].x][block[i].y].type) {
121  vpr_printf(TIO_MESSAGE_ERROR, "A block is in a grid location (%d x %d) with a conflicting type.\n",
122  block[i].x, block[i].y);
123  exit(1);
124  }
125 
126  /* Check already in use */
127  if (OPEN != L_grid[block[i].x][block[i].y].blocks[block[i].z]) {
128  vpr_printf(TIO_MESSAGE_ERROR, "Location (%d, %d, %d) is used more than once.\n",
129  block[i].x, block[i].y, block[i].z);
130  exit(1);
131  }
132 
133  if (L_grid[block[i].x][block[i].y].offset != 0) {
134  vpr_printf(TIO_MESSAGE_ERROR, "Large block not aligned in placment for block %d at (%d, %d, %d).",
135  i, block[i].x, block[i].y, block[i].z);
136  exit(1);
137  }
138 
139  /* Set the block */
140  for (j = 0; j < block[i].type->height; j++) {
141  L_grid[block[i].x][block[i].y + j].blocks[block[i].z] = i;
142  L_grid[block[i].x][block[i].y + j].usage++;
143  assert(L_grid[block[i].x][block[i].y + j].offset == j);
144  }
145  }
146 }
int x
Definition: vpr_types.h:563
t_type_ptr type
Definition: vpr_types.h:561
int y
Definition: vpr_types.h:564
static void * my_malloc(int ibytes)
Definition: graphics.c:499
struct s_block * block
Definition: globals.c:31
Definition: slre.c:50
int z
Definition: vpr_types.h:565
messagelogger vpr_printf
Definition: util.c:17

+ Here is the call graph for this function:

+ Here is the caller graph for this function: