Bitstream Interpretation Library (BIL)  0.1
Correlator.cpp
Go to the documentation of this file.
1 
6 #include <algorithm>
7 #include <utility>
10 #include <exception/Exception.hpp>
11 
12 using namespace bil;
13 
14 
15 void Correlator::run(DeviceCfgDb& db, const Design& design,
16  const Device& device, CfgExtractor& cfgExtractor)
17 {
18  // init data base
19  {
20  DeviceCfgDbFiller dbFiller;
21  dbFiller.initDeviceDb(db, device);
22  }
23  // get tile type database entries
24  TileTypeCfgDbs& tileTypeDbs = db.tileTypeDbs();
25 
26  // loop over all entries
27  size_t tileTypeDBCount = tileTypeDbs.size();
28  for (size_t i = 0; i < tileTypeDBCount; ++i)
29  {
30  // get tile type database
31  TileTypeCfgDb& tileTypeDb = tileTypeDbs[i];
32 
33  // Gather correlation units for that tile type. If there are no units
34  // available, skip this type and continue with next.
35  gatherCorrelationUnits(tileTypeDb.typeIndex(), design, device, cfgExtractor);
36  if (m_tileUnits.size() == 0) continue;
37 
38  // Build PIP control set map. It will map the index of a PIP to its
39  // corresponding control set.
40  buildPIPControlSetMap(tileTypeDb.pipControlSets());
41 
42  // Init PIP result states. Use first tile correlation unit for
43  // determining the pip and configuration bit size (all units are
44  // required to have the same sizes).
45  const CorrelationUnit& firstUnit = m_tileUnits[0];
46  initPIPStates(firstUnit.pipBitSize(), firstUnit.cfgBitSize());
47 
48  // Do PIP isolation. Walks over the correlation units extracted from
49  // XDL, and writes the results to the PIP result states.
50  isolatePIPs(m_tileUnits);
51 
52  // Write the PIP result states into the data base.
53  writePIPsToDb(tileTypeDb);
54  }
55 }
56 
57 
58 void Correlator::gatherCorrelationUnits(size_t tileTypeIndex,
59  const Design& design, const Device& device, CfgExtractor& cfgExtractor)
60 {
61  // gather correlation units from XDL
62  m_tileUnits.clear();
63  m_tileIndices.clear();
64  XDLExtractor xdlExtractor(design, device);
65  xdlExtractor.getTileTypeUnits(m_tileUnits, m_tileIndices, tileTypeIndex);
66 
67  // loop over gathered units
68  size_t unitIndex = 0;
69  size_t tileIndicesIndex = 0;
70  const Tiles& tiles = device.tiles();
71  while (unitIndex < (m_tileUnits.size()))
72  {
73  // get current unit
74  CorrelationUnit& unit = m_tileUnits[unitIndex];
75  // get corresponding tile and its position
76  size_t tileIndex = m_tileIndices[tileIndicesIndex++];
77  const Tile& tile = tiles.at(tileIndex);
78  unsigned tileRow = tile.row();
79  unsigned tileColumn = tile.column();
80 
81  // get configuration data size of this tile
82  size_t dataWordCount = cfgExtractor.getDataWordCount(tileRow, tileColumn);
83  // if there is no data for it, delete current unit (this happens when
84  // the configuration extractor does not know where to find the data and
85  // returns zero)
86  if (0 != dataWordCount) ++unitIndex;
87  else
88  {
89  m_tileUnits.erase(m_tileUnits.begin() + unitIndex);
90  continue;
91  }
92 
93  // enlarge buffer to hold this data
94  if (m_buffer.size() < dataWordCount) m_buffer.resize(dataWordCount);
95  // copy configuration data into buffer
96  cfgExtractor.getDataWords(tileRow, tileColumn, &(m_buffer[0]), dataWordCount);
97  // set unit's configuration bits accordingly
98  unit.appendCfgBits(&(m_buffer[0]), dataWordCount);
99  }
100 
101  // clear temporary data
102  m_buffer.clear();
103  m_tileIndices.clear();
104 }
105 
106 
107 void Correlator::buildPIPControlSetMap(const PIPControlSets& pipControlSets)
108 {
109  // clear old data
110  m_pipControlSetMap.clear();
111 
112  // loop over all given PIP control sets
113  size_t controlSetCount = pipControlSets.size();
114  for (size_t i = 0; i < controlSetCount; ++i)
115  {
116  // get current PIP control set
117  const PIPControlSet& controlSet = pipControlSets[i];
118 
119  // loop over all its PIPs and their values
120  const PIPBitValues& pipBitValues = controlSet.pipBitValues();
121  size_t pipCount = pipBitValues.size();
122  for (size_t j = 0; j < pipCount; ++j)
123  {
124  // get current PIP index
125  size_t pipIndex = (pipBitValues[j]).pipIndex();
126 
127  // check if every PIP index is used only one time
128  pipControlSetMap_t::iterator lb = m_pipControlSetMap.lower_bound(pipIndex);
129  if ((m_pipControlSetMap.end() != lb) && (pipIndex == lb->first))
130  throw Exception();
131  // insert PIP index with its corresponding control set into map
132  m_pipControlSetMap.insert(lb, std::make_pair(pipIndex, &controlSet));
133  }
134  }
135 }
136 
137 
138 void Correlator::initPIPStates(size_t pipCount, size_t cfgBitCount)
139 {
140  // create as many PIP states as we have got PIPs and init them
141  m_pipStates.resize(pipCount);
142  for (size_t i = 0; i < pipCount; ++i)
143  {
144  CorrelationUnit& pipState = m_pipStates[i];
145  pipState.pipBitSize(pipCount);
146  pipState.setPIPBits();
147  pipState.cfgBitSize(cfgBitCount);
148  pipState.setCfgBits();
149  }
150 }
151 
152 
153 void Correlator::isolatePIPs(CorrelationUnits& correlationUnits)
154 {
155  // loop over all PIPs
156  size_t pipCount = m_pipStates.size();
157  for (size_t i = 0; i < pipCount; ++i)
158  {
159  // get PIP state for current PIP
160  CorrelationUnit& state = m_pipStates[i];
161 
162  // get control set the current PIP is in
163  pipControlSetMap_t::const_iterator it = m_pipControlSetMap.find(i);
164  if (m_pipControlSetMap.end() == it) throw Exception();
165  const PIPControlSet& controlSet = *(it->second);
166  // get the control set's PIPs
167  const PIPBitValues& pipBitValues = controlSet.pipBitValues();
168  size_t pipCountCs = pipBitValues.size();
169 
170  // loop over all given correlation units
171  size_t unitCount = correlationUnits.size();
172  for (size_t j = 0; j < unitCount; ++j)
173  {
174  // Get current unit and intersect state with it if compatible. An
175  // unit is compatible, if the current PIP is active in it, or if the
176  // current PIP and all other PIPs of its control set are inactive.
177  const CorrelationUnit& unit = correlationUnits[j];
178  if (unit.testPIPBit(i)) state.intersect(unit);
179  else
180  {
181  // check if all PIPs in control set are also inactive
182  bool compatible = true;
183  for (size_t k = 0; k < pipCountCs; ++k)
184  if (unit.testPIPBit((pipBitValues[k]).pipIndex()))
185  {
186  compatible = false;
187  break;
188  }
189  // if compatible do intersection with the inverse
190  if (compatible) state.intersectInverted(unit);
191  }
192  }
193  }
194 }
195 
196 
197 void Correlator::writePIPsToDb(TileTypeCfgDb& tileTypeDb)
198 {
199  // loop over all control sets of this type
200  PIPControlSets& controlSets = tileTypeDb.pipControlSets();
201  size_t controlSetCount = controlSets.size();
202  for (size_t i = 0; i < controlSetCount; ++i)
203  {
204  // get current control set and its sub objects
205  PIPControlSet& controlSet = controlSets[i];
206  BitPositions& bitPositions = controlSet.bitPositions();
207  PIPBitValues& pipBitValues = controlSet.pipBitValues();
208 
209  // read out the correlation results into them
210  getCfgBitPositions(bitPositions, pipBitValues);
211  getCfgBitValues(pipBitValues, bitPositions);
212 
213  // sort the retrieved values, eases later usage
214  PIPBitValues::iterator itBegin = pipBitValues.begin();
215  PIPBitValues::iterator itEnd = pipBitValues.end();
216  std::sort(itBegin, itEnd);
217  }
218 }
219 
220 
221 void Correlator::getCfgBitPositions(BitPositions &bitPositions,
222  const PIPBitValues& pipBitValues) const
223 {
224  // clear old data
225  bitPositions.clear();
226 
227  // loop over all given PIPs
228  size_t pipCount = pipBitValues.size();
229  for (size_t i = 0; i < pipCount; ++i)
230  {
231  // get index of current PIP and its correlation state
232  size_t pipIndex = (pipBitValues[i]).pipIndex();
233  const CorrelationUnit& pipState = m_pipStates.at(pipIndex);
234 
235  // take only isolated PIPs in account
236  if (!pipState.isIsolated()) continue;
237 
238  // get positions of all set bits in state and insert it ordered
239  size_t bitIndex = pipState.firstCfgBit();
240  while (CorrelationUnit::INVALID_BIT_INDEX != bitIndex)
241  {
242  // get insertion point
243  BitPositions::iterator itBegin = bitPositions.begin();
244  BitPositions::iterator itEnd = bitPositions.end();
245  BitPositions::iterator it = std::lower_bound(itBegin, itEnd, bitIndex);
246  // insert it, if its not in list
247  if ((it == itEnd) || (*it != bitIndex))
248  bitPositions.insert(it, bitIndex);
249  // get next set bit
250  bitIndex = pipState.nextCfgBit(bitIndex);
251  }
252  }
253 }
254 
255 
256 void Correlator::getCfgBitValues(PIPBitValues& pipBitValues,
257  const BitPositions &bitPositions) const
258 {
259  // Get number of bits/bit positions and check, that it fits into the bit
260  // value entries (highest bit is used for encoding if PIP is isolated).
261  size_t bitPositionCount = bitPositions.size();
262  if (PIPBitValue::MAX_BIT_COUNT <= bitPositionCount) throw Exception();
263 
264  // loop over all given PIPs and their cfg values
265  size_t pipCount = pipBitValues.size();
266  for (size_t i = 0; i < pipCount; ++i)
267  {
268  // get value object of current PIP
269  PIPBitValue& pipBitValue = pipBitValues[i];
270 
271  // get corresponding correlation result
272  size_t pipIndex = pipBitValue.pipIndex();
273  const CorrelationUnit& pipState = m_pipStates.at(pipIndex);
274 
275  // loop over given bit positions and read out these result bits
276  boost::uint32_t value = 0;
277  for (size_t j = bitPositionCount; j-- > 0;)
278  {
279  value <<= 1;
280  size_t bitPosition = bitPositions[j];
281  if (pipState.testCfgBit(bitPosition)) value |= 1;
282  }
283 
284  // flag PIPs that are not isolated
285  if (!pipState.isIsolated()) value |= PIPBitValue::VALUE_UNUSED;
286 
287  // write new value
288  pipBitValue.bitValue(value);
289  }
290 }