00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef TORC_ROUTER_NETROUTER_HPP
00020 #define TORC_ROUTER_NETROUTER_HPP
00021
00022 #include "torc/router/NetRouterBase.hpp"
00023 #include "torc/architecture/DDB.hpp"
00024 #include "torc/router/RouteNode.hpp"
00025 #include "torc/router/RouteNet.hpp"
00026 #include "torc/router/NetRouterHeuristicBase.hpp"
00027 #include "torc/architecture/OutputStreamHelpers.hpp"
00028 #include <set>
00029 #include <iostream>
00030 #include <algorithm>
00031 #include <queue>
00032 #include <boost/cstdint.hpp>
00033 #include <boost/timer.hpp>
00034 #include <boost/unordered_map.hpp>
00035 #include <boost/unordered_set.hpp>
00036 #include <boost/functional/hash.hpp>
00037
00038 namespace torc {
00039 namespace router {
00040
00041
00042 class NetRouter : public NetRouterBase {
00043
00044
00045 typedef architecture::DDB DDB;
00046 typedef architecture::ArcUsage ArcUsage;
00047 typedef architecture::WireUsage WireUsage;
00048 typedef architecture::Tilewire Tilewire;
00049 typedef architecture::Arc Arc;
00050 typedef architecture::TilewireVector TilewireVector;
00051 typedef architecture::ArcVector ArcVector;
00052
00053 typedef std::priority_queue<RouteNode*, std::vector<RouteNode*>,
00054 RouteNodePtrCostCompare> RouteNodePtrQueue;
00055 typedef boost::unordered_map<Tilewire, RouteNode*,
00056 boost::hash<architecture::Tilewire> > RouteNodePtrMap;
00057 typedef boost::unordered_set<Tilewire, boost::hash<architecture::Tilewire> > TilewireSet;
00058
00059 protected:
00060
00061
00062
00063
00064 ArcUsage& mArcUsage;
00065
00066 WireUsage& mWireUsage;
00067
00068
00069
00070
00071
00072 RouteNodePtrQueue mOrder;
00073
00074 RouteNodePtrMap mOpen;
00075
00076 RouteNodePtrMap mClosed;
00077
00078 RouteNodePtrMap mSkipped;
00079
00080 RouteNodePtrVector mPreRoute;
00081
00082 TilewireSet mAuxClosed;
00083
00084
00085 TilewireVector mSegmentBuf;
00086
00087 ArcVector mArcsBuf;
00088
00089
00090 boost::uint32_t mSearchLimit;
00091
00092 boost::uint32_t mStatNets;
00093
00094 boost::uint32_t mStatLoopPasses;
00095
00096 boost::uint32_t mStatExpanded;
00097
00098 boost::uint32_t mStatSources;
00099
00100 boost::uint32_t mStatSinks;
00101
00102 public:
00103
00104
00105 NetRouter(DDB& inDB, NetRouterHeuristicBase* inHeuristic) :
00106 NetRouterBase(inDB, inHeuristic), mArcUsage(inDB.getArcUsage()),
00107 mWireUsage(inDB.getWireUsage()) {
00108
00109 mSearchLimit = 0x001FFFFF;
00110 mStatNets = 0u;
00111 mStatLoopPasses = 0u;
00112 mStatExpanded = 0u;
00113 mStatSources = 0u;
00114 mStatSinks = 0u;
00115
00116 mTotalRouteTime = 0;
00117 }
00118
00119 ~NetRouter() {}
00120
00121
00122 void routeNet(RouteNet& net) {
00123
00124 if (!net.hasOneSource()) {
00125 std::cout << "NetRouter does not support multiple sources" << std::endl;
00126 throw;
00127 }
00128 Tilewire source = *net.sourcesBegin();
00129 TilewireVector sinks;
00130 TilewireVector::iterator p;
00131 TilewireVector::iterator e = net.sinksEnd();
00132 for (p = net.sinksBegin(); p != e; p++) {
00133 sinks.push_back(*p);
00134 }
00135
00136
00137 if (source == Tilewire::sInvalid) {
00138 std::cout << net.getName() << ": source is INVALID" << std::endl;
00139 return;
00140 }
00141 if (mWireUsage.isUsed(source)) {
00142
00143 std::cout << "!Source already in use! " << source << std::endl;
00144 throw;
00145 }
00146 e = sinks.end();
00147 for (p = sinks.begin(); p != e; p++) {
00148 if (*p == Tilewire::sInvalid) {
00149 std::cout << net.getName() << ": sink is INVALID" << std::endl;
00150 return;
00151 }
00152 if (mWireUsage.isUsed(*p)) {
00153
00154 std::cout << "!Sink already in use! " << *p << std::endl;
00155 throw;
00156 }
00157 }
00158
00159
00160
00161 if (sinks.size() == 1 && testDedicatedPath(source, sinks[0], mPreRoute)) {
00162 RouteNodePtrVector::iterator p;
00163 RouteNodePtrVector::iterator e;
00164 e = mPreRoute.end();
00165
00166 for (p = mPreRoute.begin(); p != e; p++) {
00167 net.routeNodes().push_back(*p);
00168 }
00169 mPreRoute.clear();
00170 } else {
00171 if (!expandNetTerminals(source, sinks, mPreRoute)) {
00172 std::cout << "DISCARDED in expand function: " << net.getName() << std::endl;
00173 throw;
00174 }
00175
00176 graphSearch(source, sinks, net.routeNodes());
00177 }
00178
00179 mStatNets++;
00180 mStatSources++;
00181 mStatSinks += sinks.size();
00182 }
00183 void resetStats() {
00184 mStatNets = 0u;
00185 mStatLoopPasses = 0u;
00186 mStatExpanded = 0u;
00187 mStatSources = 0u;
00188 mStatSinks = 0u;
00189 }
00190 void printStats(std::ostream& out) {
00191 out << "Nets routed: " << mStatNets
00192 << " Sources: " << mStatSources
00193 << " Sinks : " << mStatSinks
00194 << " Arcs expanded: " << mStatExpanded
00195 << " Loop passes: " << mStatLoopPasses
00196 << " Total routing time: " << mTotalRouteTime
00197 << std::endl;
00198 }
00199 protected:
00200
00201 void graphSearch(const Tilewire& inSource, TilewireVector& inSinks,
00202 RouteNodePtrVector& outRoute) {
00203
00204 clearContainers();
00205
00206 mWireUsage.release(inSource);
00207 TilewireVector::const_iterator p;
00208 TilewireVector::const_iterator e = inSinks.end();
00209 for (p = inSinks.begin(); p != e; p++) {
00210 mWireUsage.release(*p);
00211
00212 }
00213 mHeuristic->reorderSinks(inSource, inSinks);
00214
00215 RouteNode* s = new RouteNode(inSource, inSource, 0, 0, 0, 0);
00216
00217 mOpen.insert(std::pair<Tilewire, RouteNode*>(inSource, s));
00218 mOrder.push(s);
00219 e = inSinks.end();
00220 for (p = inSinks.begin(); p != e; p++) {
00221
00222 RouteNodePtrVector::iterator q;
00223 RouteNodePtrVector::iterator f = outRoute.end();
00224 for (q = outRoute.begin(); q != f; q++) {
00225
00226 mOpen.insert(std::pair<Tilewire, RouteNode*>((*q)->getSinkTilewire(), (*q)));
00227 mOrder.push(*q);
00228 }
00229 mHeuristic->setSink(*p);
00230
00231 graphSearchLoop(inSource, *p, outRoute);
00232
00233 f = outRoute.end();
00234 for (q = outRoute.begin(); q != f; q++) {
00235 Tilewire tw = (*q)->getSinkTilewire();
00236 mOpen.erase(tw);
00237 mClosed.erase(tw);
00238 mSkipped.erase(tw);
00239 }
00240 clearContainers();
00241 }
00242
00243 mWireUsage.use(inSource);
00244 e = inSinks.end();
00245 for (p = inSinks.begin(); p != e; p++) {
00246 mWireUsage.use(*p);
00247 }
00248 }
00249
00250 void graphSearchLoop(const Tilewire& inSource, const Tilewire& inSink,
00251 RouteNodePtrVector& outRoute) {
00252
00253 boost::uint32_t expanded = 0;
00254 boost::uint32_t processed = 0;
00255 while (true) {
00256 mStatLoopPasses++;
00257 if (mOrder.size() == 0) {
00258 std::cout << "ROUTING FAILED!" << std::endl;
00259 clearContainers();
00260
00261 throw;
00262 }
00263
00264 if (++processed > mSearchLimit) {
00265 std::cout << "ROUTE LIMIT!" << std::endl;
00266
00267 throw;
00268 }
00269 RouteNode* n = mOrder.top();
00270 Tilewire key = n->getSinkTilewire();
00271 RouteNodePtrMap::iterator pk = mOpen.find(key);
00272 mClosed.insert(std::pair<Tilewire, RouteNode*>(key, n));
00273 mOpen.erase(pk);
00274 mOrder.pop();
00275
00276
00277
00278
00279 mSegmentBuf.clear();
00280 mDB.expandSegment(key, mSegmentBuf);
00281 TilewireVector::iterator p;
00282 TilewireVector::iterator e = mSegmentBuf.end();
00283 for (p = mSegmentBuf.begin(); p != e; p++) {
00284 if (*p == inSink) {
00285 recordPath(n, key, inSource, outRoute);
00286 mStatExpanded += expanded;
00287 return;
00288 }
00289 mAuxClosed.insert(*p);
00290 }
00291
00292 mArcsBuf.clear();
00293
00294 mHeuristic->expandSegmentSinks(key, mArcsBuf);
00295
00296 ArcVector::iterator q;
00297 ArcVector::iterator f = mArcsBuf.end();
00298 for (q = mArcsBuf.begin(); q != f; q++) {
00299 expanded++;
00300 graphSearchFilter(n, *q, outRoute);
00301 }
00302 }
00303 }
00304
00305 void graphSearchFilter(RouteNode* inParent, const Arc& inArc,
00306 RouteNodePtrVector& outRoute) {
00307
00308 const Tilewire& arcSink = inArc.getSinkTilewire();
00309
00310 if (mWireUsage.isUsed(arcSink)) return;
00311 if (mOpen.find(arcSink) != mOpen.end()) return;
00312 if (mClosed.find(arcSink) != mClosed.end()) return;
00313 if (mSkipped.find(arcSink) != mSkipped.end()) return;
00314
00315 if (mAuxClosed.find(arcSink) != mAuxClosed.end()) {
00316
00317 return;
00318 }
00319
00320 RouteNode* node = new RouteNode(inArc, 0, 0, inParent->getDepth() + 1, inParent);
00321
00322
00323 mHeuristic->nodeCost(*node);
00324
00325 mOpen.insert(std::pair<Tilewire, RouteNode*>(arcSink, node));
00326 mOrder.push(node);
00327 }
00328
00329 void recordPath(RouteNode* node, Tilewire key, Tilewire inSource,
00330 RouteNodePtrVector& outRoute) {
00331
00332 RouteNodePtrVector::iterator p;
00333 RouteNodePtrVector::iterator e;
00334 e = mPreRoute.end();
00335
00336 for (p = mPreRoute.begin(); p != e; p++) {
00337 outRoute.push_back(*p);
00338 }
00339 mPreRoute.clear();
00340 while (true) {
00341 node->setCost(0);
00342 e = outRoute.end();
00343 for (p = outRoute.begin(); p != e; p++) {
00344 if ((*p)->getSinkTilewire() == node->getSinkTilewire()) return;
00345 }
00346 outRoute.push_back(node);
00347 if (key == inSource) return;
00348 node = node->getParent();
00349 if (node == 0) return;
00350 key = node->getSinkTilewire();
00351 }
00352 }
00353
00354 void clearContainers() {
00355
00356 RouteNodePtrMap::iterator p;
00357 RouteNodePtrMap::iterator e = mOpen.end();
00358 for (p = mOpen.begin(); p != e; p++) { delete (*p).second; }
00359 e = mClosed.end();
00360 for (p = mClosed.begin(); p != e; p++) { delete (*p).second; }
00361 e = mSkipped.end();
00362 for (p = mSkipped.begin(); p != e; p++) { delete (*p).second; }
00363 while (!mOrder.empty()) { mOrder.pop(); }
00364 mOpen.clear();
00365 mClosed.clear();
00366 mSkipped.clear();
00367 mAuxClosed.clear();
00368 }
00369
00370 bool expandNetTerminals(Tilewire& inSource, TilewireVector& inSinks,
00371 RouteNodePtrVector& outRoute) {
00372
00373 if (inSource == Tilewire::sInvalid) return false;
00374 inSource = expandSourceTerminal(inSource, outRoute);
00375 TilewireVector::iterator e = inSinks.end();
00376 for (TilewireVector::iterator p = inSinks.begin(); p != e; p++) {
00377 if (*p == Tilewire::sInvalid) return false;
00378 *p = expandSinkTerminal(*p, outRoute);
00379 }
00380 return true;
00381 }
00382
00383 bool testDedicatedPath(Tilewire inSource, Tilewire inSink, RouteNodePtrVector& outRoute) {
00384 ArcVector arcs;
00385 RouteNodePtrVector tempRoute;
00386 Tilewire tempsink = inSink;
00387 mDB.expandSegmentSources(inSink, arcs);
00388 while (arcs.size() == 1) {
00389 RouteNode* node = new RouteNode(arcs[0], 0, 0, 0, 0);
00390 tempRoute.push_back(node);
00391 mDB.useArc(arcs[0]);
00392 tempsink = arcs[0].getSourceTilewire();
00393 if (tempsink == inSource) {
00394
00395
00396 for (unsigned int i = 0; i < tempRoute.size(); i++) {
00397 outRoute.push_back(tempRoute[i]);
00398 }
00399 return true;
00400 }
00401 arcs.clear();
00402 mDB.expandSegmentSources(tempsink, arcs);
00403 }
00404 return false;
00405 }
00406
00407 Tilewire expandSourceTerminal(Tilewire inSource, RouteNodePtrVector& outRoute) {
00408 ArcVector arcs;
00409
00410 Tilewire tempsource = inSource;
00411 mDB.expandSegmentSinks(inSource, arcs);
00412 while (arcs.size() == 1) {
00413
00414 RouteNode* node = new RouteNode(arcs[0], 0, 0, 0, 0);
00415 outRoute.push_back(node);
00416 mDB.useArc(arcs[0]);
00417 tempsource = arcs[0].getSinkTilewire();
00418 arcs.clear();
00419 mDB.expandSegmentSinks(tempsource, arcs);
00420 }
00421 return tempsource;
00422
00423 }
00424
00425 Tilewire expandSinkTerminal(Tilewire inSink, RouteNodePtrVector& outRoute) {
00426 ArcVector arcs;
00427
00428 Tilewire tempsink = inSink;
00429 mDB.expandSegmentSources(inSink, arcs);
00430 while (arcs.size() == 1) {
00431
00432 RouteNode* node = new RouteNode(arcs[0], 0, 0, 0, 0);
00433 outRoute.push_back(node);
00434 mDB.useArc(arcs[0]);
00435 tempsink = arcs[0].getSourceTilewire();
00436 arcs.clear();
00437 mDB.expandSegmentSources(tempsink, arcs);
00438 }
00439 return arcs[0].getSinkTilewire();
00440 }
00441 };
00442 }
00443 }
00444
00445 #endif // TORC_ROUTER_NETROUTER_HPP