#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "hash.h"
#include "read_place.h"
Go to the source code of this file.
Functions | |
char ** | ReadLineTokens (INOUT FILE *InFile, INOUT int *LineNum) |
void | read_place (IN const char *place_file, IN const char *arch_file, IN const char *net_file, IN int nx, IN int ny, IN int num_blocks, INOUT struct s_block block_list[]) |
void | read_user_pad_loc (char *pad_loc_file) |
void | print_place (char *place_file, char *net_file, char *arch_file) |
void print_place | ( | char * | place_file, | |
char * | net_file, | |||
char * | arch_file | |||
) |
Definition at line 319 of file read_place.c.
00322 { 00323 00324 /* Prints out the placement of the circuit. The architecture and * 00325 * netlist files used to generate this placement are recorded in the * 00326 * file to avoid loading a placement with the wrong support files * 00327 * later. */ 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 }
void read_place | ( | IN const char * | place_file, | |
IN const char * | arch_file, | |||
IN const char * | net_file, | |||
IN int | nx, | |||
IN int | ny, | |||
IN int | num_blocks, | |||
INOUT struct s_block | block_list[] | |||
) |
Definition at line 17 of file read_place.c.
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 /* 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 }
void read_user_pad_loc | ( | char * | pad_loc_file | ) |
Definition at line 168 of file read_place.c.
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 = 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; /* 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 }
char** ReadLineTokens | ( | INOUT FILE * | InFile, | |
INOUT int * | LineNum | |||
) |
Definition at line 48 of file ReadLine.c.
00050 { 00051 00052 enum 00053 { BUFFSIZE = 65536 }; /* This is much more than enough */ 00054 char Buffer[BUFFSIZE]; /* Must match BUFFSIZE */ 00055 char *Res; 00056 char *Last; 00057 char *Cur; 00058 char *Dst; 00059 char **Tokens; 00060 int TokenCount; 00061 int Len; 00062 int CurToken; 00063 boolean InToken; 00064 00065 do 00066 { 00067 /* Read the string */ 00068 Res = fgets(Buffer, BUFFSIZE, InFile); 00069 if(NULL == Res) 00070 { 00071 if(feof(InFile)) 00072 { 00073 return NULL; /* Return NULL on EOF */ 00074 } 00075 else 00076 { 00077 printf(ERRTAG "Unexpected error reading file\n"); 00078 exit(1); 00079 } 00080 } 00081 ++(*LineNum); 00082 00083 /* Strip newline if any */ 00084 Last = Buffer + strlen(Buffer); 00085 if((Last > Buffer) && ('\n' == Last[-1])) 00086 { 00087 --Last; 00088 } 00089 if((Last > Buffer) && ('\r' == Last[-1])) 00090 { 00091 --Last; 00092 } 00093 00094 /* Handle continued lines */ 00095 while((Last > Buffer) && ('\\' == Last[-1])) 00096 { 00097 /* Strip off the backslash */ 00098 --Last; 00099 00100 /* Read next line by giving pointer to null-char as start for next */ 00101 Res = fgets(Last, (BUFFSIZE - (Last - Buffer)), InFile); 00102 if(NULL == Res) 00103 { 00104 if(feof(InFile)) 00105 { 00106 return NULL; /* Return NULL on EOF */ 00107 } 00108 else 00109 { 00110 printf(ERRTAG 00111 "Unexpected error reading file\n"); 00112 exit(1); 00113 } 00114 } 00115 ++(*LineNum); 00116 00117 /* Strip newline */ 00118 Last = Buffer + strlen(Buffer); 00119 if((Last > Buffer) && ('\n' == Last[-1])) 00120 { 00121 --Last; 00122 } 00123 if((Last > Buffer) && ('\r' == Last[-1])) 00124 { 00125 --Last; 00126 } 00127 } 00128 00129 /* Strip comment if any */ 00130 Cur = Buffer; 00131 while(Cur < Last) 00132 { 00133 if('#' == *Cur) 00134 { 00135 Last = Cur; 00136 break; 00137 } 00138 ++Cur; 00139 } 00140 00141 /* Count tokens and find size */ 00142 assert(Last < (Buffer + BUFFSIZE)); 00143 Len = 0; 00144 TokenCount = 0; 00145 Cur = Buffer; 00146 InToken = FALSE; 00147 while(Cur < Last) 00148 { 00149 if(InToken) 00150 { 00151 if((' ' == *Cur) || ('\t' == *Cur)) 00152 { 00153 InToken = FALSE; 00154 } 00155 else 00156 { 00157 ++Len; 00158 } 00159 } 00160 else 00161 { 00162 if((' ' != *Cur) && ('\t' != *Cur)) 00163 { 00164 ++TokenCount; 00165 ++Len; 00166 InToken = TRUE; 00167 } 00168 } 00169 ++Cur; /* Advance pointer */ 00170 } 00171 } 00172 while(0 == TokenCount); 00173 00174 /* Find the size of mem to alloc. Use a contiguous block so is 00175 * easy to deallocate */ 00176 Len = (sizeof(char) * Len) + /* Length of actual data */ 00177 (sizeof(char) * TokenCount); /* Null terminators */ 00178 00179 /* Alloc the pointer list and data list. Count the final 00180 * empty string we will use as list terminator */ 00181 Tokens = (char **)my_malloc(sizeof(char *) * (TokenCount + 1)); 00182 *Tokens = (char *)my_malloc(sizeof(char) * Len); 00183 00184 /* Copy tokens to result */ 00185 Cur = Buffer; 00186 Dst = *Tokens; 00187 InToken = FALSE; 00188 CurToken = 0; 00189 while(Cur < Last) 00190 { 00191 if(InToken) 00192 { 00193 if((' ' == *Cur) || ('\t' == *Cur)) 00194 { 00195 InToken = FALSE; 00196 *Dst = '\0'; /* Null term token */ 00197 ++Dst; 00198 ++CurToken; 00199 } 00200 else 00201 { 00202 *Dst = *Cur; /* Copy char */ 00203 ++Dst; 00204 } 00205 } 00206 else 00207 { 00208 if((' ' != *Cur) && ('\t' != *Cur)) 00209 { 00210 Tokens[CurToken] = Dst; /* Set token start pointer */ 00211 *Dst = *Cur; /* Copy char */ 00212 ++Dst; 00213 InToken = TRUE; 00214 } 00215 } 00216 ++Cur; /* Advance pointer */ 00217 } 00218 if(InToken) 00219 { 00220 *Dst = '\0'; /* Null term final token */ 00221 ++Dst; 00222 ++CurToken; 00223 } 00224 assert(CurToken == TokenCount); 00225 00226 /* Set the final empty string entry */ 00227 Tokens[CurToken] = NULL; 00228 00229 /* Return the string list */ 00230 return Tokens; 00231 }