00001 #include <assert.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include "util.h"
00005 #include "vpr_types.h"
00006 #include "globals.h"
00007 #include "hash.h"
00008 #include "read_place.h"
00009
00010
00011
00012 char **ReadLineTokens(INOUT FILE * InFile,
00013 INOUT int *LineNum);
00014
00015
00016 void
00017 read_place(IN const char *place_file,
00018 IN const char *arch_file,
00019 IN const char *net_file,
00020 IN int nx,
00021 IN int ny,
00022 IN int num_blocks,
00023 INOUT struct s_block block_list[])
00024 {
00025
00026 FILE *infile;
00027 char **tokens;
00028 int line;
00029 int i;
00030 int error;
00031 struct s_block *cur_blk;
00032
00033 infile = my_fopen(place_file, "r");
00034
00035
00036 tokens = ReadLineTokens(infile, &line);
00037 error = 0;
00038 if(NULL == tokens)
00039 {
00040 error = 1;
00041 }
00042 for(i = 0; i < 6; ++i)
00043 {
00044 if(!error)
00045 {
00046 if(NULL == tokens[i])
00047 {
00048 error = 1;
00049 }
00050 }
00051 }
00052 if(!error)
00053 {
00054 if((0 != strcmp(tokens[0], "Netlist")) ||
00055 (0 != strcmp(tokens[1], "file:")) ||
00056 (0 != strcmp(tokens[3], "Architecture")) ||
00057 (0 != strcmp(tokens[4], "file:")))
00058 {
00059 error = 1;
00060 };
00061 }
00062 if(error)
00063 {
00064 printf(ERRTAG
00065 "'%s' - Bad filename specification line in placement file\n",
00066 place_file);
00067 exit(1);
00068 }
00069 if(0 != strcmp(tokens[2], arch_file))
00070 {
00071 printf(ERRTAG
00072 "'%s' - Architecture file that generated placement (%s) does "
00073 "not match current architecture file (%s)\n", place_file,
00074 tokens[2], arch_file);
00075 exit(1);
00076 }
00077 if(0 != strcmp(tokens[5], net_file))
00078 {
00079 printf(ERRTAG
00080 "'%s' - Netlist file that generated placement (%s) does "
00081 "not match current netlist file (%s)\n", place_file,
00082 tokens[5], net_file);
00083 exit(1);
00084 }
00085
00086
00087 tokens = ReadLineTokens(infile, &line);
00088 error = 0;
00089 if(NULL == tokens)
00090 {
00091 error = 1;
00092 }
00093 for(i = 0; i < 7; ++i)
00094 {
00095 if(!error)
00096 {
00097 if(NULL == tokens[i])
00098 {
00099 error = 1;
00100 }
00101 }
00102 }
00103 if(!error)
00104 {
00105 if((0 != strcmp(tokens[0], "Array")) ||
00106 (0 != strcmp(tokens[1], "size:")) ||
00107 (0 != strcmp(tokens[3], "x")) ||
00108 (0 != strcmp(tokens[5], "logic")) ||
00109 (0 != strcmp(tokens[6], "blocks")))
00110 {
00111 error = 1;
00112 };
00113 }
00114 if(error)
00115 {
00116 printf(ERRTAG
00117 "'%s' - Bad fpga size specification line in placement file\n",
00118 place_file);
00119 exit(1);
00120 }
00121 if((my_atoi(tokens[2]) != nx) || (my_atoi(tokens[4]) != ny))
00122 {
00123 printf(ERRTAG
00124 "'%s' - Current FPGA size (%d x %d) is different from "
00125 "size when placement generated (%d x %d)\n", place_file,
00126 nx, ny, my_atoi(tokens[2]), my_atoi(tokens[4]));
00127 exit(1);
00128 }
00129
00130 tokens = ReadLineTokens(infile, &line);
00131 while(tokens)
00132 {
00133
00134 cur_blk = NULL;
00135 for(i = 0; i < num_blocks; ++i)
00136 {
00137 if(0 == strcmp(block_list[i].name, tokens[0]))
00138 {
00139 cur_blk = (block_list + i);
00140 break;
00141 }
00142 }
00143
00144
00145 if(NULL == cur_blk)
00146 {
00147 printf(ERRTAG "'%s':%d - Block in placement file does "
00148 "not exist in netlist\n", place_file, line);
00149 exit(1);
00150 }
00151
00152
00153 cur_blk->x = my_atoi(tokens[1]);
00154 cur_blk->y = my_atoi(tokens[2]);
00155 cur_blk->z = my_atoi(tokens[3]);
00156
00157
00158 assert(*tokens);
00159 free(*tokens);
00160 free(tokens);
00161 tokens = ReadLineTokens(infile, &line);
00162 }
00163
00164 fclose(infile);
00165 }
00166
00167 void
00168 read_user_pad_loc(char *pad_loc_file)
00169 {
00170
00171
00172
00173 struct s_hash **hash_table, *h_ptr;
00174 int iblk, i, j, xtmp, ytmp, bnum, k;
00175 FILE *fp;
00176 char buf[BUFSIZE], bname[BUFSIZE], *ptr;
00177
00178 printf("\nReading locations of IO pads from %s.\n", pad_loc_file);
00179 linenum = 0;
00180 fp = my_fopen(pad_loc_file, "r");
00181
00182 hash_table = alloc_hash_table();
00183 for(iblk = 0; iblk < num_blocks; iblk++)
00184 {
00185 if(block[iblk].type == IO_TYPE)
00186 {
00187 h_ptr =
00188 insert_in_hash_table(hash_table, block[iblk].name,
00189 iblk);
00190 block[iblk].x = OPEN;
00191 }
00192 }
00193
00194 for(i = 0; i <= nx + 1; i++)
00195 {
00196 for(j = 0; j <= ny + 1; j++)
00197 {
00198 if(grid[i][j].type == IO_TYPE)
00199 {
00200 for(k = 0; k < IO_TYPE->capacity; k++)
00201 grid[i][j].blocks[k] = OPEN;
00202 }
00203 }
00204 }
00205
00206 ptr = my_fgets(buf, BUFSIZE, fp);
00207
00208 while(ptr != NULL)
00209 {
00210 ptr = my_strtok(buf, TOKENS, fp, buf);
00211 if(ptr == NULL)
00212 {
00213 ptr = my_fgets(buf, BUFSIZE, fp);
00214 continue;
00215 }
00216
00217 strcpy(bname, ptr);
00218
00219 ptr = my_strtok(NULL, TOKENS, fp, buf);
00220 if(ptr == NULL)
00221 {
00222 printf("Error: line %d is incomplete.\n", linenum);
00223 exit(1);
00224 }
00225 sscanf(ptr, "%d", &xtmp);
00226
00227 ptr = my_strtok(NULL, TOKENS, fp, buf);
00228 if(ptr == NULL)
00229 {
00230 printf("Error: line %d is incomplete.\n", linenum);
00231 exit(1);
00232 }
00233 sscanf(ptr, "%d", &ytmp);
00234
00235 ptr = my_strtok(NULL, TOKENS, fp, buf);
00236 if(ptr == NULL)
00237 {
00238 printf("Error: line %d is incomplete.\n", linenum);
00239 exit(1);
00240 }
00241 sscanf(ptr, "%d", &k);
00242
00243 ptr = my_strtok(NULL, TOKENS, fp, buf);
00244 if(ptr != NULL)
00245 {
00246 printf("Error: extra characters at end of line %d.\n",
00247 linenum);
00248 exit(1);
00249 }
00250
00251 h_ptr = get_hash_entry(hash_table, bname);
00252 if(h_ptr == NULL)
00253 {
00254 printf("Error: block %s on line %d: no such IO pad.\n",
00255 bname, linenum);
00256 exit(1);
00257 }
00258 bnum = h_ptr->index;
00259 i = xtmp;
00260 j = ytmp;
00261
00262 if(block[bnum].x != OPEN)
00263 {
00264 printf
00265 ("Error: line %d. Block %s listed twice in pad file.\n",
00266 linenum, bname);
00267 exit(1);
00268 }
00269
00270 if(i < 0 || i > nx + 1 || j < 0 || j > ny + 1)
00271 {
00272 printf("Error: block #%d (%s) location\n", bnum, bname);
00273 printf("(%d,%d) is out of range.\n", i, j);
00274 exit(1);
00275 }
00276
00277 block[bnum].x = i;
00278 block[bnum].y = j;
00279
00280 if(grid[i][j].type != IO_TYPE)
00281 {
00282 printf("Error: attempt to place IO block %s in \n",
00283 bname);
00284 printf("an illegal location (%d, %d).\n", i, j);
00285 exit(1);
00286 }
00287
00288 if(k >= IO_TYPE->capacity || k < 0)
00289 {
00290 printf
00291 ("Error: Block %s subblock number (%d) on line %d is out of "
00292 "range.\n", bname, k, linenum);
00293 exit(1);
00294 }
00295 grid[i][j].blocks[k] = bnum;
00296 grid[i][j].usage++;
00297
00298 ptr = my_fgets(buf, BUFSIZE, fp);
00299 }
00300
00301 for(iblk = 0; iblk < num_blocks; iblk++)
00302 {
00303 if(block[iblk].type == IO_TYPE && block[iblk].x == OPEN)
00304 {
00305 printf
00306 ("Error: IO block %s location was not specified in "
00307 "the pad file.\n", block[iblk].name);
00308 exit(1);
00309 }
00310 }
00311
00312 fclose(fp);
00313 free_hash_table(hash_table);
00314 printf("Successfully read %s.\n\n", pad_loc_file);
00315 }
00316
00317
00318 void
00319 print_place(char *place_file,
00320 char *net_file,
00321 char *arch_file)
00322 {
00323
00324
00325
00326
00327
00328
00329 FILE *fp;
00330 int i;
00331
00332 fp = my_fopen(place_file, "w");
00333
00334 fprintf(fp, "Netlist file: %s Architecture file: %s\n", net_file,
00335 arch_file);
00336 fprintf(fp, "Array size: %d x %d logic blocks\n\n", nx, ny);
00337 fprintf(fp, "#block name\tx\ty\tsubblk\tblock number\n");
00338 fprintf(fp, "#----------\t--\t--\t------\t------------\n");
00339
00340 for(i = 0; i < num_blocks; i++)
00341 {
00342 fprintf(fp, "%s\t", block[i].name);
00343 if(strlen(block[i].name) < 8)
00344 fprintf(fp, "\t");
00345
00346 fprintf(fp, "%d\t%d\t%d", block[i].x, block[i].y, block[i].z);
00347 fprintf(fp, "\t#%d\n", i);
00348 }
00349
00350 fclose(fp);
00351 }