00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef TORC_ROUTER_PATHFINDER_HPP
00017 #define TORC_ROUTER_PATHFINDER_HPP
00018
00019 #include "torc/architecture/DDB.hpp"
00020 #include "NetRouterBase.hpp"
00021 #include "NetVectorRouterHeuristicBase.hpp"
00022 #include "RouteNet.hpp"
00023 #include "RouteNode.hpp"
00024 #include <boost/functional/hash.hpp>
00025
00026
00027 #include <iostream>
00028 #include <fstream>
00029 #include <vector>
00030 #include <list>
00031 #include <map>
00032 #include <algorithm>
00033 #include "NetVectorRouterBase.hpp"
00034 #include <boost/timer.hpp>
00035 #include <boost/unordered_map.hpp>
00036 #include <boost/functional/hash.hpp>
00037 #include <boost/cstdint.hpp>
00038
00039 #include "torc/architecture/Tilewire.hpp"
00040
00041 namespace torc {
00042
00043 namespace router {
00044
00045 struct TilewireData {
00046 boost::uint32_t mPresentSharing;
00047 boost::uint32_t mHistorySharing;
00048 };
00049
00050 class PathFinder : public NetVectorRouterBase
00051 {
00052 typedef std::string string;
00053 typedef architecture::DDB DDB;
00054 typedef architecture::WireUsage WireUsage;
00055 typedef architecture::Tilewire Tilewire;
00056 typedef architecture::Arc Arc;
00057 typedef architecture::TilewireVector TilewireVector;
00058 typedef TilewireVector::const_iterator TilewireConstIterator;
00059
00060 typedef boost::unordered_map<Tilewire, TilewireData> PathFinderSharingMap;
00061
00062 protected:
00063
00064 PathFinderSharingMap mConflicts;
00065 WireUsage mConflictWireUsage;
00066
00067 TilewireVector mTempWireSources;
00068 TilewireVector mTempWireSinks;
00069
00070 boost::timer routetimer;
00071 boost::timer iterationtimer;
00072 boost::timer totaltimer;
00073 boost::timer updatetimer;
00074
00075 long deleteCount;
00076
00077 public:
00078
00079 PathFinder(DDB& inDB, NetVectorRouterHeuristicBase* inHeuristic,
00080 NetRouterBase* inNetRouter) : NetVectorRouterBase(inDB, inHeuristic, inNetRouter),
00081 mConflictWireUsage(mDB.getTiles()) {
00082
00083 mTempWireSources.reserve(200);
00084 mTempWireSinks.reserve(200);
00085 mTempWireSources.clear();
00086 mTempWireSinks.clear();
00087 deleteCount = 0;
00088
00089 mConflictWireUsage.autosize();
00090 mNetRouter->getHeuristic()->setParameter(0, &mConflicts);
00091 mNetRouter->getHeuristic()->processParameters();
00092 }
00093
00094
00095 ~PathFinder() {}
00096
00097 void routeNets(RouteNetVector& nets) {
00098
00099 bool flag_resources = true;
00100
00101 unsigned int numNets = nets.size();
00102
00103 flag_resources = true;
00104
00105 int routingPasses = 0;
00106
00107
00108
00109 totaltimer.restart();
00110 double updatetime = 0;
00111 iterationtimer.restart();
00112 for (unsigned int i = 0; i < numNets; i++) {
00113 RouteNet& net = nets[i];
00114
00115
00116 if (!(net.hasOneSource() && net.hasAnySinks())) {
00117 std::cout << "BAD NET: " << net.getName() << std::endl;
00118 continue;
00119 }
00120 try {
00121
00122
00123
00124 routetimer.restart();
00125 unmarkSourcesAndSinks(net);
00126 mNetRouter->route(net);
00127 markSourcesAndSinks(net);
00128 updateSharing(net.routeNodes());
00129
00130 }
00131 catch (...) {
00132 std::cout << "Failed routing net " << i << ": " << std::endl;
00133 throw;
00134 }
00135 mConflictWireUsage.clear();
00136 }
00137
00138 mConflicts.clear();
00139 std::cout << "Initial routes time: " << iterationtimer.elapsed() << std::endl;
00140
00141 for (unsigned int i = 0; i < numNets; i++) {
00142 for (unsigned int j = 0; j < nets[i].routeNodes().size(); j++) {
00143 updateSharing(nets[i].routeNodes()[j]->getSinkTilewire());
00144 }
00145 }
00146
00147
00148 while (flag_resources) {
00149 iterationtimer.restart();
00150 std::cout << "." << std::flush;
00151
00152 double avgroutetime = 0;
00153 double minroutetime = std::numeric_limits<double>::max();
00154 double maxroutetime = std::numeric_limits<double>::min();
00155 double routetime;
00156 int netsRouted = 0;
00157
00158 for (unsigned int n = 0; n < numNets; n++) {
00159 RouteNet& net = nets[n];
00160 routetimer.restart();
00161
00162 if (true) {
00163
00164 unrouteNet(net.routeNodes(), net.getName());
00165
00166 try {
00167 unmarkSourcesAndSinks(net);
00168 mNetRouter->route(net);
00169 markSourcesAndSinks(net);
00170 updateSharing(net.routeNodes());
00171 }
00172 catch (...) {
00173 std::cout << "Failed routing net " << net.getName() << " index: "
00174 << n << " of " << nets.size() << std::endl;
00175 throw;
00176 }
00177
00178 routetime = routetimer.elapsed();
00179
00180 if (routetime < minroutetime)
00181 minroutetime = routetime;
00182 if (routetime > maxroutetime)
00183 maxroutetime = routetime;
00184 avgroutetime += routetime;
00185 netsRouted++;
00186 }
00187 }
00188 avgroutetime = avgroutetime / netsRouted;
00189
00190 updatetimer.restart();
00191 PathFinderSharingMap::iterator p;
00192 unsigned int conflicts = 0;
00193 unsigned int maxpresent = 0;
00194 unsigned int maxhistory = 0;
00195 Tilewire maxPresentTilewire;
00196 Tilewire maxHistoryTilewire;
00197 for (p = mConflicts.begin(); p != mConflicts.end(); p++)
00198 {
00199 if ((*p).second.mPresentSharing > 1)
00200 {
00201 (*p).second.mHistorySharing += (*p).second.mPresentSharing;
00202 conflicts++;
00203 }
00204
00205 if ((*p).second.mPresentSharing > maxpresent)
00206 {
00207 maxpresent = (*p).second.mPresentSharing;
00208 maxPresentTilewire = (*p).first;
00209 }
00210 if ((*p).second.mHistorySharing > maxhistory)
00211 {
00212 maxhistory = (*p).second.mHistorySharing;
00213 maxHistoryTilewire = (*p).first;
00214 }
00215 }
00216 updatetime += updatetimer.elapsed();
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 if (netsRouted == 1) {
00229 flag_resources = false;
00230 for (unsigned int i = 0; i < numNets; i++) {
00231 RouteNet& net = nets[i];
00232 if (testReroute(net.routeNodes())) {
00233 std::cout << "FOUND SELF CONFLICT NET: " << net.getName() << std::endl;
00234 std::cout << mDB;
00235 for (unsigned int j = 0; j < net.routeNodes().size(); j++) {
00236 std::cout << "\t" << net.routeNodes()[j]->getArc() << std::endl;
00237 }
00238 }
00239 }
00240 }
00241
00242
00243
00244
00245 if (conflicts == 0) flag_resources = false;
00246 routingPasses++;
00247 }
00248 std::cout << std::endl;
00249 std::cout << "Total time: " << totaltimer.elapsed() << " Update time: " << updatetime
00250 << std::endl;
00251
00252
00253 }
00254
00255 void unrouteNet(RouteNodePtrVector& routeVector, const string& netname)
00256 {
00257 int rVecSize = routeVector.size();
00258 for (int x = 0; x < rVecSize; x++)
00259 {
00260 mTempWireSources.clear();
00261 mDB.expandSegment(routeVector[x]->getSinkTilewire(), mTempWireSources);
00262 int numWireSources = mTempWireSources.size();
00263 for (int i = 0; i < numWireSources; i++)
00264 {
00265 Tilewire tw = mTempWireSources[i];
00266 if (mConflicts.find(tw) != mConflicts.end())
00267 {
00268 mConflicts[tw].mPresentSharing--;
00269 if (mConflicts[tw].mPresentSharing == 0)
00270 {
00271 mConflictWireUsage.release(tw);
00272 }
00273 if (mConflicts[tw].mPresentSharing < 0)
00274 {
00275 std::cout << "ERROR PRESENT: " << tw << " net " << netname << std::endl;
00276 throw;
00277 }
00278 }
00279 else
00280 {
00281 mConflictWireUsage.release(tw);
00282 }
00283 }
00284 delete routeVector[x];
00285 deleteCount++;
00286 }
00287 routeVector.clear();
00288 }
00289 void updateSharing(RouteNodePtrVector& outRoute) {
00290 for (unsigned int i = 0; i < outRoute.size(); i++) {
00291 updateSharing(outRoute[i]->getSinkTilewire());
00292 }
00293 }
00294 void updateSharing(const Tilewire& inTilewire) {
00295 mTempWireSources.clear();
00296 mDB.expandSegment(inTilewire, mTempWireSources);
00297 int numWireSources = mTempWireSources.size();
00298 for (int i = 0; i < numWireSources; i++) {
00299 Tilewire tw = mTempWireSources[i];
00300 if (mConflictWireUsage.isUsed(tw)) {
00301 if (mConflicts.find(tw) != mConflicts.end()) {
00302 mConflicts[tw].mPresentSharing++;
00303 } else {
00304 mConflicts[tw].mPresentSharing = 2;
00305 mConflicts[tw].mHistorySharing = 0;
00306 }
00307 } else {
00308 if (mConflicts.find(tw) != mConflicts.end()) {
00309 mConflicts[tw].mPresentSharing++;
00310 }
00311 mConflictWireUsage.use(tw);
00312 }
00313 }
00314
00315 }
00316
00317 void recordResult(std::vector<RouteNodePtrVector>& outRoutes,
00318 std::vector<RouteNodePtrVector>& tempRoutes,
00319 std::vector<unsigned int>& priorities, unsigned int plevel) {
00320 if (outRoutes.size() != tempRoutes.size()) {
00321 std::cout << "BAD SIZE: " << outRoutes.size() << " " << tempRoutes.size() << std::endl;
00322 return;
00323 }
00324 for (unsigned int i = 0; i < outRoutes.size(); i++) {
00325 recordResult(outRoutes[i], tempRoutes[i]);
00326 }
00327 }
00328 void recordResult(RouteNodePtrVector& outRoute, RouteNodePtrVector& tempRoute) {
00329 Arc arc;
00330 for (unsigned int i = 0; i < tempRoute.size(); i++) {
00331 outRoute.push_back(tempRoute[i]);
00332 arc = tempRoute[i]->getArc();
00333 mDB.useArc(arc);
00334 }
00335 }
00336
00337 bool testReroute(RouteNodePtrVector& currentRoute) {
00338 for (unsigned int i = 0; i < currentRoute.size(); i++) {
00339 if (mConflicts.find(currentRoute[i]->getSinkTilewire()) != mConflicts.end()
00340 && mConflicts[currentRoute[i]->getSinkTilewire()].mPresentSharing > 1) {
00341 return true;
00342 }
00343 }
00344 return false;
00345 }
00346
00347 void unmarkSourcesAndSinks(RouteNet& net) {
00348 mDB.releaseSegment(*net.sourcesBegin());
00349 RouteNet::TilewireConstIterator p;
00350 RouteNet::TilewireConstIterator e = net.sinksEnd();
00351 for (p = net.sinksBegin(); p != e; p++) {
00352 mDB.releaseSegment(*p);
00353 }
00354 }
00355 void markSourcesAndSinks(RouteNet& net)
00356 {
00357 mDB.useSegment(*net.sourcesBegin());
00358 RouteNet::TilewireConstIterator p;
00359 RouteNet::TilewireConstIterator e = net.sinksEnd();
00360 for (p = net.sinksBegin(); p != e; p++) {
00361 mDB.useSegment(*p);
00362 }
00363 }
00364
00365 };
00366 }
00367 }
00368 #endif // TORC_ROUTER_PATHFINDER_HPP