From 9db97608cbdef5936261f4203ba7bbb436d6e3bc Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 18 Aug 2015 15:42:28 +0200 Subject: [PATCH] More clever way of taking into account constraints on caged terminals. * Change: In vlsispad, in Dots, add an enable/disable flag because when printing into a cmess, it is only the base class ostream which is took into account as none of it's methods are virtuals (silly me). * Bug: In Etesian, print into cmess instead of cout and make use of the Dots enabling feature. * New: In Katabatic, added AutoContact::migrateConstraintBox() to transfert constraint from one contact to another. New flag for AutoContact, CntWeakTerminal for AutoContact which are at the other of a segment directly connected to a terminal. They may hold special constraints in case of caged terminals (computed in Kite). In AutoHorizontal & AutoVertical, in ::_makeDogleg(), transfert flags and constraints when breaking a segment directly connected to a terminal. * New: In Kite, in protectCagedTerminals(), uses cross constraint on the AutoContact opposite to the ContactTerminal (CntWeakTerminal) instead of moving up one terminal over two consecutives. This is simpler without degrading the routing quality. --- etesian/src/Configuration.cpp | 16 ++++++------ etesian/src/EtesianEngine.cpp | 3 +++ katabatic/doc/AutoContact.dox | 6 +++++ katabatic/src/AutoContact.cpp | 17 +++++++++++++ katabatic/src/AutoContactHTee.cpp | 2 ++ katabatic/src/AutoContactTurn.cpp | 1 + katabatic/src/AutoContactVTee.cpp | 2 ++ katabatic/src/AutoHorizontal.cpp | 8 ++++++ katabatic/src/AutoSegment.cpp | 4 +++ katabatic/src/AutoVertical.cpp | 8 ++++++ katabatic/src/katabatic/AutoContact.h | 2 ++ kite/src/PreProcess.cpp | 25 ++++++++++++++----- knik/src/Graph.cpp | 4 +-- vlsisapd/src/utilities/src/Dots.cpp | 3 ++- .../utilities/src/vlsisapd/utilities/Dots.h | 12 +++++++-- 15 files changed, 94 insertions(+), 19 deletions(-) diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index bf992b46..a554790f 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -91,14 +91,14 @@ namespace Etesian { void Configuration::print ( Cell* cell ) const { - cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; - cout << Dots::asIdentifier(" - Cell Gauge" ,getString(_cg->getName())) << endl; - cout << Dots::asInt (" - Place Effort" ,_placeEffort ) << endl; - cout << Dots::asInt (" - Update Conf" ,_updateConf ) << endl; - cout << Dots::asInt (" - Spreading Conf",_spreadingConf) << endl; - cout << Dots::asBool (" - Routing driven",_routingDriven) << endl; - cout << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl; - cout << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl; + cmess1 << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; + cmess1 << Dots::asIdentifier(" - Cell Gauge" ,getString(_cg->getName())) << endl; + cmess1 << Dots::asInt (" - Place Effort" ,_placeEffort ) << endl; + cmess1 << Dots::asInt (" - Update Conf" ,_updateConf ) << endl; + cmess1 << Dots::asInt (" - Spreading Conf",_spreadingConf) << endl; + cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl; + cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl; + cmess1 << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl; } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 39610890..a76f207d 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -404,6 +404,7 @@ namespace Etesian { _flatDesign = true; Dots dots ( cmess2, " ", 80, 1000 ); + if (not cmess2.enabled()) dots.disable(); cmess1 << " o Erasing previous placement of <" << getCell()->getName() << ">" << endl; @@ -450,6 +451,8 @@ namespace Etesian { AllianceFramework* af = AllianceFramework::get(); DbU::Unit pitch = getPitch(); + if (not cmess2.enabled()) dots.disable(); + cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); getCell()->flattenNets( Cell::Flags::NoClockFlatten ); diff --git a/katabatic/doc/AutoContact.dox b/katabatic/doc/AutoContact.dox index 4d4b623d..b4f2831d 100644 --- a/katabatic/doc/AutoContact.dox +++ b/katabatic/doc/AutoContact.dox @@ -380,6 +380,12 @@ //! will not lead to an empty interval, in that case, do nothing and //! return \false. + //! \function void AutoContact::migrateConstraintBox ( AutoContact* other ); + //! Transfer the user constraint box from \c other to the current + //! object \c this. The constraints of \c other are restored to their + //! native values. The two contacts must belong to the same GCell for + //! this method to take effect. + /*! \class LocatorHelper * diff --git a/katabatic/src/AutoContact.cpp b/katabatic/src/AutoContact.cpp index 665d5adc..85e5cb74 100644 --- a/katabatic/src/AutoContact.cpp +++ b/katabatic/src/AutoContact.cpp @@ -500,6 +500,23 @@ namespace Katabatic { { return box = box.getIntersection ( getConstraintBox() ); } + void AutoContact::migrateConstraintBox ( AutoContact* other ) + { + if (_gcell != other->_gcell) { + cerr << Error( "AutoContact::migrateConstraintBox(): AutoContacts do not belongs to the same GCell:\n" + " from: %s\n" + " to: %s" + , getString(other).c_str() + , getString(this ).c_str() + ) << endl; + return; + } + + setConstraintBox( other->getConstraintBox() ); + other->restoreNativeConstraintBox(); + } + + Box AutoContact::getBoundingBox () const { return _gcell->getBoundingBox (); } diff --git a/katabatic/src/AutoContactHTee.cpp b/katabatic/src/AutoContactHTee.cpp index 27625c37..ddd2687b 100644 --- a/katabatic/src/AutoContactHTee.cpp +++ b/katabatic/src/AutoContactHTee.cpp @@ -294,6 +294,8 @@ namespace Katabatic { ltrace(110) << "delta:" << delta << endl; + unsetFlags( CntWeakTerminal ); + if (maxDepth - minDepth > 3) { showTopologyError( "Sheared HTee, layer delta exceed 3." ); setFlags( CntBadTopology ); diff --git a/katabatic/src/AutoContactTurn.cpp b/katabatic/src/AutoContactTurn.cpp index 294a00dd..00d37828 100644 --- a/katabatic/src/AutoContactTurn.cpp +++ b/katabatic/src/AutoContactTurn.cpp @@ -239,6 +239,7 @@ namespace Katabatic { size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; size_t delta = abssub ( depthH1, depthV1 ); + unsetFlags( CntWeakTerminal ); if (delta > 3) { showTopologyError( "Sheared Turn, layer delta exceed 3." ); setFlags( CntBadTopology ); diff --git a/katabatic/src/AutoContactVTee.cpp b/katabatic/src/AutoContactVTee.cpp index 59ae782d..a3fecb80 100644 --- a/katabatic/src/AutoContactVTee.cpp +++ b/katabatic/src/AutoContactVTee.cpp @@ -262,6 +262,8 @@ namespace Katabatic { ltrace(110) << "maxDepth:" << maxDepth << endl; ltrace(110) << "delta:" << delta << endl; + unsetFlags( CntWeakTerminal ); + if ( maxDepth - minDepth > 3 ) { showTopologyError( "Sheared VTee, layer delta exceed 3." ); setFlags( CntBadTopology ); diff --git a/katabatic/src/AutoHorizontal.cpp b/katabatic/src/AutoHorizontal.cpp index fc1e2e5b..53eef1ba 100644 --- a/katabatic/src/AutoHorizontal.cpp +++ b/katabatic/src/AutoHorizontal.cpp @@ -747,11 +747,19 @@ namespace Katabatic { if (isSourceTerminal()) { segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 ); + autoTarget->unsetFlags( CntWeakTerminal ); + dlContact1->setFlags ( CntWeakTerminal ); + if (autoTarget->getGCell() == doglegGCell) + dlContact1->migrateConstraintBox( autoTarget ); } else if (isTargetTerminal()) { unsetFlags( SegTargetTerminal ); setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegTargetTerminal ); + autoSource->unsetFlags( CntWeakTerminal ); + dlContact2->setFlags ( CntWeakTerminal ); + if (autoSource->getGCell() == doglegGCell) + dlContact2->migrateConstraintBox( autoSource ); } else if (isWeakTerminal()) { segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 ); diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index 1f2b95a5..cb8787b2 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -873,9 +873,13 @@ namespace Katabatic { if (source->isTerminal()) { unsetFlags( SegWeakTerminal ); setFlags ( SegSourceTerminal ); + if (not target->isTerminal()) + target->setFlags( CntWeakTerminal ); } else if (target->isTerminal()) { unsetFlags( SegWeakTerminal ); setFlags ( SegTargetTerminal ); + if (not source->isTerminal()) + source->setFlags( CntWeakTerminal ); } else { unsigned int terminalFlag = 0; switch ( _getFlags() & SegWeakTerminal ) { diff --git a/katabatic/src/AutoVertical.cpp b/katabatic/src/AutoVertical.cpp index ac3da7dc..72cc9b30 100644 --- a/katabatic/src/AutoVertical.cpp +++ b/katabatic/src/AutoVertical.cpp @@ -668,11 +668,19 @@ namespace Katabatic { if (isSourceTerminal()) { segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 ); + autoTarget->unsetFlags( CntWeakTerminal ); + dlContact1->setFlags ( CntWeakTerminal ); + if (autoTarget->getGCell() == doglegGCell) + dlContact1->migrateConstraintBox( autoTarget ); } else if (isTargetTerminal()) { unsetFlags( SegTargetTerminal ); setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegTargetTerminal ); + autoSource->unsetFlags( CntWeakTerminal ); + dlContact2->setFlags ( CntWeakTerminal ); + if (autoSource->getGCell() == doglegGCell) + dlContact2->migrateConstraintBox( autoSource ); } else if (isWeakTerminal()) { segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 ); diff --git a/katabatic/src/katabatic/AutoContact.h b/katabatic/src/katabatic/AutoContact.h index 52327661..528f4d62 100644 --- a/katabatic/src/katabatic/AutoContact.h +++ b/katabatic/src/katabatic/AutoContact.h @@ -66,6 +66,7 @@ namespace Katabatic { , CntInCreationStage = 0x00000080 , CntBadTopology = 0x00000100 , CntIgnoreAnchor = 0x00000200 + , CntWeakTerminal = 0x00000400 }; class AutoContact { @@ -161,6 +162,7 @@ namespace Katabatic { , DbU::Unit constraintMax , unsigned int flags=KbWarnOnError ); void restoreNativeConstraintBox (); + void migrateConstraintBox ( AutoContact* other ); void destroy (); // Inspector Management. Record* _getRecord () const; diff --git a/kite/src/PreProcess.cpp b/kite/src/PreProcess.cpp index e367bc2e..4b7aaa36 100644 --- a/kite/src/PreProcess.cpp +++ b/kite/src/PreProcess.cpp @@ -226,8 +226,8 @@ namespace { ltrace(150) << "protectCagedTerminals() " << track << endl; ltracein(150); - DbU::Unit lastMovedUp = track->getMin(); - unsigned int moveUpCount = 0; + DbU::Unit lastMovedUp = track->getMin(); + unsigned int moveUpCount = 0; Configuration* configuration = Session::getConfiguration(); const Layer* metal2 = configuration->getRoutingLayer( 1 ); @@ -258,9 +258,22 @@ namespace { continue; } - Katabatic::AutoContact* support = segment->base()->getAutoSource(); - RoutingPad* rp = dynamic_cast(support->getAnchor()); - Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() ); + Katabatic::AutoContact* support = NULL; + Katabatic::AutoContact* turn = NULL; + if (segment->base()->isSourceTerminal()) { + support = segment->base()->getAutoSource(); + turn = segment->base()->getAutoTarget(); + } else { + support = segment->base()->getAutoTarget(); + turn = segment->base()->getAutoSource(); + } + + RoutingPad* rp = dynamic_cast(support->getAnchor()); + Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() ); + + turn->restrictConstraintBox( freeInterval.getVMin() + , freeInterval.getVMax() + , KbVertical ); if (metal3track->getFreeInterval(segment->getAxis(),segment->getNet()).isEmpty()) { cparanoid << "[INFO] Cannot protect caged terminal because top layer (metal3) is obstructed." << endl; @@ -270,7 +283,7 @@ namespace { if (segment->getSourceU() - lastMovedUp < ppitch*4) { ++moveUpCount; if (moveUpCount % 2 == 0) { - moveUpCaged( segment ); + //moveUpCaged( segment ); } } else { moveUpCount = 0; diff --git a/knik/src/Graph.cpp b/knik/src/Graph.cpp index e4453b98..c4dffba2 100644 --- a/knik/src/Graph.cpp +++ b/knik/src/Graph.cpp @@ -170,12 +170,12 @@ void Graph::_postCreate() } if (_lowerLeftVertex->getHEdgeOut()) - cout << Dots::asUInt (" - Global router H edges capacity" ,_lowerLeftVertex->getHEdgeOut()->getCapacity()) << endl; + cmess1 << Dots::asUInt (" - Global router H edges capacity" ,_lowerLeftVertex->getHEdgeOut()->getCapacity()) << endl; else cerr << Warning( "Knik::Graph: Design has only one column, H edge capacity is zero." ) << endl; if (_lowerLeftVertex->getVEdgeOut()) - cout << Dots::asUInt (" - Global router V edges capacity" ,_lowerLeftVertex->getVEdgeOut()->getCapacity()) << endl; + cmess1 << Dots::asUInt (" - Global router V edges capacity" ,_lowerLeftVertex->getVEdgeOut()->getCapacity()) << endl; else cerr << Warning( "Knik::Graph: Design has only one row, V edge capacity is zero." ) << endl; diff --git a/vlsisapd/src/utilities/src/Dots.cpp b/vlsisapd/src/utilities/src/Dots.cpp index d18551cf..6ff55197 100644 --- a/vlsisapd/src/utilities/src/Dots.cpp +++ b/vlsisapd/src/utilities/src/Dots.cpp @@ -30,7 +30,8 @@ namespace Utilities { CR(); else _flags &= ~FirstDot; - _ostream << _indent; + if (enabled()) + _ostream << _indent; } _flush( '.' ); diff --git a/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h b/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h index a9cbf95a..30c9a838 100644 --- a/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h +++ b/vlsisapd/src/utilities/src/vlsisapd/utilities/Dots.h @@ -26,7 +26,7 @@ namespace Utilities { class Dots { public: - enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02 }; + enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02, Disabled=0x04 }; public: inline Dots ( std::ostream& , const std::string& indent @@ -38,6 +38,9 @@ namespace Utilities { inline void CR (); void dot (); void finish ( unsigned int flags ); + inline bool enabled (); + inline void enable (); + inline void disable (); private: inline void _flush ( char ); private: @@ -61,9 +64,14 @@ namespace Utilities { inline void Dots::setWidth ( unsigned int w ) { _width=w; } inline void Dots::setDivider ( unsigned int d ) { _divider=d; } + inline bool Dots::enabled () { return not (_flags & Disabled); } + inline void Dots::enable () { _flags &= ~Disabled; } + inline void Dots::disable () { _flags |= Disabled; } inline void Dots::_flush ( char c ) { + if (not enabled()) return; + _ostream << c; _ostream.flush(); } @@ -75,7 +83,7 @@ namespace Utilities { inline void Dots::reset ( unsigned int flags ) { - _flags = flags; + _flags = flags | ((not enabled()) ? Disabled : NoFlags); _count = 0; }