#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "hash.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "ReadLine.h"
#include "globals.h"
Go to the source code of this file.
Enumerations | |
enum | special_blk { NORMAL = 0, INPAD, OUTPAD } |
Functions | |
static t_type_ptr | get_type_by_name (IN const char *name, IN int num_types, IN const struct s_type_descriptor block_types[], IN t_type_ptr IO_type, IN const char *net_file, IN int line, OUT enum special_blk *overide) |
void | read_netlist (IN const char *net_file, IN int num_types, IN const struct s_type_descriptor block_types[], IN t_type_ptr IO_type, IN int io_ipin, IN int io_opin, OUT t_subblock_data *subblock_data_ptr, OUT int *num_blocks, OUT struct s_block *block_list[], OUT int *num_nets, OUT struct s_net *net_list[]) |
Variables | |
static char * | pinlist_str = "pinlist:" |
enum special_blk |
Definition at line 13 of file read_netlist.c.
static t_type_ptr get_type_by_name | ( | IN const char * | name, | |
IN int | num_types, | |||
IN const struct s_type_descriptor | block_types[], | |||
IN t_type_ptr | IO_type, | |||
IN const char * | net_file, | |||
IN int | line, | |||
OUT enum special_blk * | overide | |||
) | [static] |
Definition at line 464 of file read_netlist.c.
00471 { 00472 00473 /* Just does a simple linear search for now */ 00474 int i; 00475 00476 /* pin_overide is used to specify that the .input and .output 00477 * blocks only have one pin specified and should be treated 00478 * as if used as a .io with a full pin spec */ 00479 *overide = NORMAL; 00480 00481 /* .input and .output are special names that map to the basic IO type */ 00482 if(0 == strcmp(".input", name)) 00483 { 00484 *overide = INPAD; 00485 return IO_type; 00486 } 00487 if(0 == strcmp(".output", name)) 00488 { 00489 *overide = OUTPAD; 00490 return IO_type; 00491 } 00492 00493 /* Linear type search. Don't really expect to have too many 00494 * types for it to be a problem */ 00495 for(i = 0; i < num_types; ++i) 00496 { 00497 if(0 == strcmp(block_types[i].name, name)) 00498 { 00499 return (block_types + i); 00500 } 00501 } 00502 00503 /* No type matched */ 00504 printf(ERRTAG "'%s':%d - Invalid block type '%s'\n", 00505 net_file, line, name); 00506 exit(1); 00507 }
void read_netlist | ( | IN const char * | net_file, | |
IN int | num_types, | |||
IN const struct s_type_descriptor | block_types[], | |||
IN t_type_ptr | IO_type, | |||
IN int | io_ipin, | |||
IN int | io_opin, | |||
OUT t_subblock_data * | subblock_data_ptr, | |||
OUT int * | num_blocks, | |||
OUT struct s_block * | block_list[], | |||
OUT int * | num_nets, | |||
OUT struct s_net * | net_list[] | |||
) |
Definition at line 29 of file read_netlist.c.
00040 { 00041 00042 FILE *infile; 00043 int bcount; 00044 struct s_block *blist; 00045 int ncount; 00046 struct s_net *nlist; 00047 00048 int i, j, k, l, m; 00049 enum 00050 { COUNT, LOAD, MAP, STOP } 00051 pass; 00052 int line, prev_line; 00053 enum special_blk overide; 00054 char **block_tokens; 00055 char **pin_tokens; 00056 char **tokens; 00057 t_subblock **slist = NULL; 00058 int *scount = NULL; 00059 t_type_ptr type = NULL; 00060 00061 00062 infile = my_fopen(net_file, "r"); 00063 bcount = 0; 00064 blist = NULL; 00065 ncount = 0; 00066 nlist = NULL; 00067 memset(subblock_data_ptr, 0, sizeof(t_subblock_data)); 00068 00069 /* Multi-pass load 00070 * COUNT 00071 * -> count blocks 00072 * -> count nets 00073 * 00074 * LOAD 00075 * -> alloc num_subblocks_per_block list 00076 * -> allocate s_block list at start 00077 * -> allocate s_net list at start 00078 * -> count subblocks per block 00079 * -> sets block names 00080 * -> sets block types 00081 * -> allocs block net lists 00082 * -> sets net names 00083 * 00084 * MAP 00085 * -> fills in s_block:nets list 00086 * -> fills in subblocks */ 00087 00088 for(pass = 0; pass < STOP; ++pass) 00089 { 00090 rewind(infile); 00091 line = 0; 00092 i = 0; 00093 j = 0; 00094 overide = NORMAL; 00095 00096 /* Alloc the lists */ 00097 if(LOAD == pass) 00098 { 00099 blist = 00100 (struct s_block *)my_malloc(sizeof(struct s_block) * 00101 bcount); 00102 memset(blist, 0, (sizeof(struct s_block) * bcount)); 00103 00104 nlist = 00105 (struct s_net *)my_malloc(sizeof(struct s_net) * 00106 ncount); 00107 memset(nlist, 0, (sizeof(struct s_net) * ncount)); 00108 00109 slist = 00110 (t_subblock **) my_malloc(sizeof(t_subblock *) * 00111 bcount); 00112 memset(slist, 0, (sizeof(t_subblock *) * bcount)); 00113 00114 scount = (int *)my_malloc(sizeof(int) * bcount); 00115 memset(scount, 0, (sizeof(int) * bcount)); 00116 } 00117 00118 /* Read file line by line */ 00119 block_tokens = ReadLineTokens(infile, &line); 00120 prev_line = line; 00121 while(block_tokens) 00122 { 00123 00124 /* .global directives have special meaning */ 00125 if(0 == strcmp(block_tokens[0], ".global")) 00126 { 00127 if(MAP == pass) 00128 { 00129 for(l = 0; l < ncount; ++l) 00130 { 00131 if(0 == 00132 strcmp(nlist[l].name, 00133 block_tokens[1])) 00134 { 00135 nlist[l].is_global = TRUE; 00136 break; 00137 } 00138 } 00139 if(l == ncount) 00140 { 00141 printf(ERRTAG 00142 "'%s':%d - '.global' specified an invalid net\n", 00143 net_file, prev_line); 00144 exit(1); 00145 } 00146 } 00147 00148 /* Don't do any more processing on this */ 00149 FreeTokens(&block_tokens); 00150 block_tokens = ReadLineTokens(infile, &line); 00151 prev_line = line; 00152 continue; 00153 } 00154 pin_tokens = ReadLineTokens(infile, &line); 00155 00156 if(CountTokens(block_tokens) != 2) 00157 { 00158 printf(ERRTAG "'%s':%d - block type line should " 00159 "be in form '.type_name block_name'\n", 00160 net_file, prev_line); 00161 exit(1); 00162 } 00163 if(NULL == pin_tokens) 00164 { 00165 printf(ERRTAG 00166 "'%s':%d - blocks must be follow by a 'pinlist:' line\n", 00167 net_file, line); 00168 exit(1); 00169 } 00170 if(0 != strcmp("pinlist:", pin_tokens[0])) 00171 { 00172 printf(ERRTAG 00173 "'%s':%d - 'pinlist:' line must follow " 00174 "block type line\n", net_file, line); 00175 exit(1); 00176 } 00177 00178 type = 00179 get_type_by_name(block_tokens[0], num_types, 00180 block_types, IO_type, net_file, 00181 prev_line, &overide); 00182 /* Check if we are overiding the pinlist format for this block */ 00183 if(overide) 00184 { 00185 if(CountTokens(pin_tokens) != 2) 00186 { /* 'pinlist:' and name */ 00187 printf(ERRTAG 00188 "'%s':%d - pinlist for .input and .output should " 00189 "only have one item.\n", net_file, 00190 line); 00191 exit(1); 00192 } 00193 00194 /* Make a new faked token list with 'pinlist:' and then pin mappings and a null */ 00195 tokens = 00196 (char **)my_malloc(sizeof(char *) * 00197 (type->num_pins + 2)); 00198 00199 l = strlen(pinlist_str) + 1; 00200 k = strlen(pin_tokens[1]) + 1; 00201 tokens[0] = 00202 (char *)my_malloc(sizeof(char) * (k + l)); 00203 memcpy(tokens[0], pinlist_str, l * sizeof(char)); 00204 memcpy(tokens[0] + l, pin_tokens[1], 00205 k * sizeof(char)); 00206 00207 /* Set all other pins to open */ 00208 for(k = 0; k < type->num_pins; ++k) 00209 { 00210 tokens[1 + k] = "open"; /* free wont be called on this so is safe */ 00211 } 00212 tokens[1 + k] = NULL; /* End of token list marker */ 00213 /* Set the one pin with the value given */ 00214 for(k = 0; k < type->num_pins; ++k) 00215 { 00216 switch (overide) 00217 { 00218 case INPAD: 00219 tokens[1 + io_opin] = 00220 (tokens[0] + l); 00221 break; 00222 case OUTPAD: 00223 tokens[1 + io_ipin] = 00224 (tokens[0] + l); 00225 break; 00226 } 00227 } 00228 FreeTokens(&pin_tokens); 00229 pin_tokens = tokens; 00230 tokens = NULL; 00231 } 00232 00233 if(CountTokens(pin_tokens) != (type->num_pins + 1)) 00234 { 00235 printf(ERRTAG 00236 "'%s':%d - 'pinlist:' line has %d pins instead of " 00237 "expect %d pins.\n", net_file, line, 00238 CountTokens(pin_tokens) - 1, 00239 type->num_pins); 00240 exit(1); 00241 } 00242 00243 /* Load block name and type and alloc net list */ 00244 if(LOAD == pass) 00245 { 00246 blist[i].name = my_strdup(block_tokens[1]); 00247 blist[i].type = type; 00248 blist[i].nets = 00249 (int *)my_malloc(sizeof(int) * 00250 type->num_pins); 00251 for(k = 0; k < type->num_pins; ++k) 00252 { 00253 blist[i].nets[k] = OPEN; 00254 } 00255 } 00256 00257 /* Examine pin list to determine nets */ 00258 for(k = 0; k < type->num_pins; ++k) 00259 { 00260 if(0 != strcmp("open", pin_tokens[1 + k])) 00261 { 00262 if(DRIVER == 00263 type->class_inf[type->pin_class[k]]. 00264 type) 00265 { 00266 if(LOAD == pass) 00267 { 00268 nlist[j].name = 00269 my_strdup(pin_tokens 00270 [1 + k]); 00271 } 00272 if(MAP == pass) 00273 { 00274 blist[i].nets[k] = j; /* If we are net source we don't need to search */ 00275 } 00276 00277 ++j; /* This was an active netlist */ 00278 } 00279 else 00280 { 00281 if(MAP == pass) 00282 { 00283 /* Map sinks by doing a linear search to find the net */ 00284 blist[i].nets[k] = OPEN; 00285 for(l = 0; l < ncount; 00286 ++l) 00287 { 00288 if(0 == 00289 strcmp(nlist 00290 [l]. 00291 name, 00292 pin_tokens 00293 [1 + 00294 k])) 00295 { 00296 blist[i]. 00297 nets 00298 [k] = 00299 l; 00300 break; 00301 } 00302 } 00303 if(OPEN == 00304 blist[i].nets[k]) 00305 { 00306 printf(ERRTAG 00307 "'%s':%d - Net '%s' not found\n", 00308 net_file, 00309 line, 00310 pin_tokens 00311 [1 + k]); 00312 exit(1); 00313 } 00314 } 00315 } 00316 } 00317 } 00318 00319 /* Allocating subblocks */ 00320 if(MAP == pass) 00321 { 00322 /* All blocks internally have subblocks but I/O subblocks are 00323 allocated and loaded elsewhere */ 00324 if(scount[i] > 0) { 00325 slist[i] = (t_subblock *) 00326 my_malloc(sizeof(t_subblock) * scount[i]); 00327 for(k = 0; k < scount[i]; ++k) 00328 { 00329 slist[i][k].name = NULL; 00330 slist[i][k].clock = OPEN; 00331 slist[i][k].inputs = 00332 (int *)my_malloc(sizeof(int) * 00333 type-> 00334 max_subblock_inputs); 00335 for(l = 0; l < type->max_subblock_inputs; 00336 ++l) 00337 { 00338 slist[i][k].inputs[l] = OPEN; 00339 } 00340 slist[i][k].outputs = 00341 (int *)my_malloc(sizeof(int) * 00342 type-> 00343 max_subblock_outputs); 00344 for(l = 0; l < type->max_subblock_outputs; 00345 ++l) 00346 { 00347 slist[i][k].outputs[l] = OPEN; 00348 } 00349 } 00350 } 00351 } 00352 00353 /* Ignore subblock data */ 00354 tokens = ReadLineTokens(infile, &line); 00355 prev_line = line; 00356 m = 0; 00357 while(tokens && (0 == strcmp(tokens[0], "subblock:"))) 00358 { 00359 if(CountTokens(tokens) != (type->max_subblock_inputs + type->max_subblock_outputs + 1 + /* clocks */ 00360 2)) 00361 { /* 'subblock:', name */ 00362 printf("subblock wrong pin count, netlist has %d, architecture as %d on line %d \n" , 00363 CountTokens(tokens) - 2, (type->max_subblock_inputs + type->max_subblock_outputs + 1), 00364 line); 00365 exit(1); 00366 } 00367 00368 /* Count subblocks given */ 00369 if(LOAD == pass) 00370 { 00371 scount[i]++; 00372 } 00373 00374 /* Load subblock name */ 00375 if(MAP == pass) 00376 { 00377 assert(i < bcount); 00378 assert(m < scount[i]); 00379 slist[i][m].name = my_strdup(tokens[1]); 00380 for(k = 0; k < type->max_subblock_inputs; 00381 ++k) 00382 { 00383 /* Check prefix and load pin num */ 00384 l = 2 + k; 00385 if(0 == 00386 strncmp("ble_", tokens[l], 4)) 00387 { 00388 slist[i][m].inputs[k] = type->num_pins + my_atoi(tokens[l] + 4); /* Skip the 'ble_' part */ 00389 } 00390 else if(0 != 00391 strcmp("open", tokens[l])) 00392 { 00393 slist[i][m].inputs[k] = 00394 my_atoi(tokens[l]); 00395 } 00396 } 00397 for(k = 0; k < type->max_subblock_outputs; 00398 ++k) 00399 { 00400 l = 2 + 00401 type->max_subblock_inputs + k; 00402 if(0 != strcmp("open", tokens[l])) 00403 { 00404 slist[i][m].outputs[k] = 00405 my_atoi(tokens[l]); 00406 } 00407 } 00408 l = 2 + type->max_subblock_inputs + 00409 type->max_subblock_outputs; 00410 if(0 != strcmp("open", tokens[l])) 00411 { 00412 slist[i][m].clock = 00413 my_atoi(tokens[l]); 00414 } 00415 } 00416 00417 ++m; /* Next subblock */ 00418 00419 FreeTokens(&tokens); 00420 tokens = ReadLineTokens(infile, &line); 00421 prev_line = line; 00422 } 00423 00424 if(pass > COUNT) 00425 { 00426 /* Check num of subblocks read */ 00427 if(scount[i] > type->max_subblocks) 00428 { 00429 printf("too many subblocks on block [%d] %s\n", i, blist[i].name); 00430 exit(1); 00431 } 00432 } 00433 00434 ++i; /* End of this block */ 00435 00436 FreeTokens(&block_tokens); 00437 FreeTokens(&pin_tokens); 00438 block_tokens = tokens; 00439 } 00440 00441 /* Save counts */ 00442 if(COUNT == pass) 00443 { 00444 bcount = i; 00445 ncount = j; 00446 } 00447 } 00448 fclose(infile); 00449 00450 /* Builds mappings from each netlist to the blocks contained */ 00451 sync_nets_to_blocks(bcount, blist, ncount, nlist); 00452 00453 /* Send values back to caller */ 00454 *num_blocks = bcount; 00455 *block_list = blist; 00456 *num_nets = ncount; 00457 *net_list = nlist; 00458 subblock_data_ptr->subblock_inf = slist; 00459 subblock_data_ptr->num_subblocks_per_block = scount; 00460 }
char* pinlist_str = "pinlist:" [static] |
Definition at line 12 of file read_netlist.c.