VPR-6.0

vpr/SRC/pack/pb_type_graph_annotations.c

Go to the documentation of this file.
00001 /*
00002  * @file
00003  *
00004  * Jason Luu
00005  * April 15, 2011
00006  * Loads statistical information (min/max delays, power) onto the pb_graph.  
00007  */
00008 
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <assert.h>
00012 #include <string.h>
00013 
00014 #include "util.h"
00015 #include "arch_types.h"
00016 #include "vpr_types.h"
00017 #include "globals.h"
00018 #include "vpr_utils.h"
00019 #include "pb_type_graph.h"
00020 #include "token.h"
00021 #include "pb_type_graph_annotations.h"
00022 
00023 
00024 
00025 static void load_critical_path_annotations(INOUTP t_pb_graph_node *pb_graph_node, 
00026                                                                                    INP int mode,
00027                                                                                    INP enum e_pin_to_pin_annotation_format input_format,
00028                                                                                    INP enum e_pin_to_pin_delay_annotations delay_type,
00029                                                                                    INP char *annot_in_pins,
00030                                                                                    INP char *annot_out_pins,
00031                                                                                    INP char* value);
00032 
00033 static t_tedge * find_edge();
00034 
00035 void load_pb_graph_pin_to_pin_annotations(INOUTP t_pb_graph_node *pb_graph_node)
00036 {
00037         int i, j, k, m;
00038         const t_pb_type *pb_type;
00039         t_pin_to_pin_annotation *annotations;
00040         
00041         pb_type = pb_graph_node->pb_type;
00042 
00043         /* Load primitive critical path delays */
00044         if(pb_type->num_modes == 0) {
00045                 annotations = pb_type->annotations;
00046                 for(i = 0; i < pb_type->num_annotations; i++) {
00047                         if(annotations[i].type == E_ANNOT_PIN_TO_PIN_DELAY) {
00048                                 for(j = 0; j < annotations[i].num_value_prop_pairs; j++) {
00049                                         if(     annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_MAX || 
00050                                                 annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX ||
00051                                                 annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP ) {
00052                                                         load_critical_path_annotations(pb_graph_node, OPEN, annotations[i].format, annotations[i].prop[j], annotations[i].input_pins, annotations[i].output_pins, annotations[i].value[j]);
00053                                         } else {
00054                                                 assert(annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_MIN ||
00055                                                         annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN ||
00056                                                         annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_THOLD );
00057                                         }
00058                                 }
00059                         } else {
00060                                 /* Todo:
00061                                 load_hold_time_constraints_annotations(pb_graph_node); 
00062                                 load_power_annotations(pb_graph_node);
00063                                 */
00064                         }
00065                 }
00066         } else {
00067                 /* Load interconnect delays */
00068                 for(i = 0; i < pb_type->num_modes; i++) {
00069                         for(j = 0; j < pb_type->modes[i].num_interconnect; j++) {
00070                                 annotations = pb_type->modes[i].interconnect[j].annotations;
00071                                 for(k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; k++) {
00072                                         if(annotations[k].type == E_ANNOT_PIN_TO_PIN_DELAY) {
00073                                                 for(m = 0; m < annotations[k].num_value_prop_pairs; m++) {
00074                                                         if(     annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_MAX || 
00075                                                                 annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX ||
00076                                                                 annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP ) {
00077                                                                         load_critical_path_annotations(pb_graph_node, i, annotations[k].format, annotations[k].prop[m], 
00078                                                                                 annotations[k].input_pins, annotations[k].output_pins, annotations[k].value[m]);
00079                                                         } else {
00080                                                                 assert(annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_MIN ||
00081                                                                         annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN ||
00082                                                                         annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_THOLD );
00083                                                         }
00084                                                 }
00085                                         } else {
00086                                                 /* Todo:
00087                                                 load_hold_time_constraints_annotations(pb_graph_node); 
00088                                                 load_power_annotations(pb_graph_node);
00089                                                 */
00090                                         }
00091                                 }
00092                         }
00093                 }
00094         }
00095 
00096         for(i = 0; i < pb_type->num_modes; i++) {
00097                 for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
00098                         for(k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) {
00099                                 load_pb_graph_pin_to_pin_annotations(&pb_graph_node->child_pb_graph_nodes[i][j][k]);
00100                         }
00101                 }
00102         }
00103 }
00104 
00105 
00106 static void load_critical_path_annotations(INOUTP t_pb_graph_node *pb_graph_node, 
00107                                                                                    INP int mode,
00108                                                                                    INP enum e_pin_to_pin_annotation_format input_format,
00109                                                                                    INP enum e_pin_to_pin_delay_annotations delay_type,
00110                                                                                    INP char *annot_in_pins,
00111                                                                                    INP char *annot_out_pins,
00112                                                                                    INP char* value) {
00113 
00114     int i, j, k, m, n, p, iedge;
00115         t_pb_graph_pin ***in_port, ***out_port;
00116         int *num_in_ptrs, *num_out_ptrs, num_in_sets, num_out_sets;
00117         float **delay_matrix;
00118         t_pb_graph_node **children = NULL;
00119 
00120         int count;
00121         int num_inputs, num_outputs;
00122         
00123         in_port = out_port = NULL;
00124         num_out_sets = num_in_sets = 0;
00125         num_out_ptrs = num_in_ptrs = NULL;
00126 
00127 
00128         /* Primarily 3 kinds of delays that affect critical path:
00129                 1.  Intrablock interconnect delays
00130                 2.  Combinational primitives (pin-to-pin delays of primitive)
00131                 3.  Sequential primitives (setup and clock-to-q times)
00132 
00133                 Note:   Proper I/O modelling requires knowledge of the extra-chip world (eg. the load that pin is driving, drive strength, etc)
00134                                 For now, I/O delays are modelled as a constant in the architecture file by setting the pad-I/O block interconnect delay to be a constant I/O delay
00135 
00136                 Algorithm: Intrablock and combinational primitive delays apply to edges
00137                            Sequential delays apply to pins
00138                                    1.  Determine if delay applies to pin or edge
00139                                    2.  Format the delay information
00140                                    3.  Load delay information
00141         */
00142 
00143 
00144     /* Determine what pins to read based on delay type */
00145         num_inputs = num_outputs = 0;
00146         if(mode == OPEN) {
00147                 children = NULL;
00148         } else {
00149                 children = pb_graph_node->child_pb_graph_nodes[mode];
00150         }
00151         if(delay_type == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP) {
00152                 assert(pb_graph_node->pb_type->blif_model != NULL);
00153                 in_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node,
00154                                                                                                                         children,
00155                                                                                                                         annot_in_pins, 
00156                                                                                                                         &num_in_ptrs,
00157                                                                                                                         &num_in_sets,
00158                                                                                                                         FALSE,
00159                                                                                                                         FALSE);
00160         } else if (delay_type == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX) {
00161                 assert(pb_graph_node->pb_type->blif_model != NULL);
00162                 in_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node,
00163                                                                                                                         children,
00164                                                                                                                         annot_in_pins, 
00165                                                                                                                         &num_in_ptrs,
00166                                                                                                                         &num_in_sets,
00167                                                                                                                         FALSE,
00168                                                                                                                         FALSE);
00169         } else {
00170                 assert(delay_type == E_ANNOT_PIN_TO_PIN_DELAY_MAX);
00171                 in_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node,
00172                                                                                                                         children,
00173                                                                                                                         annot_in_pins, 
00174                                                                                                                         &num_in_ptrs,
00175                                                                                                                         &num_in_sets,
00176                                                                                                                         FALSE,
00177                                                                                                                         FALSE);
00178                 out_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node,
00179                                                                                                                         children,
00180                                                                                                                         annot_out_pins, 
00181                                                                                                                         &num_out_ptrs,
00182                                                                                                                         &num_out_sets,
00183                                                                                                                         FALSE,
00184                                                                                                                         FALSE);
00185         }
00186 
00187         num_inputs = 0;
00188         for(i = 0; i < num_in_sets; i++) {
00189                 num_inputs += num_in_ptrs[i];
00190         }
00191 
00192         if(out_port != NULL) {
00193                 num_outputs = 0;
00194                 for(i = 0; i < num_out_sets; i++) {
00195                         num_outputs += num_out_ptrs[i];
00196                 }
00197         } else {
00198                 num_outputs = 1;
00199         }
00200 
00201         delay_matrix = my_malloc(sizeof(float*) * num_inputs);
00202         for(i = 0; i < num_inputs; i++) {
00203                 delay_matrix[i] = my_malloc(sizeof(float) * num_outputs);
00204         }
00205 
00206         if(input_format == E_ANNOT_PIN_TO_PIN_MATRIX) {
00207                 my_atof_2D(delay_matrix, num_inputs, num_outputs, value);
00208         } else {
00209                 assert(input_format == E_ANNOT_PIN_TO_PIN_CONSTANT);
00210                 for(i = 0; i < num_inputs; i++) {
00211                         for(j = 0; j < num_outputs; j++) {
00212                                 delay_matrix[i][j] = atof(value);
00213                         }
00214                 }
00215         }
00216 
00217         if(delay_type == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP || delay_type == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX) {
00218                 k = 0;
00219                 for(i = 0; i < num_in_sets; i++) {
00220                         for(j = 0; j < num_in_ptrs[i]; j++) {
00221                                 in_port[i][j]->tsu_tco = delay_matrix[k][0];
00222                                 k++;
00223                         }
00224                 }
00225         } else {
00226                 if(pb_graph_node->pb_type->num_modes != 0) {
00227                         /* Not a primitive, find pb_graph_edge */
00228                         k = 0;
00229                         for(i = 0; i < num_in_sets; i++) {
00230                                 for(j = 0; j < num_in_ptrs[i]; j++) {
00231                                         p = 0;
00232                                         for(m = 0; m < num_out_sets; m++) {
00233                                                 for(n = 0; n < num_out_ptrs[m]; n++) {
00234                                                         for(iedge = 0; iedge < in_port[i][j]->num_output_edges; iedge++) {
00235                                                                 if(in_port[i][j]->output_edges[iedge]->output_pins[0] == out_port[m][n]) {
00236                                                                         assert(in_port[i][j]->output_edges[iedge]->delay_max == 0);
00237                                                                         break;                                                          
00238                                                                 }
00239                                                         }
00240                                                         /* jluu Todo: This is inefficient, I know the interconnect so I know what edges exist
00241                                                                 can use this info to only annotate existing edges */
00242                                                         if(iedge != in_port[i][j]->num_output_edges) {
00243                                                                 in_port[i][j]->output_edges[iedge]->delay_max = delay_matrix[k][p];                                                             
00244                                                         }
00245                                                         p++;
00246                                                 }
00247                                         }
00248                                         k++;
00249                                 }
00250                         }
00251                 } else {
00252                         /* Primitive, allocate appropriate nodes */
00253                         k = 0;
00254                         for(i = 0; i < num_in_sets; i++) {
00255                                 for(j = 0; j < num_in_ptrs[i]; j++) {
00256                                         delay_matrix[k][0];
00257                                         count = p = 0;
00258                                         for(m = 0; m < num_out_sets; m++) {
00259                                                 for(n = 0; n < num_out_ptrs[m]; n++) {
00260                                                         /* OPEN indicates that connection does not exist */
00261                                                         if(delay_matrix[k][p] != OPEN) {
00262                                                                 count++;                                                                
00263                                                         }
00264                                                         p++;
00265                                                 }
00266                                         }
00267                                         in_port[i][j]->num_pin_timing = count;
00268                                         in_port[i][j]->pin_timing_del_max = my_malloc(sizeof(float) * count);
00269                                         in_port[i][j]->pin_timing = my_malloc(sizeof(t_pb_graph_pin*) * count);
00270                                         p = 0;
00271                                         count = 0;
00272                                         for(m = 0; m < num_out_sets; m++) {
00273                                                 for(n = 0; n < num_out_ptrs[m]; n++) {
00274                                                         if(delay_matrix[k][p] != OPEN) {
00275                                                                 in_port[i][j]->pin_timing_del_max[count] = delay_matrix[k][p];
00276                                                                 in_port[i][j]->pin_timing[count] = out_port[m][n];
00277                                                                 count++;
00278                                                         }
00279                                                         p++;
00280                                                 }
00281                                         }
00282                                         assert(in_port[i][j]->num_pin_timing == count);
00283                                         k++;
00284                                 }
00285                         }
00286                 }
00287         }
00288         if(in_port != NULL) {
00289                 for(i = 0; i < num_in_sets; i++) {
00290                         free(in_port[i]);
00291                 }
00292                 free(in_port);
00293                 free(num_in_ptrs);
00294         }
00295         if(out_port != NULL) {
00296                 for(i = 0; i < num_out_sets; i++) {
00297                         free(out_port[i]);
00298                 }
00299                 free(out_port);
00300                 free(num_out_ptrs);
00301         }
00302         for(i = 0; i < num_inputs; i++) {
00303                 free(delay_matrix[i]);
00304         }
00305         free(delay_matrix);
00306 }