00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <assert.h>
00004 #include "util.h"
00005 #include "hash.h"
00006 #include "vpr_types.h"
00007 #include "vpr_utils.h"
00008 #include "ReadLine.h"
00009 #include "globals.h"
00010
00011
00012 static char *pinlist_str = "pinlist:";
00013 enum special_blk
00014 { NORMAL = 0, INPAD, OUTPAD };
00015
00016 static t_type_ptr get_type_by_name(IN const char *name,
00017 IN int num_types,
00018 IN const struct s_type_descriptor
00019 block_types[],
00020 IN t_type_ptr IO_type,
00021 IN const char *net_file,
00022 IN int line,
00023 OUT enum special_blk *overide);
00024
00025
00026
00027
00028 void
00029 read_netlist(IN const char *net_file,
00030 IN int num_types,
00031 IN const struct s_type_descriptor block_types[],
00032 IN t_type_ptr IO_type,
00033 IN int io_ipin,
00034 IN int io_opin,
00035 OUT t_subblock_data * subblock_data_ptr,
00036 OUT int *num_blocks,
00037 OUT struct s_block *block_list[],
00038 OUT int *num_nets,
00039 OUT struct s_net *net_list[])
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
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
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
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
00119 block_tokens = ReadLineTokens(infile, &line);
00120 prev_line = line;
00121 while(block_tokens)
00122 {
00123
00124
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
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
00183 if(overide)
00184 {
00185 if(CountTokens(pin_tokens) != 2)
00186 {
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
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
00208 for(k = 0; k < type->num_pins; ++k)
00209 {
00210 tokens[1 + k] = "open";
00211 }
00212 tokens[1 + k] = NULL;
00213
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
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
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;
00275 }
00276
00277 ++j;
00278 }
00279 else
00280 {
00281 if(MAP == pass)
00282 {
00283
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
00320 if(MAP == pass)
00321 {
00322
00323
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
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 +
00360 2))
00361 {
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
00369 if(LOAD == pass)
00370 {
00371 scount[i]++;
00372 }
00373
00374
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
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);
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;
00418
00419 FreeTokens(&tokens);
00420 tokens = ReadLineTokens(infile, &line);
00421 prev_line = line;
00422 }
00423
00424 if(pass > COUNT)
00425 {
00426
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;
00435
00436 FreeTokens(&block_tokens);
00437 FreeTokens(&pin_tokens);
00438 block_tokens = tokens;
00439 }
00440
00441
00442 if(COUNT == pass)
00443 {
00444 bcount = i;
00445 ncount = j;
00446 }
00447 }
00448 fclose(infile);
00449
00450
00451 sync_nets_to_blocks(bcount, blist, ncount, nlist);
00452
00453
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 }
00461
00462
00463 static t_type_ptr
00464 get_type_by_name(IN const char *name,
00465 IN int num_types,
00466 IN const struct s_type_descriptor block_types[],
00467 IN t_type_ptr IO_type,
00468 IN const char *net_file,
00469 IN int line,
00470 OUT enum special_blk *overide)
00471 {
00472
00473
00474 int i;
00475
00476
00477
00478
00479 *overide = NORMAL;
00480
00481
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
00494
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
00504 printf(ERRTAG "'%s':%d - Invalid block type '%s'\n",
00505 net_file, line, name);
00506 exit(1);
00507 }