Bitstream Interpretation Library (BIL)  0.1
XDLRCParserImp3.cpp
Go to the documentation of this file.
1 
10 
11 using namespace bil;
12 using namespace bil::xdlrcparser_detail;
13 
14 
15 void XDLRCParserImp::parse2ndTiles()
16 {
17  // skip row count
18  unsigned rows;
19  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
20  if (!m_tok->uintToken(rows)) throw Exception();
21 
22  // skip column count
23  unsigned cols;
24  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
25  if (!m_tok->uintToken(cols)) throw Exception();
26 
27  // parse tiles
28  m_tileIndex = 0;
29  for (;;)
30  {
31  // skip opening parenthesis
32  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
33  if (')' == m_tok->separatorToken()) return;
34  if ('(' != m_tok->separatorToken()) throw Exception();
35 
36  // skip keyword
37  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
38  if (strcmp(m_tok->wordToken(), XDLRCKeywords::TILE) != 0) throw Exception();
39  parse2ndTile();
40  // keep track of tile index
41  ++m_tileIndex;
42  }
43 }
44 
45 
46 void XDLRCParserImp::parse2ndTile()
47 {
48  // fetch corresponding tile and its primitive sites
49  m_tile = &(m_tiles->at(m_tileIndex));
50  m_sites = &(m_tile->primitiveSites());
51  // get its tile type
52  m_tileType = &(m_tileTypes->at(m_tile->typeIndex()));
53  m_tileTypeEx = &(m_tileTypesEx.at(m_tile->typeIndex()));
54  // get site types, wires and wire map of tile type
55  m_siteTypes = &(m_tileType->siteTypes());
56  m_wires = &(m_tileType->wires());
57  m_wireMap = &(m_tileTypeEx->wireMap);
58 
59  // read row position and check it
60  unsigned pos;
61  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
62  if (!m_tok->uintToken(pos)) throw Exception();
63  if (m_tile->row() != pos) throw Exception();
64 
65  // read column position and check it
66  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
67  if (!m_tok->uintToken(pos)) throw Exception();
68  if (m_tile->column() != pos) throw Exception();
69 
70  // read tile name and check it
71  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
72  if ((m_tile->name()).compare(m_tok->wordToken()) != 0) throw Exception();
73 
74  // read tile type name and check it
75  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
76  if ((m_tileType->name()).compare(m_tok->wordToken()) != 0) throw Exception();
77 
78  // skip primitive site count
79  size_t count;
80  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
81  if (!m_tok->uintToken(count)) throw Exception();
82 
83  // parse primitive sites
84  m_primitiveSiteIndex = 0;
85  for (;;)
86  {
87  // skip parenthesis
88  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
89  if (')' == m_tok->separatorToken()) return;
90  if ('(' != m_tok->separatorToken()) throw Exception();
91 
92  // parse primitive site if keyword matches
93  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
94  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PRIMITIVE_SITE) != 0) break;
95  // determine if site type has to be written
96  if (m_tileTypeEx->writeSiteTypes) parse2ndPrimitiveSite();
97  else parse2ndPrimitiveSiteSkip();
98  // keep track of site index
99  ++m_primitiveSiteIndex;
100  }
101  // a site type is only written once
102  m_tileTypeEx->writeSiteTypes = false;
103 
104  // parse wires
105  for (;;)
106  {
107  // parse a wire if keyword matches
108  if (strcmp(m_tok->wordToken(), XDLRCKeywords::WIRE) != 0) break;
109  parse2ndWire();
110 
111  // skip parenthesis
112  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
113  if (')' == m_tok->separatorToken()) return;
114  if ('(' != m_tok->separatorToken()) throw Exception();
115 
116  // skip keyword
117  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
118  }
119 
120  // parse PIPs
121  for (;;)
122  {
123  // parse a PIP if keyword matches
124  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PIP) != 0) break;
125  parse2ndPIP();
126 
127  // skip parenthesis
128  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
129  if (')' == m_tok->separatorToken()) return;
130  if ('(' != m_tok->separatorToken()) throw Exception();
131 
132  // skip keyword
133  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
134  }
135 
136  // skip keyword
137  if (strcmp(m_tok->wordToken(), XDLRCKeywords::TILE_SUMMARY) != 0) throw Exception();
138  // parse tile summary
139  parseTileSummary();
140 
141  // skip closing parenthesis
142  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
143  if (')' != m_tok->separatorToken()) throw Exception();
144 }
145 
146 
147 void XDLRCParserImp::parse2ndPrimitiveSite()
148 {
149  // fetch corresponding primitive site
150  PrimitiveSite& site = m_sites->at(m_primitiveSiteIndex);
151 
152  // read site name and check it
153  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
154  if ((site.name()).compare(m_tok->wordToken()) != 0) throw Exception();
155 
156  // read primitive type name and get its index
157  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
158  size_t primitiveTypeIndex = findPrimitiveType(m_tok->wordToken());
159  // get primitive type, its pin list and pin map
160  m_primitiveType = &(m_primitiveTypes->at(primitiveTypeIndex));
161  m_pins = &(m_primitiveType->pins());
162  m_pinMap = &(m_pinMaps.at(m_primitiveType->tag()));
163 
164  // read keyword and check bonded flag
165  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
166  const char* s = m_tok->wordToken();
167  bool bonded;
168  if (strcmp(s, XDLRCKeywords::INTERNAL) == 0) bonded = false;
169  else if (strcmp(s, XDLRCKeywords::BONDED) == 0) bonded = true;
170  else if (strcmp(s, XDLRCKeywords::UNBONDED) == 0) bonded = false;
171  else throw Exception();
172  if (site.isBonded() != bonded) throw Exception();
173 
174  // create new site type
175  size_t siteTypeCount = m_siteTypes->size();
176  m_siteTypes->push_back(PrimitiveSiteType());
177  m_siteType = &((*m_siteTypes)[siteTypeCount]);
178  // set its primitive type index
179  m_siteType->primitiveTypeIndex(static_cast<unsigned short>(primitiveTypeIndex));
180  // cache pointer to its pin wires
181  m_pinWires = &(m_siteType->pinWires());
182 
183  // read pin wire count (lower bound)
184  size_t count;
185  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
186  if (!m_tok->uintToken(count)) throw Exception();
187  m_pinWires->reserve(count);
188 
189  // pin wires
190  PinWire pinWire;
191  for (;;)
192  {
193  // skip parenthesis
194  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
195  if (')' == m_tok->separatorToken()) return;
196  if ('(' != m_tok->separatorToken()) throw Exception();
197 
198  // skip keyword
199  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
200  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PINWIRE) != 0) throw Exception();
201 
202  // read pin name, get pin index and pin
203  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
204  size_t pinIndex = findPin(m_tok->wordToken());
205  m_pin = &(m_pins->at(pinIndex));
206 
207  // read in/out keyword and check
208  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
209  s = m_tok->wordToken();
210  bool inputFlag;
211  if (strcmp(s, XDLRCKeywords::INPUT) == 0) inputFlag = true;
212  else if (strcmp(s, XDLRCKeywords::OUTPUT) == 0) inputFlag = false;
213  else throw Exception();
214  if (m_pin->isInput() != inputFlag) throw Exception();
215 
216  // read wire name and search it in current tile types wire map
217  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
218  size_t wireIndex = findWire(m_tok->wordToken(), *m_wireMap);
219 
220  // create and add pin wire
221  pinWire.pinIndex(static_cast<unsigned short>(pinIndex));
222  pinWire.wireIndex(static_cast<unsigned short>(wireIndex));
223  m_pinWires->push_back(pinWire);
224 
225  // skip closing parenthesis
226  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
227  if (')' != m_tok->separatorToken()) throw Exception();
228  }
229 }
230 
231 
232 void XDLRCParserImp::parse2ndPrimitiveSiteSkip()
233 {
234  // skip site name
235  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
236 
237  // skip primitive type name
238  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
239 
240  // skip keyword and check bonded flag
241  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
242  const char* s = m_tok->wordToken();
243  if ((strcmp(s, XDLRCKeywords::INTERNAL) != 0) &&
244  (strcmp(s, XDLRCKeywords::BONDED) != 0) &&
245  (strcmp(s, XDLRCKeywords::UNBONDED) != 0))
246  throw Exception();
247 
248  // skip pin wire count
249  size_t count;
250  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
251  if (!m_tok->uintToken(count)) throw Exception();
252 
253  // pin wires
254  for (;;)
255  {
256  // skip parenthesis
257  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
258  if (')' == m_tok->separatorToken()) return;
259  if ('(' != m_tok->separatorToken()) throw Exception();
260 
261  // skip keyword
262  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
263  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PINWIRE) != 0) throw Exception();
264 
265  // skip pin name
266  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
267 
268  // skip in/out keyword
269  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
270  s = m_tok->wordToken();
271  if ((strcmp(s, XDLRCKeywords::INPUT) != 0) &&
272  (strcmp(s, XDLRCKeywords::OUTPUT) != 0))
273  throw Exception();
274 
275  // skip wire name
276  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
277 
278  // skip closing parenthesis
279  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
280  if (')' != m_tok->separatorToken()) throw Exception();
281  }
282 }
283 
284 
285 void XDLRCParserImp::parse2ndWire()
286 {
287  // read wire name and find it
288  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
289  size_t wireIndex = findWire(m_tok->wordToken(), *m_wireMap);
290  Wire& wire = m_wires->at(wireIndex);
291  m_connections = &(wire.connections());
292 
293  // read connection count and reserve it (min value)
294  size_t count;
295  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
296  if (!m_tok->uintToken(count)) throw Exception();
297  m_connections->reserve(count);
298 
299  // connections
300  WireConnection connection;
301  for (;;)
302  {
303  // skip parenthesis
304  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
305  if (')' == m_tok->separatorToken()) return;
306  if ('(' != m_tok->separatorToken()) throw Exception();
307 
308  // skip keyword
309  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
310  if (strcmp(m_tok->wordToken(), XDLRCKeywords::CONN) != 0) throw Exception();
311 
312  // read destination tile name and find tile
313  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
314  size_t tileIndex = findTile(m_tok->wordToken());
315  Tile& tile = m_tiles->at(tileIndex);
316  size_t tileTypeIndex = tile.typeIndex();
317  // set connection tile type and offset
318  connection.xOffset(tile.siteX() - (m_tile->siteX()));
319  connection.yOffset(tile.siteY() - (m_tile->siteY()));
320  connection.tileTypeIndex(static_cast<unsigned short>(tileTypeIndex));
321 
322  // get destination tile type
323  TileTypeEx& tileTypeEx = m_tileTypesEx.at(tileTypeIndex);
324  // read destination wire name and find it
325  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
326  wireIndex = findWire(m_tok->wordToken(), tileTypeEx.wireMap);
327  // set connection wire index
328  connection.wireIndex(static_cast<unsigned short>(wireIndex));
329 
330  // add connection to current wire
331  addConnection(connection);
332 
333  // skip closing parenthesis
334  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
335  if (')' != m_tok->separatorToken()) throw Exception();
336  }
337 }
338 
339 
340 void XDLRCParserImp::parse2ndPIP()
341 {
342  // skip tile name
343  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
344 
345  // skip start wire
346  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
347 
348  // skip keyword
349  m_tok->wordChar('=');
350  m_tok->wordChar('>');
351  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
352  PIPDirection::fromString(m_tok->wordToken());
353  m_tok->separatorChar('=');
354  m_tok->separatorChar('>');
355 
356  // skip end wire
357  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
358 
359  // skip parenthesis
360  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
361  if (')' == m_tok->separatorToken()) return;
362  if ('(' != m_tok->separatorToken()) throw Exception();
363 
364  // skip route-through name
365  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
366  // skip route-through site type
367  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
368  // skip closing parenthesis
369  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
370  if (')' != m_tok->separatorToken()) throw Exception();
371  // skip closing parenthesis
372  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
373  if (')' != m_tok->separatorToken()) throw Exception();
374 }