VPR-6.0
|
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 #include "read_xml_arch_file.h" 00010 00011 /* extern, should be a header */ 00012 char **ReadLineTokens(INOUTP FILE * InFile, 00013 INOUTP int *LineNum); 00014 00015 00016 void 00017 read_place(INP const char *place_file, 00018 INP const char *arch_file, 00019 INP const char *net_file, 00020 INP int nx, 00021 INP int ny, 00022 INP int num_blocks, 00023 INOUTP 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 = fopen(place_file, "r"); 00034 00035 /* Check filenames in first line match */ 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 /* Check array size in second line matches */ 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 /* Linear search to match pad to netlist */ 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 /* Error if invalid block */ 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 /* Set pad coords */ 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 /* Get next line */ 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 /* Reads in the locations of the IO pads from a file. */ 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 = 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; /* Mark as not seen yet. */ 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; /* Flag for err. check */ 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; /* Skip blank or comment lines. */ 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; /* Will be reloaded by initial_placement anyway. */ 00278 block[bnum].y = j; /* I need to set .x only as a done flag. */ 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 /** Prints out the placement of the circuit. The architecture and 00319 * netlist files used to generate this placement are recorded in the 00320 * file to avoid loading a placement with the wrong support files 00321 * later. 00322 */ 00323 void 00324 print_place(char *place_file, 00325 char *net_file, 00326 char *arch_file) 00327 { 00328 FILE *fp; 00329 int i; 00330 00331 fp = fopen(place_file, "w"); 00332 00333 fprintf(fp, "Netlist file: %s Architecture file: %s\n", net_file, 00334 arch_file); 00335 fprintf(fp, "Array size: %d x %d logic blocks\n\n", nx, ny); 00336 fprintf(fp, "#block name\tx\ty\tsubblk\tblock number\n"); 00337 fprintf(fp, "#----------\t--\t--\t------\t------------\n"); 00338 00339 for(i = 0; i < num_blocks; i++) 00340 { 00341 fprintf(fp, "%s\t", block[i].name); 00342 if(strlen(block[i].name) < 8) 00343 fprintf(fp, "\t"); 00344 00345 fprintf(fp, "%d\t%d\t%d", block[i].x, block[i].y, block[i].z); 00346 fprintf(fp, "\t#%d\n", i); 00347 } 00348 fclose(fp); 00349 }