VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
read_place.c File Reference
#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"
#include "read_xml_arch_file.h"
#include "ReadLine.h"
+ Include dependency graph for read_place.c:

Go to the source code of this file.

Functions

char ** ReadLineTokens (INOUTP FILE *InFile, INOUTP int *LineNum)
 
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[])
 
void read_user_pad_loc (char *pad_loc_file)
 
void print_place (char *place_file, char *net_file, char *arch_file)
 

Function Documentation

void print_place ( char *  place_file,
char *  net_file,
char *  arch_file 
)

Definition at line 262 of file read_place.c.

262  {
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 }
int x
Definition: vpr_types.h:563
int num_blocks
Definition: globals.c:30
char * name
Definition: vpr_types.h:560
int y
Definition: vpr_types.h:564
struct s_block * block
Definition: globals.c:31
int nx
Definition: globals.c:46
int z
Definition: vpr_types.h:565
int ny
Definition: globals.c:47

+ Here is the caller graph for this function:

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 at line 15 of file read_place.c.

17  {
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 }
int x
Definition: vpr_types.h:563
char * name
Definition: vpr_types.h:560
int y
Definition: vpr_types.h:564
char ** ReadLineTokens(INOUTP FILE *InFile, INOUTP int *LineNum)
Definition: ReadLine.c:39
int z
Definition: vpr_types.h:565
int my_atoi(const char *str)
Definition: util.c:116
messagelogger vpr_printf
Definition: util.c:17

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void read_user_pad_loc ( char *  pad_loc_file)

Definition at line 134 of file read_place.c.

134  {
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 }
struct s_hash ** alloc_hash_table(void)
Definition: hash.c:7
int index
Definition: hash.h:5
#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
int num_blocks
Definition: globals.c:30
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
int nx
Definition: globals.c:46
char * my_strtok(char *ptr, const char *tokens, FILE *fp, char *buf)
Definition: util.c:472
struct s_grid_tile ** grid
Definition: globals.c:59
int * blocks
Definition: vpr_types.h:525
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 ny
Definition: globals.c:47
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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

char** ReadLineTokens ( INOUTP FILE *  InFile,
INOUTP int *  LineNum 
)

Definition at line 39 of file ReadLine.c.

39  {
40 
41  enum {
42  BUFFSIZE = 65536
43  };
44  /* This is much more than enough */
45  char Buffer[BUFFSIZE]; /* Must match BUFFSIZE */
46  char *Res;
47  char *Last;
48  char *Cur;
49  char *Dst;
50  char **Tokens;
51  int TokenCount;
52  int Len;
53  int CurToken;
54  boolean InToken;
55 
56  do {
57  /* Read the string */
58  Res = fgets(Buffer, BUFFSIZE, InFile);
59  if (NULL == Res) {
60  if (feof(InFile)) {
61  return NULL; /* Return NULL on EOF */
62  } else {
63  vpr_printf(TIO_MESSAGE_ERROR, "Unexpected error reading file\n");
64  exit(1);
65  }
66  }
67  ++(*LineNum);
68 
69  /* Strip newline if any */
70  Last = Buffer + strlen(Buffer);
71  if ((Last > Buffer) && ('\n' == Last[-1])) {
72  --Last;
73  }
74  if ((Last > Buffer) && ('\r' == Last[-1])) {
75  --Last;
76  }
77 
78  /* Handle continued lines */
79  while ((Last > Buffer) && ('\\' == Last[-1])) {
80  /* Strip off the backslash */
81  --Last;
82 
83  /* Read next line by giving pointer to null-char as start for next */
84  Res = fgets(Last, (BUFFSIZE - (Last - Buffer)), InFile);
85  if (NULL == Res) {
86  if (feof(InFile)) {
87  return NULL; /* Return NULL on EOF */
88  } else {
89  vpr_printf(TIO_MESSAGE_ERROR,
90  "Unexpected error reading file\n");
91  exit(1);
92  }
93  }
94  ++(*LineNum);
95 
96  /* Strip newline */
97  Last = Buffer + strlen(Buffer);
98  if ((Last > Buffer) && ('\n' == Last[-1])) {
99  --Last;
100  }
101  if ((Last > Buffer) && ('\r' == Last[-1])) {
102  --Last;
103  }
104  }
105 
106  /* Strip comment if any */
107  Cur = Buffer;
108  while (Cur < Last) {
109  if ('#' == *Cur) {
110  Last = Cur;
111  break;
112  }
113  ++Cur;
114  }
115 
116  /* Count tokens and find size */
117  assert(Last < (Buffer + BUFFSIZE));
118  Len = 0;
119  TokenCount = 0;
120  Cur = Buffer;
121  InToken = FALSE;
122  while (Cur < Last) {
123  if (InToken) {
124  if ((' ' == *Cur) || ('\t' == *Cur)) {
125  InToken = FALSE;
126  } else {
127  ++Len;
128  }
129  } else {
130  if ((' ' != *Cur) && ('\t' != *Cur)) {
131  ++TokenCount;
132  ++Len;
133  InToken = TRUE;
134  }
135  }
136  ++Cur; /* Advance pointer */
137  }
138  } while (0 == TokenCount);
139 
140  /* Find the size of mem to alloc. Use a contiguous block so is
141  * easy to deallocate */
142  Len = (sizeof(char) * Len) + /* Length of actual data */
143  (sizeof(char) * TokenCount); /* Null terminators */
144 
145  /* Alloc the pointer list and data list. Count the final
146  * empty string we will use as list terminator */
147  Tokens = (char **) my_malloc(sizeof(char *) * (TokenCount + 1));
148  *Tokens = (char *) my_malloc(sizeof(char) * Len);
149 
150  /* Copy tokens to result */
151  Cur = Buffer;
152  Dst = *Tokens;
153  InToken = FALSE;
154  CurToken = 0;
155  while (Cur < Last) {
156  if (InToken) {
157  if ((' ' == *Cur) || ('\t' == *Cur)) {
158  InToken = FALSE;
159  *Dst = '\0'; /* Null term token */
160  ++Dst;
161  ++CurToken;
162  } else {
163  *Dst = *Cur; /* Copy char */
164  ++Dst;
165  }
166  } else {
167  if ((' ' != *Cur) && ('\t' != *Cur)) {
168  Tokens[CurToken] = Dst; /* Set token start pointer */
169  *Dst = *Cur; /* Copy char */
170  ++Dst;
171  InToken = TRUE;
172  }
173  }
174  ++Cur; /* Advance pointer */
175  }
176  if (InToken) {
177  *Dst = '\0'; /* Null term final token */
178  ++Dst;
179  ++CurToken;
180  }
181  assert(CurToken == TokenCount);
182 
183  /* Set the final empty string entry */
184  Tokens[CurToken] = NULL;
185 
186  /* Return the string list */
187  return Tokens;
188 }
Definition: util.h:12
static void * my_malloc(int ibytes)
Definition: graphics.c:499
messagelogger vpr_printf
Definition: util.c:17
Definition: util.h:12

+ Here is the caller graph for this function: