diff --git a/katabatic/src/AutoContact.cpp b/katabatic/src/AutoContact.cpp index d6a6ae9a..39db6baa 100644 --- a/katabatic/src/AutoContact.cpp +++ b/katabatic/src/AutoContact.cpp @@ -32,8 +32,14 @@ #include "hurricane/DebugSession.h" #include "crlcore/RoutingGauge.h" #include "katabatic/AutoContact.h" +#include "katabatic/AutoContactTerminal.h" +#include "katabatic/AutoContactTurn.h" +#include "katabatic/AutoContactHTee.h" +#include "katabatic/AutoContactVTee.h" #include "katabatic/AutoVertical.h" #include "katabatic/AutoHorizontal.h" +#include "katabatic/KatabaticEngine.h" +#include "katabatic/GCellGrid.h" #include "katabatic/Session.h" @@ -57,9 +63,7 @@ namespace Katabatic { AutoContact::AutoContact ( GCell* gcell, Contact* contact ) - : ExtensionGo(contact->getCell()) - //, _id (_maxId++) - , _id (contact->getId()) + : _id (contact->getId()) , _contact (contact) , _gcell (gcell) , _flags (CntInvalidatedCache|CntInCreationStage) @@ -83,8 +87,6 @@ namespace Katabatic { void AutoContact::_postCreate () { - ExtensionGo::_postCreate(); - restoreNativeConstraintBox(); ltrace(90) << "Native CBox: " << this @@ -100,6 +102,13 @@ namespace Katabatic { } + void AutoContact::destroy () + { + _preDestroy (); + delete this; + } + + void AutoContact::_preDestroy () { DebugSession::open( _contact->getNet() ); @@ -128,7 +137,6 @@ namespace Katabatic { Session::unlink( this ); } - ExtensionGo::_preDestroy(); #if 0 if (Session::doDestroyBaseContact() and canDestroyBase) _contact->destroy(); @@ -317,7 +325,7 @@ namespace Katabatic { } - void AutoContact::_getTopology ( Component*& anchor, Horizontal**& horizontals, Vertical**& verticals, size_t size ) + void AutoContact::_getTopology ( Contact* support, Component*& anchor, Horizontal**& horizontals, Vertical**& verticals, size_t size ) { size_t hcount = 0; size_t vcount = 0; @@ -327,9 +335,9 @@ namespace Katabatic { verticals [i] = NULL; } - anchor = getAnchor(); + anchor = support->getAnchor(); - forEach ( Component*, icomponent, getSlaveComponents() ) { + forEach ( Component*, icomponent, support->getSlaveComponents() ) { Horizontal* h = dynamic_cast(*icomponent); if (h != NULL) { if (hcount < size) horizontals[hcount++] = h; @@ -349,7 +357,7 @@ namespace Katabatic { if (not (flags & KbCParanoid)) cparanoid.setStreamMask( mstream::PassThrough ); - _getTopology ( anchor, horizontals, verticals, 10 ); + _getTopology ( base(), anchor, horizontals, verticals, 10 ); cparanoid << Error("In topology of %s",getString(this).c_str()) << endl; if (anchor) cparanoid << " A: " << anchor << endl; @@ -499,6 +507,67 @@ namespace Katabatic { } + AutoContact* AutoContact::createFrom ( Contact* hurricaneContact ) + { + AutoContact* autoContact = NULL; + Component* anchor; + size_t hSize = 0; + size_t vSize = 0; + Horizontal** horizontals = new Horizontal* [4]; + Vertical** verticals = new Vertical* [4]; + GCell* gcell = Session::getKatabatic()->getGCellGrid()->getGCell( hurricaneContact->getCenter() ); + + if (not gcell) { + throw Error("AutoContact::createFrom( %s ):\n" + " Contact is *not* under a GCell (outside routed area?)" + , getString(hurricaneContact).c_str() + ); + } + + _getTopology ( hurricaneContact, anchor, horizontals, verticals, 4 ); + + for ( size_t i=0 ; i<4 ; ++i ) { + hSize += (horizontals[i] != NULL) ? 1 : 0; + vSize += (verticals [i] != NULL) ? 1 : 0; + } + + if (anchor) { + if (hSize+vSize == 1) { + autoContact = new AutoContactTerminal( gcell, hurricaneContact ); + autoContact->_postCreate(); + autoContact->unsetFlags( CntInCreationStage ); + } + } else { + if ((hSize == 1) and (vSize == 1)) { + autoContact = new AutoContactTurn ( gcell, hurricaneContact ); + autoContact->_postCreate(); + autoContact->unsetFlags( CntInCreationStage ); + } else if ((hSize == 2) and (vSize == 1)) { + autoContact = new AutoContactHTee ( gcell, hurricaneContact ); + autoContact->_postCreate(); + autoContact->unsetFlags( CntInCreationStage ); + } else if ((hSize == 1) and (vSize == 2)) { + autoContact = new AutoContactVTee ( gcell, hurricaneContact ); + } + } + + if (not autoContact) { + throw Error("AutoContact::createFrom( %s ):\n" + " Contact do not have a manageable topology (a:%u, h:%u, v:%u)" + , getString(hurricaneContact).c_str() + , ((anchor) ? 1 : 0) + , hSize + , vSize + ); + } + + autoContact->_postCreate(); + autoContact->unsetFlags( CntInCreationStage ); + + return autoContact; + } + + string AutoContact::_getTypeName () const { return "AutoContact"; } diff --git a/katabatic/src/AutoContactHTee.cpp b/katabatic/src/AutoContactHTee.cpp index 687ae475..5ef12635 100644 --- a/katabatic/src/AutoContactHTee.cpp +++ b/katabatic/src/AutoContactHTee.cpp @@ -180,7 +180,7 @@ namespace Katabatic { Horizontal** horizontals = new Horizontal* [3]; Vertical** verticals = new Vertical* [3]; - _getTopology( anchor, horizontals, verticals, 3 ); + _getTopology( base(), anchor, horizontals, verticals, 3 ); _horizontal1 = static_cast( Session::lookup(horizontals[0]) ); _horizontal2 = static_cast( Session::lookup(horizontals[1]) ); @@ -192,6 +192,9 @@ namespace Katabatic { else if (horizontals[2] != NULL) message = "HTee has more than two horizontal segments."; else if (verticals [0] == NULL) message = "HTee is missing mandatory vertical segment."; else if (verticals [1] != NULL) message = "HTee has more than one vertical segment."; + else if (_horizontal1 == NULL) message = "AutoSegment lookup failed on first horizontal segment."; + else if (_horizontal2 == NULL) message = "AutoSegment lookup failed on second horizontal segment."; + else if (_vertical1 == NULL) message = "AutoSegment lookup failed on vertical segment."; else if ( (not _horizontal1->isCreated() and not _horizontal2->isCreated()) and (_horizontal1->getY() != _horizontal2->getY()) ) { message = "HTee has misaligned horizontal segments"; diff --git a/katabatic/src/AutoContactTerminal.cpp b/katabatic/src/AutoContactTerminal.cpp index 95a7293f..3b1f6b88 100644 --- a/katabatic/src/AutoContactTerminal.cpp +++ b/katabatic/src/AutoContactTerminal.cpp @@ -44,6 +44,7 @@ namespace Katabatic { using Hurricane::Bug; using Hurricane::Error; using Hurricane::DebugSession; + using Hurricane::Entity; using Hurricane::ltracein; using Hurricane::ltraceout; @@ -60,7 +61,7 @@ namespace Katabatic { , DbU::Unit height ) { - ltrace(90) << "AutoContactTerminal::create(... Point ...)" << endl; + ltrace(90) << "AutoContactTerminal::create(... Point, ...)" << endl; ltracein(90); ltrace(90) << "@" << point << endl; @@ -86,7 +87,7 @@ namespace Katabatic { , const DbU::Unit height ) { - ltrace(90) << "AutoContactTerminal::create(... x, y ...)" << endl; + ltrace(90) << "AutoContactTerminal::create(... x, y, ...)" << endl; ltrace(90) << "@ x:" << DbU::getValueString(x) << " y:" << DbU::getValueString(y) << endl; Point anchorPosition = anchor->getPosition(); @@ -232,7 +233,7 @@ namespace Katabatic { Horizontal** horizontals = new Horizontal* [2]; Vertical** verticals = new Vertical* [2]; - _getTopology( anchor, horizontals, verticals, 2 ); + _getTopology( base(), anchor, horizontals, verticals, 2 ); if (anchor == NULL) showTopologyError( "Terminal is missing an anchor (RoutingPad or Component)." ); diff --git a/katabatic/src/AutoContactTurn.cpp b/katabatic/src/AutoContactTurn.cpp index 6affe780..35f1fbb8 100644 --- a/katabatic/src/AutoContactTurn.cpp +++ b/katabatic/src/AutoContactTurn.cpp @@ -151,7 +151,7 @@ namespace Katabatic { Horizontal** horizontals = new Horizontal* [2]; Vertical** verticals = new Vertical* [2]; - _getTopology ( anchor, horizontals, verticals, 2 ); + _getTopology ( base(), anchor, horizontals, verticals, 2 ); _horizontal1 = static_cast( Session::lookup(horizontals[0]) ); _vertical1 = static_cast( Session::lookup(verticals [0]) ); @@ -161,6 +161,8 @@ namespace Katabatic { else if (horizontals[1] != NULL) message = "Turn has more than one horizontal segment."; else if (verticals [0] == NULL) message = "Turn is missing mandatory vertical segment."; else if (verticals [1] != NULL) message = "Turn has more than one vertical segment."; + else if (_horizontal1 == NULL) message = "AutoSegment lookup failed on horizontal segment."; + else if (_vertical1 == NULL) message = "AutoSegment lookup failed on vertical segment."; if (not message.empty()) { showTopologyError( message ); setFlags( CntBadTopology ); diff --git a/katabatic/src/AutoContactVTee.cpp b/katabatic/src/AutoContactVTee.cpp index 842862b0..8c6c387c 100644 --- a/katabatic/src/AutoContactVTee.cpp +++ b/katabatic/src/AutoContactVTee.cpp @@ -166,7 +166,7 @@ namespace Katabatic { Horizontal** horizontals = new Horizontal* [3]; Vertical** verticals = new Vertical* [3]; - _getTopology ( anchor, horizontals, verticals, 3 ); + _getTopology ( base(), anchor, horizontals, verticals, 3 ); _horizontal1 = static_cast( Session::lookup(horizontals[0]) ); _vertical1 = static_cast( Session::lookup(verticals [0]) ); @@ -178,6 +178,9 @@ namespace Katabatic { else if (verticals [2] != NULL) message = "VTee has more than two vertical segments."; else if (horizontals[0] == NULL) message = "VTee is missing mandatory horizontal segment."; else if (horizontals[1] != NULL) message = "VTee has more than one horizontal segment."; + else if (_horizontal1 == NULL) message = "AutoSegment lookup failed on horizontal segment."; + else if (_vertical1 == NULL) message = "AutoSegment lookup failed on first vertical segment."; + else if (_vertical2 == NULL) message = "AutoSegment lookup failed on second vertical segment."; else if ( (not _vertical1->isCreated() and not _vertical2->isCreated()) and (_vertical1->getY() != _vertical2->getY()) ) message = "VTee has misaligned vertical segments"; diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index 79fcc7f7..9205445f 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -909,91 +909,96 @@ namespace Katabatic { ltrace(89) << "computeOptimal() - " << this << endl; ltracein(89); - DbU::Unit minGCell = getOrigin(); - DbU::Unit maxGCell = getExtremity(); - DbU::Unit terminalMin; - DbU::Unit terminalMax; - AttractorsMap attractors; - - AutoContact* anchor = getAutoSource(); - if (anchor->isTerminal()) { - Box constraintBox = anchor->getConstraintBox(); - if ( isHorizontal() ) { - terminalMin = constraintBox.getYMin(); - terminalMax = constraintBox.getYMax(); - } else { - terminalMin = constraintBox.getXMin(); - terminalMax = constraintBox.getXMax(); - } - - attractors.addAttractor( terminalMin ); - if (terminalMin != terminalMax) - attractors.addAttractor( terminalMax ); - } - - anchor = getAutoTarget(); - if (anchor->isTerminal()) { - Box constraintBox = anchor->getConstraintBox(); - if (isHorizontal()) { - terminalMin = constraintBox.getYMin(); - terminalMax = constraintBox.getYMax(); - } else { - terminalMin = constraintBox.getXMin(); - terminalMax = constraintBox.getXMax(); - } - - attractors.addAttractor( terminalMin ); - if (terminalMin != terminalMax) - attractors.addAttractor( terminalMax ); - } - - forEach( AutoSegment*, autoSegment, getPerpandiculars() ) { - ltrace(89) << "Perpandicular " << *autoSegment << endl; - ltracein(89); - if (autoSegment->isLocal()) { - if (not autoSegment->isStrongTerminal()) { ltraceout(89); continue; } - - DbU::Unit terminalMin; - DbU::Unit terminalMax; - - if (getTerminalInterval( *autoSegment - , NULL - , isHorizontal() - , terminalMin - , terminalMax )) { - attractors.addAttractor( terminalMin ); - if (terminalMin != terminalMax) - attractors.addAttractor( terminalMax ); - } - } else { - bool isMin = true; - if ( isHorizontal() - and (autoSegment->getAutoSource()->getGCell()->getRow() == _gcell->getRow()) ) - isMin = false; - if ( isVertical() - and (autoSegment->getAutoSource()->getGCell()->getColumn() == _gcell->getColumn()) ) - isMin = false; - attractors.addAttractor( (isMin) ? minGCell : maxGCell ); - } - ltraceout(89); - } - DbU::Unit optimalMin; DbU::Unit optimalMax; DbU::Unit constraintMin; DbU::Unit constraintMax; + getConstraints( constraintMin, constraintMax ); - if (attractors.getAttractorsCount()) { - ltrace(89) << "Lower Median " << DbU::toLambda(attractors.getLowerMedian()) << endl; - ltrace(89) << "Upper Median " << DbU::toLambda(attractors.getUpperMedian()) << endl; - - optimalMin = attractors.getLowerMedian(); - optimalMax = attractors.getUpperMedian(); + if (isUserDefined()) { + optimalMin = optimalMax = getAxis(); } else { - optimalMin = 0; - optimalMax = (isHorizontal()) ? _gcell->getBoundingBox().getYMax() - : _gcell->getBoundingBox().getXMax(); + DbU::Unit minGCell = getOrigin(); + DbU::Unit maxGCell = getExtremity(); + DbU::Unit terminalMin; + DbU::Unit terminalMax; + AttractorsMap attractors; + + AutoContact* anchor = getAutoSource(); + if (anchor->isTerminal()) { + Box constraintBox = anchor->getConstraintBox(); + if ( isHorizontal() ) { + terminalMin = constraintBox.getYMin(); + terminalMax = constraintBox.getYMax(); + } else { + terminalMin = constraintBox.getXMin(); + terminalMax = constraintBox.getXMax(); + } + + attractors.addAttractor( terminalMin ); + if (terminalMin != terminalMax) + attractors.addAttractor( terminalMax ); + } + + anchor = getAutoTarget(); + if (anchor->isTerminal()) { + Box constraintBox = anchor->getConstraintBox(); + if (isHorizontal()) { + terminalMin = constraintBox.getYMin(); + terminalMax = constraintBox.getYMax(); + } else { + terminalMin = constraintBox.getXMin(); + terminalMax = constraintBox.getXMax(); + } + + attractors.addAttractor( terminalMin ); + if (terminalMin != terminalMax) + attractors.addAttractor( terminalMax ); + } + + forEach( AutoSegment*, autoSegment, getPerpandiculars() ) { + ltrace(89) << "Perpandicular " << *autoSegment << endl; + ltracein(89); + if (autoSegment->isLocal()) { + if (not autoSegment->isStrongTerminal()) { ltraceout(89); continue; } + + DbU::Unit terminalMin; + DbU::Unit terminalMax; + + if (getTerminalInterval( *autoSegment + , NULL + , isHorizontal() + , terminalMin + , terminalMax )) { + attractors.addAttractor( terminalMin ); + if (terminalMin != terminalMax) + attractors.addAttractor( terminalMax ); + } + } else { + bool isMin = true; + if ( isHorizontal() + and (autoSegment->getAutoSource()->getGCell()->getRow() == _gcell->getRow()) ) + isMin = false; + if ( isVertical() + and (autoSegment->getAutoSource()->getGCell()->getColumn() == _gcell->getColumn()) ) + isMin = false; + attractors.addAttractor( (isMin) ? minGCell : maxGCell ); + } + ltraceout(89); + } + + if (attractors.getAttractorsCount()) { + ltrace(89) << "Lower Median " << DbU::toLambda(attractors.getLowerMedian()) << endl; + ltrace(89) << "Upper Median " << DbU::toLambda(attractors.getUpperMedian()) << endl; + + optimalMin = attractors.getLowerMedian(); + optimalMax = attractors.getUpperMedian(); + } else { + optimalMin = 0; + optimalMax = (isHorizontal()) ? _gcell->getBoundingBox().getYMax() + : _gcell->getBoundingBox().getXMax(); + } } setInBound( constraintMin, constraintMax, optimalMin ); @@ -1925,12 +1930,16 @@ namespace Katabatic { if (horizontal) { if (horizontal->getLayer() != horizontalLayer) { - if ( not Session::getKatabatic()->isGMetal(horizontal->getLayer()) ) - cerr << Warning("Segment %s forced to %s." - ,getString(horizontal).c_str() - ,getString(horizontalLayer).c_str()) << endl; - horizontal->setLayer( horizontalLayer ); - horizontal->setWidth( horizontalWidth ); + if (Session::getKatabatic()->isGMetal(horizontal->getLayer())) { + horizontal->setLayer( horizontalLayer ); + horizontal->setWidth( horizontalWidth ); + } else { + if (horizontal->getWidth() != horizontalWidth) { + cerr << Warning("Segment %s has non-default width %s." + ,getString(horizontal).c_str() + ,DbU::getValueString(horizontal->getWidth()).c_str()) << endl; + } + } } horizontal->setY( reference->getY() ); @@ -1938,12 +1947,15 @@ namespace Katabatic { segment->_postCreate(); } else if (vertical) { if (vertical->getLayer() != verticalLayer) { - if ( not Session::getKatabatic()->isGMetal(vertical->getLayer()) ) - cerr << Warning("Segment %s forced to %s." - ,getString(vertical).c_str() - ,getString(verticalLayer).c_str()) << endl; + if (Session::getKatabatic()->isGMetal(vertical->getLayer()) ) vertical->setLayer( verticalLayer ); vertical->setWidth( verticalWidth ); + } else { + if (vertical->getWidth() != verticalWidth) { + cerr << Warning("Segment %s has non-default width %s." + ,getString(horizontal).c_str() + ,DbU::getValueString(horizontal->getWidth()).c_str()) << endl; + } } vertical->setX( reference->getX() ); diff --git a/katabatic/src/KatabaticEngine.cpp b/katabatic/src/KatabaticEngine.cpp index 53ec4e79..09f92b46 100644 --- a/katabatic/src/KatabaticEngine.cpp +++ b/katabatic/src/KatabaticEngine.cpp @@ -459,7 +459,7 @@ namespace Katabatic { { return _configuration; } - void KatabaticEngine::loadGlobalRouting ( unsigned int method, NetSet& nets ) + void KatabaticEngine::loadGlobalRouting ( unsigned int method, NetSet& nets, const map& excludeds ) { if (_state < EngineGlobalLoaded) throw Error ("KatabaticEngine::loadGlobalRouting() : global routing not present yet."); @@ -480,6 +480,7 @@ namespace Katabatic { continue; } if (af->isBLOCKAGE(net->getName())) continue; + if (excludeds.find(net->getName()) != excludeds.end()) continue; _routingNets.insert ( *net ); } } else { @@ -493,8 +494,10 @@ namespace Katabatic { if (excludedType) { cparanoid << Warning( "%s is not a routable net (%s), removed from set." , getString(*it).c_str(), excludedType ) << endl; - } else + } else { + if (excludeds.find((*it)->getName()) != excludeds.end()) continue; _routingNets.insert( *it ); + } } } diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index dbe12250..ec49236d 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -427,7 +427,7 @@ namespace Katabatic { for ( ; ilut!=_autoSegmentLut.end() ; ++ilut ) { AutoSegment* segment = (*ilut).second; - if (segment->isLocal()) continue; + if (segment->isLocal() or segment->isFixed()) continue; if (not segment->isCanonical()) continue; segments.push_back( segment ); diff --git a/katabatic/src/katabatic/AutoContact.h b/katabatic/src/katabatic/AutoContact.h index 358254d4..3394b33a 100644 --- a/katabatic/src/katabatic/AutoContact.h +++ b/katabatic/src/katabatic/AutoContact.h @@ -68,7 +68,9 @@ namespace Katabatic { , CntIgnoreAnchor = 0x00000200 }; - class AutoContact : public ExtensionGo { + class AutoContact { + public: + static AutoContact* createFrom ( Contact* ); public: // Wrapped Contact Accessors. inline Hook* getBodyHook (); @@ -158,6 +160,7 @@ namespace Katabatic { , DbU::Unit constraintMax , unsigned int flags=KbWarnOnError ); void restoreNativeConstraintBox (); + void destroy (); // Inspector Management. Record* _getRecord () const; virtual string _getString () const; @@ -193,7 +196,7 @@ namespace Katabatic { protected: inline int _getDeltaMin ( DbU::Unit x, DbU::Unit xMin ); inline int _getDeltaMax ( DbU::Unit x, DbU::Unit xMin, DbU::Unit xMax ); - void _getTopology ( Component*& anchor, Horizontal**&, Vertical**&, size_t ); + static void _getTopology ( Contact*, Component*& anchor, Horizontal**&, Vertical**&, size_t ); virtual void _invalidate ( unsigned int flags ) = 0; }; diff --git a/katabatic/src/katabatic/AutoContactHTee.h b/katabatic/src/katabatic/AutoContactHTee.h index 744a58c3..f6ee3d48 100644 --- a/katabatic/src/katabatic/AutoContactHTee.h +++ b/katabatic/src/katabatic/AutoContactHTee.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2012-2013, All Rights Reserved +// Copyright (c) UPMC 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -32,6 +31,7 @@ namespace Katabatic { class AutoContactHTee : public AutoContact { + friend class AutoContact; public: static AutoContactHTee* create ( GCell*, Net*, const Layer* ); protected: diff --git a/katabatic/src/katabatic/AutoContactTerminal.h b/katabatic/src/katabatic/AutoContactTerminal.h index 8c2ab882..8bbcff53 100644 --- a/katabatic/src/katabatic/AutoContactTerminal.h +++ b/katabatic/src/katabatic/AutoContactTerminal.h @@ -28,6 +28,7 @@ namespace Katabatic { class AutoContactTerminal : public AutoContact { + friend class AutoContact; public: static AutoContactTerminal* create ( GCell* gcell , Component* anchor diff --git a/katabatic/src/katabatic/AutoContactTurn.h b/katabatic/src/katabatic/AutoContactTurn.h index 393b42e2..a33d2529 100644 --- a/katabatic/src/katabatic/AutoContactTurn.h +++ b/katabatic/src/katabatic/AutoContactTurn.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2012-2013, All Rights Reserved +// Copyright (c) UPMC 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -31,6 +30,7 @@ namespace Katabatic { class AutoContactTurn : public AutoContact { + friend class AutoContact; public: static AutoContactTurn* create ( GCell*, Net*, const Layer* ); static void insert ( AutoContactTerminal* ); diff --git a/katabatic/src/katabatic/AutoContactVTee.h b/katabatic/src/katabatic/AutoContactVTee.h index f93e1402..bbb9f84b 100644 --- a/katabatic/src/katabatic/AutoContactVTee.h +++ b/katabatic/src/katabatic/AutoContactVTee.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2012-2013, All Rights Reserved +// Copyright (c) UPMC 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -29,6 +28,7 @@ namespace Katabatic { class AutoContactVTee : public AutoContact { + friend class AutoContact; public: static AutoContactVTee* create ( GCell*, Net*, const Layer* ); protected: diff --git a/katabatic/src/katabatic/AutoSegment.h b/katabatic/src/katabatic/AutoSegment.h index 192d42cc..94d356ce 100644 --- a/katabatic/src/katabatic/AutoSegment.h +++ b/katabatic/src/katabatic/AutoSegment.h @@ -90,6 +90,7 @@ namespace Katabatic { , SegInvalidatedTarget = 0x04000000 , SegInvalidatedLayer = 0x08000000 , SegCreated = 0x10000000 + , SegUserDefined = 0x20000000 // Masks. , SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2 , SegNotAligned = SegNotSourceAligned|SegNotTargetAligned @@ -182,6 +183,7 @@ namespace Katabatic { inline bool isCanonical () const; inline bool isUnsetAxis () const; inline bool isSlackened () const; + inline bool isUserDefined () const; virtual bool _canSlacken () const = 0; unsigned int canDogleg ( Interval ); virtual bool canMoveULeft ( float reserve=0.0 ) const = 0; @@ -449,6 +451,7 @@ namespace Katabatic { inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; } inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; } inline bool AutoSegment::isCreated () const { return _flags & SegCreated; } + inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; } inline void AutoSegment::setFlags ( unsigned int flags ) { _flags |= flags; } inline void AutoSegment::unsetFlags ( unsigned int flags ) { _flags &= ~flags; } diff --git a/katabatic/src/katabatic/Grid.h b/katabatic/src/katabatic/Grid.h index a2e781cc..55bbe028 100644 --- a/katabatic/src/katabatic/Grid.h +++ b/katabatic/src/katabatic/Grid.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -20,7 +19,6 @@ #include #include - #include "hurricane/Point.h" #include "hurricane/Box.h" #include "hurricane/Collection.h" @@ -28,7 +26,6 @@ namespace Katabatic { - using std::string; using std::vector; using Hurricane::_TName; diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index c2d56412..10136b39 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "hurricane/Timer.h" #include "hurricane/DbU.h" #include "hurricane/Torus.h" @@ -134,7 +135,7 @@ namespace Katabatic { virtual void createDetailedGrid (); void chipPrep (); void makePowerRails (); - virtual void loadGlobalRouting ( unsigned int method, NetSet& ); + virtual void loadGlobalRouting ( unsigned int method, NetSet&, const std::map& ); void slackenBorder ( Box bb, Layer::Mask, unsigned int flags ); void slackenBlockIos ( Instance* core ); bool moveUpNetTrunk ( AutoSegment*, set& globalNets, GCell::SetIndex& invalidateds ); diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index c2f20403..913eee9f 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -97,7 +97,7 @@ namespace { class GlobalNetTable { public: - GlobalNetTable ( Cell* ); + GlobalNetTable ( KiteEngine* ); Net* getRootNet ( const Net*, Path ) const; inline Net* getVdde () const; inline Net* getVddi () const; @@ -139,7 +139,7 @@ namespace { inline Net* GlobalNetTable::getBlockage () const { return _blockage; } inline void GlobalNetTable::setBlockage ( Net* net ) { _blockage=net; } - GlobalNetTable::GlobalNetTable ( Cell* topCell ) + GlobalNetTable::GlobalNetTable ( KiteEngine* kite ) : _vddeName("vdde") , _vddiName("vddi") , _vsseName("vsse") @@ -156,9 +156,10 @@ namespace { , _cko (NULL) , _blockage(NULL) { - if ( topCell == NULL ) return; + Cell* topCell = kite->getCell(); + if (topCell == NULL) return; - AllianceFramework* af = AllianceFramework::get (); + AllianceFramework* af = AllianceFramework::get(); bool hasPad = false; forEach ( Instance*, iinstance, topCell->getInstances() ) { @@ -235,7 +236,11 @@ namespace { _vssiName = ""; _ckoName = ""; + map preRouteds = kite->getPreRouteds(); + forEach ( Net*, inet, topCell->getNets() ) { + if (preRouteds.find(inet->getName()) != preRouteds.end()) continue; + Net::Type netType = inet->getType(); if (netType == Net::Type::POWER) { if (_vddiName.isEmpty()) { @@ -478,12 +483,6 @@ namespace { }; -} // Anonymous namespace. - - -namespace { - - PowerRailsPlanes::Rail::Rail ( Rails* rails, DbU::Unit axis, DbU::Unit width ) : _rails (rails) , _axis (axis) @@ -847,7 +846,7 @@ namespace { PowerRailsPlanes::PowerRailsPlanes ( KiteEngine* kite ) : _kite (kite) - , _globalNets (kite->getCell()) + , _globalNets (kite) , _planes () , _activePlane(NULL) { diff --git a/kite/src/BuildPreRouteds.cpp b/kite/src/BuildPreRouteds.cpp new file mode 100644 index 00000000..e22b442a --- /dev/null +++ b/kite/src/BuildPreRouteds.cpp @@ -0,0 +1,177 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2014-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./BuildPreRouteds.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Instance.h" +#include "hurricane/Plug.h" +#include "hurricane/Path.h" +#include "hurricane/Query.h" +#include "crlcore/AllianceFramework.h" +#include "katabatic/AutoContact.h" +#include "kite/RoutingPlane.h" +#include "kite/TrackFixedSegment.h" +#include "kite/Track.h" +#include "kite/KiteEngine.h" + + +namespace { + + using namespace std; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::ForEachIterator; + using Hurricane::Warning; + using Hurricane::Error; + using Hurricane::DbU; + using Hurricane::Box; + using Hurricane::Interval; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Hurricane::NetExternalComponents; + using Hurricane::Instance; + using Hurricane::Plug; + using Hurricane::Path; + using Hurricane::Query; + using Hurricane::Go; + using Hurricane::Rubber; + using Hurricane::Layer; + using Hurricane::BasicLayer; + using Hurricane::RegularLayer; + using Hurricane::Transformation; + using Hurricane::Technology; + using Hurricane::DataBase; + using CRL::AllianceFramework; + using Katabatic::AutoContact; + using Katabatic::AutoSegment; + using Katabatic::ChipTools; + using namespace Kite; + + +} // Anonymous namespace. + + +namespace Kite { + + + using Hurricane::DataBase; + using Hurricane::Technology; + using Hurricane::BasicLayer; + using Hurricane::ForEachIterator; + + + void KiteEngine::buildPreRouteds () + { + forEach ( Net*, inet, getCell()->getNets() ) { + if (*inet == _blockageNet) continue; + if (inet->getType() == Net::Type::POWER ) continue; + if (inet->getType() == Net::Type::GROUND) continue; + // Don't consider the clock. + + vector segments; + vector contacts; + + bool isPreRouted = false; + size_t rpCount = 0; + forEach ( Component*, icomponent, inet->getComponents() ) { + Horizontal* horizontal = dynamic_cast(*icomponent); + if (horizontal) { + segments.push_back( horizontal ); + isPreRouted = true; + } else { + Vertical* vertical = dynamic_cast(*icomponent); + if (vertical) { + isPreRouted = true; + segments.push_back( vertical ); + } else { + Contact* contact = dynamic_cast(*icomponent); + if (contact) { + isPreRouted = true; + contacts.push_back( contact ); + } else { + RoutingPad* rp = dynamic_cast(*icomponent); + if (rp) { + ++rpCount; + } else { + // Plug* plug = dynamic_cast(*icomponent); + // if (plug) { + // cerr << "buildPreRouteds(): " << plug << endl; + // ++rpCount; + // } + } + } + } + } + } + + if (isPreRouted or (rpCount < 2)) { + _preRouteds.insert( make_pair(inet->getName(),*inet) ); + + if (rpCount > 1) { + for ( auto icontact : contacts ) { + AutoContact::createFrom( icontact ); + } + + for ( auto isegment : segments ) { + AutoContact* source = Session::base()->lookup( dynamic_cast( isegment->getSource() )); + AutoContact* target = Session::base()->lookup( dynamic_cast( isegment->getTarget() )); + AutoSegment* autoSegment = AutoSegment::create( source, target, isegment ); + autoSegment->setFlags( Katabatic::SegUserDefined|Katabatic::SegAxisSet ); + } + } + } + } + + Session::revalidate (); + } + + + void KiteEngine::setFixedPreRouted () + { + for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) { + RoutingPlane* rp = _routingPlanes[depth]; + if (rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; + if (rp->getLayerGauge()->getDepth() > getConfiguration()->getAllowedDepth() ) continue; + + size_t tracksSize = rp->getTracksSize(); + for ( size_t itrack=0 ; itrackgetTrackByIndex( itrack ); + + for ( size_t ielement=0 ; ielementgetSize() ; ++ielement ) { + TrackElement* element = track->getSegment( ielement ); + + if (element->getNet() == NULL) continue; + element->setRouted(); + } + } + } + } + + +} // Kite namespace. diff --git a/kite/src/CMakeLists.txt b/kite/src/CMakeLists.txt index f652e30d..e319312b 100644 --- a/kite/src/CMakeLists.txt +++ b/kite/src/CMakeLists.txt @@ -59,6 +59,7 @@ RoutingEventLoop.cpp NegociateWindow.cpp BuildPowerRails.cpp + BuildPreRouteds.cpp ProtectRoutingPads.cpp PreProcess.cpp Configuration.cpp diff --git a/kite/src/GraphicKiteEngine.cpp b/kite/src/GraphicKiteEngine.cpp index ae413c28..c48d6b0b 100644 --- a/kite/src/GraphicKiteEngine.cpp +++ b/kite/src/GraphicKiteEngine.cpp @@ -52,6 +52,7 @@ namespace Kite { using Hurricane::Breakpoint; using Hurricane::DebugSession; using Hurricane::Point; + using Hurricane::Entity; using Hurricane::Net; using Hurricane::Graphics; using Hurricane::ColorScale; @@ -190,6 +191,13 @@ namespace Kite { } + void GraphicKiteEngine::_runNegociatePreRouted () + { + KiteEngine* kite = getForFramework( CreateEngine ); + kite->runNegociate( KtPreRoutedStage ); + } + + void GraphicKiteEngine::_runNegociate () { KiteEngine* kite = getForFramework( NoFlags ); @@ -230,6 +238,12 @@ namespace Kite { { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_saveGlobalSolution,this) ); } + void GraphicKiteEngine::detailPreRoute () + { + ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_runNegociatePreRouted,this) ); + } + + void GraphicKiteEngine::detailRoute () { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_loadGlobalRouting ,this) ); @@ -248,9 +262,10 @@ namespace Kite { void GraphicKiteEngine::route () { - globalRoute(); - detailRoute(); - finalize (); + detailPreRoute(); + globalRoute (); + detailRoute (); + finalize (); } @@ -306,6 +321,12 @@ namespace Kite { else { stepMenu->addSeparator(); + QAction* dPreRouteAction = new QAction ( tr("Kite - Detailed Pre-Route"), _viewer ); + dPreRouteAction->setObjectName( "viewer.menuBar.placeAndPreRoute.stepBystep.detailedPreRoute" ); + dPreRouteAction->setStatusTip ( tr("Run the Kite detailed router on pre-routed nets") ); + dPreRouteAction->setVisible ( true ); + stepMenu->addAction( dPreRouteAction ); + QAction* gRouteAction = new QAction ( tr("Kite - &Global Route"), _viewer ); gRouteAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.globalRoute" ); gRouteAction->setStatusTip ( tr("Run the Knik global router") ); @@ -357,6 +378,7 @@ namespace Kite { connect( gLoadSolutionAction, SIGNAL(triggered()), this, SLOT(loadGlobalSolution()) ); connect( gSaveSolutionAction, SIGNAL(triggered()), this, SLOT(saveGlobalSolution()) ); connect( gRouteAction , SIGNAL(triggered()), this, SLOT(globalRoute ()) ); + connect( dPreRouteAction , SIGNAL(triggered()), this, SLOT(detailPreRoute ()) ); connect( dRouteAction , SIGNAL(triggered()), this, SLOT(detailRoute ()) ); connect( dFinalizeAction , SIGNAL(triggered()), this, SLOT(finalize ()) ); connect( dSaveAction , SIGNAL(triggered()), this, SLOT(save ()) ); diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index 269df917..841bdea5 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -105,6 +105,7 @@ namespace Kite { , _knik (NULL) , _blockageNet (NULL) , _configuration (new Configuration(getKatabaticConfiguration())) + , _preRouteds () , _routingPlanes () , _negociateWindow(NULL) , _minimumWL (0.0) @@ -115,15 +116,23 @@ namespace Kite { void KiteEngine::_postCreate () { KatabaticEngine::_postCreate (); + } -#ifdef KNIK_NOT_EMBEDDED - size_t maxDepth = getRoutingGauge()->getDepth(); - _routingPlanes.reserve( maxDepth ); - for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { - _routingPlanes.push_back( RoutingPlane::create( this, depth ) ); - } -#endif + void KiteEngine::_initDataBase () + { + ltrace(90) << "KiteEngine::_initDataBase()" << endl; + ltracein(90); + + Session::open( this ); + createGlobalGraph( KtNoFlags ); + createDetailedGrid(); + buildPreRouteds(); + buildPowerRails(); + protectRoutingPads(); + Session::close(); + + ltraceout(90); } @@ -132,6 +141,8 @@ namespace Kite { KiteEngine* kite = new KiteEngine ( cell ); kite->_postCreate(); + kite->_initDataBase(); + return kite; } @@ -370,8 +381,11 @@ namespace Kite { ltrace(300) << "Reject capacity from (not Net): " << element << endl; continue; } - if ( (not element->isFixed()) and (not element->isBlockage()) ) { - ltrace(300) << "Reject capacity from (neither fixed nor blockage): " << element << endl; + if ( (not element->isFixed()) + and (not element->isBlockage()) + and (not element->isUserDefined()) ) { + cmess2 << "Reject capacity from (neither fixed, blockage nor user defined): " << element << endl; + //ltrace(300) << "Reject capacity from (neither fixed nor blockage): " << element << endl; continue; } @@ -446,10 +460,6 @@ namespace Kite { if (getState() >= Katabatic::EngineGlobalLoaded) throw Error ("KiteEngine::runGlobalRouter(): Global routing already done or loaded."); - Session::open( this ); - - createGlobalGraph( mode ); - // Test signals from . //DebugSession::addToTrace( getCell(), "aux34" ); @@ -524,17 +534,13 @@ namespace Kite { // Test signals from . //DebugSession::addToTrace( getCell(), "core.snx_inst.not_v_inc_out(9)" ); - createDetailedGrid(); - buildPowerRails(); - protectRoutingPads(); - - Session::revalidate(); + Session::open( this ); if (mode & KtLoadGlobalRouting) { _knik->loadSolution(); } else { annotateGlobalGraph(); - _knik->run(); + _knik->run( getPreRouteds() ); } setState( Katabatic::EngineGlobalLoaded ); @@ -545,7 +551,7 @@ namespace Kite { void KiteEngine::loadGlobalRouting ( unsigned int method, KatabaticEngine::NetSet& nets ) { - KatabaticEngine::loadGlobalRouting( method, nets ); + KatabaticEngine::loadGlobalRouting( method, nets, getPreRouteds() ); Session::open( this ); getGCellGrid()->checkEdgeOverflow( getHTracksReservedLocal(), getVTracksReservedLocal() ); @@ -553,7 +559,7 @@ namespace Kite { } - void KiteEngine::runNegociate ( unsigned int slowMotion ) + void KiteEngine::runNegociate ( unsigned int flags ) { if (_negociateWindow) return; @@ -563,7 +569,7 @@ namespace Kite { _negociateWindow = NegociateWindow::create( this ); _negociateWindow->setGCells( *(getGCellGrid()->getGCellVector()) ); _computeCagedConstraints(); - _negociateWindow->run( slowMotion ); + _negociateWindow->run( flags ); _negociateWindow->printStatistics(); _negociateWindow->destroy(); _negociateWindow = NULL; diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index 7d606eda..ee61f76b 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -158,7 +158,7 @@ namespace Kite { NegociateWindow::NegociateWindow ( KiteEngine* kite ) - : _slowMotion (0) + : _flags (KtNoFlags) , _interrupt (false) , _kite (kite) , _gcells () @@ -464,7 +464,7 @@ namespace Kite { } - void NegociateWindow::run ( int slowMotion ) + void NegociateWindow::run ( unsigned int flags ) { ltrace(150) << "NegociateWindow::run()" << endl; ltracein(149); @@ -478,19 +478,26 @@ namespace Kite { _createRouting( _gcells[igcell] ); } Session::revalidate(); - _kite->preProcess(); - Session::revalidate(); - getKiteEngine()->setMinimumWL( computeWirelength() ); + if (not (flags & KtPreRoutedStage)) { + _kite->preProcess(); + Session::revalidate(); + } + + _kite->setMinimumWL( computeWirelength() ); #if defined(CHECK_DATABASE) unsigned int overlaps = 0; Session::getKiteEngine()->_check( overlaps, "after _createRouting(GCell*)" ); #endif - _slowMotion = slowMotion; + _flags |= flags; _negociate(); + if (flags & KtPreRoutedStage) { + _kite->setFixedPreRouted(); + } + Session::get()->isEmpty(); # if defined(CHECK_DATABASE) diff --git a/kite/src/PreProcess.cpp b/kite/src/PreProcess.cpp index 75e89924..9b6a2374 100644 --- a/kite/src/PreProcess.cpp +++ b/kite/src/PreProcess.cpp @@ -241,7 +241,8 @@ namespace { for ( size_t i=0 ; igetSize() ; ++i ) { TrackElement* segment = track->getSegment(i); - if ( segment and segment->isFixed() and segment->isTerminal() ) { + if (not segment or segment->isRouted()) continue; + if (segment and segment->isFixed() and segment->isTerminal()) { Interval freeInterval = track->getFreeInterval( segment->getSourceU(), segment->getNet() ); DbU::Unit ppitch = segment->getPPitch(); diff --git a/kite/src/PyKiteEngine.cpp b/kite/src/PyKiteEngine.cpp index 56132742..2a008b08 100644 --- a/kite/src/PyKiteEngine.cpp +++ b/kite/src/PyKiteEngine.cpp @@ -215,6 +215,21 @@ extern "C" { } + static PyObject* PyKiteEngine_runNegociatePreRouted ( PyKiteEngine* self ) + { + trace << "PyKiteEngine_runNegociatePreRouted()" << endl; + HTRY + METHOD_HEAD("KiteEngine.runNegociatePreRouted()") + if (kite->getViewer()) { + ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runNegociate,kite,Kite::KtPreRoutedStage) ); + } else { + kite->runNegociate( Kite::KtPreRoutedStage ); + } + HCATCH + Py_RETURN_NONE; + } + + static PyObject* PyKiteEngine_runNegociate ( PyKiteEngine* self ) { trace << "PyKiteEngine_runNegociate()" << endl; @@ -242,31 +257,33 @@ extern "C" { PyMethodDef PyKiteEngine_Methods[] = - { { "get" , (PyCFunction)PyKiteEngine_get , METH_VARARGS|METH_STATIC - , "Returns the Kite engine attached to the Cell, None if there isnt't." } - , { "create" , (PyCFunction)PyKiteEngine_create , METH_VARARGS|METH_STATIC - , "Create a Kite engine on this cell." } - , { "printConfiguration", (PyCFunction)PyKiteEngine_printConfiguration, METH_NOARGS - , "Display on the console the configuration of Kite." } - , { "saveGlobalSolution", (PyCFunction)PyKiteEngine_saveGlobalSolution, METH_NOARGS - , "Save the global routing solution on disk." } - , { "getToolSuccess" , (PyCFunction)PyKiteEngine_getToolSuccess , METH_NOARGS - , "Returns True if the detailed routing has been successful." } - , { "loadGlobalRouting" , (PyCFunction)PyKiteEngine_loadGlobalRouting , METH_VARARGS - , "Read/load the global routing and build topologies for Kite." } - , { "runGlobalRouter" , (PyCFunction)PyKiteEngine_runGlobalRouter , METH_VARARGS - , "Run the global router (Knik)." } - , { "layerAssign" , (PyCFunction)PyKiteEngine_layerAssign , METH_VARARGS - , "Run the layer assigment stage." } - , { "runNegociate" , (PyCFunction)PyKiteEngine_runNegociate , METH_NOARGS - , "Run the negociation stage of the detailed router." } - , { "finalizeLayout" , (PyCFunction)PyKiteEngine_finalizeLayout , METH_NOARGS - , "Revert to a pure Hurricane database, remove router's additionnal data structures." } - , { "dumpMeasures" , (PyCFunction)PyKiteEngine_dumpMeasures , METH_NOARGS - , "Dump to disk lots of statistical informations about the routing." } - , { "destroy" , (PyCFunction)PyKiteEngine_destroy , METH_NOARGS - , "Destroy the associated hurricane object. The python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ + { { "get" , (PyCFunction)PyKiteEngine_get , METH_VARARGS|METH_STATIC + , "Returns the Kite engine attached to the Cell, None if there isnt't." } + , { "create" , (PyCFunction)PyKiteEngine_create , METH_VARARGS|METH_STATIC + , "Create a Kite engine on this cell." } + , { "printConfiguration" , (PyCFunction)PyKiteEngine_printConfiguration , METH_NOARGS + , "Display on the console the configuration of Kite." } + , { "saveGlobalSolution" , (PyCFunction)PyKiteEngine_saveGlobalSolution , METH_NOARGS + , "Save the global routing solution on disk." } + , { "getToolSuccess" , (PyCFunction)PyKiteEngine_getToolSuccess , METH_NOARGS + , "Returns True if the detailed routing has been successful." } + , { "loadGlobalRouting" , (PyCFunction)PyKiteEngine_loadGlobalRouting , METH_VARARGS + , "Read/load the global routing and build topologies for Kite." } + , { "runGlobalRouter" , (PyCFunction)PyKiteEngine_runGlobalRouter , METH_VARARGS + , "Run the global router (Knik)." } + , { "layerAssign" , (PyCFunction)PyKiteEngine_layerAssign , METH_VARARGS + , "Run the layer assigment stage." } + , { "runNegociatePreRouted", (PyCFunction)PyKiteEngine_runNegociatePreRouted, METH_NOARGS + , "Run the negociation stage for pre-routed of the detailed router." } + , { "runNegociate" , (PyCFunction)PyKiteEngine_runNegociate , METH_NOARGS + , "Run the negociation stage of the detailed router." } + , { "finalizeLayout" , (PyCFunction)PyKiteEngine_finalizeLayout , METH_NOARGS + , "Revert to a pure Hurricane database, remove router's additionnal data structures." } + , { "dumpMeasures" , (PyCFunction)PyKiteEngine_dumpMeasures , METH_NOARGS + , "Dump to disk lots of statistical informations about the routing." } + , { "destroy" , (PyCFunction)PyKiteEngine_destroy , METH_NOARGS + , "Destroy the associated hurricane object. The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/kite/src/Session.cpp b/kite/src/Session.cpp index de3fcf42..6803e219 100644 --- a/kite/src/Session.cpp +++ b/kite/src/Session.cpp @@ -206,7 +206,7 @@ namespace Kite { (*it)->check( overlaps, "Session::_revalidate() - on packed track." ); for ( size_t i=0 ; i_check(); + revalidateds[i]->check(); } //_getKiteEngine()->_showOverlap (); diff --git a/kite/src/TrackElement.cpp b/kite/src/TrackElement.cpp index 4a7991f4..4f2d8ffd 100644 --- a/kite/src/TrackElement.cpp +++ b/kite/src/TrackElement.cpp @@ -150,6 +150,7 @@ namespace Kite { bool TrackElement::isSlackened () const { return false; } bool TrackElement::isDogleg () const { return false; } bool TrackElement::isSameLayerDogleg () const { return false; } + bool TrackElement::isUserDefined () const { return false; } // Predicates. bool TrackElement::canSlacken () const { return false; } bool TrackElement::canPivotUp ( float ) const { return false; }; diff --git a/kite/src/TrackSegment.cpp b/kite/src/TrackSegment.cpp index 5ad4fec5..d9f9cd28 100644 --- a/kite/src/TrackSegment.cpp +++ b/kite/src/TrackSegment.cpp @@ -142,6 +142,7 @@ namespace Kite { bool TrackSegment::isSlackened () const { return _base->isSlackened(); } bool TrackSegment::isDogleg () const { return _base->isDogleg(); } bool TrackSegment::isSameLayerDogleg () const { return _base->isSameLayerDogleg(); } + bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); } // Predicates. // Accessors. unsigned long TrackSegment::getId () const { return _base->getId(); } @@ -543,6 +544,11 @@ namespace Kite { return false; } + if (isRouted()) { + ltrace(200) << "Failed: belongs to an already routed net." << endl; + return false; + } + if (isSlackened()) { ltrace(200) << "Failed: is local & slackened." << endl; return false; @@ -579,6 +585,12 @@ namespace Kite { return false; } + if (isRouted()) { + ltrace(200) << "false: Cannot dogleg a segment belonging to an already routed net." << endl; + ltraceout(200); + return false; + } + if (isLocal()) { if (hasSourceDogleg() or hasTargetDogleg()) { ltrace(200) << "false: Cannot dogleg again a local segment." << endl; @@ -655,6 +667,11 @@ namespace Kite { return false; } + if (isRouted()) { + ltrace(200) << "Failed: belongs to an already routed net" << endl; + return false; + } + if (not isLocal()) { ltrace(200) << "Failed: is not local" << endl; return false; @@ -809,11 +826,15 @@ namespace Kite { base()->checkPositions(); base()->getCanonical( min, max ); if (getSourceU() != min) { - cerr << "[CHECK] " << this << " has bad source position " << DbU::getValueString(min) << "." << endl; + cerr << "[CHECK] " << this << " has bad source position " + << "cache:" << DbU::getValueString(getSourceU()) << " vs. " + << "canon:" << DbU::getValueString(min) << "." << endl; coherency = false; } if (getTargetU() != max) { - cerr << "[CHECK] " << this << " has bad target position " << DbU::getValueString(max) << "." << endl; + cerr << "[CHECK] " << this << " has bad target position " + << "cache:" << DbU::getValueString(getTargetU()) << " vs. " + << "canon:" << DbU::getValueString(max) << "." << endl; coherency = false; } @@ -833,13 +854,14 @@ namespace Kite { + " " + DbU::getValueString(_targetU-_sourceU) + " " + getString(_dogLegLevel) + " [" + ((_track) ? getString(_index) : "npos") + "] " + + ((isRouted() ) ? "R" : "-") + ((isSlackened() ) ? "S" : "-") + ((_track ) ? "T" : "-") + ((canRipple() ) ? "r" : "-") + ((hasSourceDogleg()) ? "s" : "-") + ((hasTargetDogleg()) ? "t" : "-"); - s1.insert ( s1.size()-1, s2 ); + s1.insert( s1.size()-1, s2 ); return s1; } diff --git a/kite/src/kite/Constants.h b/kite/src/kite/Constants.h index dd3479fa..e1127288 100644 --- a/kite/src/kite/Constants.h +++ b/kite/src/kite/Constants.h @@ -33,7 +33,8 @@ namespace Kite { using Katabatic::KbWarnOnError; using Katabatic::perpandicularTo; - enum FunctionFlags { KtLoadGlobalRouting = 0x00000001 + enum FunctionFlags { KtNoFlags = 0x00000000 + , KtLoadGlobalRouting = 0x00000001 , KtBuildGlobalRouting = 0x00000002 , KtAllowDoglegReuse = 0x00000004 , KtDataSelf = 0x00000008 @@ -45,6 +46,8 @@ namespace Kite { , KtMoveToLeft = 0x00000200 , KtMoveToRight = 0x00000400 , KtLoadingStage = 0x00000800 + , KtSlowMotion = 0x00001000 + , KtPreRoutedStage = 0x00002000 , }; } // Kite namespace. diff --git a/kite/src/kite/GraphicKiteEngine.h b/kite/src/kite/GraphicKiteEngine.h index 46a3977a..01fc7e92 100644 --- a/kite/src/kite/GraphicKiteEngine.h +++ b/kite/src/kite/GraphicKiteEngine.h @@ -77,6 +77,7 @@ namespace Kite { virtual void addToMenu ( CellViewer* ); void postEvent (); public slots: + void detailPreRoute (); void loadGlobalSolution (); void saveGlobalSolution (); void globalRoute (); @@ -91,16 +92,17 @@ namespace Kite { static GraphicKiteEngine* _singleton; CellViewer* _viewer; protected: - GraphicKiteEngine (); - virtual ~GraphicKiteEngine (); - void _loadGlobalSolution (); - void _saveGlobalSolution (); - void _globalRoute (); - void _loadGlobalRouting (); - void _balanceGlobalDensity (); - void _runNegociate (); - void _finalize (); - void _save (); + GraphicKiteEngine (); + virtual ~GraphicKiteEngine (); + void _loadGlobalSolution (); + void _saveGlobalSolution (); + void _globalRoute (); + void _loadGlobalRouting (); + void _balanceGlobalDensity (); + void _runNegociatePreRouted (); + void _runNegociate (); + void _finalize (); + void _save (); }; diff --git a/kite/src/kite/KiteEngine.h b/kite/src/kite/KiteEngine.h index cb07d541..801c52c4 100644 --- a/kite/src/kite/KiteEngine.h +++ b/kite/src/kite/KiteEngine.h @@ -60,64 +60,66 @@ namespace Kite { class KiteEngine : public KatabaticEngine { public: - static const Name& staticGetName (); - static KiteEngine* create ( Cell* ); - static KiteEngine* get ( const Cell* ); - public: - inline CellViewer* getViewer () const; - inline KatabaticEngine* base (); - inline Configuration* getKiteConfiguration (); - virtual Configuration* getConfiguration (); - inline Net* getBlockageNet (); - inline bool getToolSuccess () const; - inline unsigned long getEventsLimit () const; - inline unsigned int getRipupLimit ( unsigned int type ) const; - unsigned int getRipupLimit ( const TrackElement* ) const; - inline unsigned int getRipupCost () const; - inline size_t getHTracksReservedLocal () const; - inline size_t getVTracksReservedLocal () const; - virtual const Name& getName () const; + static const Name& staticGetName (); + static KiteEngine* create ( Cell* ); + static KiteEngine* get ( const Cell* ); + public: + inline CellViewer* getViewer () const; + inline KatabaticEngine* base (); + inline Configuration* getKiteConfiguration (); + virtual Configuration* getConfiguration (); + inline const map& getPreRouteds () const; + inline Net* getBlockageNet (); + inline bool getToolSuccess () const; + inline unsigned long getEventsLimit () const; + inline unsigned int getRipupLimit ( unsigned int type ) const; + unsigned int getRipupLimit ( const TrackElement* ) const; + inline unsigned int getRipupCost () const; + inline size_t getHTracksReservedLocal () const; + inline size_t getVTracksReservedLocal () const; + virtual const Name& getName () const; inline Configuration::PostEventCb_t& - getPostEventCb (); - inline NegociateWindow* getNegociateWindow (); - inline size_t getRoutingPlanesSize () const; - RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const; - RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; - Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; - inline void printConfiguration () const; - void printCompletion () const; - void dumpMeasures ( std::ostream& ) const; - void dumpMeasures () const; - inline void setViewer ( CellViewer* ); - inline void setPostEventCb ( Configuration::PostEventCb_t ); - inline void setEventLimit ( unsigned long ); - inline void setMinimumWL ( double ); - inline void setRipupLimit ( unsigned int type, unsigned int ); - inline void setRipupCost ( unsigned int ); - inline void setHTracksReservedLocal ( size_t ); - inline void setVTracksReservedLocal ( size_t ); - void buildPowerRails (); - void protectRoutingPads (); - void preProcess (); - void setInterrupt ( bool ); - void buildBlockages (); - void createGlobalGraph ( unsigned int mode ); - virtual void createDetailedGrid (); - void saveGlobalSolution (); - void annotateGlobalGraph (); - void runNegociate ( unsigned int slowMotion=0 ); - void runGlobalRouter ( unsigned int mode ); - virtual void loadGlobalRouting ( unsigned int method, KatabaticEngine::NetSet& ); - virtual void finalizeLayout (); - void _gutKite (); - void _computeCagedConstraints (); - TrackElement* _lookup ( Segment* ) const; - inline TrackElement* _lookup ( AutoSegment* ) const; - bool _check ( unsigned int& overlap, const char* message=NULL ) const; - void _check ( Net* ) const; - virtual Record* _getRecord () const; - virtual string _getString () const; - virtual string _getTypeName () const; + getPostEventCb (); + inline NegociateWindow* getNegociateWindow (); + inline size_t getRoutingPlanesSize () const; + RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const; + RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; + Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; + inline void printConfiguration () const; + void printCompletion () const; + void dumpMeasures ( std::ostream& ) const; + void dumpMeasures () const; + inline void setViewer ( CellViewer* ); + inline void setPostEventCb ( Configuration::PostEventCb_t ); + inline void setEventLimit ( unsigned long ); + inline void setMinimumWL ( double ); + inline void setRipupLimit ( unsigned int type, unsigned int ); + inline void setRipupCost ( unsigned int ); + inline void setHTracksReservedLocal ( size_t ); + inline void setVTracksReservedLocal ( size_t ); + void buildPowerRails (); + void buildPreRouteds (); + void protectRoutingPads (); + void preProcess (); + void setInterrupt ( bool ); + void createGlobalGraph ( unsigned int mode ); + virtual void createDetailedGrid (); + void saveGlobalSolution (); + void annotateGlobalGraph (); + void setFixedPreRouted (); + void runNegociate ( unsigned int flags=KtNoFlags ); + void runGlobalRouter ( unsigned int mode ); + virtual void loadGlobalRouting ( unsigned int method, KatabaticEngine::NetSet& ); + virtual void finalizeLayout (); + void _gutKite (); + void _computeCagedConstraints (); + TrackElement* _lookup ( Segment* ) const; + inline TrackElement* _lookup ( AutoSegment* ) const; + bool _check ( unsigned int& overlap, const char* message=NULL ) const; + void _check ( Net* ) const; + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; private: // Attributes. @@ -127,6 +129,7 @@ namespace Kite { Knik::KnikEngine* _knik; Net* _blockageNet; Configuration* _configuration; + map _preRouteds; vector _routingPlanes; NegociateWindow* _negociateWindow; double _minimumWL; @@ -134,13 +137,14 @@ namespace Kite { protected: // Constructors & Destructors. - KiteEngine ( Cell* ); - virtual ~KiteEngine (); - virtual void _postCreate (); - virtual void _preDestroy (); + KiteEngine ( Cell* ); + virtual ~KiteEngine (); + virtual void _postCreate (); + virtual void _preDestroy (); + void _initDataBase (); private: - KiteEngine ( const KiteEngine& ); - KiteEngine& operator= ( const KiteEngine& ); + KiteEngine ( const KiteEngine& ); + KiteEngine& operator= ( const KiteEngine& ); }; @@ -149,6 +153,7 @@ namespace Kite { inline KatabaticEngine* KiteEngine::base () { return static_cast(this); } inline Configuration* KiteEngine::getKiteConfiguration () { return _configuration; } inline Net* KiteEngine::getBlockageNet () { return _blockageNet; } + inline const map& KiteEngine::getPreRouteds () const { return _preRouteds; } inline Configuration::PostEventCb_t& KiteEngine::getPostEventCb () { return _configuration->getPostEventCb(); } inline bool KiteEngine::getToolSuccess () const { return _toolSuccess; } inline unsigned long KiteEngine::getEventsLimit () const { return _configuration->getEventsLimit(); } diff --git a/kite/src/kite/NegociateWindow.h b/kite/src/kite/NegociateWindow.h index 11cd85a7..354c561a 100644 --- a/kite/src/kite/NegociateWindow.h +++ b/kite/src/kite/NegociateWindow.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -114,7 +113,7 @@ namespace Kite { TrackElement* createTrackSegment ( AutoSegment*, unsigned int flags ); void addRoutingEvent ( TrackElement*, unsigned int level ); inline void rescheduleEvent ( RoutingEvent*, unsigned int level ); - void run ( int slowMotion=0 ); + void run ( unsigned int flags ); void printStatistics () const; void _createRouting ( Katabatic::GCell* ); size_t _negociate (); @@ -124,7 +123,7 @@ namespace Kite { private: // Attributes. - unsigned int _slowMotion; + unsigned int _flags; bool _interrupt; KiteEngine* _kite; Katabatic::GCellVector _gcells; diff --git a/kite/src/kite/TrackElement.h b/kite/src/kite/TrackElement.h index f8d82323..1df2003c 100644 --- a/kite/src/kite/TrackElement.h +++ b/kite/src/kite/TrackElement.h @@ -117,6 +117,7 @@ namespace Kite { virtual bool isSlackened () const; virtual bool isDogleg () const; virtual bool isSameLayerDogleg () const; + virtual bool isUserDefined () const; // Predicates. inline bool isCreated () const; inline bool isInvalidated () const; @@ -167,6 +168,7 @@ namespace Kite { // Mutators. inline void setFlags ( unsigned int ); inline void unsetFlags ( unsigned int ); + inline void setRouted (); virtual void setTrack ( Track* ); inline void setIndex ( size_t ); virtual void updateFreedomDegree (); @@ -240,6 +242,12 @@ namespace Kite { inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } inline void TrackElement::setIndex ( size_t index ) { _index=index; } + inline void TrackElement::setRouted() + { + _flags |= TElemRouted; + if (base()) base()->setFlags( Katabatic::SegFixed ); + } + inline Box TrackElement::getBoundingBox () const { if (getDirection() == KbHorizontal) diff --git a/kite/src/kite/TrackFixedSegment.h b/kite/src/kite/TrackFixedSegment.h index f5fab66b..97bea72e 100644 --- a/kite/src/kite/TrackFixedSegment.h +++ b/kite/src/kite/TrackFixedSegment.h @@ -1,9 +1,7 @@ - - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/kite/TrackSegment.h b/kite/src/kite/TrackSegment.h index 4235d6db..f1dc642b 100644 --- a/kite/src/kite/TrackSegment.h +++ b/kite/src/kite/TrackSegment.h @@ -68,6 +68,7 @@ namespace Kite { virtual bool isSlackened () const; virtual bool isDogleg () const; virtual bool isSameLayerDogleg () const; + virtual bool isUserDefined () const; // Predicates. virtual bool canDogleg (); virtual bool canDogleg ( Interval );