Bitstream Interpretation Library (BIL)  0.1
v5cfgmap_genAlgo.cpp
Go to the documentation of this file.
1 
10 
11 using namespace bil;
12 
13 
14 const char* const NULL_TYPENAME = "NULL";
15 const char* const T_TERM_INT_D_TYPENAME = "T_TERM_INT_D";
16 const char* const CLK_TERM_TOP_TYPENAME = "CLK_TERM_TOP";
17 const char* const INT_TYPENAME = "INT";
18 
19 static size_t nullTypeIndex;
20 static size_t tTermIntDTypeIndex;
21 static size_t clkTermTopTypeIndex;
22 static size_t intTypeIndex;
23 static size_t intInterfaceTypeIndex;
24 
25 
26 static size_t getTileTypeIndex(const char* tileTypeName, const TileTypes& types)
27 {
28  size_t tileTypeCount = types.size();
29  for (size_t i = 0; i < tileTypeCount; ++i)
30  {
31  const std::string& typeName = (types[i]).name();
32  if (0 == typeName.compare(tileTypeName)) return i;
33  }
34  throw Exception();
35 }
36 
37 
38 static size_t getTileTypeIndex(unsigned row, unsigned column, const TileLookup2D& tileLookup)
39 {
40  const Tile* tile = tileLookup.lookup(row, column);
41  if (0 == tile) throw Exception();
42  return tile->typeIndex();
43 }
44 
45 
46 static void initMap(V5CfgTileMap& map)
47 {
48  // clear all map entries and make them reference no data
49  unsigned rowCount = map.rowCount();
50  unsigned columnCount = map.columnCount();
51  for (unsigned column = 0; column < columnCount; ++column)
52  {
53  for (unsigned row = 0; row < rowCount; ++row)
54  {
55  V5CfgTileMapEntry& entry = map.entries(row, column);
56  entry.columnIndex = 0;
57  entry.lowerHalf = false;
58  entry.rowIndex = 0;
59  entry.frameBeginIndex = 1;
60  entry.frameEndIndex = 0;
61  entry.wordBeginOffset = 1;
62  entry.wordEndOffset = 0;
63  }
64  }
65 }
66 
67 
68 static void writeCfgColumnIndices(V5CfgTileMap& map, const TileLookup2D& tileLookup)
69 {
70  // init column index and first T_TERM_INT_D flag
71  unsigned char cfgColIndex = 0;
72  bool firstTTermIntD = true;
73 
74  // walk along first row from left to right
75  unsigned rowCount = tileLookup.rowCount();
76  unsigned columnCount = tileLookup.columnCount();
77  for (unsigned column = 0; column < columnCount; ++column)
78  {
79  // Get tile on top of current column and check its type: Only
80  // T_TERM_INT_D, CLK_TERM_TOP, and NULL tile types must occur.
81  // T_TERM_INT_D and CLK_TERM_TOP indicate the beginning of next
82  // configuration column.
83  size_t tileTypeIndex = getTileTypeIndex(0, column, tileLookup);
84  if (tileTypeIndex != nullTypeIndex)
85  {
86  if (tileTypeIndex == tTermIntDTypeIndex)
87  {
88  // First T_TERM_INT_D does not begin a new configuration column.
89  if (!firstTTermIntD) ++cfgColIndex;
90  firstTTermIntD = false;
91  }
92  else if (tileTypeIndex == clkTermTopTypeIndex) ++cfgColIndex;
93  else throw Exception();
94  }
95  // copy data to current column
96  for (unsigned row = 0; row < rowCount; ++row)
97  {
98  V5CfgTileMapEntry& entry = map.entries(row, column);
99  entry.columnIndex = cfgColIndex;
100  }
101  }
102 }
103 
104 
105 static void writeTileColumns(V5CfgTileMap& map, const TileLookup2D& tileLookup,
106  unsigned upperCfgRows, unsigned lowerCfgRows)
107 {
108  // walk along from left to right
109  unsigned rowCount = tileLookup.rowCount();
110  unsigned columnCount = tileLookup.columnCount();
111  for (unsigned column = 0; column < columnCount; ++column)
112  {
113  size_t frameIndexBegin;
114  size_t frameIndexEnd;
115  const FrameOffsets* frameOffsets;
116 
117  // get type of tiles in current tile column and select the appropriate
118  // tile column pattern
119  size_t tileTypeIndex = getTileTypeIndex(5, column, tileLookup);
120  if (tileTypeIndex == intTypeIndex)
121  {
122  // INT tiles (correlation gets good results on this type, so tag
123  // these tiles with the configuration addresses)
124  frameIndexBegin = V5_INT_FRAMEINDEX_BEGIN;
125  frameIndexEnd = V5_INT_FRAMEINDEX_END;
126  frameOffsets = V5_INT_TILECOLUMN;
127  }
128  else
129  {
130  // all others (correlation doesn't work at the moment with all other
131  // tile types, so don't tag them with configuration addresses)
132  frameIndexBegin = V5_NULL_FRAMEINDEX_BEGIN;
133  frameIndexEnd = V5_NULL_FRAMEINDEX_END;
134  frameOffsets = V5_NULL_TILECOLUMN;
135  }
136 
137  // walk down the column row by row, and apply the previously selected
138  // pattern
139  bool lowerHalf = false;
140  size_t cfgRowIndex = upperCfgRows - 1;
141  size_t rowState = 0;
142  for (unsigned row = 0; row < rowCount; ++row)
143  {
144  // copy temp vars into map entry
145  V5CfgTileMapEntry& entry = map.entries(row, column);
146  entry.lowerHalf = lowerHalf;
147  entry.rowIndex = static_cast<unsigned char>(cfgRowIndex);
148  entry.frameBeginIndex = static_cast<unsigned char>(frameIndexBegin);
149  entry.frameEndIndex = static_cast<unsigned char>(frameIndexEnd);
150 
151  // state machine for applying pattern
152  if (0 == rowState)
153  {
154  // tiles in the upper half of a configuration row
155  entry.wordBeginOffset = 1;
156  entry.wordEndOffset = 0;
157  ++rowState;
158  }
159  else if (rowState <= V5_FRAME_TILESPAN)
160  {
161  // middle HCLK row
162  const FrameOffsets& offsets = frameOffsets[rowState-1];
163  entry.wordBeginOffset = static_cast<unsigned char>(offsets.wordBeginOffset);
164  entry.wordEndOffset = static_cast<unsigned char>(offsets.wordEndOffset);
165  ++rowState;
166  }
167  else
168  {
169  // tiles in lower half of configuration row
170  entry.wordBeginOffset = 1;
171  entry.wordEndOffset = 0;
172  // handle configuration row count and upper/lower flag
173  if (lowerHalf)
174  {
175  if (lowerCfgRows > cfgRowIndex) ++cfgRowIndex;
176  else throw Exception();
177  }
178  else
179  {
180  if (0 != cfgRowIndex) --cfgRowIndex;
181  else lowerHalf = true;
182  }
183  rowState = 1;
184  }
185  }
186 
187  // if the bottom most tile is reached, only this state is valid
188  if (1 != rowState) throw Exception();
189  }
190 }
191 
192 
193 void generateCfgTileMap(V5CfgTileMap& map, const Device& device,
194  const V5AddressLayout& addressLayout)
195 {
196  // tiles of these types mark configuration column sections
197  const TileTypes& tileTypes = device.tileTypes();
198  nullTypeIndex = getTileTypeIndex(NULL_TYPENAME, tileTypes);
199  tTermIntDTypeIndex = getTileTypeIndex(T_TERM_INT_D_TYPENAME, tileTypes);
200  clkTermTopTypeIndex = getTileTypeIndex(CLK_TERM_TOP_TYPENAME, tileTypes);
201 
202  // these tile types are important for detecting known tile columns
203  intTypeIndex = getTileTypeIndex(INT_TYPENAME, tileTypes);
204 
205  // build tile lookup
206  TileLookup2D tileLookup;
207  tileLookup.reset(device);
208 
209  // check grid extends
210  unsigned rowCount = tileLookup.rowCount();
211  if (0 == rowCount) return;
212  unsigned columnCount = tileLookup.columnCount();
213  if (0 == columnCount) return;
214 
215  // set map size according to tile grid
216  map.resize(rowCount, columnCount);
217 
218  // fill map with data
219  initMap(map);
220  writeCfgColumnIndices(map, tileLookup);
221  writeTileColumns(map, tileLookup, addressLayout.upperRowCount(), addressLayout.lowerRowCount());
222 }