VPR-6.0
|
00001 /** 00002 * @file 00003 * 00004 * Jason Luu 00005 * July 17, 2009 00006 * pb_graph creates the internal routing edges that join together the different 00007 * pb_types modes within a pb_type 00008 */ 00009 00010 #include <stdio.h> 00011 #include <assert.h> 00012 #include <string.h> 00013 00014 #include "util.h" 00015 #include "token.h" 00016 #include "arch_types.h" 00017 #include "vpr_types.h" 00018 #include "globals.h" 00019 #include "vpr_utils.h" 00020 #include "pb_type_graph.h" 00021 #include "pb_type_graph_annotations.h" 00022 00023 /** variable global to this section that indexes each pb graph pin within a cluster */ 00024 static int pin_count_in_cluster; 00025 static struct s_linked_vptr *edges_head; 00026 static struct s_linked_vptr *num_edges_head; 00027 00028 /* TODO: Software engineering decision needed: Move this file to libarch? 00029 00030 */ 00031 00032 static int check_pb_graph (); 00033 static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, 00034 INP t_pb_graph_node *parent_pb_graph_node, 00035 INP const t_pb_type *pb_type, 00036 INP int index); 00037 00038 static void alloc_and_load_mode_interconnect(INOUTP t_pb_graph_node *pb_graph_parent_node, 00039 INOUTP t_pb_graph_node **pb_graph_children_nodes, 00040 INP const t_mode * mode); 00041 00042 static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP const t_pb_graph_node *pb_graph_parent_node, 00043 INP t_pb_graph_node **pb_graph_children_nodes, 00044 INP boolean interconnect_error_check, 00045 INP boolean is_input_to_interc, 00046 INP const t_token *tokens, 00047 INOUTP int *token_index, 00048 INOUTP int *num_pins, 00049 OUTP t_pb_graph_pin ***pb_graph_pins); 00050 00051 static t_pb_graph_pin * get_pb_graph_pin_from_name(INP const char * port_name, INP const t_pb_graph_node * pb, INP int pin); 00052 00053 00054 static void alloc_and_load_complete_interc_edges(INP t_interconnect * interconnect, 00055 INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs, 00056 INP int num_input_sets, 00057 INP int *num_input_ptrs, 00058 INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs, 00059 INP int num_output_sets, 00060 INP int *num_output_ptrs); 00061 00062 static void alloc_and_load_direct_interc_edges(INP t_interconnect * interconnect, INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs, 00063 INP int num_input_sets, 00064 INP int *num_input_ptrs, 00065 INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs, 00066 INP int num_output_sets, 00067 INP int *num_output_ptrs); 00068 00069 static void alloc_and_load_mux_interc_edges(INP t_interconnect * interconnect, INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs, 00070 INP int num_input_sets, 00071 INP int *num_input_ptrs, 00072 INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs, 00073 INP int num_output_sets, 00074 INP int *num_output_ptrs); 00075 00076 static void alloc_and_load_pin_locations_from_pb_graph(t_type_descriptor *type); 00077 00078 static void echo_pb_rec(INP const t_pb_graph_node *pb, INP int level, INP FILE * fp); 00079 static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports, INP int level, INP FILE * fp); 00080 static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node); 00081 00082 /** 00083 * Allocate memory into types and load the pb graph with interconnect edges 00084 */ 00085 void alloc_and_load_all_pb_graphs () { 00086 int i, errors; 00087 edges_head = NULL; 00088 num_edges_head = NULL; 00089 for(i = 0; i < num_types; i++) { 00090 if(type_descriptors[i].pb_type) { 00091 pin_count_in_cluster = 0; 00092 type_descriptors[i].pb_graph_head = my_calloc(1, sizeof(t_pb_graph_node)); 00093 alloc_and_load_pb_graph(type_descriptors[i].pb_graph_head, NULL, type_descriptors[i].pb_type, 0); 00094 type_descriptors[i].pb_graph_head->total_pb_pins = pin_count_in_cluster; 00095 alloc_and_load_pin_locations_from_pb_graph(&type_descriptors[i]); 00096 } else { 00097 type_descriptors[i].pb_graph_head = NULL; 00098 assert(&type_descriptors[i] == EMPTY_TYPE); 00099 } 00100 } 00101 00102 errors = check_pb_graph (); 00103 if(errors > 0) { 00104 printf("Errors in pb graph"); 00105 exit(1); 00106 } 00107 for(i = 0; i < num_types; i++) { 00108 if(type_descriptors[i].pb_type) { 00109 load_pb_graph_pin_to_pin_annotations(type_descriptors[i].pb_graph_head); 00110 } 00111 } 00112 } 00113 00114 00115 /** 00116 * Free pb graph 00117 */ 00118 void free_all_pb_graph_nodes () { 00119 int i; 00120 for(i = 0; i < num_types; i++) { 00121 if(type_descriptors[i].pb_type) { 00122 pin_count_in_cluster = 0; 00123 if(type_descriptors[i].pb_graph_head) { 00124 free_pb_graph(type_descriptors[i].pb_graph_head); 00125 } 00126 } 00127 } 00128 } 00129 00130 00131 /** 00132 * Print out the pb_type graph 00133 */ 00134 void echo_pb_graph (char * filename) { 00135 FILE *fp; 00136 int i; 00137 00138 fp = my_fopen(filename, "w", 0); 00139 00140 fprintf(fp, "Physical Blocks Graph\n"); 00141 fprintf(fp, "--------------------------------------------\n\n"); 00142 00143 for(i = 0; i < num_types; i++) 00144 { 00145 fprintf(fp, "type %s\n", type_descriptors[i].name); 00146 if(type_descriptors[i].pb_graph_head) 00147 echo_pb_rec(type_descriptors[i].pb_graph_head, 1, fp); 00148 } 00149 00150 fclose(fp); 00151 } 00152 00153 /** 00154 * check pb_type graph and return the number of errors 00155 */ 00156 static int check_pb_graph () { 00157 int num_errors; 00158 /* TODO: Error checks to do 00159 1. All pin and edge connections are bidirectional and match each other 00160 2. All pb_type names are unique in a namespace 00161 3. All ports are unique in a pb_type 00162 4. Number of pb of a pb_type in graph is the same as requested number 00163 5. All pins are connected to edges 00164 */ 00165 num_errors = 0; 00166 00167 return num_errors; 00168 } 00169 00170 static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, 00171 INP t_pb_graph_node *parent_pb_graph_node, 00172 INP const t_pb_type *pb_type, 00173 INP int index) { 00174 int i, j, k, i_input, i_output, i_clockport; 00175 00176 pb_graph_node->placement_index = index; 00177 pb_graph_node->pb_type = pb_type; 00178 pb_graph_node->parent_pb_graph_node = parent_pb_graph_node; 00179 00180 pb_graph_node->num_input_ports = 0; 00181 pb_graph_node->num_output_ports = 0; 00182 pb_graph_node->num_clock_ports = 0; 00183 00184 /* Generate ports for pb graph node */ 00185 for(i = 0; i < pb_type->num_ports; i++) { 00186 if(pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) { 00187 pb_graph_node->num_input_ports++; 00188 } else if(pb_type->ports[i].type == OUT_PORT) { 00189 assert(!pb_type->ports[i].is_clock); 00190 pb_graph_node->num_output_ports++; 00191 } else { 00192 assert(pb_type->ports[i].is_clock && pb_type->ports[i].type == IN_PORT); 00193 pb_graph_node->num_clock_ports++; 00194 } 00195 } 00196 00197 pb_graph_node->num_input_pins = my_calloc(pb_graph_node->num_input_ports, sizeof(int)); 00198 pb_graph_node->num_output_pins = my_calloc(pb_graph_node->num_output_ports, sizeof(int)); 00199 pb_graph_node->num_clock_pins = my_calloc(pb_graph_node->num_clock_ports, sizeof(int)); 00200 00201 pb_graph_node->input_pins = my_calloc(pb_graph_node->num_input_ports, sizeof(t_pb_graph_pin*)); 00202 pb_graph_node->output_pins = my_calloc(pb_graph_node->num_output_ports, sizeof(t_pb_graph_pin*)); 00203 pb_graph_node->clock_pins = my_calloc(pb_graph_node->num_clock_ports, sizeof(t_pb_graph_pin*)); 00204 00205 i_input = i_output = i_clockport = 0; 00206 for(i = 0; i < pb_type->num_ports; i++) { 00207 if(pb_type->ports[i].model_port) { 00208 assert(pb_type->num_modes == 0); 00209 } else { 00210 assert(pb_type->num_modes != 0 || pb_type->ports[i].is_clock); 00211 } 00212 if(pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) { 00213 pb_graph_node->input_pins[i_input] = my_calloc(pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin)); 00214 pb_graph_node->num_input_pins[i_input] = pb_type->ports[i].num_pins; 00215 for(j = 0; j < pb_type->ports[i].num_pins; j++) { 00216 pb_graph_node->input_pins[i_input][j].input_edges = NULL; 00217 pb_graph_node->input_pins[i_input][j].num_input_edges = 0; 00218 pb_graph_node->input_pins[i_input][j].output_edges = NULL; 00219 pb_graph_node->input_pins[i_input][j].num_output_edges = 0; 00220 pb_graph_node->input_pins[i_input][j].pin_number = j; 00221 pb_graph_node->input_pins[i_input][j].port = &pb_type->ports[i]; 00222 pb_graph_node->input_pins[i_input][j].parent_node = pb_graph_node; 00223 pb_graph_node->input_pins[i_input][j].pin_count_in_cluster = pin_count_in_cluster; 00224 pb_graph_node->input_pins[i_input][j].type = PB_PIN_NORMAL; 00225 if(pb_graph_node->pb_type->blif_model != NULL) { 00226 if(strcmp(pb_graph_node->pb_type->blif_model, ".output") == 0) { 00227 pb_graph_node->input_pins[i_input][j].type = PB_PIN_OUTPAD; 00228 } else if(pb_graph_node->num_clock_ports != 0) { 00229 pb_graph_node->input_pins[i_input][j].type = PB_PIN_SEQUENTIAL; 00230 } else { 00231 pb_graph_node->input_pins[i_input][j].type = PB_PIN_TERMINAL; 00232 } 00233 } 00234 pin_count_in_cluster++; 00235 } 00236 i_input++; 00237 } else if(pb_type->ports[i].type == OUT_PORT) { 00238 pb_graph_node->output_pins[i_output] = my_calloc(pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin)); 00239 pb_graph_node->num_output_pins[i_output] = pb_type->ports[i].num_pins; 00240 for(j = 0; j < pb_type->ports[i].num_pins; j++) { 00241 pb_graph_node->output_pins[i_output][j].input_edges = NULL; 00242 pb_graph_node->output_pins[i_output][j].num_input_edges = 0; 00243 pb_graph_node->output_pins[i_output][j].output_edges = NULL; 00244 pb_graph_node->output_pins[i_output][j].num_output_edges = 0; 00245 pb_graph_node->output_pins[i_output][j].pin_number = j; 00246 pb_graph_node->output_pins[i_output][j].port = &pb_type->ports[i]; 00247 pb_graph_node->output_pins[i_output][j].parent_node = pb_graph_node; 00248 pb_graph_node->output_pins[i_output][j].pin_count_in_cluster = pin_count_in_cluster; 00249 pb_graph_node->output_pins[i_output][j].type = PB_PIN_NORMAL; 00250 if(pb_graph_node->pb_type->blif_model != NULL) { 00251 if(strcmp(pb_graph_node->pb_type->blif_model, ".input") == 0) { 00252 pb_graph_node->output_pins[i_output][j].type = PB_PIN_INPAD; 00253 } else if(pb_graph_node->num_clock_ports != 0) { 00254 pb_graph_node->output_pins[i_output][j].type = PB_PIN_SEQUENTIAL; 00255 } else { 00256 pb_graph_node->output_pins[i_output][j].type = PB_PIN_TERMINAL; 00257 } 00258 } 00259 pin_count_in_cluster++; 00260 } 00261 i_output++; 00262 } else { 00263 assert(pb_type->ports[i].is_clock && pb_type->ports[i].type == IN_PORT); 00264 pb_graph_node->clock_pins[i_clockport] = my_calloc(pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin)); 00265 pb_graph_node->num_clock_pins[i_clockport] = pb_type->ports[i].num_pins; 00266 for(j = 0; j < pb_type->ports[i].num_pins; j++) { 00267 pb_graph_node->clock_pins[i_clockport][j].input_edges = NULL; 00268 pb_graph_node->clock_pins[i_clockport][j].num_input_edges = 0; 00269 pb_graph_node->clock_pins[i_clockport][j].output_edges = NULL; 00270 pb_graph_node->clock_pins[i_clockport][j].num_output_edges = 0; 00271 pb_graph_node->clock_pins[i_clockport][j].pin_number = j; 00272 pb_graph_node->clock_pins[i_clockport][j].port = &pb_type->ports[i]; 00273 pb_graph_node->clock_pins[i_clockport][j].parent_node = pb_graph_node; 00274 pb_graph_node->clock_pins[i_clockport][j].pin_count_in_cluster = pin_count_in_cluster; 00275 pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_NORMAL; 00276 if(pb_graph_node->pb_type->blif_model != NULL) { 00277 pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_CLOCK; 00278 } 00279 pin_count_in_cluster++; 00280 } 00281 i_clockport++; 00282 } 00283 } 00284 00285 /* Allocate and load child nodes for each mode and create interconnect in each mode */ 00286 pb_graph_node->child_pb_graph_nodes = my_calloc(pb_type->num_modes, sizeof(t_pb_graph_node **)); 00287 for(i = 0; i < pb_type->num_modes; i++) { 00288 pb_graph_node->child_pb_graph_nodes[i] = my_calloc(pb_type->modes[i].num_pb_type_children, sizeof(t_pb_graph_node *)); 00289 for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { 00290 pb_graph_node->child_pb_graph_nodes[i][j] = my_calloc(pb_type->modes[i].pb_type_children[j].num_pb, sizeof(t_pb_graph_node)); 00291 for(k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) { 00292 alloc_and_load_pb_graph(&pb_graph_node->child_pb_graph_nodes[i][j][k], 00293 pb_graph_node, 00294 &pb_type->modes[i].pb_type_children[j], 00295 k); 00296 } 00297 } 00298 } 00299 00300 for(i = 0; i < pb_type->num_modes; i++) { 00301 /* Create interconnect for mode */ 00302 alloc_and_load_mode_interconnect(pb_graph_node, pb_graph_node->child_pb_graph_nodes[i], &pb_type->modes[i]); 00303 } 00304 } 00305 00306 00307 static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node) { 00308 int i, j, k; 00309 const t_pb_type *pb_type; 00310 struct s_linked_vptr *cur, *cur_num; 00311 t_pb_graph_edge *edges; 00312 00313 pb_type = pb_graph_node->pb_type; 00314 00315 /* Free ports for pb graph node */ 00316 for(i = 0; i < pb_graph_node->num_input_ports; i++) { 00317 for(j = 0; j < pb_graph_node->num_input_pins[i]; j++) { 00318 if(pb_graph_node->input_pins[i][j].pin_timing) 00319 free(pb_graph_node->input_pins[i][j].pin_timing); 00320 if(pb_graph_node->input_pins[i][j].pin_timing_del_max) 00321 free(pb_graph_node->input_pins[i][j].pin_timing_del_max); 00322 if(pb_graph_node->input_pins[i][j].input_edges) 00323 free(pb_graph_node->input_pins[i][j].input_edges); 00324 00325 if(pb_graph_node->input_pins[i][j].output_edges) 00326 free(pb_graph_node->input_pins[i][j].output_edges); 00327 } 00328 free(pb_graph_node->input_pins[i]); 00329 } 00330 for(i = 0; i < pb_graph_node->num_output_ports; i++) { 00331 for(j = 0; j < pb_graph_node->num_output_pins[i]; j++) { 00332 if(pb_graph_node->output_pins[i][j].pin_timing) 00333 free(pb_graph_node->output_pins[i][j].pin_timing); 00334 if(pb_graph_node->output_pins[i][j].pin_timing_del_max) 00335 free(pb_graph_node->output_pins[i][j].pin_timing_del_max); 00336 if(pb_graph_node->output_pins[i][j].input_edges) 00337 free(pb_graph_node->output_pins[i][j].input_edges); 00338 if(pb_graph_node->output_pins[i][j].output_edges) 00339 free(pb_graph_node->output_pins[i][j].output_edges); 00340 } 00341 free(pb_graph_node->output_pins[i]); 00342 } 00343 for(i = 0; i < pb_graph_node->num_clock_ports; i++) { 00344 for(j = 0; j < pb_graph_node->num_clock_pins[i]; j++) { 00345 if(pb_graph_node->clock_pins[i][j].pin_timing) 00346 free(pb_graph_node->clock_pins[i][j].pin_timing); 00347 if(pb_graph_node->clock_pins[i][j].pin_timing_del_max) 00348 free(pb_graph_node->clock_pins[i][j].pin_timing_del_max); 00349 if(pb_graph_node->clock_pins[i][j].input_edges) 00350 free(pb_graph_node->clock_pins[i][j].input_edges); 00351 if(pb_graph_node->clock_pins[i][j].output_edges) 00352 free(pb_graph_node->clock_pins[i][j].output_edges); 00353 } 00354 free(pb_graph_node->clock_pins[i]); 00355 } 00356 free(pb_graph_node->input_pins); 00357 free(pb_graph_node->output_pins); 00358 free(pb_graph_node->clock_pins); 00359 00360 free(pb_graph_node->num_input_pins); 00361 free(pb_graph_node->num_output_pins); 00362 free(pb_graph_node->num_clock_pins); 00363 00364 for(i = 0; i < pb_type->num_modes; i++) { 00365 for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { 00366 for(k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) { 00367 free_pb_graph(&pb_graph_node->child_pb_graph_nodes[i][j][k]); 00368 } 00369 free(pb_graph_node->child_pb_graph_nodes[i][j]); 00370 } 00371 free(pb_graph_node->child_pb_graph_nodes[i]); 00372 } 00373 free(pb_graph_node->child_pb_graph_nodes); 00374 00375 while(edges_head != NULL) { 00376 cur = edges_head; 00377 cur_num = num_edges_head; 00378 edges = (t_pb_graph_edge*) cur->data_vptr; 00379 for(i = 0; i < (long) cur_num->data_vptr; i++) { 00380 free(edges[i].input_pins); 00381 free(edges[i].output_pins); 00382 } 00383 edges_head = edges_head->next; 00384 num_edges_head = num_edges_head->next; 00385 free(edges); 00386 free(cur_num); 00387 free(cur); 00388 } 00389 } 00390 00391 /** 00392 * Generate interconnect associated with a mode of operation 00393 * @param pb_graph_parent_node: parent node of pb in mode 00394 * @param pb_graph_children_nodes: [0..num_pb_type_in_mode-1][0..num_pb] 00395 * @param mode: mode of operation 00396 */ 00397 static void alloc_and_load_mode_interconnect(INOUTP t_pb_graph_node *pb_graph_parent_node, 00398 INOUTP t_pb_graph_node **pb_graph_children_nodes, 00399 INP const t_mode * mode) { 00400 int i, j; 00401 int *num_input_pb_graph_node_pins, *num_output_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */ 00402 int num_input_pb_graph_node_sets, num_output_pb_graph_node_sets; 00403 t_pb_graph_pin *** input_pb_graph_node_pins, ***output_pb_graph_node_pins; 00404 for(i = 0; i < mode->num_interconnect; i++) { 00405 /* determine the interconnect input and output pins */ 00406 input_pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(pb_graph_parent_node, 00407 pb_graph_children_nodes, 00408 mode->interconnect[i].input_string, 00409 &num_input_pb_graph_node_pins, 00410 &num_input_pb_graph_node_sets, 00411 TRUE, 00412 TRUE); 00413 00414 output_pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(pb_graph_parent_node, 00415 pb_graph_children_nodes, 00416 mode->interconnect[i].output_string, 00417 &num_output_pb_graph_node_pins, 00418 &num_output_pb_graph_node_sets, 00419 FALSE, 00420 TRUE); 00421 00422 /* process the interconnect based on its type */ 00423 switch ( mode->interconnect[i].type ) { 00424 00425 case COMPLETE_INTERC: 00426 alloc_and_load_complete_interc_edges(&mode->interconnect[i], 00427 input_pb_graph_node_pins, 00428 num_input_pb_graph_node_sets, 00429 num_input_pb_graph_node_pins, 00430 output_pb_graph_node_pins, 00431 num_output_pb_graph_node_sets, 00432 num_output_pb_graph_node_pins); 00433 00434 break; 00435 00436 case DIRECT_INTERC: 00437 alloc_and_load_direct_interc_edges(&mode->interconnect[i], 00438 input_pb_graph_node_pins, 00439 num_input_pb_graph_node_sets, 00440 num_input_pb_graph_node_pins, 00441 output_pb_graph_node_pins, 00442 num_output_pb_graph_node_sets, 00443 num_output_pb_graph_node_pins); 00444 break; 00445 00446 case MUX_INTERC: 00447 alloc_and_load_mux_interc_edges(&mode->interconnect[i], 00448 input_pb_graph_node_pins, 00449 num_input_pb_graph_node_sets, 00450 num_input_pb_graph_node_pins, 00451 output_pb_graph_node_pins, 00452 num_output_pb_graph_node_sets, 00453 num_output_pb_graph_node_pins); 00454 00455 break; 00456 00457 default : 00458 printf(ERRTAG "Unknown interconnect %d for mode %s in pb_type %s\n", mode->interconnect[i].type, 00459 mode->name, pb_graph_parent_node->pb_type->name); 00460 printf("\tinput %s output %s\n", mode->interconnect[i].input_string, mode->interconnect[i].output_string); 00461 exit(1); 00462 } 00463 for(j = 0; j < num_input_pb_graph_node_sets; j++) { 00464 free(input_pb_graph_node_pins[j]); 00465 } 00466 free(input_pb_graph_node_pins); 00467 for(j = 0; j < num_output_pb_graph_node_sets; j++) { 00468 free(output_pb_graph_node_pins[j]); 00469 } 00470 free(output_pb_graph_node_pins); 00471 free(num_input_pb_graph_node_pins); 00472 free(num_output_pb_graph_node_pins); 00473 } 00474 } 00475 00476 /** 00477 * creates an array of pointers to the pb graph node pins in order from the port string 00478 * @returns t_pb_graph_pin ptr indexed by [0..num_sets_in_port - 1][0..num_ptrs - 1] 00479 */ 00480 t_pb_graph_pin *** alloc_and_load_port_pin_ptrs_from_string(INP const t_pb_graph_node *pb_graph_parent_node, 00481 INP t_pb_graph_node **pb_graph_children_nodes, 00482 INP const char * port_string, 00483 OUTP int ** num_ptrs, 00484 OUTP int * num_sets, 00485 INP boolean is_input_to_interc, 00486 INP boolean interconnect_error_check) { 00487 t_token * tokens; 00488 int num_tokens, curr_set; 00489 int i; 00490 boolean in_squig_bracket, success; 00491 00492 t_pb_graph_pin ***pb_graph_pins; 00493 00494 num_tokens = 0; 00495 tokens = GetTokensFromString(port_string, &num_tokens); 00496 *num_sets = 0; 00497 in_squig_bracket = FALSE; 00498 00499 /* count the number of sets available */ 00500 for(i = 0; i < num_tokens; i++) { 00501 assert(tokens[i].type != TOKEN_NULL); 00502 if(tokens[i].type == TOKEN_OPEN_SQUIG_BRACKET) { 00503 if(in_squig_bracket) { 00504 printf(ERRTAG "{ inside { in port %s\n", port_string); 00505 exit(1); 00506 } 00507 in_squig_bracket = TRUE; 00508 } else if(tokens[i].type == TOKEN_CLOSE_SQUIG_BRACKET) { 00509 if(!in_squig_bracket) { 00510 (*num_sets)++; 00511 printf(ERRTAG "No matching '{' for '}' in port %s\n", port_string); 00512 exit(1); 00513 } 00514 in_squig_bracket = FALSE; 00515 } else if(tokens[i].type == TOKEN_DOT) { 00516 if(!in_squig_bracket) { 00517 (*num_sets)++; 00518 } 00519 } 00520 } 00521 00522 if(in_squig_bracket) { 00523 (*num_sets)++; 00524 printf(ERRTAG "No matching '{' for '}' in port %s\n", port_string); 00525 exit(1); 00526 } 00527 00528 pb_graph_pins = my_calloc(*num_sets, sizeof(t_pb_graph_pin**)); 00529 *num_ptrs = my_calloc(*num_sets, sizeof(int)); 00530 00531 00532 curr_set = 0; 00533 for(i = 0; i < num_tokens; i++) { 00534 assert(tokens[i].type != TOKEN_NULL); 00535 if(tokens[i].type == TOKEN_OPEN_SQUIG_BRACKET) { 00536 if(in_squig_bracket) { 00537 printf(ERRTAG "{ inside { in port %s\n", port_string); 00538 exit(1); 00539 } 00540 in_squig_bracket = TRUE; 00541 } else if(tokens[i].type == TOKEN_CLOSE_SQUIG_BRACKET) { 00542 if((*num_ptrs)[curr_set] == 0) { 00543 printf(ERRTAG "No data contained in {} in port %s\n", port_string); 00544 exit(1); 00545 } 00546 if(!in_squig_bracket) { 00547 curr_set++; 00548 printf(ERRTAG "No matching '{' for '}' in port %s\n", port_string); 00549 exit(1); 00550 } 00551 in_squig_bracket = FALSE; 00552 } else if(tokens[i].type == TOKEN_STRING) { 00553 00554 success = realloc_and_load_pb_graph_pin_ptrs_at_var(pb_graph_parent_node, 00555 pb_graph_children_nodes, 00556 interconnect_error_check, 00557 is_input_to_interc, 00558 tokens, 00559 &i, 00560 &((*num_ptrs)[curr_set]), 00561 &pb_graph_pins[curr_set]); 00562 00563 if(!success) { 00564 printf(ERRTAG "syntax error processing port string %s\n", port_string); 00565 exit(1); 00566 } 00567 00568 if(!in_squig_bracket) { 00569 curr_set++; 00570 } 00571 } 00572 } 00573 assert(curr_set == *num_sets); 00574 freeTokens(tokens, num_tokens); 00575 return pb_graph_pins; 00576 } 00577 00578 /** 00579 * Creates edges to connect all input pins to output pins 00580 */ 00581 static void alloc_and_load_complete_interc_edges(INP t_interconnect *interconnect, 00582 INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs, 00583 INP int num_input_sets, 00584 INP int *num_input_ptrs, 00585 INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs, 00586 INP int num_output_sets, 00587 INP int *num_output_ptrs) { 00588 int i_inset, i_outset, i_inpin, i_outpin; 00589 int in_count, out_count; 00590 t_pb_graph_edge *edges; 00591 int i_edge; 00592 struct s_linked_vptr *cur; 00593 00594 00595 /* Allocate memory for edges, and reallocate more memory for pins connecting to those edges */ 00596 in_count = out_count = 0; 00597 00598 for(i_inset = 0; i_inset < num_input_sets; i_inset++) { 00599 in_count += num_input_ptrs[i_inset]; 00600 } 00601 for(i_outset = 0; i_outset < num_output_sets; i_outset++) { 00602 out_count += num_output_ptrs[i_outset]; 00603 } 00604 00605 edges = my_calloc(in_count * out_count, sizeof(t_pb_graph_edge)); 00606 cur = my_malloc(sizeof(struct s_linked_vptr)); 00607 cur->next = edges_head; 00608 edges_head = cur; 00609 cur->data_vptr = (void *)edges; 00610 cur = my_malloc(sizeof(struct s_linked_vptr)); 00611 cur->next = num_edges_head; 00612 num_edges_head = cur; 00613 cur->data_vptr = (void *)((long)in_count * out_count); 00614 00615 00616 for(i_inset = 0; i_inset < num_input_sets; i_inset++) { 00617 for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) { 00618 input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges = my_realloc(input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges, 00619 (input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges + out_count) * sizeof(t_pb_graph_edge *)); 00620 } 00621 } 00622 00623 for(i_outset = 0; i_outset < num_output_sets; i_outset++) { 00624 for(i_outpin = 0; i_outpin < num_output_ptrs[i_outset]; i_outpin++) { 00625 output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges = my_realloc(output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges, 00626 (output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges + in_count) * sizeof(t_pb_graph_edge *)); 00627 } 00628 } 00629 00630 i_edge = 0; 00631 00632 /* Load connections between pins and record these updates in the edges */ 00633 for(i_inset = 0; i_inset < num_input_sets; i_inset++) { 00634 for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) { 00635 for(i_outset = 0; i_outset < num_output_sets; i_outset++) { 00636 for(i_outpin = 0; i_outpin < num_output_ptrs[i_outset]; i_outpin++) { 00637 00638 input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges[input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges] = &edges[i_edge]; 00639 input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges++; 00640 output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges[output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges] = &edges[i_edge]; 00641 output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges++; 00642 00643 edges[i_edge].num_input_pins = 1; 00644 edges[i_edge].input_pins = my_malloc(sizeof(t_pb_graph_pin *)); 00645 edges[i_edge].input_pins[0] = input_pb_graph_node_pin_ptrs[i_inset][i_inpin]; 00646 edges[i_edge].num_output_pins = 1; 00647 edges[i_edge].output_pins = my_malloc(sizeof(t_pb_graph_pin *)); 00648 edges[i_edge].output_pins[0] = output_pb_graph_node_pin_ptrs[i_outset][i_outpin]; 00649 00650 edges[i_edge].interconnect = interconnect; 00651 edges[i_edge].driver_set = i_inset; 00652 edges[i_edge].driver_pin = i_inpin; 00653 00654 i_edge++; 00655 } 00656 } 00657 } 00658 } 00659 assert(i_edge == in_count * out_count); 00660 } 00661 00662 static void alloc_and_load_direct_interc_edges( INP t_interconnect *interconnect, 00663 INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs, 00664 INP int num_input_sets, 00665 INP int *num_input_ptrs, 00666 INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs, 00667 INP int num_output_sets, 00668 INP int *num_output_ptrs) { 00669 00670 int i; 00671 t_pb_graph_edge *edges; 00672 struct s_linked_vptr *cur; 00673 00674 /* Allocate memory for edges */ 00675 assert(num_input_sets == 1 && num_output_sets == 1); 00676 if(num_input_ptrs[0] != num_output_ptrs[0]) { 00677 printf("input ptrs %d output ptrs %d input pin %s output pin %s input_pb_type %s output_pb_type %s\n", 00678 num_input_ptrs[0], num_output_ptrs[0], input_pb_graph_node_pin_ptrs[0][0]->port->name, output_pb_graph_node_pin_ptrs[0][0]->port->name, 00679 input_pb_graph_node_pin_ptrs[0][0]->parent_node->pb_type->name, output_pb_graph_node_pin_ptrs[0][0]->parent_node->pb_type->name); 00680 } 00681 assert(num_input_ptrs[0] == num_output_ptrs[0]); 00682 00683 edges = my_calloc(num_input_ptrs[0], sizeof(t_pb_graph_edge)); 00684 cur = my_malloc(sizeof(struct s_linked_vptr)); 00685 cur->next = edges_head; 00686 edges_head = cur; 00687 cur->data_vptr = (void *)edges; 00688 cur = my_malloc(sizeof(struct s_linked_vptr)); 00689 cur->next = num_edges_head; 00690 num_edges_head = cur; 00691 cur->data_vptr = (void *)((long)num_input_ptrs[0]); 00692 00693 00694 /* Reallocate memory for pins and load connections between pins and record these updates in the edges */ 00695 for(i = 0; i < num_input_ptrs[0]; i++) { 00696 input_pb_graph_node_pin_ptrs[0][i]->output_edges = my_realloc( 00697 input_pb_graph_node_pin_ptrs[0][i]->output_edges, (input_pb_graph_node_pin_ptrs[0][i]->num_output_edges + 1) * sizeof(t_pb_graph_edge *)); 00698 input_pb_graph_node_pin_ptrs[0][i]->output_edges[input_pb_graph_node_pin_ptrs[0][i]->num_output_edges] = &edges[i]; 00699 input_pb_graph_node_pin_ptrs[0][i]->num_output_edges++; 00700 00701 output_pb_graph_node_pin_ptrs[0][i]->input_edges = my_realloc( 00702 output_pb_graph_node_pin_ptrs[0][i]->input_edges, (output_pb_graph_node_pin_ptrs[0][i]->num_input_edges + 1) * sizeof(t_pb_graph_edge *)); 00703 output_pb_graph_node_pin_ptrs[0][i]->input_edges[output_pb_graph_node_pin_ptrs[0][i]->num_input_edges] = &edges[i]; 00704 output_pb_graph_node_pin_ptrs[0][i]->num_input_edges++; 00705 00706 edges[i].num_input_pins = 1; 00707 edges[i].input_pins = my_malloc(sizeof(t_pb_graph_pin *)); 00708 edges[i].input_pins[0] = input_pb_graph_node_pin_ptrs[0][i]; 00709 edges[i].num_output_pins = 1; 00710 edges[i].output_pins = my_malloc(sizeof(t_pb_graph_pin *)); 00711 edges[i].output_pins[0] = output_pb_graph_node_pin_ptrs[0][i]; 00712 00713 edges[i].interconnect = interconnect; 00714 edges[i].driver_set = 0; 00715 edges[i].driver_pin = i; 00716 } 00717 } 00718 00719 static void alloc_and_load_mux_interc_edges( INP t_interconnect * interconnect, 00720 INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs, 00721 INP int num_input_sets, 00722 INP int *num_input_ptrs, 00723 INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs, 00724 INP int num_output_sets, 00725 INP int *num_output_ptrs) { 00726 int i_inset, i_inpin, i_outpin; 00727 t_pb_graph_edge *edges; 00728 struct s_linked_vptr *cur; 00729 00730 /* Allocate memory for edges, and reallocate more memory for pins connecting to those edges */ 00731 assert(num_output_sets == 1); 00732 00733 edges = my_calloc(num_input_sets, sizeof(t_pb_graph_edge)); 00734 cur = my_malloc(sizeof(struct s_linked_vptr)); 00735 cur->next = edges_head; 00736 edges_head = cur; 00737 cur->data_vptr = (void *)edges; 00738 cur = my_malloc(sizeof(struct s_linked_vptr)); 00739 cur->next = num_edges_head; 00740 num_edges_head = cur; 00741 cur->data_vptr = (void *)((long)num_input_sets); 00742 00743 00744 for(i_inset = 0; i_inset < num_input_sets; i_inset++) { 00745 for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) { 00746 input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges = my_realloc(input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges, 00747 (input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges + 1) * sizeof(t_pb_graph_edge *)); 00748 } 00749 } 00750 00751 for(i_outpin = 0; i_outpin < num_output_ptrs[0]; i_outpin++) { 00752 output_pb_graph_node_pin_ptrs[0][i_outpin]->input_edges = my_realloc(output_pb_graph_node_pin_ptrs[0][i_outpin]->input_edges, 00753 (output_pb_graph_node_pin_ptrs[0][i_outpin]->num_input_edges + num_input_sets) * sizeof(t_pb_graph_edge *)); 00754 } 00755 00756 /* Load connections between pins and record these updates in the edges */ 00757 for(i_inset = 0; i_inset < num_input_sets; i_inset++) { 00758 assert(num_output_ptrs[0] == num_input_ptrs[i_inset]); 00759 edges[i_inset].input_pins = my_calloc(num_output_ptrs[0], sizeof(t_pb_graph_pin *)); 00760 edges[i_inset].output_pins = my_calloc(num_output_ptrs[0], sizeof(t_pb_graph_pin *)); 00761 edges[i_inset].num_input_pins = num_output_ptrs[0]; 00762 edges[i_inset].num_output_pins = num_output_ptrs[0]; 00763 for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) { 00764 input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges[input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges] = &edges[i_inset]; 00765 input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges++; 00766 output_pb_graph_node_pin_ptrs[0][i_inpin]->input_edges[output_pb_graph_node_pin_ptrs[0][i_inpin]->num_input_edges] = &edges[i_inset]; 00767 output_pb_graph_node_pin_ptrs[0][i_inpin]->num_input_edges++; 00768 00769 edges[i_inset].input_pins[i_inpin] = input_pb_graph_node_pin_ptrs[i_inset][i_inpin]; 00770 edges[i_inset].output_pins[i_inpin] = output_pb_graph_node_pin_ptrs[0][i_inpin]; 00771 00772 assert(i_inpin == 0); /* current does not support bus-based routing, TODO: Support bus based routing */ 00773 edges[i_inset].interconnect = interconnect; 00774 edges[i_inset].driver_set = i_inset; 00775 edges[i_inset].driver_pin = i_inpin; 00776 } 00777 } 00778 } 00779 00780 00781 /** 00782 * populate array of pb graph pins for a single variable of type pb_type[int:int].port[int:int] 00783 * @param pb_graph_pins: pointer to array from [0..num_port_pins] of pb_graph_pin pointers 00784 * @param tokens: array of tokens to scan 00785 * @param num_pins: current number of pins in pb_graph_pin array 00786 */ 00787 static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP const t_pb_graph_node *pb_graph_parent_node, 00788 INP t_pb_graph_node **pb_graph_children_nodes, 00789 INP boolean interconnect_error_check, 00790 INP boolean is_input_to_interc, 00791 INP const t_token *tokens, 00792 INOUTP int *token_index, 00793 INOUTP int *num_pins, 00794 OUTP t_pb_graph_pin ***pb_graph_pins) { 00795 00796 int i, j, ipin, ipb; 00797 int pb_msb, pb_lsb; 00798 int pin_msb, pin_lsb; 00799 const t_pb_graph_node *pb_node_array; 00800 char *port_name; 00801 t_port *iport; 00802 int add_or_subtract_pb, add_or_subtract_pin; 00803 boolean found; 00804 t_mode *mode = NULL; 00805 00806 assert(tokens[*token_index].type == TOKEN_STRING); 00807 pb_node_array = NULL; 00808 00809 00810 if(pb_graph_children_nodes) 00811 mode = pb_graph_children_nodes[0][0].pb_type->parent_mode; 00812 00813 pb_msb = pb_lsb = OPEN; 00814 pin_msb = pin_lsb = OPEN; 00815 00816 /* parse pb */ 00817 found = FALSE; 00818 if(0 == strcmp(pb_graph_parent_node->pb_type->name, tokens[*token_index].data)) { 00819 pb_node_array = pb_graph_parent_node; 00820 pb_msb = pb_lsb = 0; 00821 found = TRUE; 00822 (*token_index)++; 00823 if(tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) { 00824 (*token_index)++; 00825 if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; } 00826 pb_msb = my_atoi(tokens[*token_index].data); 00827 (*token_index)++; 00828 if(!checkTokenType(tokens[*token_index], TOKEN_COLON)) { 00829 if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { 00830 return FALSE; 00831 } 00832 pb_lsb = pb_msb; 00833 (*token_index)++; 00834 } else { 00835 (*token_index)++; 00836 if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; } 00837 pb_lsb= my_atoi(tokens[*token_index].data); 00838 (*token_index)++; 00839 if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { return FALSE; } 00840 (*token_index)++; 00841 } 00842 /* Check to make sure indices from user match internal data structures for the indices of the parent */ 00843 if((pb_lsb != pb_msb) && (pb_lsb != pb_graph_parent_node->placement_index)) { 00844 printf(ERRTAG "Incorrect placement index for %s, expected index %d\n", 00845 tokens[0].data, pb_graph_parent_node->placement_index); 00846 return FALSE; 00847 } 00848 pb_lsb = pb_msb = 0; /* Internal representation of parent is always 0 */ 00849 } 00850 } else { 00851 if(mode == NULL) { 00852 printf(ERRTAG "pb_graph_parent_node %s failed\n", pb_graph_parent_node->pb_type->name); 00853 } 00854 assert(mode); 00855 for(i = 0; i < mode->num_pb_type_children; i++) { 00856 assert(&mode->pb_type_children[i] == pb_graph_children_nodes[i][0].pb_type); 00857 if(0 == strcmp(mode->pb_type_children[i].name, tokens[*token_index].data)) { 00858 pb_node_array = pb_graph_children_nodes[i]; 00859 found = TRUE; 00860 (*token_index)++; 00861 00862 if(tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) { 00863 (*token_index)++; 00864 if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; } 00865 pb_msb = my_atoi(tokens[*token_index].data); 00866 (*token_index)++; 00867 if(!checkTokenType(tokens[*token_index], TOKEN_COLON)) { 00868 if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { 00869 return FALSE; 00870 } 00871 pb_lsb = pb_msb; 00872 (*token_index)++; 00873 } else { 00874 (*token_index)++; 00875 if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; } 00876 pb_lsb= my_atoi(tokens[*token_index].data); 00877 (*token_index)++; 00878 if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { return FALSE; } 00879 (*token_index)++; 00880 } 00881 } else { 00882 pb_msb = pb_node_array[0].pb_type->num_pb - 1; 00883 pb_lsb = 0; 00884 } 00885 break; 00886 } 00887 } 00888 } 00889 00890 if(!found) { 00891 printf(ERRTAG "Unknown pb_type name %s, not defined in namespace of mode %s\n", tokens[*token_index].data, mode->name); 00892 return FALSE; 00893 } 00894 00895 found = FALSE; 00896 00897 if(!checkTokenType(tokens[*token_index], TOKEN_DOT)) { return FALSE; } 00898 (*token_index)++; 00899 if(!checkTokenType(tokens[*token_index], TOKEN_STRING)) { return FALSE; } 00900 00901 /* parse ports and port pins of pb */ 00902 port_name = tokens[*token_index].data; 00903 00904 (*token_index)++; 00905 if(tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) { 00906 (*token_index)++; 00907 if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; } 00908 pin_msb = my_atoi(tokens[*token_index].data); 00909 (*token_index)++; 00910 if(!checkTokenType(tokens[*token_index], TOKEN_COLON)) { 00911 if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { 00912 return FALSE; 00913 } 00914 pin_lsb = pin_msb; 00915 (*token_index)++; 00916 } else { 00917 (*token_index)++; 00918 if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; } 00919 pin_lsb= my_atoi(tokens[*token_index].data); 00920 (*token_index)++; 00921 if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { return FALSE; } 00922 (*token_index)++; 00923 } 00924 } else { 00925 if(get_pb_graph_pin_from_name(port_name, &pb_node_array[pb_lsb], 0) == NULL) { 00926 printf("failed to find port name %s\n", port_name); 00927 exit(1); 00928 } 00929 iport = get_pb_graph_pin_from_name(port_name, &pb_node_array[pb_lsb], 0)->port; 00930 pin_msb = iport->num_pins - 1; 00931 pin_lsb = 0; 00932 } 00933 (*token_index)--; 00934 00935 if(pb_msb < pb_lsb) { 00936 add_or_subtract_pb = -1; 00937 } else { 00938 add_or_subtract_pb = 1; 00939 } 00940 00941 if(pin_msb < pin_lsb) { 00942 add_or_subtract_pin = -1; 00943 } else { 00944 add_or_subtract_pin = 1; 00945 } 00946 *num_pins += (abs(pb_msb - pb_lsb) + 1) * (abs(pin_msb - pin_lsb) + 1); 00947 *pb_graph_pins = my_calloc(*num_pins, sizeof(t_pb_graph_pin *)); 00948 i = j = 0; 00949 00950 ipb = pb_lsb; 00951 00952 while(ipb != pb_msb + add_or_subtract_pin) { 00953 ipin = pin_lsb; 00954 j = 0; 00955 while(ipin != pin_msb + add_or_subtract_pin) { 00956 (*pb_graph_pins)[i*(abs(pin_msb - pin_lsb) + 1) + j] = get_pb_graph_pin_from_name(port_name, &pb_node_array[ipb], ipin); 00957 iport = (*pb_graph_pins)[i*(abs(pin_msb - pin_lsb) + 1) + j]->port; 00958 if(!iport) { return FALSE; } 00959 00960 /* Error checking before assignment */ 00961 if(interconnect_error_check) { 00962 if(pb_node_array == pb_graph_parent_node) { 00963 if(is_input_to_interc) { 00964 if(iport->type != IN_PORT) { 00965 printf(ERRTAG "input to interconnect from parent is not an input or clock pin\n"); 00966 return FALSE; 00967 } 00968 } else { 00969 if(iport->type != OUT_PORT) { 00970 printf(ERRTAG "output from interconnect from parent is not an input or clock pin\n"); 00971 return FALSE; 00972 } 00973 } 00974 } else { 00975 if(is_input_to_interc) { 00976 if(iport->type != OUT_PORT) { 00977 printf(ERRTAG "output from interconnect from parent is not an input or clock pin\n"); 00978 return FALSE; 00979 } 00980 } else { 00981 if(iport->type != IN_PORT) { 00982 printf(ERRTAG "input to interconnect from parent is not an input or clock pin\n"); 00983 return FALSE; 00984 } 00985 } 00986 } 00987 } 00988 00989 00990 /* load pb_graph_pin for pin */ 00991 00992 ipin += add_or_subtract_pin; 00993 j++; 00994 } 00995 i++; 00996 ipb += add_or_subtract_pb; 00997 } 00998 00999 assert((abs(pb_msb - pb_lsb) + 1) * (abs(pin_msb - pin_lsb) + 1) == i * j); 01000 01001 return TRUE; 01002 } 01003 01004 static t_pb_graph_pin * get_pb_graph_pin_from_name(INP const char * port_name, INP const t_pb_graph_node * pb, INP int pin) { 01005 int i; 01006 01007 for(i = 0; i < pb->num_input_ports; i++) { 01008 if(0 == strcmp(port_name, pb->input_pins[i][0].port->name)) { 01009 if(pin < pb->input_pins[i][0].port->num_pins) { 01010 return &pb->input_pins[i][pin]; 01011 } else { 01012 return NULL; 01013 } 01014 } 01015 } 01016 for(i = 0; i < pb->num_output_ports; i++) { 01017 if(0 == strcmp(port_name, pb->output_pins[i][0].port->name)) { 01018 if(pin < pb->output_pins[i][0].port->num_pins) { 01019 return &pb->output_pins[i][pin]; 01020 } else { 01021 return NULL; 01022 } 01023 } 01024 } 01025 for(i = 0; i < pb->num_clock_ports; i++) { 01026 if(0 == strcmp(port_name, pb->clock_pins[i][0].port->name)) { 01027 if(pin < pb->clock_pins[i][0].port->num_pins) { 01028 return &pb->clock_pins[i][pin]; 01029 } else { 01030 return NULL; 01031 } 01032 } 01033 } 01034 return NULL; 01035 } 01036 01037 static void alloc_and_load_pin_locations_from_pb_graph(t_type_descriptor *type) { 01038 int i, j, k, m, icapacity; 01039 int num_sides; 01040 int side_index; 01041 int pin_num; 01042 int count; 01043 01044 int *num_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */ 01045 int num_pb_graph_node_sets; 01046 t_pb_graph_pin*** pb_graph_node_pins; 01047 01048 num_sides = 2 * (type->height + 1); 01049 side_index = 0; 01050 count = 0; 01051 01052 if(type->pin_location_distribution == E_SPREAD_PIN_DISTR) { 01053 pin_num = 0; 01054 /* evenly distribute pins starting at bottom left corner */ 01055 for(j = 0; j < 4; j++) { 01056 for(i = 0; i < type->height; i++) { 01057 if(j == TOP && i != type->height - 1) { 01058 continue; 01059 } 01060 if(j == BOTTOM && i != 0) { 01061 continue; 01062 } 01063 for(k = 0; k < (type->num_pins / num_sides) + 1; k++) { 01064 pin_num = side_index + k * num_sides; 01065 if(pin_num < type->num_pins) { 01066 type->pinloc[i][j][pin_num] = 1; 01067 type->pin_height[pin_num] = i; 01068 count++; 01069 } 01070 } 01071 side_index++; 01072 } 01073 } 01074 assert(side_index == num_sides); 01075 assert(count == type->num_pins); 01076 } else { 01077 assert(type->pin_location_distribution == E_CUSTOM_PIN_DISTR); 01078 for(i = 0; i < type->height; i++) { 01079 for(j = 0; j < 4; j++) { 01080 if(j == TOP && i != type->height - 1) { 01081 continue; 01082 } 01083 if(j == BOTTOM && i != 0) { 01084 continue; 01085 } 01086 for(k = 0; k < type->num_pin_loc_assignments[i][j]; k++) { 01087 pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(type->pb_graph_head, 01088 type->pb_graph_head->child_pb_graph_nodes[0], 01089 type->pin_loc_assignments[i][j][k], 01090 &num_pb_graph_node_pins, 01091 &num_pb_graph_node_sets, 01092 FALSE, 01093 FALSE); 01094 assert(num_pb_graph_node_sets == 1); 01095 01096 01097 for(m = 0; m < num_pb_graph_node_pins[0]; m++) { 01098 pin_num = pb_graph_node_pins[0][m]->pin_count_in_cluster; 01099 assert(pin_num < type->num_pins / type->capacity); 01100 for(icapacity = 0; icapacity < type->capacity; icapacity++) { 01101 type->pinloc[i][j][pin_num + icapacity * type->num_pins / type->capacity] = 1; 01102 type->pin_height[pin_num] = i; 01103 assert(count < type->num_pins); 01104 } 01105 } 01106 free(pb_graph_node_pins[0]); 01107 free(pb_graph_node_pins); 01108 free(num_pb_graph_node_pins); 01109 } 01110 } 01111 } 01112 } 01113 } 01114 01115 static void echo_pb_rec(const INP t_pb_graph_node *pb_graph_node, INP int level, INP FILE *fp) { 01116 int i, j, k; 01117 01118 print_tabs(fp, level); 01119 fprintf(fp, "Physical Block: type \"%s\" index %d num_children %d\n", 01120 pb_graph_node->pb_type->name, pb_graph_node->placement_index, pb_graph_node->pb_type->num_pb); 01121 01122 if(pb_graph_node->parent_pb_graph_node) { 01123 print_tabs(fp, level + 1); 01124 fprintf(fp, "Parent Block: type \"%s\" index %d \n", pb_graph_node->parent_pb_graph_node->pb_type->name, 01125 pb_graph_node->parent_pb_graph_node->placement_index); 01126 } 01127 01128 print_tabs(fp, level); 01129 fprintf(fp, "Input Ports: total ports %d\n", pb_graph_node->num_input_ports); 01130 echo_pb_pins(pb_graph_node->input_pins, pb_graph_node->num_input_ports, level, fp); 01131 print_tabs(fp, level); 01132 fprintf(fp, "Output Ports: total ports %d\n", pb_graph_node->num_output_ports); 01133 echo_pb_pins(pb_graph_node->output_pins, pb_graph_node->num_output_ports, level, fp); 01134 print_tabs(fp, level); 01135 fprintf(fp, "Clock Ports: total ports %d\n", pb_graph_node->num_clock_ports); 01136 echo_pb_pins(pb_graph_node->clock_pins, pb_graph_node->num_clock_ports, level, fp); 01137 if(pb_graph_node->pb_type->num_modes > 0) { 01138 print_tabs(fp, level); 01139 fprintf(fp, "Children:\n"); 01140 } 01141 for(i = 0; i < pb_graph_node->pb_type->num_modes; i++) { 01142 for(j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children; j++) { 01143 for(k = 0; k < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb; k++) { 01144 echo_pb_rec(&pb_graph_node->child_pb_graph_nodes[i][j][k], level + 1, fp); 01145 } 01146 } 01147 } 01148 } 01149 01150 static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports, INP int level, INP FILE * fp) { 01151 int i, j, k, m; 01152 t_port *port; 01153 01154 print_tabs(fp, level); 01155 01156 for(i = 0; i < num_ports; i++) { 01157 port = pb_graph_pins[i][0].port; 01158 print_tabs(fp, level); 01159 fprintf(fp, "Port \"%s\": num_pins %d type %d parent name \"%s\"\n", 01160 port->name, port->num_pins, port->type, port->parent_pb_type->name); 01161 01162 for(j = 0; j < port->num_pins; j++) { 01163 print_tabs(fp, level + 1); 01164 assert(j == pb_graph_pins[i][j].pin_number); 01165 assert(pb_graph_pins[i][j].port == port); 01166 fprintf(fp, "Pin %d port name \"%s\" num input edges %d num output edges %d parent type \"%s\" parent index %d\n", 01167 pb_graph_pins[i][j].pin_number, pb_graph_pins[i][j].port->name, pb_graph_pins[i][j].num_input_edges, pb_graph_pins[i][j].num_output_edges, 01168 pb_graph_pins[i][j].parent_node->pb_type->name, pb_graph_pins[i][j].parent_node->placement_index); 01169 for(k = 0; k < pb_graph_pins[i][j].num_input_edges; k++) { 01170 print_tabs(fp, level + 2); 01171 fprintf(fp, "Input edge %d num inputs %d num outputs %d\n", 01172 k, pb_graph_pins[i][j].input_edges[k]->num_input_pins, pb_graph_pins[i][j].input_edges[k]->num_output_pins); 01173 print_tabs(fp, level + 3); 01174 fprintf(fp, "Input edge inputs\n"); 01175 for(m = 0; m < pb_graph_pins[i][j].input_edges[k]->num_input_pins; m++) { 01176 print_tabs(fp, level + 3); 01177 fprintf(fp, "pin number %d port_name \"%s\"\n", 01178 pb_graph_pins[i][j].input_edges[k]->input_pins[m]->pin_number, pb_graph_pins[i][j].input_edges[k]->input_pins[m]->port->name); 01179 } 01180 print_tabs(fp, level + 3); 01181 fprintf(fp, "Input edge outputs\n"); 01182 for(m = 0; m < pb_graph_pins[i][j].input_edges[k]->num_output_pins; m++) { 01183 print_tabs(fp, level + 3); 01184 fprintf(fp, "pin number %d port_name \"%s\" parent type \"%s\" parent index %d\n", 01185 pb_graph_pins[i][j].input_edges[k]->output_pins[m]->pin_number, pb_graph_pins[i][j].input_edges[k]->output_pins[m]->port->name, 01186 pb_graph_pins[i][j].input_edges[k]->output_pins[m]->parent_node->pb_type->name, 01187 pb_graph_pins[i][j].input_edges[k]->output_pins[m]->parent_node->placement_index); 01188 } 01189 } 01190 for(k = 0; k < pb_graph_pins[i][j].num_output_edges; k++) { 01191 print_tabs(fp, level + 2); 01192 fprintf(fp, "Output edge %d num inputs %d num outputs %d\n", 01193 k, pb_graph_pins[i][j].output_edges[k]->num_input_pins, pb_graph_pins[i][j].output_edges[k]->num_output_pins); 01194 print_tabs(fp, level + 3); 01195 fprintf(fp, "Output edge inputs\n"); 01196 for(m = 0; m < pb_graph_pins[i][j].output_edges[k]->num_input_pins; m++) { 01197 print_tabs(fp, level + 3); 01198 fprintf(fp, "pin number %d port_name \"%s\"\n", 01199 pb_graph_pins[i][j].output_edges[k]->input_pins[m]->pin_number, pb_graph_pins[i][j].output_edges[k]->input_pins[m]->port->name); 01200 } 01201 print_tabs(fp, level + 3); 01202 fprintf(fp, "Output edge outputs\n"); 01203 for(m = 0; m < pb_graph_pins[i][j].output_edges[k]->num_output_pins; m++) { 01204 print_tabs(fp, level + 3); 01205 fprintf(fp, "pin number %d port_name \"%s\" parent type \"%s\" parent index %d\n", 01206 pb_graph_pins[i][j].output_edges[k]->output_pins[m]->pin_number, pb_graph_pins[i][j].output_edges[k]->output_pins[m]->port->name, 01207 pb_graph_pins[i][j].output_edges[k]->output_pins[m]->parent_node->pb_type->name, 01208 pb_graph_pins[i][j].output_edges[k]->output_pins[m]->parent_node->placement_index); 01209 } 01210 } 01211 } 01212 } 01213 } 01214