VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
read_place.c
Go to the documentation of this file.
1 #include <assert.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "util.h"
5 #include "vpr_types.h"
6 #include "globals.h"
7 #include "hash.h"
8 #include "read_place.h"
9 #include "read_xml_arch_file.h"
10 #include "ReadLine.h"
11 
12 /* extern, should be a header */
13 char **ReadLineTokens(INOUTP FILE * InFile, INOUTP int *LineNum);
14 
15 void read_place(INP const char *place_file, INP const char *arch_file,
16  INP const char *net_file, INP int L_nx, INP int L_ny,
17  INP int L_num_blocks, INOUTP struct s_block block_list[]) {
18 
19  FILE *infile;
20  char **tokens;
21  int line;
22  int i;
23  int error;
24  struct s_block *cur_blk;
25 
26  infile = fopen(place_file, "r");
27 
28  /* Check filenames in first line match */
29  tokens = ReadLineTokens(infile, &line);
30  error = 0;
31  if (NULL == tokens) {
32  error = 1;
33  }
34  for (i = 0; i < 6; ++i) {
35  if (!error) {
36  if (NULL == tokens[i]) {
37  error = 1;
38  }
39  }
40  }
41  if (!error) {
42  if ((0 != strcmp(tokens[0], "Netlist"))
43  || (0 != strcmp(tokens[1], "file:"))
44  || (0 != strcmp(tokens[3], "Architecture"))
45  || (0 != strcmp(tokens[4], "file:"))) {
46  error = 1;
47  };
48  }
49  if (error) {
50  vpr_printf(TIO_MESSAGE_ERROR, "'%s' - Bad filename specification line in placement file.\n", place_file);
51  exit(1);
52  }
53  if (0 != strcmp(tokens[2], arch_file)) {
54  vpr_printf(TIO_MESSAGE_ERROR, "'%s' - Architecture file that generated placement (%s) does not match current architecture file (%s).\n",
55  place_file, tokens[2], arch_file);
56  exit(1);
57  }
58  if (0 != strcmp(tokens[5], net_file)) {
59  vpr_printf(TIO_MESSAGE_ERROR, "'%s' - Netlist file that generated placement (%s) does not match current netlist file (%s).\n",
60  place_file, tokens[5], net_file);
61  exit(1);
62  }
63  free(*tokens);
64  free(tokens);
65 
66  /* Check array size in second line matches */
67  tokens = ReadLineTokens(infile, &line);
68  error = 0;
69  if (NULL == tokens) {
70  error = 1;
71  }
72  for (i = 0; i < 7; ++i) {
73  if (!error) {
74  if (NULL == tokens[i]) {
75  error = 1;
76  }
77  }
78  }
79  if (!error) {
80  if ((0 != strcmp(tokens[0], "Array"))
81  || (0 != strcmp(tokens[1], "size:"))
82  || (0 != strcmp(tokens[3], "x"))
83  || (0 != strcmp(tokens[5], "logic"))
84  || (0 != strcmp(tokens[6], "blocks"))) {
85  error = 1;
86  };
87  }
88  if (error) {
89  vpr_printf(TIO_MESSAGE_ERROR, "'%s' - Bad FPGA size specification line in placement file.\n",
90  place_file);
91  exit(1);
92  }
93  if ((my_atoi(tokens[2]) != L_nx) || (my_atoi(tokens[4]) != L_ny)) {
94  vpr_printf(TIO_MESSAGE_ERROR, "'%s' - Current FPGA size (%d x %d) is different from size when placement generated (%d x %d).\n",
95  place_file, L_nx, L_ny, my_atoi(tokens[2]), my_atoi(tokens[4]));
96  exit(1);
97  }
98  free(*tokens);
99  free(tokens);
100 
101  tokens = ReadLineTokens(infile, &line);
102  while (tokens) {
103  /* Linear search to match pad to netlist */
104  cur_blk = NULL;
105  for (i = 0; i < L_num_blocks; ++i) {
106  if (0 == strcmp(block_list[i].name, tokens[0])) {
107  cur_blk = (block_list + i);
108  break;
109  }
110  }
111 
112  /* Error if invalid block */
113  if (NULL == cur_blk) {
114  vpr_printf(TIO_MESSAGE_ERROR, "'%s':%d - Block in placement file does not exist in netlist.\n",
115  place_file, line);
116  exit(1);
117  }
118 
119  /* Set pad coords */
120  cur_blk->x = my_atoi(tokens[1]);
121  cur_blk->y = my_atoi(tokens[2]);
122  cur_blk->z = my_atoi(tokens[3]);
123 
124  /* Get next line */
125  assert(*tokens);
126  free(*tokens);
127  free(tokens);
128  tokens = ReadLineTokens(infile, &line);
129  }
130 
131  fclose(infile);
132 }
133 
134 void read_user_pad_loc(char *pad_loc_file) {
135 
136  /* Reads in the locations of the IO pads from a file. */
137 
138  struct s_hash **hash_table, *h_ptr;
139  int iblk, i, j, xtmp, ytmp, bnum, k;
140  FILE *fp;
141  char buf[BUFSIZE], bname[BUFSIZE], *ptr;
142 
143  vpr_printf(TIO_MESSAGE_INFO, "\n");
144  vpr_printf(TIO_MESSAGE_INFO, "Reading locations of IO pads from '%s'.\n", pad_loc_file);
145  file_line_number = 0;
146  fp = fopen(pad_loc_file, "r");
147 
148  hash_table = alloc_hash_table();
149  for (iblk = 0; iblk < num_blocks; iblk++) {
150  if (block[iblk].type == IO_TYPE) {
151  h_ptr = insert_in_hash_table(hash_table, block[iblk].name, iblk);
152  block[iblk].x = OPEN; /* Mark as not seen yet. */
153  }
154  }
155 
156  for (i = 0; i <= nx + 1; i++) {
157  for (j = 0; j <= ny + 1; j++) {
158  if (grid[i][j].type == IO_TYPE) {
159  for (k = 0; k < IO_TYPE->capacity; k++)
160  grid[i][j].blocks[k] = OPEN; /* Flag for err. check */
161  }
162  }
163  }
164 
165  ptr = my_fgets(buf, BUFSIZE, fp);
166 
167  while (ptr != NULL) {
168  ptr = my_strtok(buf, TOKENS, fp, buf);
169  if (ptr == NULL) {
170  ptr = my_fgets(buf, BUFSIZE, fp);
171  continue; /* Skip blank or comment lines. */
172  }
173 
174  strcpy(bname, ptr);
175 
176  ptr = my_strtok(NULL, TOKENS, fp, buf);
177  if (ptr == NULL) {
178  vpr_printf(TIO_MESSAGE_ERROR, "[Line %d] Incomplete.\n", file_line_number);
179  exit(1);
180  }
181  sscanf(ptr, "%d", &xtmp);
182 
183  ptr = my_strtok(NULL, TOKENS, fp, buf);
184  if (ptr == NULL) {
185  vpr_printf(TIO_MESSAGE_ERROR, "[Line %d] Incomplete.\n", file_line_number);
186  exit(1);
187  }
188  sscanf(ptr, "%d", &ytmp);
189 
190  ptr = my_strtok(NULL, TOKENS, fp, buf);
191  if (ptr == NULL) {
192  vpr_printf(TIO_MESSAGE_ERROR, "[Line %d] Incomplete.\n", file_line_number);
193  exit(1);
194  }
195  sscanf(ptr, "%d", &k);
196 
197  ptr = my_strtok(NULL, TOKENS, fp, buf);
198  if (ptr != NULL) {
199  vpr_printf(TIO_MESSAGE_ERROR, "[Line %d] Extra characters at end of line.\n",
201  exit(1);
202  }
203 
204  h_ptr = get_hash_entry(hash_table, bname);
205  if (h_ptr == NULL) {
206  vpr_printf(TIO_MESSAGE_WARNING, "[Line %d] Block %s invalid, no such IO pad.\n",
207  file_line_number, bname);
208  ptr = my_fgets(buf, BUFSIZE, fp);
209  continue;
210  }
211  bnum = h_ptr->index;
212  i = xtmp;
213  j = ytmp;
214 
215  if (block[bnum].x != OPEN) {
216  vpr_printf(TIO_MESSAGE_ERROR, "[Line %d] Block %s is listed twice in pad file.\n",
217  file_line_number, bname);
218  exit(1);
219  }
220 
221  if (i < 0 || i > nx + 1 || j < 0 || j > ny + 1) {
222  vpr_printf(TIO_MESSAGE_ERROR, "Block #%d (%s) location, (%d,%d) is out of range.\n",
223  bnum, bname, i, j);
224  exit(1);
225  }
226 
227  block[bnum].x = i; /* Will be reloaded by initial_placement anyway. */
228  block[bnum].y = j; /* I need to set .x only as a done flag. */
229  block[bnum].isFixed = TRUE;
230 
231  if (grid[i][j].type != IO_TYPE) {
232  vpr_printf(TIO_MESSAGE_ERROR, "Attempt to place IO block %s at illegal location (%d, %d).\n",
233  bname, i, j);
234  exit(1);
235  }
236 
237  if (k >= IO_TYPE->capacity || k < 0) {
238  vpr_printf(TIO_MESSAGE_ERROR, "[Line %d] Block %s subblock number (%d) is out of range.\n",
239  file_line_number, bname, k);
240  exit(1);
241  }
242  grid[i][j].blocks[k] = bnum;
243  grid[i][j].usage++;
244 
245  ptr = my_fgets(buf, BUFSIZE, fp);
246  }
247 
248  for (iblk = 0; iblk < num_blocks; iblk++) {
249  if (block[iblk].type == IO_TYPE && block[iblk].x == OPEN) {
250  vpr_printf(TIO_MESSAGE_ERROR, "IO block %s location was not specified in the pad file.\n",
251  block[iblk].name);
252  exit(1);
253  }
254  }
255 
256  fclose(fp);
257  free_hash_table(hash_table);
258  vpr_printf(TIO_MESSAGE_INFO, "Successfully read %s.\n", pad_loc_file);
259  vpr_printf(TIO_MESSAGE_INFO, "\n");
260 }
261 
262 void print_place(char *place_file, char *net_file, char *arch_file) {
263 
264  /* Prints out the placement of the circuit. The architecture and *
265  * netlist files used to generate this placement are recorded in the *
266  * file to avoid loading a placement with the wrong support files *
267  * later. */
268 
269  FILE *fp;
270  int i;
271 
272  fp = fopen(place_file, "w");
273 
274  fprintf(fp, "Netlist file: %s Architecture file: %s\n", net_file,
275  arch_file);
276  fprintf(fp, "Array size: %d x %d logic blocks\n\n", nx, ny);
277  fprintf(fp, "#block name\tx\ty\tsubblk\tblock number\n");
278  fprintf(fp, "#----------\t--\t--\t------\t------------\n");
279 
280  for (i = 0; i < num_blocks; i++) {
281  fprintf(fp, "%s\t", block[i].name);
282  if (strlen(block[i].name) < 8)
283  fprintf(fp, "\t");
284 
285  fprintf(fp, "%d\t%d\t%d", block[i].x, block[i].y, block[i].z);
286  fprintf(fp, "\t#%d\n", i);
287  }
288  fclose(fp);
289 }
struct s_hash ** alloc_hash_table(void)
Definition: hash.c:7
int index
Definition: hash.h:5
void read_place(INP const char *place_file, INP const char *arch_file, INP const char *net_file, INP int L_nx, INP int L_ny, INP int L_num_blocks, INOUTP struct s_block block_list[])
Definition: read_place.c:15
#define TOKENS
Definition: vpr_types.h:66
struct s_hash * get_hash_entry(struct s_hash **hash_table, char *name)
Definition: hash.c:119
int x
Definition: vpr_types.h:563
char * name
Definition: hash.h:4
#define BUFSIZE
Definition: graphics.c:184
#define INOUTP
Definition: util.h:21
int num_blocks
Definition: globals.c:30
char * name
Definition: vpr_types.h:560
void free_hash_table(struct s_hash **hash_table)
Definition: hash.c:18
int y
Definition: vpr_types.h:564
boolean isFixed
Definition: vpr_types.h:569
struct s_block * block
Definition: globals.c:31
#define INP
Definition: util.h:19
int nx
Definition: globals.c:46
void read_user_pad_loc(char *pad_loc_file)
Definition: read_place.c:134
char * my_strtok(char *ptr, const char *tokens, FILE *fp, char *buf)
Definition: util.c:472
void print_place(char *place_file, char *net_file, char *arch_file)
Definition: read_place.c:262
struct s_grid_tile ** grid
Definition: globals.c:59
int * blocks
Definition: vpr_types.h:525
char ** ReadLineTokens(INOUTP FILE *InFile, INOUTP int *LineNum)
Definition: ReadLine.c:39
t_type_ptr IO_TYPE
Definition: globals.c:40
char * my_fgets(char *buf, int max_size, FILE *fp)
Definition: util.c:412
Definition: slre.c:50
int file_line_number
Definition: util.c:15
int z
Definition: vpr_types.h:565
int ny
Definition: globals.c:47
int my_atoi(const char *str)
Definition: util.c:116
messagelogger vpr_printf
Definition: util.c:17
struct s_hash * insert_in_hash_table(struct s_hash **hash_table, char *name, int next_free_index)
Definition: hash.c:76
Definition: hash.h:3
Definition: util.h:12