VPR-6.0

vpr/SRC/base/read_place.c

Go to the documentation of this file.
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 }