SRC/path_delay2.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  t_tedge
struct  t_tnode
struct  t_tnode_descript

Enumerations

enum  t_tnode_type {
  INPAD_SOURCE, INPAD_OPIN, OUTPAD_IPIN, OUTPAD_SINK,
  FB_IPIN, FB_OPIN, SUBBLK_IPIN, SUBBLK_OPIN,
  FF_SINK, FF_SOURCE, CONSTANT_GEN_SOURCE
}

Functions

int alloc_and_load_timing_graph_levels (void)
void check_timing_graph (int num_const_gen, int num_ff, int num_sinks)
float print_critical_path_node (FILE *fp, t_linked_int *critical_path_node, t_subblock_data subblock_data)

Variables

t_tnodetnode
t_tnode_descripttnode_descript
int num_tnodes
int * net_to_driver_tnode
struct s_ivectnodes_at_level
int num_tnode_levels

Enumeration Type Documentation

Enumerator:
INPAD_SOURCE 
INPAD_OPIN 
OUTPAD_IPIN 
OUTPAD_SINK 
FB_IPIN 
FB_OPIN 
SUBBLK_IPIN 
SUBBLK_OPIN 
FF_SINK 
FF_SOURCE 
CONSTANT_GEN_SOURCE 

Definition at line 35 of file path_delay2.h.


Function Documentation

int alloc_and_load_timing_graph_levels ( void   ) 

Definition at line 104 of file path_delay2.c.

00105 {
00106 
00107 /* Does a breadth-first search through the timing graph in order to levelize *
00108  * it.  This allows subsequent breadth-first traversals to be faster. Also   *
00109  * returns the number of sinks in the graph (nodes with no fanout).          */
00110 
00111     t_linked_int *free_list_head, *nodes_at_level_head;
00112     int inode, num_at_level, iedge, to_node, num_edges, num_sinks,
00113         num_levels, i;
00114     t_tedge *tedge;
00115 
00116 /* [0..num_tnodes-1]. # of in-edges to each tnode that have not yet been    *
00117  * seen in this traversal.                                                  */
00118 
00119     int *tnode_fanin_left;
00120 
00121 
00122     tnode_fanin_left = alloc_and_load_tnode_fanin_and_check_edges(&num_sinks);
00123 
00124     free_list_head = NULL;
00125     nodes_at_level_head = NULL;
00126 
00127 /* Very conservative -> max number of levels = num_tnodes.  Realloc later.  *
00128  * Temporarily need one extra level on the end because I look at the first  *
00129  * empty level.                                                             */
00130 
00131     tnodes_at_level = (struct s_ivec *)my_malloc((num_tnodes + 1) *
00132                                                  sizeof(struct s_ivec));
00133 
00134 /* Scan through the timing graph, putting all the primary input nodes (no    *
00135  * fanin) into level 0 of the level structure.                               */
00136 
00137     num_at_level = 0;
00138 
00139     for(inode = 0; inode < num_tnodes; inode++)
00140         {
00141             if(tnode_fanin_left[inode] == 0)
00142                 {
00143                     num_at_level++;
00144                     nodes_at_level_head =
00145                         insert_in_int_list(nodes_at_level_head, inode,
00146                                            &free_list_head);
00147                 }
00148         }
00149 
00150     alloc_ivector_and_copy_int_list(&nodes_at_level_head, num_at_level,
00151                                     &tnodes_at_level[0], &free_list_head);
00152 
00153     num_levels = 0;
00154 
00155     while(num_at_level != 0)
00156         {                       /* Until there's nothing in the queue. */
00157             num_levels++;
00158             num_at_level = 0;
00159 
00160             for(i = 0; i < tnodes_at_level[num_levels - 1].nelem; i++)
00161                 {
00162                     inode = tnodes_at_level[num_levels - 1].list[i];
00163                     tedge = tnode[inode].out_edges;
00164                     num_edges = tnode[inode].num_edges;
00165 
00166                     for(iedge = 0; iedge < num_edges; iedge++)
00167                         {
00168                             to_node = tedge[iedge].to_node;
00169                             tnode_fanin_left[to_node]--;
00170 
00171                             if(tnode_fanin_left[to_node] == 0)
00172                                 {
00173                                     num_at_level++;
00174                                     nodes_at_level_head =
00175                                         insert_in_int_list
00176                                         (nodes_at_level_head, to_node,
00177                                          &free_list_head);
00178                                 }
00179                         }
00180                 }
00181 
00182             alloc_ivector_and_copy_int_list(&nodes_at_level_head,
00183                                             num_at_level,
00184                                             &tnodes_at_level[num_levels],
00185                                             &free_list_head);
00186         }
00187 
00188     tnodes_at_level =
00189         (struct s_ivec *)my_realloc(tnodes_at_level,
00190                                     num_levels * sizeof(struct s_ivec));
00191     num_tnode_levels = num_levels;
00192 
00193     free(tnode_fanin_left);
00194     free_int_list(&free_list_head);
00195     return (num_sinks);
00196 }

Here is the call graph for this function:

Here is the caller graph for this function:

void check_timing_graph ( int  num_const_gen,
int  num_ff,
int  num_sinks 
)

Definition at line 200 of file path_delay2.c.

00203 {
00204 
00205 /* Checks the timing graph to see that: (1) all the tnodes have been put    *
00206  * into some level of the timing graph; (2) the number of primary inputs    *
00207  * to the timing graph is equal to the number of input pads + the number of *
00208  * constant generators; and (3) the number of sinks (nodes with no fanout)  *
00209  * equals the number of output pads + the number of flip flops.             */
00210 
00211     int i, j, num_tnodes_check, ilevel, inet, inode, error, num_p_inputs,
00212         num_p_outputs;
00213 
00214     error = 0;
00215     num_tnodes_check = 0;
00216     num_p_inputs = 0;
00217     num_p_outputs = 0;
00218 
00219     /* Count I/O input and output pads */
00220     for(i = 0; i < num_blocks; i++)
00221         {
00222             if(block[i].type == IO_TYPE)
00223                 {
00224                     for(j = 0; j < IO_TYPE->num_pins; j++)
00225                         {
00226                             if(block[i].nets[j] != OPEN)
00227                                 {
00228                                     if(IO_TYPE->
00229                                        class_inf[IO_TYPE->pin_class[j]].
00230                                        type == DRIVER)
00231                                         {
00232                                             num_p_inputs++;
00233                                         }
00234                                     else
00235                                         {
00236                                             assert(IO_TYPE->
00237                                                    class_inf[IO_TYPE->
00238                                                              pin_class[j]].
00239                                                    type == RECEIVER);
00240                                             num_p_outputs++;
00241                                         }
00242                                 }
00243                         }
00244                 }
00245         }
00246 
00247     for(ilevel = 0; ilevel < num_tnode_levels; ilevel++)
00248         num_tnodes_check += tnodes_at_level[ilevel].nelem;
00249 
00250     if(num_tnodes_check != num_tnodes)
00251         {
00252             printf
00253                 ("Error in check_timing_graph: %d tnodes appear in the tnode level "
00254                  "structure.  Expected %d.\n", num_tnodes_check, num_tnodes);
00255             printf("Check the netlist for combinational cycles.\n");
00256             error++;
00257         }
00258 
00259     if(num_const_gen + num_p_inputs != tnodes_at_level[0].nelem)
00260         {
00261             printf
00262                 ("Error in check_timing_graph: %d tnodes are sources (have no "
00263                  "inputs -- expected %d.\n", tnodes_at_level[0].nelem,
00264                  num_const_gen + num_p_inputs);
00265             error++;
00266         }
00267 
00268     if(num_sinks != num_p_outputs + num_ff)
00269         {
00270             printf
00271                 ("Error in check_timing_graph: %d tnodes are sinks (have no "
00272                  "outputs -- expected %d.\n", num_sinks,
00273                  num_ff + num_p_outputs);
00274             error++;
00275         }
00276 
00277     for(inet = 0; inet < num_nets; inet++)
00278         {
00279             inode = net_to_driver_tnode[inet];
00280             if(inode < 0 || inode >= num_tnodes)
00281                 {
00282                     printf("Error in check_timing_graph:\n"
00283                            "\tdriver of net %d has a tnode mapping of %d (out of range).\n",
00284                            inet, inode);
00285                     error++;
00286                 }
00287         }
00288 
00289     if(error != 0)
00290         {
00291             printf("Found %d Errors in the timing graph.  Aborting.\n",
00292                    error);
00293             exit(1);
00294         }
00295 }

Here is the caller graph for this function:

float print_critical_path_node ( FILE *  fp,
t_linked_int critical_path_node,
t_subblock_data  subblock_data 
)

Definition at line 299 of file path_delay2.c.

00302 {
00303 
00304 /* Prints one tnode on the critical path out to fp. Returns the delay to    *
00305  * the next node.                                                           */
00306 
00307     int inode, iblk, ipin, inet, downstream_node;
00308     t_tnode_type type;
00309     static char *tnode_type_names[] = { "INPAD_SOURCE", "INPAD_OPIN",
00310         "OUTPAD_IPIN", "OUTPAD_SINK", "CLB_IPIN", "CLB_OPIN",
00311         "SUBBLK_IPIN", "SUBBLK_OPIN", "FF_SINK", "FF_SOURCE",
00312         "CONSTANT_GEN_SOURCE"
00313     };                          /* NB: static for speed */
00314     t_linked_int *next_crit_node;
00315     float Tdel;
00316 
00317     inode = critical_path_node->data;
00318     type = tnode_descript[inode].type;
00319     iblk = tnode_descript[inode].iblk;
00320     ipin = tnode_descript[inode].ipin;
00321 
00322     fprintf(fp, "Node: %d  %s Block #%d (%s)\n", inode,
00323             tnode_type_names[type], iblk, block[iblk].name);
00324 
00325     if(type != INPAD_SOURCE && type != OUTPAD_SINK && type != FF_SINK &&
00326        type != FF_SOURCE && type != CONSTANT_GEN_SOURCE)
00327         {
00328             fprintf(fp, "Pin: %d ", ipin);
00329         }
00330 
00331     if(type == SUBBLK_IPIN || type == SUBBLK_OPIN || type == FF_SINK
00332        || type == FF_SOURCE || type == CONSTANT_GEN_SOURCE)
00333         {
00334             fprintf(fp, "Subblock #%d subpin #%d",
00335                     tnode_descript[inode].isubblk,
00336                     tnode_descript[inode].ipin);
00337         }
00338 
00339     if(type != INPAD_SOURCE && type != OUTPAD_SINK)
00340         {
00341             fprintf(fp, "\n");
00342         }
00343 
00344     fprintf(fp, "T_arr: %g  T_req: %g  ", tnode[inode].T_arr,
00345             tnode[inode].T_req);
00346 
00347     next_crit_node = critical_path_node->next;
00348     if(next_crit_node != NULL)
00349         {
00350             downstream_node = next_crit_node->data;
00351             Tdel = tnode[downstream_node].T_arr - tnode[inode].T_arr;
00352             fprintf(fp, "Tdel: %g\n", Tdel);
00353         }
00354     else
00355         {                       /* last node, no Tdel. */
00356             Tdel = 0.;
00357             fprintf(fp, "\n");
00358         }
00359 
00360     if(type == FB_OPIN)
00361         {
00362             inet = block[iblk].nets[ipin];
00363             fprintf(fp, "Net to next node: #%d (%s).  Pins on net: %d.\n",
00364                     inet, net[inet].name, (net[inet].num_sinks + 1));
00365         }
00366 
00367     if(type == INPAD_OPIN)
00368         {
00369             ipin =
00370                 subblock_data.subblock_inf[iblk][tnode_descript[inode].
00371                                                  isubblk].outputs[ipin];
00372             inet = block[iblk].nets[ipin];
00373             fprintf(fp, "Net to next node: #%d (%s).  Pins on net: %d.\n",
00374                     inet, net[inet].name, (net[inet].num_sinks + 1));
00375         }
00376 
00377     fprintf(fp, "\n");
00378     return (Tdel);
00379 }

Here is the caller graph for this function:


Variable Documentation

Definition at line 16 of file path_delay2.c.

Definition at line 23 of file path_delay2.c.

Definition at line 12 of file path_delay2.c.

Definition at line 10 of file path_delay2.c.

Definition at line 11 of file path_delay2.c.

Definition at line 22 of file path_delay2.c.


Generated on Tue Jan 5 15:25:55 2010 for VPR5.0 by  doxygen 1.6.1