torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VprExporter.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 VprExporter class.
18 
22 #include <boost/algorithm/string.hpp>
23 #include <iostream>
24 #include <fstream>
25 #include <sstream>
26 
27 // avoid pulling in additional structures
28 typedef void t_pb_graph_pin;
29 typedef void t_tnode;
30 
31 // =================================================================================================
32 // begin declarations imported verbatim from VPR v6.0
33 // =================================================================================================
34 
35 typedef enum e_rr_type
37 t_rr_type;
38 
40 {
44 }; /* UDSD by AY */
45 
47 { MULTI_BUFFERED, SINGLE }; /* legacy routing drivers by Andy Ye (remove or integrate in future) */
48 
49 typedef struct s_rr_node
50 {
51  short xlow;
52  short xhigh;
53  short ylow;
54  short yhigh;
55 
56  short ptc_num;
57 
58  short cost_index;
59  short occ;
60  short capacity;
61  short fan_in;
62  short num_edges;
64  int *edges;
65  short *switches;
66 
67  float R;
68  float C;
69 
70  enum e_direction direction; /* UDSD by AY */
71  enum e_drivers drivers; /* UDSD by AY */
72  int num_wire_drivers; /* UDSD by WMF */
73  int num_opin_drivers; /* UDSD by WMF (could use "short") */
74 
75  /* Used by clustering only (TODO, may wish to extend to regular router) */
76  int prev_node;
77  int prev_edge;
78  int net_num;
82 }
83 t_rr_node;
84 
85 // =================================================================================================
86 // end declarations imported verbatim from VPR v6.0
87 // =================================================================================================
88 
89 namespace torc {
90 namespace architecture {
91 
92 // 10x10 bounding box
93 // xc6vlx240t (ml605)
94 
95  using namespace std;
96 
98 
99  bool debug = true;
100 
101  cout << mDDB;
102  cout << "sizeof(short) = " << sizeof(short) << endl;
103  cout << "sizeof(int) = " << sizeof(int) << endl;
104  cout << "sizeof(float) = " << sizeof(float) << endl;
105  cout << "sizeof(t_rr_node) = " << sizeof(t_rr_node) << endl;
106 
107  // name the output file
108  mMaxTileRow = min(mMaxTileRow, mDDB.getTiles().getRowCount());
109  mMaxTileCol = min(mMaxTileCol, mDDB.getTiles().getColCount());
110  stringstream ss;
111  ss << mDDB.getDeviceName() << "-[" << mMinTileRow << "," << mMinTileCol << "]-["
112  << mMaxTileRow << "," << mMaxTileCol << "].vpr";
114  / "regression" / ss.str();
115  mStream.open(generatedPath.string().c_str(), std::ios::out | std::ios::binary);
116 
117  // declare maps to track tilewires
118  typedef map<Tilewire, uint32_t> TilewireToIndex;
119  TilewireToIndex tilewireToIndex;
120  typedef map<Tilewire, bool> TilewireIsExcluded;
121  TilewireIsExcluded tilewireIsExcluded;
122  // iterate over every tile
123  TileCount tileCount = mTiles.getTileCount();
124  size_t size = 0;
125  for(TileIndex tileIndex(0); tileIndex < tileCount; tileIndex++) {
126  // iterate over every wire in the tile
127  const TileInfo& tileInfo = mTiles.getTileInfo(tileIndex);
128  TileTypeIndex tileTypeIndex = tileInfo.getTypeIndex();
129  // TileRow TileRow = tileInfo.getRow();
130  // TileCol TileCol = tileInfo.getCol();
131  WireCount wireCount = mTiles.getWireCount(tileTypeIndex);
132  for(WireIndex wireIndex(0); wireIndex < wireCount; wireIndex++) {
133  // take a quick exit if we've already looked at this segment
134  Tilewire currentTilewire(tileIndex, wireIndex);
135  if(tilewireIsExcluded.find(currentTilewire) != tilewireIsExcluded.end()) continue;
136  // look up the segment information for this tilewire
137  TilewireVector tilewires;
138  mDDB.expandSegment(currentTilewire, tilewires);
139  // if a segment is not real in this device, it won't have any tilewires
140  if(tilewires.empty()) continue;
141  // determine whether to include this segment or not
142  TilewireVector::iterator tp = tilewires.begin();
143  TilewireVector::iterator te = tilewires.end();
144  bool include = true;
145  while(include && tp < te) {
146  ExtendedWireInfo ewi(mDDB, *tp++);
147  if(ewi.mTileRow < mMinTileRow) include = false;
148  if(ewi.mTileCol < mMinTileCol) include = false;
149  if(ewi.mTileRow > mMaxTileRow) include = false;
150  if(ewi.mTileCol > mMaxTileCol) include = false;
151  }
152  // mark the tilewires as visited
153  tp = tilewires.begin();
154  while(tp < te) tilewireIsExcluded[*tp++] = !include;
155  if(!include) continue;
156  // push the anchor tilewire if we haven't seen it before
157  if(tilewireToIndex.find(tilewires[0]) == tilewireToIndex.end())
158  tilewireToIndex[tilewires[0]] = size++;
159  }
160  }
161  cout << "Found " << tilewireToIndex.size() << " total segments compared to expected "
162  << mSegments.getTotalSegmentCount() << endl;
163 
164  // create a vector of Node elements
165  typedef vector<Node> NodeVector;
166  NodeVector nodes;
167  nodes.resize(tilewireToIndex.size());
168  // iterate over every indexed wire and write it out
169  TilewireToIndex::const_iterator p = tilewireToIndex.begin();
170  TilewireToIndex::const_iterator e = tilewireToIndex.end();
171  while(p != e) {
172  TilewireToIndex::value_type value = *p++;
173  uint32_t index = value.second;
174  Tilewire tilewire = value.first;
175  nodes[index].mIndex = index;
176  nodes[index].mTilewire = tilewire;
177  // expand this segment's sinks
178  ArcVector arcVector;
179  mDDB.expandSegmentSinks(tilewire, arcVector, DDB::eExpandDirectionNone, true, true,
180  true, false);
181  ArcVector::const_iterator ap = arcVector.begin();
182  ArcVector::const_iterator ae = arcVector.end();
183  while(ap < ae) {
184  Arc arc = *ap++;
185  // expand the sink wire's segment to recover the anchor and segment index
186  TilewireVector tilewires;
187  mDDB.expandSegment(arc.getSinkTilewire(), tilewires);
188  // if we have deliberately pruned this sink tilewire, do not include it in the data
189  if(tilewireToIndex.find(tilewires[0]) == tilewireToIndex.end()) continue;
190  // convert the sink tilewire to an index
191  uint32_t sinkIndex = tilewireToIndex[tilewires[0]];
192  nodes[index].mEdges.push_back(sinkIndex);
193  }
194  // iterate over every segment wire to extract attributes
195  {
196  TilewireVector tilewires;
197  mDDB.expandSegment(tilewire, tilewires);
198  TilewireVector::iterator tp = tilewires.begin();
199  TilewireVector::iterator te = tilewires.end();
200  while(tp < te) {
201  ExtendedWireInfo ewi(mDDB, *tp++);
202  nodes[index].mMinRow = min(nodes[index].mMinRow, ewi.mTileRow);
203  nodes[index].mMinCol = min(nodes[index].mMinCol, ewi.mTileCol);
204  nodes[index].mMaxRow = max(nodes[index].mMaxRow, ewi.mTileRow);
205  nodes[index].mMaxCol = max(nodes[index].mMaxCol, ewi.mTileCol);
206  nodes[index].mRowRange = nodes[index].mMaxRow - nodes[index].mMinRow;
207  nodes[index].mColRange = nodes[index].mMaxCol - nodes[index].mMinCol;
208  nodes[index].mFlags |= ewi.mWireFlags;
209  }
210  }
211  }
212 
213  // iterate through the VPR nodes and output everything except for the edges
214  size_t nodeCount = tilewireToIndex.size();
215  size_t edgeCount = 0;
216  mStream.write(reinterpret_cast<char*>(&nodeCount), sizeof(nodeCount));
217  int* edgePtr = 0;
218  NodeVector::iterator np = nodes.begin();
219  NodeVector::iterator ne = nodes.end();
220  while(np < ne) {
221  Node& node = *np++;
222  if(debug) cout << node.mIndex << ": (" << node.mTilewire << "): ";
223  if(debug) cout << "[" << node.mMinRow << "," << node.mMinCol << "]-["
224  << node.mMaxRow << "," << node.mMaxCol << "] ";
225  if(debug) cout << (WireInfo::isInput(node.mFlags) ? "INPUT " : "");
226  if(debug) cout << (WireInfo::isOutput(node.mFlags) ? "OUTPUT " : "");
227  Uint32Vector::const_iterator ep = node.mEdges.begin();
228  Uint32Vector::const_iterator ee = node.mEdges.end();
229  if(debug) while(ep < ee) {
230  cout << *ep++ << " ";
231  }
232  if(debug) cout << endl;
233 
234  t_rr_node vpr_rr_node;
235  // segment bounds
236  vpr_rr_node.xlow = node.mMinCol;
237  vpr_rr_node.xhigh = node.mMaxCol;
238  vpr_rr_node.ylow = node.mMinRow;
239  vpr_rr_node.yhigh = node.mMaxRow;
240  // we don't have track numbers, but perhaps the wire index will do
241  vpr_rr_node.ptc_num = node.mTilewire.getWireIndex();
242  // no intrinsic cost, and current occupancy is zero
243  vpr_rr_node.cost_index = vpr_rr_node.occ = 0;
244  // the capacity of every XDLRC wire is one
245  vpr_rr_node.capacity = 1;
246  // does VPR really use fanin information? we can provide this if it's important
247  vpr_rr_node.fan_in = 0;
248  // fanout
249  vpr_rr_node.num_edges = node.mEdges.size();
250  // node type; not sure if this captures what Eddie Hung was saying about their types
251  if(WireInfo::isInput(node.mFlags)) { vpr_rr_node.type = SINK; }
252  else if(WireInfo::isOutput(node.mFlags)) { vpr_rr_node.type = SOURCE; }
253  else if(node.mColRange > node.mRowRange) { vpr_rr_node.type = CHANX; }
254  else if(node.mColRange < node.mRowRange) { vpr_rr_node.type = CHANY; }
255  else { vpr_rr_node.type = CHANX; /* what if we can't tell? */ }
256  // we will fill this in in a minute
257  vpr_rr_node.edges = edgePtr;
258  edgePtr += vpr_rr_node.num_edges + 1;
259  edgeCount += vpr_rr_node.num_edges + 1;
260  // Eddie is supposed to look this up
261  vpr_rr_node.switches = 0;
262  // we have no resistance or capacitance data
263  vpr_rr_node.R = vpr_rr_node.C = 0;
264  // all I know is that most wires are not bidirectional
265  vpr_rr_node.direction = INC_DIRECTION; // what does INC_DIRECTION mean?
266  // all XDLRC wires have a single driver
267  vpr_rr_node.drivers = SINGLE;
268  // what exactly do the following two fields mean?
269  vpr_rr_node.num_wire_drivers = 0; // unless it's important to provide this
270  vpr_rr_node.num_opin_drivers = 0; // unless it's important to provide this
271  // VPR will use this to trace back after routing
272  vpr_rr_node.prev_node = vpr_rr_node.prev_edge = vpr_rr_node.net_num = 0;
273  // we aren't populating graph or timing information
274  vpr_rr_node.pb_graph_pin = 0;
275  vpr_rr_node.tnode = 0;
276  // we currently provide no packing cost hints
277  vpr_rr_node.pack_intrinsic_cost = 0;
278 
279  // write the node to the file
280  mStream.write(reinterpret_cast<char*>(&vpr_rr_node), sizeof(t_rr_node));
281  }
282 
283  // iterate through the VPR nodes and output everything except for the edges
284  mStream.write(reinterpret_cast<char*>(&edgeCount), sizeof(edgeCount));
285  uint32_t delimiter = -1;
286  np = nodes.begin();
287  while(np < ne) {
288  Node& node = *np++;
289  Uint32Vector::const_iterator ep = node.mEdges.begin();
290  Uint32Vector::const_iterator ee = node.mEdges.end();
291  while(ep < ee) {
292  uint32_t edge = *ep++;
293  mStream.write(reinterpret_cast<char*>(&edge), sizeof(edge));
294  }
295  mStream.write(reinterpret_cast<char*>(&delimiter), sizeof(delimiter));
296  }
297 
298  }
299 
300 } // namespace architecture
301 } // namespace torc
short xhigh
Definition: VprExporter.cpp:52
short num_edges
Definition: VprExporter.cpp:62
const WireIndex & getWireIndex(void) const
Returns the wire index.
Definition: Tilewire.hpp:66
Encapsulation of a tile index in an unsigned 32-bit integer.
VPR node temporary class.
Definition: VprExporter.hpp:48
short cost_index
Definition: VprExporter.cpp:58
int * edges
Definition: VprExporter.cpp:64
bool isOutput(void) const
Returns true if the wire is a logic output.
Definition: WireInfo.hpp:132
Encapsulation of an arc between two tilewires.
Definition: Arc.hpp:28
std::vector< Tilewire > TilewireVector
Vector of Tilewire objects.
Definition: Tilewire.hpp:101
e_drivers
Definition: VprExporter.cpp:46
short ptc_num
Definition: VprExporter.cpp:56
t_tnode * tnode
Definition: VprExporter.cpp:80
Header for the DirectoryTree class.
short ylow
Definition: VprExporter.cpp:53
void operator()(void)
Exports routing graph information for VPR v6.0.
Definition: VprExporter.cpp:97
bool isInput(void) const
Returns true if the wire is a logic input.
Definition: WireInfo.hpp:130
enum e_rr_type t_rr_type
enum e_drivers drivers
Definition: VprExporter.cpp:71
enum e_direction direction
Definition: VprExporter.cpp:70
Encapsulation of a wire index in an unsigned 16-bit integer.
std::vector< Arc > ArcVector
Vector of Arc objects.
Definition: Arc.hpp:78
Header for the DDB class.
const Tilewire & getSinkTilewire(void) const
Returns the sink tilewire.
Definition: Arc.hpp:47
Header for torc::physical output stream helpers.
Encapsulation of a device tile and wire pair.
Definition: Tilewire.hpp:39
Encapsulation of a wire count in an unsigned 16-bit integer.
Encapsulation of a tile count in an unsigned 32-bit integer.
Encapsulation of a tile within a device tile map.
Definition: TileInfo.hpp:33
Verbose encapsulation of a wire's information.
short capacity
Definition: VprExporter.cpp:60
boost::filesystem::path path
const TileTypeIndex & getTypeIndex(void) const
Returns the tile type index for this tile.
Definition: TileInfo.hpp:92
int num_opin_drivers
Definition: VprExporter.cpp:73
void t_pb_graph_pin
Definition: VprExporter.cpp:28
short fan_in
Definition: VprExporter.cpp:61
short yhigh
Definition: VprExporter.cpp:54
short * switches
Definition: VprExporter.cpp:65
struct s_rr_node t_rr_node
t_pb_graph_pin * pb_graph_pin
Definition: VprExporter.cpp:79
Encapsulation of a tile type index in an unsigned 16-bit integer.
short xlow
Definition: VprExporter.cpp:51
float pack_intrinsic_cost
Definition: VprExporter.cpp:81
void t_tnode
Definition: VprExporter.cpp:29
WireFlags mWireFlags
The wire flags.
static const boost::filesystem::path & getExecutablePath(void)
Returns the absolute path to the executable directory.
e_rr_type
Definition: VprExporter.cpp:35
t_rr_type type
Definition: VprExporter.cpp:63
e_direction
Definition: VprExporter.cpp:39
int num_wire_drivers
Definition: VprExporter.cpp:72