torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Segments.cpp
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 Source for the Segments class.
18 
20 #include <iostream>
21 
22 namespace torc {
23 namespace architecture {
24 
25  const Segments::SegmentReference Segments::SegmentReference::sTrivialSegmentReference;
26 
27  Segments::Segments(void) : mCompactSegments(), mTilewireSegments(), mIrregularArcs(),
28  mCompactSegmentCount(), mIrregularArcCount(), mTotalWireCount(), mPrunedWireCount(),
29  mActualWireCount(), mTrivialSegmentCount(), mNonTrivialSegmentCount(), mTotalSegmentCount()
30  {}
31 
33  // prepare to read from the stream
34  size_t bytesReadOffset = inStream.getBytesRead();
35  TileCount tileCount; // number of tiles
36  uint16_t tileWireCount = 0; // number of wires in the current tile
37  uint16_t extraWireCount = 0; // number of extra wires in the current tile
38  WireIndex wireIndex; // index of extra wire
39 
40  //mErr() << "NOTICE: Remove unnecessary clearing of mTilewireSegment wires."
41  // << std::endl;
42  // read the section header
43  string sectionName;
44  inStream.readSectionHeader(sectionName);
45  /// \todo Throw a proper exception.
46  if(sectionName != ">>>>TileSegs>>>>") throw -1;
47 
48  // initialize the tile segment array
49  inStream.read(tileCount);
50  mTilewireSegments.setSize(tileCount);
51  mOut() << "\tReading " << tileCount << " tiles..." << std::endl;
52  // loop through each tile
53  for(TileIndex i; i < tileCount; i++) {
54  // initialize each tile sub-array
55  inStream.read(tileWireCount);
56  mTilewireSegments[i].setSize(tileWireCount);
57  // the following clearing of SegementReference entris should no longer be necessary
58  // for(WireIndex j; j < tileWireCount; j++)
59  // mTilewireSegments[i][j] = SegmentReference();
60  // read the extra wires that we can't infer from the segments
61  inStream.read(extraWireCount);
62  // mErr() << i << "#" << tileWireCount << ":" << extraWireCount << "="
63  // << mActualWireCount << " ";
64  mTotalWireCount += tileWireCount;
65  mActualWireCount += tileWireCount - extraWireCount;
66  mPrunedWireCount += extraWireCount;
67  // mErr() << "\t" << i << ": ";
68  for(WireIndex j; j < extraWireCount; j++) {
69  // read the wire index
70  inStream.read(wireIndex);
71  // the current database implicitly assumes that only -1 (non-existent) wires are
72  // encoded, so we don't need to read the segment index; that assumption would not
73  // hold if we had to handle removed wires.
74  //// read the segment value
75  //inStream.read(segmentIndex);
76  // store the data
77  mTilewireSegments[i][wireIndex].undefine();
78  // mErr() << wireIndex << " ";
79  }
80  // mErr() << std::endl;
81  mTotalSegmentCount += tileWireCount - extraWireCount;
82  }
83  //mOut() << "\t" << mActualWireCount << " total wires" << std::endl;
84 
85  // return the number of bytes read
86  return inStream.getBytesRead() - bytesReadOffset;
87  }
88 
89  size_t Segments::readSegments(DigestStream& inStream, bool inExtendedAnchorTileCount) {
90  // prepare to read from the stream
91  size_t bytesReadOffset = inStream.getBytesRead();
92  uint16_t wireCount = 0; // number of wires in the segment
93  uint32_t offsetCount = 0; // number of offset tiles which use the segment
94  WireIndex wireIndex; // current wire index
95  TileOffset tileOffset; // current tile offset
96  TileIndex rootTileIndex; // compact segment root tile index
97 
98  // read the section header
99  string sectionName;
100  inStream.readSectionHeader(sectionName);
101  /// \todo Throw a proper exception.
102  if(sectionName != ">>>>Segments>>>>") throw -1;
103 
104  // initialize the tile segment array
105  inStream.read(mCompactSegmentCount);
107  mOut() << "\tReading " << mCompactSegmentCount << " segments..." << std::endl;
108  // loop through each segment (except segment zero)
109  for(CompactSegmentIndex i; i < mCompactSegmentCount; i++) {
110  // initialize each segment sub-array
111  inStream.read(wireCount);
112  mCompactSegments[i].setSize(wireCount);
113  // loop through each wire in the segment
114  for(WireIndex j; j < wireCount; j++) {
115  // read the wire and tile indexes
116  inStream.read(wireIndex);
117  inStream.read(tileOffset);
118  // store the data
119  mCompactSegments[i][j] = CompactSegmentTilewire(wireIndex, tileOffset);
120  }
121  // initialize each offset location
122  if(inExtendedAnchorTileCount) {
123  // read a 32-bit anchor tile count
124  inStream.read(offsetCount);
125  } else {
126  // read the standard 16-bit anchor tile count
127  uint16_t shortOffsetCount;
128  inStream.read(shortOffsetCount);
129  offsetCount = shortOffsetCount;
130  }
131  // loop through each offset for this segment
132  for(uint32_t j = 0; j < offsetCount; j++) {
134  // read the root tile
135  inStream.read(rootTileIndex);
136  // expand the data into each applicable tile
137  for(WireIndex k; k < wireCount; k++) {
138  const CompactSegmentTilewire compactSegmentTilewire = mCompactSegments[i][k];
139  TileIndex tileIndex = TileIndex(rootTileIndex + compactSegmentTilewire.getTileOffset());
140  WireIndex wireIndex = compactSegmentTilewire.getWireIndex();
141 const SegmentReference& existing = mTilewireSegments[tileIndex][wireIndex];
142 if(existing.getCompactSegmentIndex() != 0 || existing.getAnchorTileIndex() != 0) {
143  mErr() << "WARNING: Overwriting mTilewireSegments[" << tileIndex << "][" << wireIndex << "]: "
144  << "conflict is " << i << "@" << rootTileIndex << " versus " << existing.getCompactSegmentIndex()
145  << "@" << existing.getAnchorTileIndex() << std::endl;
146 }
147  mTilewireSegments[tileIndex][wireIndex] = SegmentReference(i, rootTileIndex);
148  }
149  }
150  }
151 
152  // clear the usage information for all tilewires
153  TileCount tileCount(mTilewireSegments.getSize());
154  for(TileIndex tileIndex; tileIndex < tileCount; tileIndex++) {
155  const Array<SegmentReference>& tilewireSegments = mTilewireSegments[tileIndex];
156  Array<SegmentReference>::const_iterator p = tilewireSegments.begin();
157  Array<SegmentReference>::const_iterator e = tilewireSegments.end();
158  while(p < e) {
159  const SegmentReference& segmentReference = *p++;
160  if(segmentReference.isTrivial()) mTrivialSegmentCount++;
161  }
162  }
163 
164  // be sure to add up the total segment count
166  mOut() << "\t" << mTotalSegmentCount << " total segments" << " (" << (mTrivialSegmentCount)
167  << " trivial + " << mNonTrivialSegmentCount << " non-trivial)" << std::endl;
168 
169  // return the number of bytes read
170  return inStream.getBytesRead() - bytesReadOffset;
171  }
172 
174  // prepare to read from the stream
175  size_t bytesReadOffset = inStream.getBytesRead();
176  TileCount tileCount; // number of tiles
177  uint16_t arcCount = 0; // number of irregular arcs in the tile
178  WireIndex sourceWireIndex; // arc source wire index
179  WireIndex sinkWireIndex; // arc sink wire index
180 
181  // read the section header
182  string sectionName;
183  inStream.readSectionHeader(sectionName);
184  /// \todo Throw a proper exception.
185  if(sectionName != ">>>>IrrgArcs>>>>") throw -1;
186 
187  // initialize the irregular arc array
188  inStream.read(tileCount);
189  mIrregularArcs.setSize(tileCount);
190  mOut() << "\tReading irregular arcs for " << tileCount << " tiles..." << std::endl;
191  // loop through each tile
192  for(TileIndex i; i < tileCount; i++) {
193  Array<IrregularArc>& irregularArcs = mIrregularArcs[i];
194  // read the number of irregular arcs
195  inStream.read(arcCount);
196  irregularArcs.setSize(arcCount);
197  // read the irregular arcs
198  for(uint16_t j = 0; j < arcCount; j++) {
199  // read the arc wire indexes
200  inStream.read(sourceWireIndex);
201  inStream.read(sinkWireIndex);
202  // store the irregular arc
203  irregularArcs[j] = IrregularArc(sourceWireIndex, sinkWireIndex);
204  }
205  }
206 
207  // return the number of bytes read
208  return inStream.getBytesRead() - bytesReadOffset;
209  }
210 
211 
212  // it would be nice to convert this to a binary search
214  WireIndex inSourceWireIndex, WireIndex inSinkWireIndex) {
215  // look up the tile's irregular arcs
216  const Array<IrregularArc>& irregularArcs = mIrregularArcs[inTileIndex];
217  // iterate through the arcs and look for a match
218  Array<IrregularArc>::const_iterator p = irregularArcs.begin();
219  Array<IrregularArc>::const_iterator e = irregularArcs.end();
220  while(p < e) {
221  // look for a matching source wire index
222  WireIndex sourceWireIndex = p->getSourceWireIndex();
223  if(sourceWireIndex < inSourceWireIndex) { p++; continue; }
224  if(sourceWireIndex > inSourceWireIndex) return NULL;
225  // look for a matching sink wire index
226  WireIndex sinkWireIndex = p->getSinkWireIndex();
227  if(sinkWireIndex < inSinkWireIndex) { p++; continue; }
228  if(sinkWireIndex > inSinkWireIndex) return NULL;
229  // if we got here, we found the requested arc
230  return p;
231  }
232  // we didn't find the arc
233  return 0;
234  }
235 
236 } // namespace architecture
237 } // namespace torc
Encapsulation of a wire belonging to a compact segment.
Definition: Segments.hpp:64
uint32_t mTrivialSegmentCount
The number of defined trivial segments.
Definition: Segments.hpp:141
Encapsulation of a tile index in an unsigned 32-bit integer.
CompactSegmentIndex getCompactSegmentIndex(void) const
Definition: Segments.hpp:82
std::istream & read(uint8_t &outValue)
Read and return a uint8_t.
Header for the Segments class.
CompactSegmentCount mCompactSegmentCount
The number of compact segments in the device.
Definition: Segments.hpp:123
uint32_t mNonTrivialSegmentCount
The number of defined non-trivial segments.
Definition: Segments.hpp:145
T * end(void)
Returns the non-constant end iterator.
Definition: Array.hpp:97
ostream & mErr(void)
Returns the database console error stream.
size_t readIrregularArcs(DigestStream &inStream)
Read the irregular arcs for the device.
Definition: Segments.cpp:173
Encapsulation of an irregular arc.
Definition: Segments.hpp:105
Array2D< SegmentReference > mTilewireSegments
The segment references for every wire in every tile.
Definition: Segments.hpp:119
Encapsulation of a wire index in an unsigned 16-bit integer.
xilinx::TileIndex TileIndex
Imported type name.
Definition: Segments.hpp:52
Encapsulation of a tile offset in an unsigned 32-bit integer.
Segments(void)
Protected constructor.
Definition: Segments.cpp:27
Array2D< CompactSegmentTilewire > mCompactSegments
The compact segments in the device.
Definition: Segments.hpp:117
Encapsulation of a tile count in an unsigned 32-bit integer.
uint32_t mActualWireCount
The number of actual wires on non-trivial segments in the device.
Definition: Segments.hpp:137
uint32_t mTotalWireCount
The total number of wires in the device (pruned and actual).
Definition: Segments.hpp:129
Encapsulation of a compact segment index in an unsigned 32-bit integer.
uint32_t mTotalSegmentCount
The total number of defined segments.
Definition: Segments.hpp:149
void readSectionHeader(string &outHeader)
Read and return a section header.
ostream & mOut(void)
Returns the database console output stream.
const Segments::IrregularArc * getIrregularArc(TileIndex inTileIndex, WireIndex inSourceWireIndex, WireIndex inSinkWireIndex)
Return a pointer to the requested IrregularArc, or 0 if the arc does not exist.
Definition: Segments.cpp:213
Encapsulation of compact segment index and an anchoring tile index.
Definition: Segments.hpp:78
Array2D< IrregularArc > mIrregularArcs
The irregular arcs for in the device.
Definition: Segments.hpp:121
T * begin(void)
Returns the non-constant begin iterator.
Definition: Array.hpp:95
void setSize(uint32_t inSize)
Discards all contents and resizes the array.
Definition: Array.hpp:107
Encapsulation of a device or family digest stream.
size_t readTilewireSegments(DigestStream &inStream)
Read the segment entries for every tile.
Definition: Segments.cpp:32
size_t getBytesRead(void) const
Returns the number of bytes read.
static const SegmentReference sTrivialSegmentReference
Definition: Segments.hpp:97
uint32_t mPrunedWireCount
The number of pruned wires in the device.
Definition: Segments.hpp:133
size_t readSegments(DigestStream &inStream, bool inExtendedAnchorTileCount)
Read the compact segments for the device.
Definition: Segments.cpp:89
Encapsulation of a static array.
Definition: Array.hpp:39