torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ArcUsage.hpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
16 /// \file
17 /// \brief Header for the ArcUsage class.
18 
19 #ifndef TORC_ARCHITECTURE_ARCUSAGE_HPP
20 #define TORC_ARCHITECTURE_ARCUSAGE_HPP
21 
26 #include <boost/dynamic_bitset.hpp>
27 
28 namespace torc {
29 namespace architecture {
30 
31 namespace architecture { class ArcUsageUnitTest; }
32 
33  /// \brief Encapsulation the design arc usage.
34  /// \details This class uses a compact bitset representation to very efficiently track the arc
35  /// usage of a design in an entire device. Internal bitset objects are maintained on a
36  /// per-tile basis, and are not allocated until at least one arc in the tile has been
37  /// marked used.
38  class ArcUsage {
39  /// \brief Our unit test class has access to our internals.
41  protected:
42  // types
43  typedef boost::dynamic_bitset<> dynamic_bitset; ///< \brief Imported type name.
44  typedef xilinx::TileIndex TileIndex; ///< \brief Imported type name.
45  typedef xilinx::TileCount TileCount; ///< \brief Imported type name.
46  typedef xilinx::TileTypeIndex TileTypeIndex; ///< \brief Imported type name.
47  typedef xilinx::WireIndex WireIndex; ///< \brief Imported type name.
48  // members
49  /// \brief Reference to the database Tiles object.
50  const Tiles& mTiles;
51  /// \brief The number of tiles for which bitsets are allocated.
53  /// \brief The wire usage bitset array.
55  /// \brief The number of bits allocated by the usage bitsets.
56  uint32_t mBitCount;
57  /// \brief The mask of tile bitsets that contain changes.
59  // functions
60  /// \brief Returns the offset into the bitset for the specified arc.
61  /// \note The ordering of regular, irregular, routethrough, and tied sinks does not matter
62  /// as long as it is consistent. The only impact comes from the likelihood of access
63  /// for the different types, where more common ones ought to be visited first.
64  uint32_t getArcOffset(const Tilewire& inTilewire1, const Tilewire& inTilewire2) const {
65  // first make sure the arc is defined
66  if(inTilewire1.isUndefined() || inTilewire2.isUndefined())
67  throw InvalidArcException(Arc(inTilewire1, inTilewire2));
68  // look up the relevant tile and wire indexes
69  TileIndex tile1 = inTilewire1.getTileIndex();
70  WireIndex wire1 = inTilewire1.getWireIndex();
71  WireIndex wire2 = inTilewire2.getWireIndex();
72  // determine the tile type
73  const TileInfo& tileInfo = mTiles.getTileInfo(tile1);
74  TileTypeIndex type = tileInfo.getTypeIndex();
75  // next get the wire's base arc offset
76  const WireInfo& wireInfo = mTiles.getWireInfo(type, wire1);
77  uint32_t offset = wireInfo.getArcOffset();
78  // look for a regular sink
79  const WireArray& sinks = wireInfo.getSinks();
80  for(WireIndex i; i < sinks.getSize(); i++) {
81  if(sinks[i] == wire2) return offset;
82  offset++;
83  }
84  // look for an irregular sink
85  const WireArray& irregularSinks = wireInfo.getIrregularSinks();
86  for(WireIndex i; i < irregularSinks.getSize(); i++) {
87  if(irregularSinks[i] == wire2) return offset;
88  offset++;
89  }
90  // look for a routethrough sink
91  const WireArray& routethroughSinks = wireInfo.getRoutethroughSinks();
92  for(WireIndex i; i < routethroughSinks.getSize(); i++) {
93  if(routethroughSinks[i] == wire2) return offset;
94  offset++;
95  }
96  // look for a tied sink
97  const WireArray& tiedSinks = wireInfo.getTiedSinks();
98  for(WireIndex i; i < tiedSinks.getSize(); i++) {
99  if(tiedSinks[i] == wire2) return offset;
100  offset++;
101  }
102  // if we didn't find the sink in the regular or irregular arcs, the call failed
103  /// \todo Throw a meaningful exception.
104  throw InvalidArcException(Arc(inTilewire1, inTilewire2));
105  }
106  public:
107  // constructors
108  /// \brief Public constructor.
109  ArcUsage(const Tiles& inTiles) : mTiles(inTiles), mTileUsageCount(), mBitsets(0),
110  mBitCount(0), mTileDirty(0) {}
111  /// \brief Non-virtual destructor.
112  ~ArcUsage(void) {
113  size_t tileCount = mBitsets.getSize();
114  for(TileIndex i; i < tileCount; i++) {
115  if(mBitsets[i] != 0) { delete mBitsets[i]; mBitsets[i] = 0; }
116  }
117  }
118  // functions
119  /// \brief Size the wire usage according to the number of device tiles.
120  void autosize(void) {
121  // release any existing bitsets
122  for(TileCount i; i < mBitsets.getSize(); i++) {
123  if(mBitsets[i] != 0) { delete mBitsets[i]; mBitsets[i] = 0; }
124  mTileDirty.reset(i);
125  }
126  // resize for the new dimensions
127  TileCount tileCount = mTiles.getTileCount();
128  mBitsets.setSize(tileCount);
129  for(TileCount i; i < tileCount; i++) mBitsets[i] = 0;
130  mTileDirty.resize(tileCount);
131  }
132  /// \brief Marks the specified arc as being used.
133  inline void use(const Arc& inArc)
134  { use(inArc.getSourceTilewire(), inArc.getSinkTilewire()); }
135  /// \brief Marks the specified arc as being used.
136  void use(const Tilewire& inTilewire1, const Tilewire& inTilewire2) {
137  // extract the tile indexes
138  TileIndex tileIndex1 = inTilewire1.getTileIndex();
139  TileIndex tileIndex2 = inTilewire2.getTileIndex();
140  // ensure that these tilewires belong to the same tile
141  /// \todo Throw a meaningful exception.
142  if(tileIndex1 != tileIndex2) throw InvalidArcException(Arc(inTilewire1, inTilewire2));
143 
144  // make sure we have a bitset for this tile
145  dynamic_bitset* bitset = mBitsets[tileIndex1];
146  if(bitset == 0) {
147  // determine how many arcs are in this tile
148  const TileInfo& tileInfo = mTiles.getTileInfo(tileIndex1);
149  TileTypeIndex type = tileInfo.getTypeIndex();
150  const Array<const WireInfo>& wires = mTiles.getWireInfo(type);
151  if(wires.getSize() == 0) return;
152  const WireInfo& wireInfo = mTiles.getWireInfo(type, WireIndex(wires.getSize() - 1));
153  // caution: we have to add the regular and irregular sink count from the last wire
154  size_t size = wireInfo.getArcOffset() + wireInfo.getSinks().getSize()
155  + wireInfo.getIrregularSinks().getSize()
156  + wireInfo.getRoutethroughSinks().getSize()
157  + wireInfo.getTiedSinks().getSize();
158  bitset = mBitsets[tileIndex1] = new dynamic_bitset(size);
159  // track the statistics
160  mTileUsageCount++;
161  mBitCount += size;
162  }
163 
164  // set the bit and mark the tile dirty
165  bitset->set(getArcOffset(inTilewire1, inTilewire2));
166  mTileDirty.set(tileIndex1, true);
167  }
168  /// \brief Marks the specified arc as being unused.
169  inline void release(const Arc& inArc)
170  { release(inArc.getSourceTilewire(), inArc.getSinkTilewire()); }
171  /// \brief Marks the specified arc as being unused.
172  void release(const Tilewire& inTilewire1, const Tilewire& inTilewire2) {
173  // extract the tile indexes
174  TileIndex tileIndex1 = inTilewire1.getTileIndex();
175  TileIndex tileIndex2 = inTilewire2.getTileIndex();
176  // ensure that these tilewires belong to the same tile
177  /// \todo Throw a meaningful exception.
178  if(tileIndex1 != tileIndex2) throw -1;
179 
180  // if there is no entry for the tile, the arc is already implicitly unused.
181  dynamic_bitset* bitset = mBitsets[tileIndex1];
182  if(bitset == 0) return;
183 
184  // otherwise clear the bit and mark the tile dirty
185  bitset->set(getArcOffset(inTilewire1, inTilewire2), false);
186  mTileDirty.set(tileIndex1, true);
187  }
188  /// \brief Marks all arcs as being unused, without releasing the bitset objects.
189  /// \details This capability allows the tracer to track the wires that it has visited while
190  /// processing a particular net, and then to start again from scratch without incurring
191  /// allocation and construction overheads.
192  void clear(void) {
193  // iterate over all of the tiles
194  size_t tileCount = mBitsets.getSize();
195  for(TileIndex i; i < tileCount; i++) {
196  // skip this tile if it isn't dirty
197  if(!mTileDirty[i]) continue;
198  // mark the tile clean
199  mTileDirty.reset(i);
200  // look up the bitset for this tile
201  dynamic_bitset* bitset = mBitsets[i];
202  // skip tiles without an associated bitset (should never happen for dirty tiles)
203  if(bitset == 0) continue;
204  // clear the entire bitset
205  bitset->reset();
206  }
207  }
208  /// \brief Determines whether the specified arc is in use.
209  inline bool isUsed(const Arc& inArc)
210  { return isUsed(inArc.getSourceTilewire(), inArc.getSinkTilewire()); }
211  /// \brief Determines whether the specified arc is in use.
212  bool isUsed(const Tilewire& inTilewire1, const Tilewire& inTilewire2) const {
213  // extract the tile indexes
214  TileIndex tileIndex1 = inTilewire1.getTileIndex();
215  TileIndex tileIndex2 = inTilewire2.getTileIndex();
216  // ensure that these tilewires belong to the same tile
217  /// \todo Throw a meaningful exception.
218  if(tileIndex1 != tileIndex2) throw -1;
219 
220  // if there is no entry for the tile, the tilewire is already implicitly unused.
221  dynamic_bitset* bitset = mBitsets[tileIndex1];
222  if(bitset == 0) return false;
223 
224  // otherwise, interrogate the bit
225  return bitset->test(getArcOffset(inTilewire1, inTilewire2));
226  }
227  /// \brief Returns the number of arcs in use.
228  uint32_t getArcUsageCount(void) const {
229  uint32_t usageCount = 0;
230  size_t tileCount = mBitsets.getSize();
231  for(TileIndex i; i < tileCount; i++) {
232  /// \todo Question: can we get away with only checking dirty bitsets?
233  //// skip this tile if it isn't dirty
234  //if(!mTileDirty[i]) continue;
235  // look up the bitset for this tile
236  dynamic_bitset* bitset = mBitsets[i];
237  // skip tiles without an associated bitset
238  if(bitset == 0) continue;
239  // clear the entire bitset
240  usageCount += bitset->count();
241  }
242  return usageCount;
243  }
244  // accessors
245  /// \brief Returns the number of tiles that have been touched.
247  /// \brief Returns the number of bits allocated.
248  uint32_t getBitCount(void) const { return mBitCount; }
249  };
250 
251 } // namespace architecture
252 } // namespace torc
253 
254 #endif // TORC_ARCHITECTURE_ARCUSAGE_HPP
xilinx::TileIndex TileIndex
Imported type name.
Definition: ArcUsage.hpp:44
const WireIndex & getWireIndex(void) const
Returns the wire index.
Definition: Tilewire.hpp:66
Encapsulation of a tile index in an unsigned 32-bit integer.
Encapsulation of an arc between two tilewires.
Definition: Arc.hpp:28
void autosize(void)
Size the wire usage according to the number of device tiles.
Definition: ArcUsage.hpp:120
const Tiles & mTiles
Reference to the database Tiles object.
Definition: ArcUsage.hpp:50
void clear(void)
Marks all arcs as being unused, without releasing the bitset objects.
Definition: ArcUsage.hpp:192
~ArcUsage(void)
Non-virtual destructor.
Definition: ArcUsage.hpp:112
Array of wire indexes.
Definition: WireInfo.hpp:31
Array< dynamic_bitset * > mBitsets
The wire usage bitset array.
Definition: ArcUsage.hpp:54
TileCount getTileUsageCount(void) const
Returns the number of tiles that have been touched.
Definition: ArcUsage.hpp:246
uint32_t mBitCount
The number of bits allocated by the usage bitsets.
Definition: ArcUsage.hpp:56
const TileInfo & getTileInfo(TileIndex inTileIndex) const
Returns the TileInfo object for the specified tile.
Definition: Tiles.hpp:137
const uint16_t getArcOffset(void) const
Returns this wire's offset into the arc usage bitset.
Definition: WireInfo.hpp:105
ArcUsage(const Tiles &inTiles)
Public constructor.
Definition: ArcUsage.hpp:109
friend class torc::architecture::architecture::ArcUsageUnitTest
Our unit test class has access to our internals.
Definition: ArcUsage.hpp:40
Header for the Arc class.
const WireArray & getIrregularSinks(void) const
Returns the irregular sink array for this wire.
Definition: WireInfo.hpp:119
uint32_t getArcUsageCount(void) const
Returns the number of arcs in use.
Definition: ArcUsage.hpp:228
uint32_t getArcOffset(const Tilewire &inTilewire1, const Tilewire &inTilewire2) const
Returns the offset into the bitset for the specified arc.
Definition: ArcUsage.hpp:64
const Array< const WireInfo > & getWireInfo(TileTypeIndex inTileTypeIndex) const
Returns the WireInfo array for the specified tile type.
Definition: Tiles.hpp:140
void use(const Tilewire &inTilewire1, const Tilewire &inTilewire2)
Marks the specified arc as being used.
Definition: ArcUsage.hpp:136
Encapsulation of a wire index in an unsigned 16-bit integer.
TileCount getTileCount(void) const
Returns the tile count for this device.
Definition: Tiles.hpp:149
const Tilewire & getSourceTilewire(void) const
Returns the source tilewire.
Definition: Arc.hpp:45
bool isUsed(const Tilewire &inTilewire1, const Tilewire &inTilewire2) const
Determines whether the specified arc is in use.
Definition: ArcUsage.hpp:212
const Tilewire & getSinkTilewire(void) const
Returns the sink tilewire.
Definition: Arc.hpp:47
xilinx::WireIndex WireIndex
Imported type name.
Definition: ArcUsage.hpp:47
uint32_t getBitCount(void) const
Returns the number of bits allocated.
Definition: ArcUsage.hpp:248
void use(const Arc &inArc)
Marks the specified arc as being used.
Definition: ArcUsage.hpp:133
Encapsulation of a device tile and wire pair.
Definition: Tilewire.hpp:39
Encapsulation the design arc usage.
Definition: ArcUsage.hpp:38
Tile map, tile type, and wire information for the family and device.
Definition: Tiles.hpp:36
Encapsulation of a tile count in an unsigned 32-bit integer.
const WireArray & getSinks(void) const
Returns the sink array for this wire.
Definition: WireInfo.hpp:115
Encapsulation of a tile within a device tile map.
Definition: TileInfo.hpp:33
xilinx::TileCount TileCount
Imported type name.
Definition: ArcUsage.hpp:45
const TileTypeIndex & getTypeIndex(void) const
Returns the tile type index for this tile.
Definition: TileInfo.hpp:92
const WireArray & getRoutethroughSinks(void) const
Returns the routethrough sink array for this wire.
Definition: WireInfo.hpp:123
Header for the Tilewire class.
dynamic_bitset mTileDirty
The mask of tile bitsets that contain changes.
Definition: ArcUsage.hpp:58
Header for the Array class.
Encapsulation of a tile type index in an unsigned 16-bit integer.
xilinx::TileTypeIndex TileTypeIndex
Imported type name.
Definition: ArcUsage.hpp:46
void release(const Tilewire &inTilewire1, const Tilewire &inTilewire2)
Marks the specified arc as being unused.
Definition: ArcUsage.hpp:172
const WireArray & getTiedSinks(void) const
Returns the tied sink array for this wire.
Definition: WireInfo.hpp:111
const TileIndex & getTileIndex(void) const
Returns the tile index.
Definition: Tilewire.hpp:64
void setSize(uint32_t inSize)
Discards all contents and resizes the array.
Definition: Array.hpp:107
void release(const Arc &inArc)
Marks the specified arc as being unused.
Definition: ArcUsage.hpp:169
Encapsulation of a wire within a tile type.
Definition: WireInfo.hpp:36
bool isUndefined(void) const
Definition: Tilewire.hpp:86
Header for the Tiles class.
bool isUsed(const Arc &inArc)
Determines whether the specified arc is in use.
Definition: ArcUsage.hpp:209
boost::dynamic_bitset dynamic_bitset
Imported type name.
Definition: ArcUsage.hpp:43
TileCount mTileUsageCount
The number of tiles for which bitsets are allocated.
Definition: ArcUsage.hpp:52
uint32_t getSize(void) const
Returns the array size.
Definition: Array.hpp:104