diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index d1c20413..1f6b8a6c 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -878,7 +878,7 @@ namespace Anabatic { and north->canDrag() and (south->getNet() != north->getNet()) and (south->getX () == north->getX ()) ) { - Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() ); + Interval constraints ( gcell->getYMin(), north->getCBYMin() /*- pitch3*/ ); AutoSegment* terminal = south->getSegment(); AutoContact* opposite = terminal->getOppositeAnchor( south ); @@ -887,7 +887,7 @@ namespace Anabatic { constraineds.insert( segment ); } - constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() ); + constraints = Interval( south->getCBYMax() /*+ pitch3*/, gcell->getYMax() ); terminal = north->getSegment(); opposite = terminal->getOppositeAnchor( north ); @@ -919,7 +919,7 @@ namespace Anabatic { sort( aligneds.begin(), aligneds.end(), AutoSegment::CompareBySourceU() ); - AutoSegment* previous = NULL; + //AutoSegment* previous = NULL; for ( AutoSegment* aligned : aligneds ) { Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() ); @@ -959,7 +959,7 @@ namespace Anabatic { userConstraints = constraints; } - previous = aligned; + //previous = aligned; } } @@ -971,6 +971,8 @@ namespace Anabatic { { cmess1 << " o Building detailed routing from global. " << endl; + size_t shortNets = 0; + startMeasures(); openSession(); @@ -981,6 +983,10 @@ namespace Anabatic { if (gaugeKind < 3) { for ( Net* net : getCell()->getNets() ) { + if (NetRoutingExtension::isShortNet(net)) { + AutoSegment::setShortNetMode( true ); + ++shortNets; + } if (NetRoutingExtension::isAutomaticGlobalRoute(net)) { DebugSession::open( net, 145, 150 ); AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) ); @@ -994,8 +1000,9 @@ namespace Anabatic { Session::revalidate(); DebugSession::close(); } + AutoSegment::setAnalogMode ( false ); + AutoSegment::setShortNetMode( false ); } - AutoSegment::setAnalogMode( false ); } #if defined(CHECK_DATABASE) @@ -1005,6 +1012,8 @@ namespace Anabatic { Session::close(); stopMeasures(); + cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl; + if (gaugeKind > 2) { throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"." , getString(getConfiguration()->getRoutingGauge()->getName()).c_str() ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index d1829adc..2ee677f1 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -14,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/Bug.h" #include "hurricane/DataBase.h" @@ -33,7 +34,6 @@ namespace { - using namespace std; using namespace CRL; using namespace Hurricane; @@ -413,12 +413,14 @@ namespace Anabatic { size_t AutoSegment::_allocateds = 0; size_t AutoSegment::_globalsCount = 0; bool AutoSegment::_analogMode = false; + bool AutoSegment::_shortNetMode = false; bool AutoSegment::_initialized = false; vector< array > AutoSegment::_extensionCaps; - void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; } - bool AutoSegment::getAnalogMode () { return _analogMode; } + void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; } + bool AutoSegment::getAnalogMode () { return _analogMode; } + void AutoSegment::setShortNetMode ( bool state ) { _shortNetMode = state; } void AutoSegment::_initialize () @@ -491,6 +493,7 @@ namespace Anabatic { if (source->isTerminal()) setFlags( SegSourceTerminal ); if (target->isTerminal()) setFlags( SegTargetTerminal ); if (_analogMode) setFlags( SegAnalog ); + if (_shortNetMode) setFlags( SegShortNet ); source->invalidate( Flags::Topology ); } @@ -982,9 +985,11 @@ namespace Anabatic { void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { + DebugSession::open( getNet(), 149, 160 ); cdebug_log(149,0) << "mergeUserConstraints() " << this << endl; cdebug_log(149,0) << "| " << constraints << " merged with " << _userConstraints << endl; _userConstraints.intersection(constraints); + DebugSession::close(); } @@ -2328,6 +2333,8 @@ namespace Anabatic { else if (_flags & SegTargetBottom) state += 'b'; else state += '-'; + state += isShortNet () ? "s": "-"; + return state; } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 3c0f6f3b..6ea9d630 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -2028,6 +2028,10 @@ namespace Anabatic { { cdebug_log(112,1) << "Dijkstra::_materialize() " << _net << " _sources:" << _sources.size() << endl; + if (_sources.size() < 2) + NetRoutingExtension::create( _net )->setFlags( NetRoutingState::ShortNet + | NetRoutingState::AutomaticGlobalRoute ); + if (_sources.size() < 2) { cdebug_tabw(112,-1); return; } NetRoutingState* state = NetRoutingExtension::get( _net ); diff --git a/anabatic/src/LayerAssign.cpp b/anabatic/src/LayerAssign.cpp index f9cd27ab..0f3f01c1 100644 --- a/anabatic/src/LayerAssign.cpp +++ b/anabatic/src/LayerAssign.cpp @@ -616,12 +616,13 @@ namespace Anabatic { globalNets.clear(); Session::revalidate(); - if (getConfiguration()->getAllowedDepth() > 2) { + if ( (method != EngineLayerAssignNoGlobalM2V) + and (getConfiguration()->getAllowedDepth() > 2) ) { for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) { _desaturate( depth, globalNets, total, global ); if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate(); } - + globalNets.clear (); Session::revalidate(); } diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 57dd4800..6dcd5ecd 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -1084,9 +1084,31 @@ namespace Anabatic { doRp_AutoContacts( gcell1, rpM1s[irp-1], source, turn1, DoSourceContact ); doRp_AutoContacts( gcell1, rpM1s[irp ], target, turn1, DoSourceContact ); - if (source->getUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) + if (source->getUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) { + uint64_t flags = checkRoutingPadSize( rpM1s[irp-1] ); + if ((flags & VSmall) or Session::getConfiguration()->isVH()) { + if (Session::getConfiguration()->isHV()) { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( source, turn1, Flags::Horizontal ); + source = turn1; + } + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( source, turn1 , Flags::Vertical ); + source = turn1; + } + flags = checkRoutingPadSize( rpM1s[irp] ); + if ((flags & VSmall) or Session::getConfiguration()->isVH()) { + if (Session::getConfiguration()->isHV()) { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( target, turn1, Flags::Horizontal ); + target = turn1; + } + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( target, turn1 , Flags::Vertical ); + target = turn1; + } AutoSegment::create( source, target, Flags::Horizontal ); - else { + } else { turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); turn2 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); AutoSegment::create( source, turn1 , Flags::Horizontal ); diff --git a/anabatic/src/PreRouteds.cpp b/anabatic/src/PreRouteds.cpp index 96c337ff..2168fab7 100644 --- a/anabatic/src/PreRouteds.cpp +++ b/anabatic/src/PreRouteds.cpp @@ -152,7 +152,8 @@ namespace Anabatic { state->setFlags ( NetRoutingState::Unconnected ); if (isFixed) { - cmess2 << " - <" << net->getName() << "> is fixed." << endl; + if (rpCount > 1) + cmess2 << " - <" << net->getName() << "> is fixed." << endl; state->unsetFlags( NetRoutingState::ManualGlobalRoute ); state->setFlags ( NetRoutingState::Fixed ); } else { diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index ef819c8c..ddb0cfc1 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -105,6 +105,7 @@ namespace Anabatic { static const uint64_t SegUserDefined = (1L<<32); static const uint64_t SegAnalog = (1L<<33); static const uint64_t SegWide = (1L<<34); + static const uint64_t SegShortNet = (1L<<35); // Masks. static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; @@ -135,6 +136,7 @@ namespace Anabatic { public: static void setAnalogMode ( bool ); static bool getAnalogMode (); + static void setShortNetMode ( bool ); inline static DbU::Unit getViaToTopCap ( size_t depth ); inline static DbU::Unit getViaToBottomCap ( size_t depth ); inline static DbU::Unit getViaToSameCap ( size_t depth ); @@ -216,6 +218,7 @@ namespace Anabatic { bool isUTurn () const; inline bool isAnalog () const; inline bool isWide () const; + inline bool isShortNet () const; virtual bool _canSlacken () const = 0; bool canReduce () const; bool mustRaise () const; @@ -358,6 +361,7 @@ namespace Anabatic { static size_t _allocateds; static size_t _globalsCount; static bool _analogMode; + static bool _shortNetMode; static bool _initialized; static vector< array > _extensionCaps; // Internal: Attributes. @@ -525,6 +529,7 @@ namespace Anabatic { inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; } inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; } inline bool AutoSegment::isWide () const { return _flags & SegWide; } + inline bool AutoSegment::isShortNet () const { return _flags & SegShortNet; } inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; } inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; } diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index 7cd1a182..efa7a696 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -372,14 +372,18 @@ namespace { if (_zero) { for ( Net* net : _zero->getNets() ) - if (not net->isSupply() and not net->isAutomatic()) { _masterNetZero = net; break; } + if ( not net->isSupply () + and not net->isAutomatic() + and not net->isBlockage () ) { _masterNetZero = net; break; } } else cerr << Warning( "BlifParser::Model::connectSubckts(): The zero (tie high) cell \"%s\" has not been found." , zeroName.c_str() ) << endl; if (_one) { for ( Net* net : _one->getNets() ) - if (not net->isSupply() and not net->isAutomatic()) { _masterNetOne = net; break; } + if ( not net->isSupply () + and not net->isAutomatic() + and not net->isBlockage () ) { _masterNetOne = net; break; } } else cerr << Warning( "BlifParser::Model::connectSubckts(): The one (tie low) cell \"%s\" has not been found." , oneName.c_str() ) << endl; diff --git a/hurricane/src/hurricane/hurricane/NetRoutingProperty.h b/hurricane/src/hurricane/hurricane/NetRoutingProperty.h index e237b2ca..bd411fda 100644 --- a/hurricane/src/hurricane/hurricane/NetRoutingProperty.h +++ b/hurricane/src/hurricane/hurricane/NetRoutingProperty.h @@ -49,6 +49,7 @@ namespace Hurricane { , Symmetric = (1<< 7) , SymmetricMaster = (1<< 8) , Analog = (1<< 9) + , ShortNet = (1<<10) }; public: inline bool isExcluded () const; @@ -63,6 +64,7 @@ namespace Hurricane { inline bool isSymMaster () const; inline bool isSymSlave () const; inline bool isAnalog () const; + inline bool isShortNet () const; inline Net* getNet () const; inline Net* getSymNet () const; inline DbU::Unit getSymAxis () const; @@ -103,6 +105,7 @@ namespace Hurricane { inline bool NetRoutingState::isSymVertical () const { return _flags & Vertical; } inline bool NetRoutingState::isSymMaster () const { return _flags & SymmetricMaster; } inline bool NetRoutingState::isAnalog () const { return _flags & Analog; } + inline bool NetRoutingState::isShortNet () const { return _flags & ShortNet; } inline Net* NetRoutingState::getSymNet () const { return _symNet; } inline DbU::Unit NetRoutingState::getSymAxis () const { return _axis; } inline uint32_t NetRoutingState::getFlags () const { return _flags; }; @@ -177,6 +180,7 @@ namespace Hurricane { static inline bool isSymVertical ( const Net* ); static inline bool isSymMaster ( const Net* ); static inline bool isAnalog ( const Net* ); + static inline bool isShortNet ( const Net* ); static inline uint32_t getFlags ( const Net* ); static inline Net* getSymNet ( const Net* ); static inline DbU::Unit getSymAxis ( const Net* ); @@ -266,6 +270,13 @@ namespace Hurricane { } + inline bool NetRoutingExtension::isShortNet ( const Net* net ) + { + NetRoutingState* state = get( net ); + return (state == NULL) ? false : state->isShortNet(); + } + + inline uint32_t NetRoutingExtension::getFlags ( const Net* net ) { NetRoutingState* state = get( net ); diff --git a/katana/src/Configuration.cpp b/katana/src/Configuration.cpp index b8f2be2c..99663b7f 100644 --- a/katana/src/Configuration.cpp +++ b/katana/src/Configuration.cpp @@ -52,6 +52,7 @@ namespace Katana { _ripupLimits[LocalRipupLimit] = Cfg::getParamInt("katana.localRipupLimit" , 7)->asInt(); _ripupLimits[GlobalRipupLimit] = Cfg::getParamInt("katana.globalRipupLimit" , 5)->asInt(); _ripupLimits[LongGlobalRipupLimit] = Cfg::getParamInt("katana.longGlobalRipupLimit" , 5)->asInt(); + _ripupLimits[ShortNetRipupLimit] = Cfg::getParamInt("katana.shortNetRipupLimit" ,16)->asInt(); // for ( size_t i=0 ; iisBlockage()) return 0; - if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isShortNet()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); if (segment->isGlobal()) { vector gcells; segment->getGCells( gcells ); diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index a358cee5..c2b45d43 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -1226,7 +1226,7 @@ namespace Katana { } - bool Manipulator::makeDogleg ( Interval overlap ) + bool Manipulator::makeDogleg ( Interval overlap, Flags flags ) { cdebug_log(159,0) << "Manipulator::makeDogleg(Interval) " << _segment << endl; cdebug_log(159,0) << overlap << endl; @@ -1234,11 +1234,15 @@ namespace Katana { if ( _segment->isFixed () ) return false; if (not _segment->canDogleg(overlap)) return false; - Flags flags = Flags::NoFlags; - TrackElement* dogleg = _segment->makeDogleg(overlap,flags); + TrackElement* dogleg = NULL; + TrackElement* parallel = NULL; + _segment->makeDogleg( overlap, dogleg, parallel, flags ); if (dogleg) { cdebug_log(159,0) << "Manipulator::makeDogleg(Interval) - Push dogleg to the " << ((flags&Flags::DoglegOnLeft)?"left":"right") << endl; + if (flags & Flags::ShortDogleg) + Session::addShortDogleg( _segment, parallel ); + if (_segment->isTerminal()) { Anabatic::AutoContact* contact = (flags&Flags::DoglegOnLeft) ? _segment->base()->getAutoSource() diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 43c894a6..10f32206 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -117,7 +117,7 @@ namespace { { AllianceFramework* af = AllianceFramework::get (); RoutingGauge* rg = nw->getKatanaEngine()->getConfiguration()->getRoutingGauge(); - bool isVH = rg->isVH(); + //bool isVH = rg->isVH(); for( Net* net : nw->getCell()->getNets() ) { if (net->getType() == Net::Type::POWER ) continue; @@ -529,7 +529,7 @@ namespace Katana { cmess2.flush (); } else { cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() << endl; diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index f833e122..67d103ff 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -208,6 +208,7 @@ namespace { Interval constraints ( minConstraint, maxConstraint ); for ( size_t iperpand=0 ; iperpandbase()->mergeUserConstraints( constraints ); if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) { cdebug_log(159,0) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl; diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 63a8c187..a586963b 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -415,6 +415,7 @@ namespace Katana { loop.erase( _segment ); setState( DataNegociate::RepairFailed ); setDisabled( true ); + setProcessed(); } //DebugSession::open( _segment->getNet(), 155, 160 ); @@ -594,18 +595,30 @@ namespace Katana { if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) { cdebug_log(159,0) << "Insert in free space." << endl; fsm.bindToTrack( 0 ); + + cdebug_log(159,0) << "Re-try perpandiculars:" << endl; + for ( TrackElement* perpandicular : getPerpandiculars() ) { + if (not perpandicular->getTrack() ) { + cdebug_log(159,0) << "| " << perpandicular << endl; + fsm.addAction( perpandicular, SegmentAction::SelfInsert ); + DataNegociate* data = perpandicular->getDataNegociate(); + if (data) data->setState( DataNegociate::Repair ); + } + } + fsm.doActions(); + queue.commit(); } else { switch ( fsm.getData()->getStateCount() ) { case 1: // First try: minimize. - Manipulator(_segment,fsm).minimize (); + Manipulator(_segment,fsm).minimize(); fsm.addAction( _segment, SegmentAction::SelfInsert ); fsm.doActions(); queue.commit(); break; case 2: // Second try: failed re-inserted first. - Manipulator(_segment,fsm).repackPerpandiculars (); + Manipulator(_segment,fsm).repackPerpandiculars(); fsm.addAction( _segment, SegmentAction::SelfInsert ); fsm.doActions(); queue.commit(); @@ -650,6 +663,18 @@ namespace Katana { cdebug_log(159,0) << "Expanding (after):" << _constraints << endl; } } + + if (_segment->isShortDogleg()) { + TrackElement* parallel = Session::getDoglegPaired( _segment ); + if (parallel and parallel->getTrack()) { + Interval delta ( parallel->getAxis() - _segment->getPitch() + , parallel->getAxis() + _segment->getPitch() ); + _constraints.intersection( delta ); + cdebug_log(159,0) << "Short parallel to: " << parallel << endl; + cdebug_log(159,0) << "Constraints restricted to: " << delta << endl; + } + } + cdebug_log(159,0) << "| Raw Track Constraint: " << _constraints << " [" << _constraints.getVMin() << "," << _constraints.getVMax() << "]" << endl; diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index ef42fa36..ca785832 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -776,6 +776,7 @@ namespace Katana { and (not _event2 or Manipulator(getSegment2(),*this).canRipup(flags)); } + bool SegmentFsm::conflictSolveByHistory () { bool success = false; @@ -976,24 +977,32 @@ namespace Katana { continue; } - if (other->isGlobal()) { - cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl; - if ((success = Manipulator(other,*this).moveUp())) break; - } - - cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl; - - if (Manipulator(segment,*this).relax(overlap0,relaxFlags)) { - success = true; - break; - } else { - if ( not canMoveUp - and (relaxFlags != Manipulator::NoExpand) - and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) { - cdebug_log(159,0) << "Cannot move up but successful narrow breaking." << endl; + if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) { + if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) { + cerr << "Break using ShortDogleg." << endl; success = true; break; } + } else { + if (other->isGlobal()) { + cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl; + if ((success = Manipulator(other,*this).moveUp())) break; + } + + cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl; + + if (Manipulator(segment,*this).relax(overlap0,relaxFlags)) { + success = true; + break; + } else { + if ( not canMoveUp + and (relaxFlags != Manipulator::NoExpand) + and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) { + cdebug_log(159,0) << "Cannot move up but successful narrow breaking." << endl; + success = true; + break; + } + } } } @@ -1181,10 +1190,10 @@ namespace Katana { if (not success and (nextState != DataNegociate::Unimplemented)) success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit); - if (not (flags&NoTransition)) { + // if (not (flags&NoTransition)) { data->setState( nextState ); cdebug_log(159,0) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl; - } + // } return success; } @@ -1281,11 +1290,11 @@ namespace Katana { if (solveFullBlockages()) nextState = DataNegociate::MoveUp; } - if (not (flags&NoTransition)) { + // if (not (flags&NoTransition)) { data->setState( nextState ); cdebug_log(159,0) << "Incrementing state (after): " << DataNegociate::getStateString(nextState,data->getStateCount()) << endl; - } + // } return success; } @@ -1368,7 +1377,7 @@ namespace Katana { if (solveFullBlockages()) nextState = DataNegociate::MoveUp; } - if (not (flags&NoTransition)) { + //if (not (flags&NoTransition)) { if (data->getChildSegment()) { TrackElement* child = segment; cdebug_log(159,0) << "Incrementing state of childs (after): " << endl; @@ -1387,7 +1396,7 @@ namespace Katana { cdebug_log(159,0) << "Incrementing state (after): " << segment << endl; cdebug_log(159,0) << "| " << nextState << " count:" << data->getStateCount() << endl; } - } + //} return success; } @@ -1410,6 +1419,13 @@ namespace Katana { return false; } + if (segment1->isShortNet()) { + cdebug_log(159,0) << "Short net segments are not allowed to slacken" << endl; + cdebug_tabw(159,-1); + DebugSession::close(); + return false; + } + if (not segment1 or not _data1) { cdebug_tabw(159,-1); DebugSession::close(); return false; } _event1->resetInsertState(); diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index 64101ba4..37cf0ec5 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -157,6 +157,14 @@ namespace Katana { { return Session::get("lookup(AutoSegment*)")->_getKatanaEngine()->_lookup ( segment ); } + void Session::addShortDogleg ( TrackElement* segmentA, TrackElement* segmentB ) + { Session::get("addShortDogleg(AutoSegment*)")->_getKatanaEngine()->_addShortDogleg( segmentA, segmentB ); } + + + TrackElement* Session::getDoglegPaired ( TrackElement* segment ) + { return Session::get("getDoglegPaired(AutoSegment*)")->_getKatanaEngine()->_getDoglegPaired( segment ); } + + void Session::setInterrupt ( bool state ) { Session::get("setInterrupt()")->_getKatanaEngine()->setInterrupt(state); } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 75c683f0..6c1b8c52 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -505,7 +505,12 @@ namespace Katana { if (message) cerr << " o Checking Track - " << message << endl; cdebug_log(155,0) << (void*)this << ":" << this << endl; + for ( size_t i=0 ; i<_segments.size() ; i++ ) { + Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 + , _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 ); + bool inTrackRange = trackRange.contains( _axis ); + if (_segments[i]) { if (i) { if (_segments[i-1] == _segments[i]) { @@ -519,14 +524,15 @@ namespace Katana { << _segments[i] << " is detached." << endl; coherency = false; } else { - if (_segments[i]->getTrack() != this) { + if ( (_segments[i]->getTrack() != this) and not inTrackRange ) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is in track " << _segments[i]->getTrack() << endl; coherency = false; + cerr << _segments[i]->getTrackSpan() << endl; } } - if (_segments[i]->getAxis() != getAxis()) { + if ( (_segments[i]->getAxis() != getAxis()) and not inTrackRange ) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is not on Track axis " << DbU::getValueString(getAxis()) << "." << endl; diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index ee78a0bc..af1c484f 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -243,6 +243,8 @@ namespace Katana { s += string ( (isOverlap() )?"o":"-" ); s += string ( (isOverlapGlobal() )?"g":"-" ); s += string ( (isGlobalEnclosed())?"e":"-" ); + s += string ( (isAnalog ())?"a":"-" ); + s += string ( (isShortNet ())?"N":"-" ); s += " " + getString(_terminals); s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 6f2edead..5e1abb58 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -143,11 +143,13 @@ namespace Katana { bool TrackElement::isStrap () const { return false; } bool TrackElement::isSlackened () const { return false; } bool TrackElement::isDogleg () const { return false; } + bool TrackElement::isShortDogleg () const { return false; } bool TrackElement::isReduced () const { return false; } bool TrackElement::isUTurn () const { return false; } bool TrackElement::isUserDefined () const { return false; } bool TrackElement::isAnalog () const { return false; } bool TrackElement::isWide () const { return false; } + bool TrackElement::isShortNet () const { return false; } // Predicates. bool TrackElement::hasSymmetric () const { return false; } bool TrackElement::canSlacken () const { return false; } @@ -161,6 +163,7 @@ namespace Katana { unsigned long TrackElement::getId () const { return 0; } unsigned long TrackElement::getFreedomDegree () const { return 0; } uint32_t TrackElement::getTrackCount () const { return 0; } + unsigned int TrackElement::getDepth () const { return 0; } DbU::Unit TrackElement::getPitch () const { return 0; } DbU::Unit TrackElement::getPPitch () const { return 0; } DbU::Unit TrackElement::getExtensionCap ( Flags ) const { return 0; } @@ -190,7 +193,7 @@ namespace Katana { void TrackElement::updatePPitch () { } void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { } TrackElement* TrackElement::makeDogleg () { return NULL; } - TrackElement* TrackElement::makeDogleg ( Interval, Flags& ) { return NULL; } + Flags TrackElement::makeDogleg ( Interval, TrackElement*&, TrackElement*&, Flags ) { return Flags::NoFlags; } TrackElement* TrackElement::makeDogleg ( Anabatic::GCell*, TrackElement*&, TrackElement*& ) { return NULL; } void TrackElement::_postDoglegs ( TrackElement*&, TrackElement*& ) { } bool TrackElement::moveAside ( Flags ) { return false; } diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index 3c5452d5..9f0fd70f 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -140,6 +140,7 @@ namespace Katana { Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); } DbU::Unit TrackFixedSegment::getWidth () const { return _segment->getWidth(); } const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); } + unsigned int TrackFixedSegment::getDepth () const { return Session::getLayerDepth(getLayer()); } Interval TrackFixedSegment::getFreeInterval () const { return Interval(); } size_t TrackFixedSegment::getTrackSpan () const { return 1; } diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index c39bd880..88b06591 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -166,11 +166,13 @@ namespace Katana { bool TrackSegment::isStrap () const { return _base->isStrap(); } bool TrackSegment::isSlackened () const { return _base->isSlackened(); } bool TrackSegment::isDogleg () const { return _base->isDogleg(); } + bool TrackSegment::isShortDogleg () const { return _flags & TElemShortDogleg; } bool TrackSegment::isReduced () const { return _base->isReduced(); } bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); } bool TrackSegment::isUTurn () const { return _base->isUTurn(); } bool TrackSegment::isAnalog () const { return _base->isAnalog(); } bool TrackSegment::isWide () const { return _base->isWide(); } + bool TrackSegment::isShortNet () const { return _base->isShortNet(); } bool TrackSegment::isPriorityLocked () const { return _flags & PriorityLocked; } // Predicates. bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; } @@ -180,6 +182,7 @@ namespace Katana { Net* TrackSegment::getNet () const { return _base->getNet(); } DbU::Unit TrackSegment::getWidth () const { return _base->getWidth(); } const Layer* TrackSegment::getLayer () const { return _base->getLayer(); } + unsigned int TrackSegment::getDepth () const { return _base->getDepth(); } DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); } DbU::Unit TrackSegment::getPPitch () const { return _ppitch; } DbU::Unit TrackSegment::getExtensionCap ( Flags flags ) const { return _base->getExtensionCap(flags); } @@ -894,16 +897,21 @@ namespace Katana { } - TrackElement* TrackSegment::makeDogleg ( Interval interval, Flags& flags ) + Flags TrackSegment::makeDogleg ( Interval interval, TrackElement*& perpandicular, TrackElement*& parallel, Flags flags ) { - TrackElement* perpandicular = NULL; - TrackElement* parallel = NULL; + perpandicular = NULL; + parallel = NULL; cdebug_log(159,0) << "TrackSegment::makeDogleg(Interval)" << endl; - flags = base()->makeDogleg( interval ); + flags |= base()->makeDogleg( interval ); _postDoglegs( perpandicular, parallel ); - return perpandicular; + if (flags & Flags::ShortDogleg) { + parallel->setFlags( TElemShortDogleg ); + Session::addShortDogleg( this, parallel ); + } + + return flags; } diff --git a/katana/src/katana/Configuration.h b/katana/src/katana/Configuration.h index c0554ebe..3107a8da 100644 --- a/katana/src/katana/Configuration.h +++ b/katana/src/katana/Configuration.h @@ -49,7 +49,8 @@ namespace Katana { , LocalRipupLimit = 1 , GlobalRipupLimit = 2 , LongGlobalRipupLimit = 3 - , RipupLimitsTableSize = 4 + , ShortNetRipupLimit = 4 + , RipupLimitsTableSize = 5 }; enum Constants { MaxMetalDepth = 20 }; enum Flag { UseClockTree = (1 << 0) }; diff --git a/katana/src/katana/Constants.h b/katana/src/katana/Constants.h index 63389dc5..8194994d 100644 --- a/katana/src/katana/Constants.h +++ b/katana/src/katana/Constants.h @@ -34,6 +34,7 @@ namespace Katana { static const Hurricane::BaseFlags WithConstraints; static const Hurricane::BaseFlags MoveToLeft; static const Hurricane::BaseFlags MoveToRight; + static const Hurricane::BaseFlags ShortDogleg; static const Hurricane::BaseFlags LoadingStage; static const Hurricane::BaseFlags SlowMotion; static const Hurricane::BaseFlags PreRoutedStage; diff --git a/katana/src/katana/DataNegociate.h b/katana/src/katana/DataNegociate.h index ee76ffe3..ca7454e8 100644 --- a/katana/src/katana/DataNegociate.h +++ b/katana/src/katana/DataNegociate.h @@ -143,18 +143,16 @@ namespace Katana { inline void DataNegociate::setState ( uint32_t state, Flags flags ) { - if ( (_state >= Repair) and (state < _state) ) { - std::cerr << "Revert DataNegociate state from Repair/RepairFailed to " << getStateString(state,_stateCount).c_str() << std::endl; - std::cerr << "On " << _getString() << std::endl; + // if ( (_state >= Repair) and (state < _state) ) { + // std::cerr << "Revert DataNegociate state from Repair/RepairFailed to " << getStateString(state,_stateCount).c_str() << std::endl; + // std::cerr << "On " << _getString() << std::endl; - std::cerr << *((char*)NULL) << std::endl; - - throw Hurricane::Error( "Revert DataNegociate state from Repair/RepairFailed to %s." - " On %s" - , getStateString(state,_stateCount).c_str() - , _getString().c_str() - ); - } + // throw Hurricane::Error( "Revert DataNegociate state from Repair/RepairFailed to %s." + // " On %s" + // , getStateString(state,_stateCount).c_str() + // , _getString().c_str() + // ); + // } if ( (_state != state) or (flags & Flags::ResetCount) ) { //std::cerr << "Changing state to:" << state << std::endl; _state = state; diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index 0cdc4c6c..85c44487 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -132,6 +132,8 @@ namespace Katana { void _computeCagedConstraints (); TrackElement* _lookup ( Segment* ) const; inline TrackElement* _lookup ( AutoSegment* ) const; + inline void _addShortDogleg ( TrackElement*, TrackElement* ); + inline TrackElement* _getDoglegPaired ( TrackElement* ) const; bool _check ( uint32_t& overlap, const char* message=NULL ) const; void _check ( Net* ) const; virtual Record* _getRecord () const; @@ -147,6 +149,7 @@ namespace Katana { vector _routingPlanes; NegociateWindow* _negociateWindow; double _minimumWL; + TrackElementPairing _shortDoglegs; DataSymmetricMap _symmetrics; uint32_t _mode; mutable bool _toolSuccess; @@ -195,6 +198,19 @@ namespace Katana { inline void KatanaEngine::printConfiguration () const { _configuration->print(getCell()); } inline TrackElement* KatanaEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver(AutoSegment::Observable::TrackSegment); } + inline void KatanaEngine::_addShortDogleg ( TrackElement* segmentA, TrackElement* segmentB ) + { + _shortDoglegs.insert( std::make_pair(segmentA,segmentB) ); + _shortDoglegs.insert( std::make_pair(segmentB,segmentA) ); + } + + inline TrackElement* KatanaEngine::_getDoglegPaired ( TrackElement* segment ) const + { + auto ipaired = _shortDoglegs.find( segment ); + if (ipaired != _shortDoglegs.end()) return ipaired->second; + return NULL; + } + // Variables. extern const char* missingRW; diff --git a/katana/src/katana/Manipulator.h b/katana/src/katana/Manipulator.h index 16de03ad..587851a9 100644 --- a/katana/src/katana/Manipulator.h +++ b/katana/src/katana/Manipulator.h @@ -74,7 +74,7 @@ namespace Katana { bool moveUp ( uint32_t flags=0 ); bool makeDogleg (); bool makeDogleg ( DbU::Unit ); - bool makeDogleg ( Interval ); + bool makeDogleg ( Interval, Flags=Flags::NoFlags ); bool relax ( Interval, uint32_t flags=AllowExpand ); bool insertInTrack ( size_t icost ); bool shrinkToTrack ( size_t icost diff --git a/katana/src/katana/Session.h b/katana/src/katana/Session.h index b1cde9e9..b92a3105 100644 --- a/katana/src/katana/Session.h +++ b/katana/src/katana/Session.h @@ -86,6 +86,8 @@ namespace Katana { static AutoContact* lookup ( Contact* ); static TrackElement* lookup ( Segment* ); static TrackElement* lookup ( AutoSegment* ); + static void addShortDogleg ( TrackElement*, TrackElement* ); + static TrackElement* getDoglegPaired ( TrackElement* ); static Session* _open ( KatanaEngine* ); private: KatanaEngine* _getKatanaEngine (); diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index e600fa6b..0bb90036 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -48,17 +48,18 @@ namespace Katana { , LocalAndTopDepth = (1 << 3) , ZeroCost = (1 << 4) , Analog = (1 << 5) - , Symmetric = (1 << 6) - , ForGlobal = (1 << 7) - , Blockage = (1 << 8) - , Fixed = (1 << 9) - , Infinite = (1 << 10) - , HardOverlap = (1 << 11) - , Overlap = (1 << 12) - , LeftOverlap = (1 << 13) - , RightOverlap = (1 << 14) - , OverlapGlobal = (1 << 15) - , GlobalEnclosed = (1 << 16) + , ShortNet = (1 << 6) + , Symmetric = (1 << 7) + , ForGlobal = (1 << 8) + , Blockage = (1 << 9) + , Fixed = (1 << 10) + , Infinite = (1 << 11) + , HardOverlap = (1 << 12) + , Overlap = (1 << 13) + , LeftOverlap = (1 << 14) + , RightOverlap = (1 << 15) + , OverlapGlobal = (1 << 16) + , GlobalEnclosed = (1 << 17) , MergeMask = ForGlobal |Blockage|Fixed |Infinite |HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal |GlobalEnclosed @@ -87,6 +88,8 @@ namespace Katana { ~TrackCost (); inline bool isForGlobal () const; inline bool isBlockage () const; + inline bool isAnalog () const; + inline bool isShortNet () const; inline bool isFixed () const; inline bool isInfinite () const; inline bool isOverlap () const; @@ -179,6 +182,8 @@ namespace Katana { // Inline Functions. inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } inline bool TrackCost::isBlockage () const { return _flags & Blockage; } + inline bool TrackCost::isAnalog () const { return _flags & Analog; } + inline bool TrackCost::isShortNet () const { return _flags & ShortNet; } inline bool TrackCost::isFixed () const { return _flags & Fixed; } inline bool TrackCost::isInfinite () const { return _flags & Infinite; } inline bool TrackCost::isOverlap () const { return _flags & Overlap; } diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 33d86c3f..93b29153 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -57,6 +57,7 @@ namespace Katana { class TrackSegment; + typedef map TrackElementPairing; typedef map TrackElementLut; typedef void (SegmentOverlapCostCB)( const TrackElement*, TrackCost& ); @@ -69,13 +70,14 @@ namespace Katana { , TElemFixed = (1 << 2) , TElemLocked = (1 << 4) , TElemRouted = (1 << 5) - , TElemSourceDogleg = (1 << 6) - , TElemTargetDogleg = (1 << 7) - , TElemAlignBottom = (1 << 8) - , TElemAlignCenter = (1 << 9) - , TElemAlignTop = (1 << 10) - , TElemRipple = (1 << 11) - , TElemInvalidated = (1 << 12) + , TElemShortDogleg = (1 << 6) + , TElemSourceDogleg = (1 << 7) + , TElemTargetDogleg = (1 << 8) + , TElemAlignBottom = (1 << 9) + , TElemAlignCenter = (1 << 10) + , TElemAlignTop = (1 << 11) + , TElemRipple = (1 << 12) + , TElemInvalidated = (1 << 13) }; @@ -113,10 +115,12 @@ namespace Katana { virtual bool isStrap () const; virtual bool isSlackened () const; virtual bool isDogleg () const; + virtual bool isShortDogleg () const; virtual bool isReduced () const; virtual bool isUTurn () const; virtual bool isUserDefined () const; virtual bool isAnalog () const; + virtual bool isShortNet () const; virtual bool isPriorityLocked () const = 0; // Predicates. inline bool isCreated () const; @@ -143,6 +147,7 @@ namespace Katana { virtual Net* getNet () const = 0; virtual DbU::Unit getWidth () const = 0; virtual const Layer* getLayer () const = 0; + virtual unsigned int getDepth () const; virtual DbU::Unit getPitch () const; virtual DbU::Unit getPPitch () const; virtual size_t getTrackSpan () const = 0; @@ -200,7 +205,7 @@ namespace Katana { virtual TrackElement* makeDogleg (); inline bool makeDogleg ( Anabatic::GCell* ); virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel ); - virtual TrackElement* makeDogleg ( Interval, Flags& flags ); + virtual Flags makeDogleg ( Interval, TrackElement*& perpandicular, TrackElement*& parallel, Flags flags ); virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ); virtual bool moveAside ( Flags flags ); virtual bool slacken ( Flags flags=Flags::NoFlags ); diff --git a/katana/src/katana/TrackFixedSegment.h b/katana/src/katana/TrackFixedSegment.h index 9ac4fb2a..977034c9 100644 --- a/katana/src/katana/TrackFixedSegment.h +++ b/katana/src/katana/TrackFixedSegment.h @@ -50,6 +50,7 @@ namespace Katana { virtual Flags getDirection () const; virtual Net* getNet () const; virtual DbU::Unit getWidth () const; + virtual unsigned int getDepth () const; virtual const Layer* getLayer () const; virtual size_t getTrackSpan () const; virtual TrackElement* getNext () const; diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index 6a672dd1..9ad446ef 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -75,11 +75,13 @@ namespace Katana { virtual bool isStrap () const; virtual bool isSlackened () const; virtual bool isDogleg () const; + virtual bool isShortDogleg () const; virtual bool isReduced () const; virtual bool isUTurn () const; virtual bool isUserDefined () const; virtual bool isAnalog () const; virtual bool isWide () const; + virtual bool isShortNet () const; virtual bool isPriorityLocked () const; // Predicates. virtual bool hasSymmetric () const; @@ -96,6 +98,7 @@ namespace Katana { virtual Net* getNet () const; virtual DbU::Unit getWidth () const; virtual const Layer* getLayer () const; + virtual unsigned int getDepth () const; virtual DbU::Unit getPitch () const; virtual DbU::Unit getPPitch () const; virtual DbU::Unit getExtensionCap ( Flags ) const; @@ -138,7 +141,7 @@ namespace Katana { virtual void setAxis ( DbU::Unit, uint32_t flags ); virtual TrackElement* makeDogleg (); virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel ); - virtual TrackElement* makeDogleg ( Interval, Flags& flags ); + virtual Flags makeDogleg ( Interval, TrackElement*& perpandicular, TrackElement*& parallel, Flags flags ); virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ); virtual bool moveAside ( Flags ); virtual bool slacken ( Flags flags=Flags::NoFlags );