torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Unrouter.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 Tracer class.
18 
19 #ifndef TORC_ROUTER_UNROUTER_HPP
20 #define TORC_ROUTER_UNROUTER_HPP
21 
24 #include <set>
25 #include <iostream>
26 
29 
30 namespace torc {
31 namespace router {
32 
33  /// \brief Unroutes connected resources in a DDB instance.
34  /// \details The unrouter allows the user to deactivate pips and wires that are associated with
35  /// one another as all or part of a net.
36  class Unrouter {
37  // types
38  /// \brief Imported type name
46  protected:
47  // members
48  /// \brief Database reference.
49  DDB& mDB;
50  /// \brief ArcUsage reference.
52  /// \brief WireUsage reference.
54  /// \brief Scratch segment storage.
56  /// \brief Scratch wire storage
58  /// \brief Scratch wire storage
60  /// \brief Traced wires collection.
61  std::set<Tilewire> mTracedWiresBuf;
62 
63 
65 
67 
68  public:
69  // constructor
70  /// \brief Public Constructor
71  Unrouter(DDB& inDB) : mDB(inDB), mArcUsage(inDB.getArcUsage()),
72  mWireUsage(inDB.getWireUsage()) {}
73  /// \brief Destructor.
74  ~Unrouter() {}
75 
76  /// \brief
77  boost::int32_t unrouteToSinks(const Tilewire inTilewire) {
78  //mTracedWiresBuf.clear();
79  mWireQueue.clear();
80  mWireQueue.push_back(inTilewire);
81  Tilewire currentTilewire;
82  boost::int32_t releasedArcs = 0;
83 
84  while (mWireQueue.size() != 0) {
85  currentTilewire = mWireQueue.back();
86  mWireQueue.pop_back();
87 
88  mSegmentBuf.clear();
89  mDB.expandSegment(currentTilewire, mSegmentBuf);
90  TilewireVector::iterator p;
91  TilewireVector::iterator e = mSegmentBuf.end();
92  for (p = mSegmentBuf.begin(); p < e; p++) {
93  const Tilewire& segmentTilewire = *p;
94  mSinksBuf.clear();
95  mDB.expandTilewireSinks(segmentTilewire, mSinksBuf);
96  TilewireVector::iterator q;
97  TilewireVector::iterator f = mSinksBuf.end();
98  for (q = mSinksBuf.begin(); q < f; q++) {
99  const Tilewire& sinkTilewire = *q;
100  if(mArcUsage.isUsed(segmentTilewire, sinkTilewire)) {
101  mWireQueue.push_back(sinkTilewire);
102  Arc arc(segmentTilewire, sinkTilewire);
103  mDB.releaseArc(arc);
104  releasedArcs++;
105  }
106  }
107  }
108  }
109  return releasedArcs;
110  }
111 
112 
113  /// \brief Trace from given Tilewire in a sinkwards direction only.
114  /// \details Traces from the specified source Tilewire in a sinkwards direction.
115  /// If the Tilewire is a logic site output, then the result will be a full net.
117  mTracedWiresBuf.clear();
118  RouteTreeNode* node = new RouteTreeNode(inTilewire, inTilewire, 0, 0);
119  traceDownstream(node);
120  // returned node is a dummy node
121  return node;
122  }
123  /// \brief Trace from given Tilewire sinkwards and sourcewards to source or branch.
124  /// \details Traces from the specified source Tilewire. All downstream sinks are found
125  /// and the closest branch point in the net or source is found.
127  mTracedWiresBuf.clear();
128  RouteTreeNode* node = new RouteTreeNode(inTilewire, inTilewire, 0, 0);
130  // returned node is a dummy node
131  return node;
132  }
133  /// \brief Trace from given Tilewire sourcewards to the source of the net.
134  /// \details Traces from the specified source Tilewire. All downstream sinks are found
135  /// and the source of the net is found. Branch points are ignored.
137  mTracedWiresBuf.clear();
138  RouteTreeNode* node = new RouteTreeNode(inTilewire, inTilewire, 0, 0);
140  // returned node is a dummy node
141  return node;
142  }
143  /// \brief Trace from given Tilewire and recover the entire net.
144  /// \details Traces from the specified Tilewire. All net sinks and the source are
145  /// recovered fully reconstructing the net to which the Tilewire belongs.
147  mTracedWiresBuf.clear();
148  RouteTreeNode* node = new RouteTreeNode(inTilewire, inTilewire, 0, 0);
150  // returned node is a dummy node
151  return node;
152  }
153  /// \brief Remove the dummy node if possible.
154  /// \details Removes the dummy node if it is at an end of the trace.
155  /// If it is in the middle, it removes it if there is only one child.
156  /// Otherwise no change is made.
157  /*RouteTreeNode* removeDummy(RouteTreeNode* inNode) {
158  std::cout << "THIS FUNCTION MAY BE CUT AND IS INCOMPELETE" << std::endl;
159  RouteTreeNode* node;
160  if (inNode->getParent() == 0) { // node has no parent
161  if (inNode->getNumChildren() == 0) { // Single node, no trace
162  return inNode;
163  } else if (inNode->getNumChildren() == 1) { // Source
164  node = inNode->getChild(0);
165  // remove parent of node
166  delete inNode;
167  return node;
168  } else { // multiple children of node with no parents
169  // no modification
170  return inNode;
171  }
172  } else { // node has a parent
173  if (inNode->getNumChildren() == 0) { // Sink
174  node = (RouteTreeNode*)inNode->getParent();
175  // remove child of node
176  delete inNode;
177  return node;
178  } else if (inNode->getNumChildren() == 1) { // Middle with one on either end
179  // move node to parent
180  node = (RouteTreeNode*)(inNode->getParent());
181  // remove child of node
182  // add child of child to node
183  // set child to new parent
184  delete inNode;
185  return node;
186  } else {
187  return inNode;
188  }
189  }
190  }*/
191  /// \brief Find the source of net that owns the given Tilewire.
192  /*Tilewire findSource(Tilewire inTilewire) {
193  Arc parentArc;
194  bool foundParent = false;
195  mSegmentBuf.clear();
196  mDB.expandSegment(inTilewire, mSegmentBuf);
197  TilewireVector::iterator p;
198  TilewireVector::iterator e = mSegmentBuf.end();
199  for (p = mSegmentBuf.begin(); p < e; p++) {
200  Tilewire segmentTilewire = *p;
201  mTracedWiresBuf.insert(segmentTilewire);
202  mSourcesBuf.clear();
203  mDB.expandTilewireSources(segmentTilewire, mSourcesBuf);
204  TilewireVector::iterator q;
205  TilewireVector::iterator f = mSourcesBuf.end();
206  for (q = mSourcesBuf.begin(); q < f; q++) {
207  Tilewire sourceTilewire = *q;
208  if (mTracedWiresBuf.count(sourceTilewire) == 1) {
209  std::cout << "TRACER ERROR: REVISITING SOURCE, POSSIBLE LOOP" << std::endl;
210  throw;
211  }
212  if (mArcUsage.isUsed(sourceTilewire, segmentTilewire)) {
213  if (foundParent) {
214  std::cout << "TRACER ERROR: MULTIPLE PARENTS" << std::endl;
215  throw;
216  }
217  parentArc = Arc(sourceTilewire, segmentTilewire);
218  foundParent = true;
219  }
220  }
221  }
222  if (foundParent) {
223  return findSource(parentArc.getSourceTilewire());
224  } else {
225  return inTilewire;
226  }
227  }
228  /// \brief Find all sinks downstream from given Tilewire.
229  void findBranchSinks(Tilewire inTilewire, TilewireVector& outSinks) {
230  std::cout << "findBranchSinks not yet implemented." << std::endl;
231  throw;
232  }
233  /// \brief Find all sinks attached to the net that includes input Tilewire.
234  void findSinks(Tilewire inTilewire, TilewireVector& outSinks) {
235  std::cout << "findSinks not yet implemented." << std::endl;
236  throw;
237  }*/
238 
239  protected:
240  /// \brief Recursively traces from the specified RouteTreeNode.
242  const Tilewire& nodeTilewire = inNode->getSinkTilewire();
243  std::vector<RouteTreeNode*> activeSinks;
244 
245  mSegmentBuf.clear();
246  mDB.expandSegment(nodeTilewire, mSegmentBuf);
247  TilewireVector::iterator p;
248  TilewireVector::iterator e = mSegmentBuf.end();
249  for (p = mSegmentBuf.begin(); p < e; p++) {
250  const Tilewire& segmentTilewire = *p;
251  mTracedWiresBuf.insert(segmentTilewire);
252  mSinksBuf.clear();
253  mDB.expandTilewireSinks(segmentTilewire, mSinksBuf);
254  TilewireVector::iterator q;
255  TilewireVector::iterator f = mSinksBuf.end();
256  for (q = mSinksBuf.begin(); q < f; q++) {
257  const Tilewire& sinkTilewire = *q;
258  if(mTracedWiresBuf.count(sinkTilewire) == 1) continue;
259  if(mArcUsage.isUsed(segmentTilewire, sinkTilewire)) {
260  activeSinks.push_back(new RouteTreeNode(
261  segmentTilewire, sinkTilewire, 0, inNode));
262  }
263  }
264  }
265  unsigned int activeSinksSize = activeSinks.size();
266  if(activeSinksSize == 0) return;
267 
268  inNode->addChildren(activeSinks);
269  for(unsigned int i = 0; i < activeSinksSize; i++) {
270  RouteTreeNode* childNode = inNode->getChild(i);
271  traceDownstream(childNode);
272  }
273  }
274  /// \brief Recursively traces from the specified RouteTreeNode in one of three modes.
275  void traceUpstream(RouteTreeNode* inNode, boost::int32_t inMode) {
276 //std::cout << mDB << "UP CALL " << inNode->getArc() << std::endl;
277  const Tilewire& nodeSourceTilewire = inNode->getSourceTilewire();
278  const Tilewire& nodeSinkTilewire = inNode->getSinkTilewire();
279  Arc parentArc;
280  bool foundParent = false;
281  std::vector<RouteTreeNode*> activeSinks;
282  mSegmentBuf.clear();
283  mDB.expandSegment(nodeSourceTilewire, mSegmentBuf);
284  TilewireVector::iterator p;
285  TilewireVector::iterator e = mSegmentBuf.end();
286  for (p = mSegmentBuf.begin(); p != e; p++) {
287  const Tilewire& segmentTilewire = *p;
288  mTracedWiresBuf.insert(segmentTilewire);
289  mSourcesBuf.clear();
290  mDB.expandTilewireSources(segmentTilewire, mSourcesBuf);
291  TilewireVector::iterator q;
292  TilewireVector::iterator f = mSourcesBuf.end();
293  for (q = mSourcesBuf.begin(); q != f; q++) {
294  const Tilewire& sourceTilewire = *q;
295  if (mTracedWiresBuf.count(sourceTilewire) == 1) {
296  std::cout << "ALREADY SEEN THIS TILEWIRE" << std::endl;
297  continue;
298  }
299  if (mArcUsage.isUsed(sourceTilewire, segmentTilewire)) {
300  if (foundParent) {
301  std::cout << "TRACER ERROR: MULTIPLE PARENTS" << std::endl;
302  throw;
303  }
304  parentArc = Arc(sourceTilewire, segmentTilewire);
305  foundParent = true;
306  }
307  }
308  }
309  // now look at the sinks unless the caller is only interested in top level source
310  if (inMode != eTraceToSource) {
311  mSegmentBuf.clear();
312  mDB.expandSegment(nodeSinkTilewire, mSegmentBuf);
313  e = mSegmentBuf.end();
314  for (p = mSegmentBuf.begin(); p < e; p++) {
315  Tilewire segmentTilewire = *p;
316  mTracedWiresBuf.insert(segmentTilewire);
317  mSinksBuf.clear();
318  mDB.expandTilewireSinks(segmentTilewire, mSinksBuf);
319  TilewireVector::iterator q;
320  TilewireVector::iterator f = mSinksBuf.end();
321  for (q = mSinksBuf.begin(); q < f; q++) {
322  Tilewire sinkTilewire = *q;
323  if (mTracedWiresBuf.count(sinkTilewire) == 1) {
324  std::cout << "ALREADY SEEN THIS TILEWIRE" << std::endl;
325  continue;
326  }
327  if (mArcUsage.isUsed(segmentTilewire, sinkTilewire)) {
328  activeSinks.push_back(new RouteTreeNode(
329  segmentTilewire, sinkTilewire, 0, inNode));
330  }
331  }
332  }
333  unsigned int activeSinksSize = activeSinks.size();
334  std::cout << "ACTIVE SINKS SIZE: " << activeSinksSize << std::endl;
335  std::cout << inMode << " " << eTraceToBranch << std::endl;
336  if (inMode == eTraceToBranch && activeSinksSize > 0) return;
337  if (activeSinksSize > 1) {
338  inNode->addChildren(activeSinks);
339  activeSinksSize = inNode->getNumChildren(); //WHY??
340  std::cout << activeSinksSize << std::endl;
341  for (unsigned int i = 0; i < activeSinksSize; i++) {
342  RouteTreeNode* newChildNode = inNode->getChild(i);
343  traceDownstream(newChildNode);
344  }
345  }
346  }
347 
348  if (foundParent) {
349 //std::cout << mDB << "\tFOUND PARENT " << parentArc << std::endl;
350  inNode->makeParent(parentArc.getSourceTilewire(), parentArc.getSinkTilewire());
351  RouteTreeNode* parentNode = (RouteTreeNode*)inNode->getParent();
352  traceUpstream(parentNode, inMode);
353  }
354  }
355 
356 /*
357 
358 
359  public:
360  bool hasSource(CTraceNode* childNode)
361  {
362 
363  // get the child's tilewire
364  CTilewire tilewire = childNode->getTilewire();
365 
366  // expand the given wire into its full segment
367  mWiresBuf.clear();
368  mDB.expandSegmentSources(mWiresBuf, tilewire);
369 
370  // loop through each wire in the segment and look for arcs
371  for(uint32 i = 0; i < mWiresBuf.size(); i++)
372  {
373  // get the wire
374  CTilewire currentTilewire = mWiresBuf[i];
375  // look for this wire's sources
376  mSourcesBuf.clear();
377  mDB.expandWireSources(mSourcesBuf, currentTilewire);
378  // loop through the source wires
379  for(uint32 j = 0; j < mSourcesBuf.size(); j++)
380  {
381  // get the source information
382  CTilewire sourceTilewire = mSourcesBuf[j];
383  // ensure that the source and sink wires live in the same tile,
384  // even though we're really not expecting any surprises
385  if(currentTilewire.getTileIndex() != sourceTilewire.getTileIndex())
386  {
387  std::cerr << "Oh yeah, it's pretty bad, the tile indices are not the same!" << std::endl;
388  }
389  // check to see if the arc is turned on
390  if(mDB.arcIsOn(sourceTilewire, currentTilewire))
391  {
392  return true;
393  }
394  }
395  }
396 
397  // if we got to here, no sources were found
398  return false;
399 
400  }
401 */
402 
403  }; // class Tracer
404 
405 
406 } // namespace router
407 } // namespace torc
408 
409 #endif // TORC_ROUTER_UNROUTER_HPP
Unroutes connected resources in a DDB instance.
Definition: Unrouter.hpp:36
architecture::TilewireVector TilewireVector
Definition: Unrouter.hpp:44
Encapsulation of an arc between two tilewires.
Definition: Arc.hpp:28
std::vector< Tilewire > TilewireVector
Vector of Tilewire objects.
Definition: Tilewire.hpp:101
void addChildren(const std::vector< RouteTreeNode * > &newChildren)
Add children to the node.
RouteNode * getParent() const
Get the node's parent.
Definition: RouteNode.hpp:98
Device database, including complete wiring and logic support.
Definition: DDB.hpp:42
WireUsage & mWireUsage
WireUsage reference.
Definition: Unrouter.hpp:53
Unrouter(DDB &inDB)
Public Constructor.
Definition: Unrouter.hpp:71
RouteTreeNode * traceToSource(Tilewire inTilewire)
Trace from given Tilewire sourcewards to the source of the net.
Definition: Unrouter.hpp:136
TilewireVector mSegmentBuf
Scratch segment storage.
Definition: Unrouter.hpp:55
TilewireVector mWireQueue
Definition: Unrouter.hpp:64
Encapsulation the design wire usage.
Definition: WireUsage.hpp:35
TilewireVector mSourcesBuf
Scratch wire storage.
Definition: Unrouter.hpp:59
architecture::ArcVector ArcVector
Definition: Unrouter.hpp:45
void releaseArc(const Arc &inArc, bool releaseSource=true, bool releaseSink=true)
Marks the arc and all of its source and sink segment wires as unused.
Definition: DDB.hpp:179
RouteTreeNode * traceFull(Tilewire inTilewire)
Trace from given Tilewire and recover the entire net.
Definition: Unrouter.hpp:146
TilewireVector mSinksBuf
Scratch wire storage.
Definition: Unrouter.hpp:57
std::vector< Arc > ArcVector
Vector of Arc objects.
Definition: Arc.hpp:78
const Tilewire & getSourceTilewire(void) const
Returns the source tilewire.
Definition: Arc.hpp:45
Header for Boost.Test helper functions.
const Tilewire & getSinkTilewire() const
Get the sink Tilewire.
Definition: RouteNode.hpp:84
void expandTilewireSinks(const Tilewire &inTilewire, TilewireVector &outSinks, bool inUseTied=true, bool inUseRegular=true, bool inUseIrregular=true, bool inUseRoutethrough=true)
Expands the given tilewire's arc sinks.
Definition: DDB.cpp:214
RouteTreeNode * traceBranch(Tilewire inTilewire)
Trace from given Tilewire sinkwards and sourcewards to source or branch.
Definition: Unrouter.hpp:126
const Tilewire & getSinkTilewire(void) const
Returns the sink tilewire.
Definition: Arc.hpp:47
Header for torc::physical output stream helpers.
void traceUpstream(RouteTreeNode *inNode, boost::int32_t inMode)
Recursively traces from the specified RouteTreeNode in one of three modes.
Definition: Unrouter.hpp:275
Encapsulation of a device tile and wire pair.
Definition: Tilewire.hpp:39
const Tilewire & getSourceTilewire() const
Get the source Tilewire.
Definition: RouteNode.hpp:82
Encapsulation the design arc usage.
Definition: ArcUsage.hpp:38
boost::uint16_t getNumChildren()
Get the number of children.
void expandTilewireSources(const Tilewire &inTilewire, TilewireVector &outSources, bool inUseTied=true, bool inUseRegular=true, bool inUseIrregular=true, bool inUseRoutethrough=true)
Expands the given tilewire's arc sources.
Definition: DDB.cpp:264
boost::int32_t unrouteToSinks(const Tilewire inTilewire)
Definition: Unrouter.hpp:77
~Unrouter()
Destructor.
Definition: Unrouter.hpp:74
std::set< Tilewire > mTracedWiresBuf
Traced wires collection.
Definition: Unrouter.hpp:61
An object that holds more complete path information for routing and tracing.
architecture::DDB DDB
Imported type name.
Definition: Unrouter.hpp:39
architecture::Arc Arc
Definition: Unrouter.hpp:43
void traceDownstream(RouteTreeNode *inNode)
Remove the dummy node if possible.
Definition: Unrouter.hpp:241
void makeParent(const Tilewire &inSource, const Tilewire &inSink)
Allocate a new node and make it the parent of this node.
ArcUsage & mArcUsage
ArcUsage reference.
Definition: Unrouter.hpp:51
Header for the DDB class.
architecture::ArcUsage ArcUsage
Definition: Unrouter.hpp:40
RouteTreeNode * getChild(unsigned int index)
Get a child by index, returns 0 for invalid index.
bool isUsed(const Arc &inArc)
Determines whether the specified arc is in use.
Definition: ArcUsage.hpp:209
RouteTreeNode * traceToSinks(Tilewire inTilewire)
Trace from given Tilewire in a sinkwards direction only.
Definition: Unrouter.hpp:116
DDB & mDB
Database reference.
Definition: Unrouter.hpp:49
void expandSegment(const Tilewire &inTilewire, TilewireVector &outTilewires, EExpandDirection inExpandDirection=eExpandDirectionNone)
Expands the given tilewire's segment.
Definition: DDB.cpp:154
architecture::WireUsage WireUsage
Definition: Unrouter.hpp:41
Header for the RouteTreeNode class.
architecture::Tilewire Tilewire
Definition: Unrouter.hpp:42