From a6f61c10441b80899e1cf6275657f0495489963c Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 22 Oct 2022 16:39:22 +0200 Subject: [PATCH] Update the channel routing feature to integrate with the OTC P&R. * Update: In CRL/node600/phenitec/kite.py, update the routing gauge to the new format. So now we can use again SxLib-2M (channel routing SxLib for two metal technologies). * Change: In CRL::BlifParser, if a master cell is not found in the AllianceFramework, then try in the Blif supplied libraries. This is used to load the zero, one and tie cells. Add a Blif::getCell() static function to look into the Blif supplied libraries. * Change: In CRL::LefImport, sometimes there can be discrepencies between the LEF ROUTING layers and the Coriolis routing gauge. Now ignore routing layers that are *not* presents in the Coriolis gauge. * Change: In AnabaticEngine, moved routingMode attribute from KatanaEngine, as some setup operations needs it. * Change: In AutoSegment::canReduce(), allow fixed segments to be reduced if they are "jumpers" (turn+turn and top+top or bot+bot). This case arise on the edge of routing channels for fixed wires to connect terminals. * Change: In AutoSegment::getTopologicalinfos(), compute differently the (leftBound,rightBound) interval when in channel mode. In over-the-cell mode, this interval is the one of the whole GCells under the wire. In channel mode, for fixed wires (that is, verticals connecteds to cells) this interval is reduced to half the GCell height, on the connected side of said channel. This allows Manipulator::_insertToTrack() to issue disantangling requests (push left/push right) for fixed segments that are face to face in the channel. * Change: In Anabatic::Configuration CTOR, allow the cellGauge to have a different name from the routingGauge. Now if the cell gauge that should match the routing gauge is not found, fallback to the name set in "anabatic.cellGauge" parameter. Case occur when we try to match with CORE sites from LEF files. * Change: In Etesian::Configuration CTOR, same change as in the Anabatic configuration. * Change: In Anabatic::GCell::updateDensity(), never set the GoStraight flag in channel mode. This flag makes sense when there is at least 4 routing layers (so we have 2 contiguous free of blockages). * Bug: In Anabatic::Session::_getNearestGridpoint(), sometimes the nearest on grid point is outside the constraint box. Now force the point to remains inside constraints even if offgrid. * Change: In Katana::DataNegociate::update(), perpandiculars that are either reduced or in non-preferred routing direction should not trigger a bug message. * Change: In KatanaEngine::_check(), do not check for fixed, horizontal non-prefs AutoSegments in channel mode (avoid false bug display). * Bug: In Manipulator::_forceToTrack(), slighty shrink (-1) the interval to free. The intersection function of intervals returns true when the two intervals *exactly* touches (1.vMax == 2.vMin). But in this specific case, they are not *overlapping* and no action should be taken... * Bug: In Manipulator::_insertInTrack(), do not reject the track when we are overlapping a fixed vertical segment in channel mode. (Hmm, maybe already corrected by the previous one). * Change: In Katana::NegociateOverlapCost(), in channel mode, do not put two overlaping vertical fixed segments into infinite cost. This happens when two cell connected verticals are face to face in a channel. We want them negociated the track (by shrinking their length) instead of excluding it right away. * Change: In NegociateWindow::createTrackSegment(), in channel mode, do not attempt to create a track segment over a fixed and reduced AutoSegment. Do not attempt to put a non-preferred AutoSegment on a Track either. * Bug: In RoutingEvent::revalidate(), the number of availables tracks was badly computed when in the pure constraint case, when there was only one it was reporting zero. * Change: In TrackElements::TrackElements_Perpandicular::Locator, do not issue a bug when an non-pref or reduced AutoSegment do not have an associated TrackElement. * Change: In TrackSegmentCost::update(), do not issue a bug when a perpandicular is reduded or non-pref and do not have a TrackElement. --- anabatic/src/AnabaticEngine.cpp | 1 + anabatic/src/AutoContactTerminal.cpp | 3 ++ anabatic/src/AutoSegment.cpp | 43 ++++++++++++++++------ anabatic/src/Configuration.cpp | 19 ++++++---- anabatic/src/GCell.cpp | 32 +++++++++------- anabatic/src/NetBuilderM2.cpp | 2 +- anabatic/src/Session.cpp | 7 ++++ anabatic/src/anabatic/AnabaticEngine.h | 32 ++++++++++++---- anabatic/src/anabatic/Session.h | 1 + crlcore/etc/node600/phenitec/kite.py | 9 +++++ crlcore/etc/node600/phenitec/technology.py | 2 +- crlcore/src/ccore/RoutingGauge.cpp | 14 +++++-- crlcore/src/ccore/blif/BlifParser.cpp | 21 +++++++++-- crlcore/src/ccore/crlcore/Blif.h | 1 + crlcore/src/ccore/crlcore/RoutingGauge.h | 5 ++- crlcore/src/ccore/lefdef/LefImport.cpp | 11 +++++- etesian/src/Configuration.cpp | 19 ++++++---- katana/src/Block.cpp | 13 ++++++- katana/src/DataNegociate.cpp | 19 ++++++---- katana/src/GlobalRoute.cpp | 3 +- katana/src/KatanaEngine.cpp | 27 ++++++++------ katana/src/Manipulator.cpp | 17 +++++++-- katana/src/NegociateWindow.cpp | 18 ++++++++- katana/src/ProtectRoutingPads.cpp | 3 +- katana/src/RoutingEvent.cpp | 12 ++++-- katana/src/TrackElements.cpp | 16 ++++++-- katana/src/TrackSegmentCost.cpp | 14 ++++--- katana/src/katana/Block.h | 6 +-- katana/src/katana/KatanaEngine.h | 13 ------- 29 files changed, 264 insertions(+), 119 deletions(-) diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 940a6c47..92b2fe88 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -376,6 +376,7 @@ namespace Anabatic { , _viewer (NULL) , _flags (Flags::DestroyBaseContact) , _stamp (-1) + , _routingMode (DigitalMode) , _densityMode (MaxDensity) , _autoSegmentLut () , _autoContactLut () diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index 19d989c4..65e2587b 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -503,6 +503,9 @@ namespace Anabatic { AutoContact* opposite = _segment->getOppositeAnchor(this); AutoSegment* perpandicular = opposite->getPerpandicular( _segment ); if (perpandicular) { + cdebug_log(145,0) << "Draging V interval [" + << DbU::getValueString(getCBYMin()) << " " + << DbU::getValueString(getCBYMax()) << "]" << endl; DbU::Unit y = perpandicular->getAxis(); y = std::min( y, getCBYMax() ); y = std::max( y, getCBYMin() ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 0cbc66e5..65dd6ea0 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -466,8 +466,10 @@ namespace Anabatic { bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical()); uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ; - //cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() - // << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; + // cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() + // << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; + // cerr << " minimalSpacing: " + // << DbU::getValueString( Session::getLayerGauge(depth)->getLayer()->getMinimalSpacing() ) << endl; *viaToSameCap = Session::getPWireWidth(depth)/2; @@ -492,12 +494,12 @@ namespace Anabatic { *minimalLength += twoGrid - modulo; } - //cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; - //cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; - //if (depth > 0) - // cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; - //cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; - //cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; + // cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; + // cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; + // if (depth > 0) + // cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; + // cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; + // cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; _extensionCaps.push_back( std::array( {{ viaToTopCap , viaToBottomCap @@ -1794,14 +1796,21 @@ namespace Anabatic { DbU::Unit length = getAnchoredLength(); if (isGlobal() and (length > getPPitch())) return false; - if (isDrag() or isFixed()) return false; + if (isDrag()) return false; if (not isSpinTopOrBottom()) return false; - if ((getDepth() == 1) and isSpinBottom()) return false; - if ((flags & Flags::WithPerpands) and _reduceds) return false; AutoContact* source = getAutoSource(); AutoContact* target = getAutoTarget(); + if (isFixed()) { + if (isSpinTopOrBottom() and source->isTurn() and target->isTurn()) + return true; + return false; + } + + if ((getDepth() == 1) and isSpinBottom()) return false; + if ((flags & Flags::WithPerpands) and _reduceds) return false; + cdebug_log(159,0) << " source:" << source->isHTee() << "+" << source->isVTee() << endl; cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl; @@ -3214,6 +3223,9 @@ namespace Anabatic { { cdebug_log(145,1) << "getTopologicalInfos() - " << seed << endl; + bool isSourceBoundToChannel = false; + bool isTargetBoundToChannel = false; + leftBound = DbU::Max; rightBound = DbU::Min; @@ -3271,10 +3283,19 @@ namespace Anabatic { Flags perpandFlags = (currentSegment->getAutoSource() == sourceContact) ? Flags::Source : Flags::Target; perpandiculars.push_back( make_tuple( currentSegment, perpandFlags )); + if (Session::getAnabatic()->isChannelMode()) { + if (currentSegment->isNonPref() and currentSegment->isFixed()) { + if (perpandFlags & Flags::Source) isSourceBoundToChannel = true; + else isTargetBoundToChannel = true; + } + } } } } + if (isSourceBoundToChannel) rightBound -= (leftBound + rightBound)/2; + if (isTargetBoundToChannel) leftBound += (leftBound + rightBound)/2; + cdebug_tabw(145,-1); } diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 5e8a7085..c8fe0fee 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -97,17 +97,22 @@ namespace Anabatic { GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); - if (cg == NULL) { + if (not cg) cg = AllianceFramework::get()->getCellGauge( gaugeName ); - if (cg == NULL) - throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." ); + if (not cg) { + string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString(); + cg = AllianceFramework::get()->getCellGauge( cellGaugeName ); } + if (not cg) + throw Error( "AnabaticEngine::Configuration(): Unable to find cell gauge \"%s\"" + , gaugeName.c_str() ); - if (rg == NULL) { + if (not rg) rg = AllianceFramework::get()->getRoutingGauge( gaugeName ); - if (rg == NULL) - throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() ); - } + if (not rg) + throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\"" + , gaugeName.c_str() ); + _cg = cg->getClone(); _rg = rg->getClone(); diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 3c2c6f44..dc8fdc93 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1551,20 +1551,24 @@ namespace Anabatic { } // Add the blockages. - int contiguousNonSaturated = 0; - for ( size_t i=0 ; i<_depth ; i++ ) { - uLengths2[i] += _blockages[i]; - if (not i) continue; - if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply) - continue; - if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height)) - contiguousNonSaturated = 0; - else - contiguousNonSaturated++; - } - if (contiguousNonSaturated < 2) { - flags() |= Flags::GoStraight; - //cerr << "| Set GoStraight on " << this << endl; + if (isStdCellRow() or isChannelRow()) { + flags().reset( Flags::GoStraight ); + } else { + int contiguousNonSaturated = 0; + for ( size_t i=0 ; i<_depth ; i++ ) { + uLengths2[i] += _blockages[i]; + if (not i) continue; + if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply) + continue; + if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height)) + contiguousNonSaturated = 0; + else + contiguousNonSaturated++; + } + if (contiguousNonSaturated < 2) { + flags() |= Flags::GoStraight; + //cerr << "| Set GoStraight on " << this << endl; + } } // Compute the number of non pass-through tracks. diff --git a/anabatic/src/NetBuilderM2.cpp b/anabatic/src/NetBuilderM2.cpp index 242b007d..f28c58fa 100644 --- a/anabatic/src/NetBuilderM2.cpp +++ b/anabatic/src/NetBuilderM2.cpp @@ -187,7 +187,7 @@ namespace Anabatic { contact2 ->setFlags( CntFixed ); AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical ); - AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal ); + AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal|Flags::UseNonPref ); fixed ->setFlags( AutoSegment::SegFixed ); dogleg->setFlags( AutoSegment::SegFixed ); diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index fe9cf416..6db09c4a 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -412,6 +412,9 @@ namespace Anabatic { if (y < constraint.getYMin()) y += lg->getPitch(); if (y > constraint.getYMax()) y -= lg->getPitch(); + y = std::max( y, constraint.getYMin() ); + y = std::min( y, constraint.getYMax() ); + return Point(x,y); } @@ -420,6 +423,10 @@ namespace Anabatic { { return get("isInDemoMode()")->_anabatic->isInDemoMode(); } + bool Session::isChannelMode () + { return get("isChannelMode()")->_anabatic->isChannelMode(); } + + float Session::getSaturateRatio () { return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); } diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 94523b13..5b633781 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -191,20 +191,27 @@ namespace Anabatic { class AnabaticEngine : public ToolEngine { public: - enum DensityMode { AverageHVDensity=1 // Average between all densities. - , AverageHDensity =2 // Average between all H densities. - , AverageVDensity =3 // Average between all V densities. - , MaxHVDensity =4 // Maximum between average H and average V. - , MaxVDensity =5 // Maximum of V densities. - , MaxHDensity =6 // Maximum of H densities. - , MaxDensity =7 // Maximum of H & V densities. - }; + static const uint32_t DigitalMode = (1 << 0); + static const uint32_t AnalogMode = (1 << 1); + static const uint32_t MixedMode = (1 << 2); + static const uint32_t ChannelMode = (1 << 3); + static const uint32_t AverageHVDensity = 1; // Average between all densities. + static const uint32_t AverageHDensity = 2; // Average between all H densities. + static const uint32_t AverageVDensity = 3; // Average between all V densities. + static const uint32_t MaxHVDensity = 4; // Maximum between average H and average V. + static const uint32_t MaxVDensity = 5; // Maximum of V densities. + static const uint32_t MaxHDensity = 6; // Maximum of H densities. + static const uint32_t MaxDensity = 7; // Maximum of H & V densities. public: typedef ToolEngine Super; public: static AnabaticEngine* create ( Cell* ); static AnabaticEngine* get ( const Cell* ); inline bool isCanonizeDisabled () const; + inline bool isDigitalMode () const; + inline bool isAnalogMode () const; + inline bool isMixedMode () const; + inline bool isChannelMode () const; static const Name& staticGetName (); virtual const Name& getName () const; virtual Configuration* getConfiguration (); @@ -269,6 +276,8 @@ namespace Anabatic { void invalidateRoutingPads (); void updateDensity (); size_t checkGCellDensities (); + inline void setRoutingMode ( uint32_t ); + inline void resetRoutingMode ( uint32_t ); inline void setGlobalThreshold ( DbU::Unit ); inline void setSaturateRatio ( float ); inline void setSaturateRp ( size_t ); @@ -350,6 +359,7 @@ namespace Anabatic { CellViewer* _viewer; Flags _flags; int _stamp; + uint32_t _routingMode; uint64_t _densityMode; AutoSegmentLut _autoSegmentLut; AutoContactLut _autoContactLut; @@ -359,6 +369,12 @@ namespace Anabatic { }; + inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); }; + inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); }; + inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); }; + inline bool AnabaticEngine::isChannelMode () const { return (_routingMode & ChannelMode); }; + inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; }; + inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; }; inline EngineState AnabaticEngine::getState () const { return _state; } inline void AnabaticEngine::setState ( EngineState state ) { _state = state; } inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index b708895c..2c76f74b 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -76,6 +76,7 @@ namespace Anabatic { static inline bool doDestroyBaseSegment (); static inline bool doDestroyTool (); static bool isInDemoMode (); + static bool isChannelMode (); static bool doWarnGCellOverload (); static Session* get ( const char* message=NULL ); static inline Technology* getTechnology (); diff --git a/crlcore/etc/node600/phenitec/kite.py b/crlcore/etc/node600/phenitec/kite.py index 66f1da0b..3bb0cc89 100644 --- a/crlcore/etc/node600/phenitec/kite.py +++ b/crlcore/etc/node600/phenitec/kite.py @@ -85,6 +85,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(2) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -97,6 +98,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -109,6 +111,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(2) # VIA side (that is VIA34). , l(8) # obstacle dW. ) ) @@ -121,6 +124,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta , l(0) # track offset from AB. , l(15) # track pitch. , l(6) # wire width. + , l(6) # perpandicular wire width. , l(4) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -137,6 +141,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(2) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -149,6 +154,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -161,6 +167,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(2) # VIA side (that is VIA34). , l(8) # obstacle dW. ) ) @@ -177,6 +184,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(3) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -189,6 +197,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , l(3) # perpandicular wire width. , l(3) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) diff --git a/crlcore/etc/node600/phenitec/technology.py b/crlcore/etc/node600/phenitec/technology.py index 8a3bbb54..10d0f68a 100644 --- a/crlcore/etc/node600/phenitec/technology.py +++ b/crlcore/etc/node600/phenitec/technology.py @@ -24,7 +24,7 @@ from Hurricane import Technology tech = DataBase.getDB().getTechnology() if tech: - print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'format(tech.getName()) )) + print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'.format(tech.getName()) )) else: tech = Technology.create( DataBase.getDB(), 'phenitec06' ) diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 21455101..3c6e58c4 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -62,6 +62,7 @@ namespace CRL { , _technology (DataBase::getDB()->getTechnology()) , _isSymbolic (true) , _isSuperPitched(true) + , _usableLayers (0) { } @@ -72,6 +73,7 @@ namespace CRL { , _technology (gauge._technology) , _isSymbolic (gauge._isSymbolic) , _isSuperPitched(gauge._isSuperPitched) + , _usableLayers (0) { // Make a deep copy of the map. for ( size_t i=0 ; i 0.00001f) _isSuperPitched = false; } + + if (layerGauge->getType() == Constant::LayerGaugeType::Default) ++_usableLayers; } @@ -354,12 +358,14 @@ namespace CRL { Record* RoutingGauge::_getRecord ( Record* record ) const { - if ( record == NULL ) + if (not record) record = new Record ( getString(this) ); - record->add ( getSlot("_name" , _name ) ); - record->add ( getSlot("_gauges" ,&_layerGauges) ); - record->add ( getSlot("_isSymbolic", _isSymbolic ) ); + record->add( getSlot("_name" , _name )); + record->add( getSlot("_gauges" ,&_layerGauges )); + record->add( getSlot("_isSymbolic" , _isSymbolic )); + record->add( getSlot("_isSuperPitched", _isSuperPitched )); + record->add( getSlot("_usableLayers" , _usableLayers )); return ( record ); } diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index 16d01f24..e80f0a86 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -377,10 +377,12 @@ namespace { static string zeroName = Cfg::getParamString("etesian.cell.zero","zero_x0")->asString(); static string oneName = Cfg::getParamString("etesian.cell.one" , "one_x0")->asString(); - _zeroCell = framework->getCell( zeroName, Catalog::State::Views|Catalog::State::Foreign ); - _oneCell = framework->getCell( oneName, Catalog::State::Views|Catalog::State::Foreign ); - _groundName = Cfg::getParamString("crlcore.groundName","vss")->asString(); - _powerName = Cfg::getParamString("crlcore.powerName" ,"vdd")->asString(); + _zeroCell = framework->getCell( zeroName, Catalog::State::Views|Catalog::State::Foreign ); + _oneCell = framework->getCell( oneName, Catalog::State::Views|Catalog::State::Foreign ); + _groundName = Cfg::getParamString("crlcore.groundName","vss")->asString(); + _powerName = Cfg::getParamString("crlcore.powerName" ,"vdd")->asString(); + if (not _zeroCell) _zeroCell = Blif::getCell( zeroName ); + if (not _oneCell) _oneCell = Blif::getCell( oneName ); if (_zeroCell) { for ( Net* net : _zeroCell->getNets() ) { @@ -818,6 +820,17 @@ namespace CRL { { if (library) _libraries.push_back( library ); } + Cell* Blif::getCell ( string name ) + { + Cell* cell = nullptr; + for ( Library* library : getLibraries() ) { + cell = library->getCell( name ); + if (cell) return cell; + } + return nullptr; + } + + Cell* Blif::load ( string cellPath, bool enforceVhdl ) { using namespace std; diff --git a/crlcore/src/ccore/crlcore/Blif.h b/crlcore/src/ccore/crlcore/Blif.h index a23f553d..caf8e14a 100644 --- a/crlcore/src/ccore/crlcore/Blif.h +++ b/crlcore/src/ccore/crlcore/Blif.h @@ -59,6 +59,7 @@ namespace CRL { static Cell* load ( std::string netlist, bool enforceVhdl=true ); static void add ( Library* ); static inline const std::vector& getLibraries (); + static Cell* getCell ( std::string ); private: static std::vector _libraries; }; diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index 4ffdef82..ce916ad9 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -64,6 +64,7 @@ namespace CRL { inline const Name getName () const; inline Technology* getTechnology () const; inline size_t getDepth () const; + inline size_t getUsableLayers () const; inline DbU::Unit getHorizontalPitch () const; inline DbU::Unit getVerticalPitch () const; RoutingLayerGauge* getHorizontalGauge () const; @@ -109,6 +110,7 @@ namespace CRL { Technology* _technology; bool _isSymbolic; bool _isSuperPitched; + size_t _usableLayers; // Internal - Constructors & Destructors. RoutingGauge ( const char* name ); @@ -121,13 +123,14 @@ namespace CRL { inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; } inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; } - inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); } + inline bool RoutingGauge::isTwoMetals () const { return (_usableLayers < 3); } inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); } inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); } inline bool RoutingGauge::hasPowerSupply () const { return (getPowerSupplyGauge() != NULL); } inline const Name RoutingGauge::getName () const { return _name; } inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); } inline Technology* RoutingGauge::getTechnology () const { return _technology; } + inline size_t RoutingGauge::getUsableLayers () const { return _usableLayers; } inline DbU::Unit RoutingGauge::getHorizontalPitch () const { return getHorizontalGauge()->getPitch(); } inline DbU::Unit RoutingGauge::getVerticalPitch () const { return getVerticalGauge ()->getPitch(); } inline unsigned int RoutingGauge::getLayerType ( size_t depth ) const { return getLayerGauge(depth)->getType(); } diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 74912ae8..27e92f01 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -104,6 +104,8 @@ namespace { inline void incNthMetal (); inline int getNthCut () const; inline void incNthCut (); + inline int getNthRouting () const; + inline void incNthRouting (); inline RoutingGauge* getRoutingGauge () const; inline void addPinSegment ( string name, Segment* ); inline void clearPinSegments (); @@ -130,6 +132,7 @@ namespace { vector _errors; int _nthMetal; int _nthCut; + int _nthRouting; RoutingGauge* _routingGauge; CellGauge* _cellGauge; DbU::Unit _minTerminalWidth; @@ -154,6 +157,8 @@ namespace { inline void LefParser::incNthMetal () { ++_nthMetal; } inline int LefParser::getNthCut () const { return _nthCut; } inline void LefParser::incNthCut () { ++_nthCut; } + inline int LefParser::getNthRouting () const { return _nthRouting; } + inline void LefParser::incNthRouting () { ++_nthRouting; } inline RoutingGauge* LefParser::getRoutingGauge () const { return _routingGauge; } inline CellGauge* LefParser::getCellGauge () const { return _cellGauge; } inline void LefParser::setCoreSite ( DbU::Unit x, DbU::Unit y ) { _coreSiteX=x; _coreSiteY=y; } @@ -210,6 +215,7 @@ namespace { , _errors () , _nthMetal (0) , _nthCut (0) + , _nthRouting (0) , _routingGauge (NULL) , _cellGauge (NULL) , _minTerminalWidth(DbU::fromPhysical(Cfg::getParamDouble("lefImport.minTerminalWidth",0.0)->asDouble(),DbU::UnitPower::Micro)) @@ -305,9 +311,9 @@ namespace { cerr << " - \"" << lefLayer->name() << "\" map to \"" << basicLayer->getName() << "\"" << endl; - RoutingLayerGauge* gauge = parser->getRoutingGauge()->getLayerGauge( parser->getNthMetal() ); + RoutingLayerGauge* gauge = parser->getRoutingGauge()->getLayerGauge( parser->getNthRouting() ); - if (gauge) { + if (gauge and (layer == gauge->getLayer())) { if (lefLayer->hasPitch()) { double lefPitch = lefLayer->pitch(); double crlPitch = DbU::toPhysical(gauge->getPitch(),DbU::Micro); @@ -336,6 +342,7 @@ namespace { cerr << Warning( "LefParser::_layerCbk(): CRL Routing direction discrepency for \"%s\", LEF is VERTICAL." , getString( basicLayer->getName() ).c_str() ) << endl; } + parser->incNthRouting(); } else { cerr << Warning( "LefParser::_layerCbk(): No CRL routing gauge defined for \"%s\"." , getString( basicLayer->getName() ).c_str() diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index 182c5c73..3f904106 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -73,18 +73,21 @@ namespace Etesian { , _antennaDiodeMaxWL( Cfg::getParamInt ("etesian.antennaDiodeMaxWL" ,0 )->asInt() ) { string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); - if (cg == NULL) { + if (not cg) cg = AllianceFramework::get()->getCellGauge( gaugeName ); - if (cg == NULL) - throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge \"%s\"." - , gaugeName.c_str() ); + if (not cg) { + string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString(); + cg = AllianceFramework::get()->getCellGauge( cellGaugeName ); } + if (not cg) + throw Error( "EtesianEngine::Configuration(): Unable to find cell gauge \"%s\"" + , gaugeName.c_str() ); - if (rg == NULL) { + if (not rg) rg = AllianceFramework::get()->getRoutingGauge( gaugeName ); - if (rg == NULL) - throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() ); - } + if (not rg) + throw Error( "EtesianEngine::Configuration(): Unable to find routing gauge \"%s\"" + , gaugeName.c_str() ); _rg = rg->getClone(); _cg = cg->getClone(); diff --git a/katana/src/Block.cpp b/katana/src/Block.cpp index 994aab7d..a165ed69 100644 --- a/katana/src/Block.cpp +++ b/katana/src/Block.cpp @@ -18,6 +18,7 @@ #include "hurricane/Warning.h" #include "hurricane/Breakpoint.h" #include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" #include "hurricane/RoutingPad.h" #include "hurricane/Cell.h" #include "anabatic/Edge.h" @@ -37,6 +38,7 @@ namespace Katana { using Hurricane::Breakpoint; using Hurricane::DebugSession; using Hurricane::SubTypeCollection; + using Hurricane::UpdateSession; using Hurricane::Transformation; using Hurricane::RoutingPad; using Hurricane::Instance; @@ -104,8 +106,14 @@ namespace Katana { throw Error( "Row::createChannel(): NULL southWest GCell." ); if (_occurrences.empty()) throw Error( "Row::createChannel(): No instances in row." ); - if (southWest->getXMin() != (*_occurrences.begin()).first) - throw Error( "Row::createChannel(): South-west GCell XMin and Row X min differs." ); + if (southWest->getXMin() != (*_occurrences.begin()).first) { + UpdateSession::close(); + throw Error( "Row::createChannel(): South-west GCell XMin and Row X min differs.\n" + " * southWest=%s\n" + " * first=%s\n" + , getString(southWest).c_str() + , DbU::getValueString((*_occurrences.begin()).first).c_str() ); + } if (southWest->getYMin() != _y) throw Error( "Row::createChannel(): South-west GCell YMIn and Row Y min differs (%s vs. %s)." , DbU::getValueString(southWest->getYMin()).c_str() @@ -198,6 +206,7 @@ namespace Katana { // _channelHeight = std::max( _channelHeight, east->getRealOccupancy() ); gcell = gcell->getEast(); } + _channelHeight += 2; return _channelHeight; } diff --git a/katana/src/DataNegociate.cpp b/katana/src/DataNegociate.cpp index 3deb05b4..20002fae 100644 --- a/katana/src/DataNegociate.cpp +++ b/katana/src/DataNegociate.cpp @@ -95,6 +95,7 @@ namespace Katana { vector collapseds; vector< tuple > perpandiculars; map attractorSpins; + size_t reducedPerpands = 0; _reduceRanges[0].makeEmpty(); _reduceRanges[1].makeEmpty(); @@ -125,12 +126,16 @@ namespace Katana { perpandicular = Session::lookup( basePerpand->getCanonical(interval)->base() ); } if (not perpandicular) { - cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)" - //, getString((void*)basePerpand->getCanonical(interval)->base()).c_str() - , getString(basePerpand->getCanonical(interval)).c_str() - //, getString((void*)basePerpand->base()).c_str() - , getString(basePerpand).c_str() - ) << endl; + if (not (Session::isChannelMode() + and (basePerpand->isReduced() or basePerpand->isNonPref()))) + cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)" + //, getString((void*)basePerpand->getCanonical(interval)->base()).c_str() + , getString(basePerpand->getCanonical(interval)).c_str() + //, getString((void*)basePerpand->base()).c_str() + , getString(basePerpand).c_str() + ) << endl; + else + ++reducedPerpands; continue; } @@ -266,7 +271,7 @@ namespace Katana { cdebug_tabw(159,-1); } - if ( not _trackSegment->isTerminal() and (_perpandiculars.size() < 2) ) + if ( not _trackSegment->isTerminal() and (_perpandiculars.size()+reducedPerpands < 2) ) cerr << Bug( "Less than two perpandiculars on %s.", getString(_trackSegment).c_str() ) << endl; map::iterator iattractor = attractorSpins.begin(); diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index f5525d87..cea65e10 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -685,7 +685,8 @@ namespace Katana { addMeasure( "H-ovE", hoverflow, 12 ); addMeasure( "V-ovE", voverflow, 12 ); - _buildBloatProfile(); + if (not Session::isChannelMode()) + _buildBloatProfile(); if (flags & Flags::ShowFailedNets ) selectNets ( this, nets ); if (flags & Flags::ShowFailedGSegments ) selectSegments ( this, segments ); diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 4ca3c75b..6a28499d 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -195,7 +195,6 @@ namespace Katana { , _minimumWL (0.0) , _shortDoglegs () , _symmetrics () - , _mode (DigitalMode) , _stage (StageNegociate) , _successState (0) { @@ -241,7 +240,7 @@ namespace Katana { { cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl; - _mode |= DigitalMode; + setRoutingMode( DigitalMode ); Super::chipPrep(); @@ -270,8 +269,8 @@ namespace Katana { { cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl; - _mode &= ~DigitalMode; - _mode |= AnalogMode; + resetRoutingMode( DigitalMode ); + setRoutingMode( AnalogMode ); Super::chipPrep(); @@ -286,11 +285,11 @@ namespace Katana { { cdebug_log(155,1) << "KatanaEngine::setupChannelMode()" << endl; - RoutingGauge* rg = getConfiguration()->getRoutingGauge(); - size_t maxDepth = rg->getDepth(); - if (maxDepth < 3) { - _mode |= ChannelMode; + RoutingGauge* rg = getConfiguration()->getRoutingGauge(); + if (rg->isTwoMetals()) { + setRoutingMode( ChannelMode ); + size_t maxDepth = rg->getDepth(); if (maxDepth < 2) { throw Error( "KatanaEngine::setupChannelMode(): Layer gauge %s must contains at least two layers (%u)." , getString(rg->getName()).c_str(), maxDepth ); @@ -554,10 +553,10 @@ namespace Katana { } } - if (Session::getConfiguration()->isTwoMetals()) { + if (Session::isChannelMode()) { for ( GCell* gcell : getGCells() ) { if (not gcell->isStdCellRow()) continue; - + set terminalsX; for ( Component* component : getCell()->getComponentsUnder(gcell->getBoundingBox()) ) { RoutingPad* rp = dynamic_cast( component ); @@ -574,7 +573,7 @@ namespace Katana { edge = gcell->getSouthEdge(); if (edge) { capacity = edge->getCapacity(); - if (terminalsX.size() < capacity) capacity = terminalsX.size(); + if (terminalsX.size()/2 < capacity) capacity = terminalsX.size()/2; edge->reserveCapacity( capacity ); } } @@ -849,9 +848,15 @@ namespace Katana { AutoSegment* autoSegment = anbtSession->lookup( segment ); if (not autoSegment) continue; if (not autoSegment->isCanonical()) continue; + if (autoSegment->isReduced()) continue; TrackElement* trackSegment = Session::lookup( segment ); if (not trackSegment) { + if ( isChannelMode() + and autoSegment->isFixed() + and autoSegment->isHorizontal() + and autoSegment->isNonPref()) + continue; coherency = false; cerr << Bug( "%p %s without Track Segment" , autoSegment diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index a39ba820..1d5f5250 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -722,8 +722,10 @@ namespace Katana { cdebug_log(159,0) << "No intersection with: " << segment2->getCanonicalInterval() << endl; continue; } - if ( segment2->isBlockage() or segment2->isFixed() ) { - cdebug_log(159,0) << "Ovelap is blockage or fixed." << endl; + if ( segment2->isBlockage() + or (segment2->isFixed() + and not (segment2->isVertical() and Session::getKatanaEngine()->isChannelMode()))) { + cdebug_log(159,0) << "Overlap is blockage or fixed." << endl; success = false; continue; } @@ -890,6 +892,7 @@ namespace Katana { set canonicals; bool success = true; + toFree.inflate( -1 ); cdebug_log(159,1) << "Manipulator::_forceToTrack(size_t) - " << toFree << endl; for ( size_t i=begin ; success and (i < end) ; ++i ) { @@ -898,7 +901,15 @@ namespace Katana { cdebug_log(159,0) << "* Looking // " << segment2 << endl; if (segment2->getNet() == ownerNet) continue; - if (not toFree.intersect(segment2->getCanonicalInterval())) continue; + Interval segCanon = segment2->getCanonicalInterval(); + if (not toFree.intersect(segment2->getCanonicalInterval())) + continue; + cdebug_log(159,0) << "toFree = " << toFree + << " [" << toFree.getVMin() + << " " << toFree.getVMax() << "]" << endl; + cdebug_log(159,0) << "segCanon = " << segCanon + << " [" << segCanon.getVMin() + << " " << segCanon.getVMax() << "]" << endl; if (segment2->isFixed()) { success = false; continue; diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 8efc0fee..2da12bf1 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -60,7 +60,9 @@ namespace { if (not intersect.intersect(cost.getInterval())) return; - if (segment->isBlockage() or segment->isFixed()) { + if ( segment->isBlockage() + or (segment->isFixed() + and not (segment->isVertical() and Session::getKatanaEngine()->isChannelMode()))) { cdebug_log(159,0) << "Infinite cost from: " << segment << endl; cost.setInfinite (); cost.setOverlap (); @@ -329,13 +331,25 @@ namespace Katana { // Special case: fixed AutoSegments must not interfere with blockages. // Ugly: uses of getExtensionCap(). if (autoSegment->isFixed()) { + if (Session::isChannelMode() and autoSegment->isReduced()) { + cdebug_log(159,0) << "* Fixed segment is reduced, ignore " << autoSegment << endl; + cdebug_tabw(159,-1); + return NULL; + } + size_t begin; size_t end; Interval fixedSpan; Interval blockageSpan; + if (Session::isChannelMode() and autoSegment->isNonPref()) { + cdebug_log(159,0) << "Fixed in non-preferred direction, do not attempt to set on track." << endl; + cdebug_tabw(159,-1); + DebugSession::close(); + return NULL; + } if (not refTrack) { - string message = "NULL refTrack for " + getString(autoSegment); + string message = "NULL refTrack for " + getString(autoSegment) + " brace for crashing!"; Breakpoint::stop( 0, message ); } diff --git a/katana/src/ProtectRoutingPads.cpp b/katana/src/ProtectRoutingPads.cpp index c8992e1c..d3366c0c 100644 --- a/katana/src/ProtectRoutingPads.cpp +++ b/katana/src/ProtectRoutingPads.cpp @@ -99,9 +99,10 @@ namespace { if (CatalogExtension::isPad(masterNet->getCell())) { if ( rp->getNet()->isPower() - or (rp->getNet()->getName() == padNetName) ) + or (rp->getNet()->getName() == padNetName) ) { cdebug_tabw(145,-1); return; + } } vector segments; diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 0d85e57c..c8dad156 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -747,16 +747,22 @@ namespace Katana { RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_segment->getLayer()); Track* track = plane->getTrackByPosition(_constraints.getVMin()); - if ( track && (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack(); - for ( ; track && (track->getAxis() <= _constraints.getVMax()) - ; track = track->getNextTrack(), _tracksNb++ ); + if ( track and (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack(); + cdebug_log(159,0) << "| Nearest " << track << endl; + while ( track and (track->getAxis() <= _constraints.getVMax()) ) { + _tracksNb++; + track = track->getNextTrack(); + cdebug_log(159,0) << "| Next " << track << endl; + } } + cdebug_log(159,0) << "| _tracksNb " << _tracksNb << endl; if (not _tracksNb) { cdebug_log(159,0) << "| Pure constraints are too tight." << endl; if (_segment->base()) _overConstrained = _segment->base()->getAutoSource()->isTerminal() and _segment->base()->getAutoTarget()->isTerminal(); } + cdebug_log(159,0) << "| _tracksNb " << _tracksNb << endl; _segment->computePriority(); diff --git a/katana/src/TrackElements.cpp b/katana/src/TrackElements.cpp index 0cb497cc..726074ac 100644 --- a/katana/src/TrackElements.cpp +++ b/katana/src/TrackElements.cpp @@ -45,8 +45,12 @@ namespace Katana { Interval bounds; if ( _locator.isValid() ) { _element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() ); - if ( !_element ) { - cerr << Bug("Canonical segment without TrackElement.") << endl; + if (not _element) { + AutoSegment* segment = _locator.getElement()->getCanonical(bounds); + if (Session::isChannelMode() + and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed())) + cerr << Bug( "Canonical segment without TrackElement on %s." + , getString(segment).c_str()) << endl; progress (); } } @@ -67,8 +71,12 @@ namespace Katana { if ( _locator.isValid() ) { _element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() ); - if ( !_element ) { - cerr << Bug("Canonical segment without TrackElement.") << endl; + if (not _element ) { + AutoSegment* segment = _locator.getElement()->getCanonical(bounds); + if (Session::isChannelMode() + and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed())) + cerr << Bug( "Canonical segment without TrackElement on %s." + , getString(segment).c_str() ) << endl; continue; } diff --git a/katana/src/TrackSegmentCost.cpp b/katana/src/TrackSegmentCost.cpp index 8fca5f32..6266f92f 100644 --- a/katana/src/TrackSegmentCost.cpp +++ b/katana/src/TrackSegmentCost.cpp @@ -105,12 +105,14 @@ namespace Katana { } if ( not perpandicular ) { - cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)" - ,getString((void*)basePerpand->getCanonical(interval)->base()).c_str() - ,getString(basePerpand->getCanonical(interval)).c_str() - ,getString((void*)basePerpand->base()).c_str() - ,getString(basePerpand).c_str() - ) << endl; + if (Session::isChannelMode() + and not (basePerpand->isReduced() or basePerpand->isNonPref())) + cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)" + ,getString((void*)basePerpand->getCanonical(interval)->base()).c_str() + ,getString(basePerpand->getCanonical(interval)).c_str() + ,getString((void*)basePerpand->base()).c_str() + ,getString(basePerpand).c_str() + ) << endl; continue; } interval.inflate ( DbU::lambda(-1.5) ); diff --git a/katana/src/katana/Block.h b/katana/src/katana/Block.h index 4e1149ee..24573b27 100644 --- a/katana/src/katana/Block.h +++ b/katana/src/katana/Block.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef KATANA_BLOCK_H -#define KATANA_BLOCK_H - +#pragma once #include #include #include @@ -113,5 +111,3 @@ namespace Katana { INSPECTOR_P_SUPPORT(Katana::Row); INSPECTOR_P_SUPPORT(Katana::Block); - -#endif // KATANA_BLOCK_H diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index a76acab9..02a93646 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -55,10 +55,6 @@ namespace Katana { class KatanaEngine : public AnabaticEngine { public: - static const uint32_t DigitalMode = (1 << 0); - static const uint32_t AnalogMode = (1 << 1); - static const uint32_t MixedMode = (1 << 2); - static const uint32_t ChannelMode = (1 << 3); static const uint32_t GlobalRoutingSuccess = (1 << 0); static const uint32_t DetailedRoutingSuccess = (1 << 1); public: @@ -68,10 +64,6 @@ namespace Katana { static KatanaEngine* create ( Cell* ); static KatanaEngine* get ( const Cell* ); public: - inline bool isDigitalMode () const; - inline bool isAnalogMode () const; - inline bool isMixedMode () const; - inline bool isChannelMode () const; inline bool isGlobalRoutingSuccess () const; inline bool isDetailedRoutingSuccess () const; inline bool useClockTree () const; @@ -172,7 +164,6 @@ namespace Katana { double _minimumWL; TrackElementPairing _shortDoglegs; DataSymmetricMap _symmetrics; - uint32_t _mode; uint32_t _stage; mutable uint32_t _successState; protected: @@ -188,10 +179,6 @@ namespace Katana { // Inline Functions. - inline bool KatanaEngine::isDigitalMode () const { return (_mode & DigitalMode); }; - inline bool KatanaEngine::isAnalogMode () const { return (_mode & AnalogMode); }; - inline bool KatanaEngine::isMixedMode () const { return (_mode & MixedMode); }; - inline bool KatanaEngine::isChannelMode () const { return (_mode & ChannelMode); }; inline bool KatanaEngine::isGlobalRoutingSuccess () const { return (_successState & GlobalRoutingSuccess); } inline bool KatanaEngine::isDetailedRoutingSuccess() const { return (_successState & DetailedRoutingSuccess); } inline bool KatanaEngine::useClockTree () const { return _configuration->useClockTree(); }