diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 4a341ba8..9f1d4530 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -412,7 +412,7 @@ namespace Anabatic { for ( auto isegment : _autoSegmentLut ) { if (isegment.second->isFixed()) ++fixedSegments; if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs; - if (isegment.second->bloatStackedStrap()) ++bloatedStraps; + //if (isegment.second->bloatStackedStrap()) ++bloatedStraps; } cmess1 << " o Driving Hurricane data-base." << endl; diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index 54b1662a..129540c3 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -205,10 +205,11 @@ namespace Anabatic { size_t maxDepth = 0; getDepthSpan( minDepth, maxDepth ); - if (minDepth == maxDepth) - setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) ); - else - setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) ); + setLayerAndWidth( maxDepth-minDepth, minDepth ); + // if (minDepth == maxDepth) + // setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) ); + // else + // setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) ); } @@ -576,8 +577,13 @@ namespace Anabatic { if (delta == 0) { setLayer( Session::getRoutingLayer(depth) ); - setSizes( Session::getWireWidth (depth) - , Session::getWireWidth (depth) ); + if (Session::getDirection(depth) & Flags::Horizontal) { + setSizes( Session::getPWireWidth(depth) + , Session::getWireWidth (depth) ); + } else { + setSizes( Session::getWireWidth (depth) + , Session::getPWireWidth(depth) ); + } } else { setLayer( Session::getContactLayer(depth) ); setSizes( Session::getViaWidth (depth) diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 9e12307c..fd076d59 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -441,7 +441,7 @@ namespace Anabatic { //cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() // << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; - *viaToSameCap = Session::getWireWidth(depth)/2; + *viaToSameCap = Session::getPWireWidth(depth)/2; // Bottom metal of the VIA going *up*. const Layer* viaLayer = dynamic_cast( Session::getContactLayer(depth) ); @@ -726,9 +726,10 @@ namespace Anabatic { if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth); else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth); else cap = getViaToSameCap (depth); - cdebug_log(145,0) << "getExtensionCap(): flags:" << getFlags() + cdebug_log(150,0) << "getExtensionCap(): flags:" << getFlags() << " VIA cap:" << DbU::getValueString(cap) - << " " << (getFlags() & SegSourceBottom) + << " t:" << (getFlags() & SegSourceBottom) + << " b:" << (getFlags() & SegSourceTop) << endl; } @@ -738,8 +739,9 @@ namespace Anabatic { else cap = getViaToSameCap (depth); } - if (cap < getWidth()/2) cap = getWidth()/2; - return cap + getLayer()->getMinimalSpacing()/2;; + if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2; + if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2; + return cap; } @@ -2088,17 +2090,49 @@ namespace Anabatic { bool AutoSegment::bloatStackedStrap () { - if (getLength() or isReduced()) return false; - if ( ((_flags & (SegSourceBottom|SegTargetTop)) != (SegSourceBottom|SegTargetTop)) - and ((_flags & (SegTargetBottom|SegSourceTop)) != (SegTargetBottom|SegSourceTop)) ) return false; - + DebugSession::open( getNet(), 145, 150 ); + cdebug_log(149,1) << "AutoSegment::bloatStackedStrap() " << this << endl; double minArea = getLayer()->getMinimalArea(); - if (minArea == 0.0) return false; + if (minArea == 0.0) { + cdebug_log(149,-1) << "False, NO minimal area." << endl; + DebugSession::close(); + return false; + } + + DbU::Unit minLength + = DbU::fromPhysical( minArea / DbU::toPhysical( getWidth(), DbU::UnitPower::Micro ) + , DbU::UnitPower::Micro ); + cdebug_log(149,0) << "Min length: " << DbU::getValueString(minLength) << " ." << endl; + + if ((getSpanLength() >= minLength) or isReduced()) { + cdebug_log(149,-1) << "False, has length or is reduced." << endl; + DebugSession::close(); + return false; + } + if (isDrag()) { + for ( AutoSegment* perpandicular : getPerpandiculars() ) { + if (perpandicular->getSpanLength() > minLength) { + cdebug_log(149,-1) << "False (drag), has length or PP has length." << endl; + DebugSession::close(); + return false; + } + } + } else { + if ( ((_flags & (SegSourceBottom|SegTargetTop)) != (SegSourceBottom|SegTargetTop)) + and ((_flags & (SegTargetBottom|SegSourceTop)) != (SegTargetBottom|SegSourceTop)) ) { + cdebug_log(149,-1) << "False, not part of a stacked VIA." << endl; + DebugSession::close(); + return false; + } + } DbU::Unit side = DbU::fromPhysical( std::sqrt(minArea) , DbU::UnitPower::Micro ); setWidth( side ); setDuSource( -side/2 ); setDuTarget( side/2 ); + + cdebug_log(149,-1) << "True, add area." << endl; + DebugSession::close(); return true; } @@ -2587,9 +2621,10 @@ namespace Anabatic { segment->_postCreate(); } else if (vertical) { if (vertical->getLayer() != verticalLayer) { - if (Session::getAnabatic()->getConfiguration()->isGMetal(vertical->getLayer()) ) - vertical->setLayer( verticalLayer ); - vertical->setWidth( verticalWidth ); + if (Session::getAnabatic()->getConfiguration()->isGMetal(vertical->getLayer()) ) { + vertical->setLayer( verticalLayer ); + vertical->setWidth( verticalWidth ); + } } else { if (vertical->getWidth() != verticalWidth) { cerr << Warning("Segment %s has non-default width %s." @@ -2630,14 +2665,16 @@ namespace Anabatic { if (dir & Flags::UseNonPref) { if (dir & Flags::Vertical) { - cdebug_log(149,0) << "Make vertical in non-preferred direction." << endl; vLayer = hLayer; - vWidth = hWidth; + vWidth = Session::getDPHorizontalWidth(); + cdebug_log(149,0) << "Make vertical in non-preferred direction (ppW:" + << DbU::getValueString(vWidth).c_str() << ")." << endl; } if (dir & Flags::Horizontal) { - cdebug_log(149,0) << "Make horizontal in non-preferred direction." << endl; hLayer = vLayer; - hWidth = vWidth; + hWidth = Session::getDPVerticalWidth(); + cdebug_log(149,0) << "Make horizontal in non-preferred direction (ppW:" + << DbU::getValueString(hWidth).c_str() << ")." << endl; } } @@ -2645,12 +2682,14 @@ namespace Anabatic { DbU::Unit horizontalWidth = hWidth; const Layer* verticalLayer = vLayer; DbU::Unit verticalWidth = vWidth; + cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl; uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() ); if (wPitch > 1) { horizontalWidth = (wPitch-1) * Session::getDHorizontalPitch() + hWidth; verticalWidth = (wPitch-1) * Session::getDVerticalPitch () + vWidth; } + cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl; if (depth != RoutingGauge::nlayerdepth) { horizontalLayer = verticalLayer = Session::getRoutingLayer( depth ); @@ -2659,9 +2698,23 @@ namespace Anabatic { horizontalWidth = verticalWidth = (wPitch-1) * Session::getPitch (depth) + Session::getWireWidth(depth); } else { - horizontalWidth = verticalWidth = Session::getWireWidth( depth ); + if (dir & Flags::Horizontal) { + horizontalWidth = Session::getWireWidth ( depth ); + verticalWidth = Session::getPWireWidth( depth ); + } else { + verticalWidth = Session::getWireWidth ( depth ); + horizontalWidth = Session::getPWireWidth( depth ); + } + cdebug_log(149,0) << "hW:" << DbU::getValueString(horizontalWidth).c_str() + << "vW:" << DbU::getValueString( verticalWidth).c_str() + << endl; + if (dir & Flags::UseNonPref) { + cdebug_log(149,0) << "swap H/W width." << endl; + std::swap( horizontalWidth, verticalWidth ); + } } } + cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl; AutoSegment* segment; AutoContact* reference = source; diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 76bfe9e5..21d85d48 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -288,6 +288,10 @@ namespace Anabatic { { return getWireWidth( getLayerDepth(layer) ); } + DbU::Unit Configuration::getPWireWidth ( const Layer* layer ) const + { return getPWireWidth( getLayerDepth(layer) ); } + + Flags Configuration::getDirection ( const Layer* layer ) const { return getDirection( getLayerDepth(layer) ); } @@ -339,6 +343,9 @@ namespace Anabatic { { return _rg->getLayerWireWidth(depth); } + DbU::Unit Configuration::getPWireWidth ( size_t depth ) const + { return _rg->getLayerPWireWidth(depth); } + DbU::Unit Configuration::getExtensionCap ( size_t depth ) const { return _extensionCaps[depth]; } diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index da12c1d2..9e7af137 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -121,6 +121,7 @@ namespace Anabatic { const BaseFlags Flags::NorthPath = (1L << 33); const BaseFlags Flags::UseNonPref = (1L << 34); const BaseFlags Flags::Force = (1L << 35); + const BaseFlags Flags::LayerCapOnly = (1L << 36); Flags::~Flags () diff --git a/anabatic/src/PreRouteds.cpp b/anabatic/src/PreRouteds.cpp index 25393b17..5ad99896 100644 --- a/anabatic/src/PreRouteds.cpp +++ b/anabatic/src/PreRouteds.cpp @@ -100,12 +100,16 @@ namespace Anabatic { continue; if ( not Session::isGaugeLayer(component->getLayer()) - and not Session::isGLayer (component->getLayer())) + and not Session::isGLayer (component->getLayer())) { + const BasicLayer* basicLayer = dynamic_cast( component->getLayer() ); + if (basicLayer and (basicLayer->getMaterial() == BasicLayer::Material::cut)) + continue; throw Error( "AnabaticEngine::setupPreRouted(): A component of \"%s\" has a routing gauge umanaged layer.\n" " (%s)" , getString(net->getName()).c_str() , getString(component).c_str() ); + } Horizontal* horizontal = dynamic_cast(component); if (horizontal) { diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index df93d797..0f133d08 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -171,6 +171,7 @@ namespace Anabatic { inline DbU::Unit getWidth () const; inline DbU::Unit getContactWidth () const; inline DbU::Unit getLength () const; + inline DbU::Unit getSpanLength () const; inline DbU::Unit getSourcePosition () const; inline DbU::Unit getTargetPosition () const; inline DbU::Unit getSourceX () const; @@ -574,6 +575,10 @@ namespace Anabatic { inline DbU::Unit AutoSegment::getContactWidth () const { return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); } + inline DbU::Unit AutoSegment::getSpanLength () const + { return getLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly ) + + getExtensionCap( Flags::Target|Flags::LayerCapOnly ); + } inline void AutoSegment::setParent ( AutoSegment* parent ) { diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index 9c440dc4..32bfbc5b 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -80,11 +80,13 @@ namespace Anabatic { inline size_t getDVerticalDepth () const; inline const Layer* getDVerticalLayer () const; inline DbU::Unit getDVerticalWidth () const; + inline DbU::Unit getDPVerticalWidth () const; inline DbU::Unit getDVerticalPitch () const; inline DbU::Unit getDVerticalOffset () const; inline size_t getDHorizontalDepth () const; inline const Layer* getDHorizontalLayer () const; inline DbU::Unit getDHorizontalWidth () const; + inline DbU::Unit getDPHorizontalWidth () const; inline DbU::Unit getDHorizontalPitch () const; inline DbU::Unit getDHorizontalOffset () const; inline size_t getDContactDepth () const; @@ -104,11 +106,13 @@ namespace Anabatic { DbU::Unit getPitch ( size_t depth, Flags flags ) const; DbU::Unit getOffset ( size_t depth ) const; DbU::Unit getWireWidth ( size_t depth ) const; + DbU::Unit getPWireWidth ( size_t depth ) const; DbU::Unit getExtensionCap ( size_t depth ) const; Flags getDirection ( size_t depth ) const; DbU::Unit getPitch ( const Layer*, Flags flags ) const; DbU::Unit getOffset ( const Layer* ) const; DbU::Unit getWireWidth ( const Layer* ) const; + DbU::Unit getPWireWidth ( const Layer* ) const; DbU::Unit getExtensionCap ( const Layer* ) const; Flags getDirection ( const Layer* ) const; float getSaturateRatio () const; @@ -169,11 +173,13 @@ namespace Anabatic { inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; } inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); } inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); } + inline DbU::Unit Configuration::getDPVerticalWidth () const { return getPWireWidth ( getDVerticalDepth() ); } inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); } inline DbU::Unit Configuration::getDVerticalOffset () const { return getOffset ( getDVerticalDepth() ); } inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; } inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); } inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); } + inline DbU::Unit Configuration::getDPHorizontalWidth () const { return getPWireWidth ( getDHorizontalDepth() ); } inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); } inline DbU::Unit Configuration::getDHorizontalOffset () const { return getOffset ( getDHorizontalDepth() ); } inline size_t Configuration::getDContactDepth () const { return _ddepthc; } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index fe75946e..35e631fe 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -102,6 +102,7 @@ namespace Anabatic { static const BaseFlags NorthPath ; static const BaseFlags UseNonPref ; static const BaseFlags Force ; + static const BaseFlags LayerCapOnly ; public: inline Flags ( uint64_t flags = NoFlags ); inline Flags ( const Hurricane::BaseFlags& ); diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index a0bcacd8..e031d39a 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -97,11 +97,13 @@ namespace Anabatic { static inline size_t getDVerticalDepth (); static inline const Layer* getDVerticalLayer (); static inline DbU::Unit getDVerticalWidth (); + static inline DbU::Unit getDPVerticalWidth (); static inline DbU::Unit getDVerticalPitch (); static inline DbU::Unit getDVerticalOffset (); static inline size_t getDHorizontalDepth (); static inline const Layer* getDHorizontalLayer (); static inline DbU::Unit getDHorizontalWidth (); + static inline DbU::Unit getDPHorizontalWidth (); static inline DbU::Unit getDHorizontalPitch (); static inline DbU::Unit getDHorizontalOffset (); static inline size_t getDContactDepth (); @@ -123,6 +125,7 @@ namespace Anabatic { static inline DbU::Unit getPitch ( size_t depth, Flags flags ); static inline DbU::Unit getOffset ( size_t depth ); static inline DbU::Unit getWireWidth ( size_t depth ); + static inline DbU::Unit getPWireWidth ( size_t depth ); static inline DbU::Unit getViaWidth ( size_t depth ); static inline Flags getDirection ( const Layer* ); static inline DbU::Unit getPitch ( const Layer*, Flags flags ); @@ -239,11 +242,13 @@ namespace Anabatic { inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); } inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); } inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); } + inline DbU::Unit Session::getDPVerticalWidth () { return getConfiguration()->getDPVerticalWidth(); } inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); } inline DbU::Unit Session::getDVerticalOffset () { return getConfiguration()->getDVerticalOffset(); } inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); } inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); } inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); } + inline DbU::Unit Session::getDPHorizontalWidth () { return getConfiguration()->getDPHorizontalWidth(); } inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); } inline DbU::Unit Session::getDHorizontalOffset () { return getConfiguration()->getDHorizontalOffset(); } inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); } @@ -263,6 +268,7 @@ namespace Anabatic { inline DbU::Unit Session::getPitch ( size_t depth, Flags flags=Flags::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); } inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); } inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); } + inline DbU::Unit Session::getPWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerPWireWidth(depth); } inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); } inline DbU::Unit Session::getPitch ( const Layer* layer, Flags flags=Flags::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); } inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); } diff --git a/crlcore/etc/symbolic/cmos/kite.py b/crlcore/etc/symbolic/cmos/kite.py index d7109ed9..9530e586 100644 --- a/crlcore/etc/symbolic/cmos/kite.py +++ b/crlcore/etc/symbolic/cmos/kite.py @@ -88,6 +88,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA12). , l(4) # obstacle dW. ) ) @@ -100,6 +101,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA23). , l(4) # obstacle dW. ) ) @@ -112,6 +114,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA34). , l(4) # obstacle dW. ) ) @@ -124,6 +127,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA23). , l(4) # obstacle dW. ) ) @@ -136,6 +140,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA23). , l(4) # obstacle dW. ) ) @@ -152,6 +157,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA12). , l(4) # obstacle dW. ) ) @@ -164,6 +170,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(5) # track pitch. , l(2) # wire width. + , 0 # perpandicular wire width. , l(1) # VIA side (that is VIA23). , l(4) # obstacle dW. ) ) diff --git a/crlcore/etc/symbolic/cmos45/kite.py b/crlcore/etc/symbolic/cmos45/kite.py index 1e622c7b..f1f1c6e9 100644 --- a/crlcore/etc/symbolic/cmos45/kite.py +++ b/crlcore/etc/symbolic/cmos45/kite.py @@ -91,6 +91,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -103,6 +104,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -115,6 +117,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA34). , l(8) # obstacle dW. ) ) @@ -127,6 +130,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -139,6 +143,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -151,6 +156,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL6') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -166,6 +172,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -178,6 +185,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -190,6 +198,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA34). , l(8) # obstacle dW. ) ) @@ -202,6 +211,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta , l(0) # track offset from AB. , l(15) # track pitch. , l(6) # wire width. + , 0 # perpandicular wire width. , l(4) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -214,6 +224,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta , l(0) # track offset from AB. , l(15) # track pitch. , l(6) # wire width. + , 0 # perpandicular wire width. , l(4) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -226,6 +237,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL6') # meta , l(0) # track offset from AB. , l(15) # track pitch. , l(6) # wire width. + , 0 # perpandicular wire width. , l(4) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -242,6 +254,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -254,6 +267,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -266,6 +280,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta , l(0) # track offset from AB. , l(8) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA12). , l(8) # obstacle dW. ) ) @@ -278,6 +293,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(2) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) @@ -294,6 +310,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(3) # VIA side (that is VIA12). , l(7) # obstacle dW. ) ) @@ -306,6 +323,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta , l(0) # track offset from AB. , l(10) # track pitch. , l(3) # wire width. + , 0 # perpandicular wire width. , l(3) # VIA side (that is VIA23). , l(8) # obstacle dW. ) ) diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index b5e94849..17f97d15 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -72,7 +72,7 @@ namespace CRL { , _isSymbolic (gauge._isSymbolic) { // Make a deep copy of the map. - for ( size_t i=0 ; igetLayer() , gauge._layerGauges[i]->getDirection() @@ -82,9 +82,11 @@ namespace CRL { , gauge._layerGauges[i]->getOffset() , gauge._layerGauges[i]->getPitch() , gauge._layerGauges[i]->getWireWidth() + , gauge._layerGauges[i]->getPWireWidth() , gauge._layerGauges[i]->getViaWidth() , gauge._layerGauges[i]->getObstacleDw() ) ); + } } @@ -228,6 +230,13 @@ namespace CRL { } + DbU::Unit RoutingGauge::getPWireWidth ( const Layer* layer ) const + { + size_t depth = getLayerDepth( layer ); + return (depth != nlayerdepth) ? _layerGauges[depth]->getPWireWidth() : 0; + } + + DbU::Unit RoutingGauge::getViaWidth ( const Layer* layer ) const { size_t depth = getLayerDepth( layer ); diff --git a/crlcore/src/ccore/RoutingLayerGauge.cpp b/crlcore/src/ccore/RoutingLayerGauge.cpp index ed72065d..95bc2bb5 100644 --- a/crlcore/src/ccore/RoutingLayerGauge.cpp +++ b/crlcore/src/ccore/RoutingLayerGauge.cpp @@ -106,6 +106,7 @@ namespace CRL { , DbU::Unit offset , DbU::Unit pitch , DbU::Unit wireWidth + , DbU::Unit pwireWidth , DbU::Unit viaWidth , DbU::Unit obsDw ) : _layer (layer) @@ -117,6 +118,7 @@ namespace CRL { , _offset (offset) , _pitch (pitch) , _wireWidth (wireWidth) + , _pwireWidth (pwireWidth) , _viaWidth (viaWidth) , _obstacleDw (obsDw) { } @@ -130,6 +132,7 @@ namespace CRL { , DbU::Unit offset , DbU::Unit pitch , DbU::Unit wireWidth + , DbU::Unit pwireWidth , DbU::Unit viaWidth , DbU::Unit obsDw ) { @@ -149,6 +152,7 @@ namespace CRL { , offset , pitch , wireWidth + , pwireWidth , viaWidth , obsDw ); @@ -327,6 +331,7 @@ namespace CRL { jsonWrite( w, "_offset" , _offset ); jsonWrite( w, "_pitch" , _pitch ); jsonWrite( w, "_wireWidth" , _wireWidth ); + jsonWrite( w, "_pwireWidth" , _pwireWidth ); jsonWrite( w, "_viaWidth" , _viaWidth ); jsonWrite( w, "_obstacleDw" , _obstacleDw ); w->endObject(); @@ -381,8 +386,9 @@ namespace CRL { DbU::Unit offset = get ( stack, "_offset" ); DbU::Unit pitch = get ( stack, "_pitch" ); DbU::Unit wireWidth = get ( stack, "_wireWidth" ); + DbU::Unit pwireWidth = get ( stack, "_pwireWidth" ); DbU::Unit viaWidth = get ( stack, "_viaWidth" ); - DbU::Unit obstacleDw = get ( stack, "_obstacleDw" ); + DbU::Unit obstacleDw = get ( stack, "_obstacleDw" ); Constant::Direction direction; Constant::LayerGaugeType type; @@ -400,6 +406,7 @@ namespace CRL { , offset , pitch , wireWidth + , pwireWidth , viaWidth , obstacleDw ); diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index b7047411..9cbe42ef 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -76,6 +76,7 @@ namespace CRL { DbU::Unit getPitch ( const Layer* ) const; DbU::Unit getOffset ( const Layer* ) const; DbU::Unit getWireWidth ( const Layer* ) const; + DbU::Unit getPWireWidth ( const Layer* ) const; DbU::Unit getViaWidth ( const Layer* ) const; RoutingLayerGauge* getLayerGauge ( size_t depth ) const; inline unsigned int getLayerDirection ( size_t depth ) const; @@ -83,6 +84,7 @@ namespace CRL { inline DbU::Unit getLayerPitch ( size_t depth ) const; inline DbU::Unit getLayerOffset ( size_t depth ) const; inline DbU::Unit getLayerWireWidth ( size_t depth ) const; + inline DbU::Unit getLayerPWireWidth ( size_t depth ) const; inline DbU::Unit getViaWidth ( size_t depth ) const; const Layer* getRoutingLayer ( size_t depth ) const; Layer* getContactLayer ( size_t depth ) const; @@ -129,6 +131,7 @@ namespace CRL { inline DbU::Unit RoutingGauge::getLayerPitch ( size_t depth ) const { return getLayerGauge(depth)->getPitch(); } inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); } inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); } + inline DbU::Unit RoutingGauge::getLayerPWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getPWireWidth(); } inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); } inline void RoutingGauge::setSymbolic ( bool state ) { _isSymbolic=state; } diff --git a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h index 73ad6207..b58bf6e8 100644 --- a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h @@ -86,6 +86,7 @@ namespace CRL { , DbU::Unit offset , DbU::Unit pitch , DbU::Unit wireWidth + , DbU::Unit pwireWidth , DbU::Unit viaWidth , DbU::Unit obsDw ); virtual void destroy (); @@ -102,6 +103,7 @@ namespace CRL { inline DbU::Unit getPitch () const; inline DbU::Unit getHalfPitch () const; inline DbU::Unit getWireWidth () const; + inline DbU::Unit getPWireWidth () const; inline DbU::Unit getHalfWireWidth () const; inline DbU::Unit getViaWidth () const; inline DbU::Unit getHalfViaWidth () const; @@ -111,6 +113,7 @@ namespace CRL { long getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const; inline DbU::Unit getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const; DbU::Unit getTrackPosition ( DbU::Unit start, long index ) const; + inline void setPWireWidth ( DbU::Unit ); // Hurricane Managment. void toJson ( JsonWriter* ) const; virtual string _getTypeName () const; @@ -128,6 +131,7 @@ namespace CRL { DbU::Unit _offset; DbU::Unit _pitch; DbU::Unit _wireWidth; + DbU::Unit _pwireWidth; DbU::Unit _viaWidth; DbU::Unit _obstacleDw; @@ -140,11 +144,13 @@ namespace CRL { , DbU::Unit offset , DbU::Unit pitch , DbU::Unit wireWidth + , DbU::Unit pwireWidth , DbU::Unit viaWidth , DbU::Unit obsDw ); + RoutingLayerGauge ( const RoutingLayerGauge& ) = delete; virtual ~RoutingLayerGauge (); virtual void _preDestroy(); - RoutingLayerGauge& operator= ( const RoutingLayerGauge& ); + RoutingLayerGauge& operator= ( const RoutingLayerGauge& ) = delete; // Friends. friend class RoutingGauge; @@ -178,12 +184,14 @@ namespace CRL { inline DbU::Unit RoutingLayerGauge::getPitch () const { return _pitch; } inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return _pitch>>1; } inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return _wireWidth; } + inline DbU::Unit RoutingLayerGauge::getPWireWidth () const { return (_pwireWidth) ? _pwireWidth : _wireWidth; } inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return _wireWidth>>1; } inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return _viaWidth; } inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return _viaWidth>>1; } inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return _obstacleDw; } inline DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const { return getTrackPosition( start, getTrackIndex(start,stop,position,mode) ); } + inline void RoutingLayerGauge::setPWireWidth ( DbU::Unit pwidth ) { _pwireWidth = pwidth; } // ------------------------------------------------------------------- diff --git a/crlcore/src/pyCRL/PyRoutingGauge.cpp b/crlcore/src/pyCRL/PyRoutingGauge.cpp index cd7e4f35..a1bd4761 100644 --- a/crlcore/src/pyCRL/PyRoutingGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingGauge.cpp @@ -252,6 +252,30 @@ extern "C" { } + static PyObject* PyRoutingGauge_getPWireWidth ( PyRoutingGauge* self, PyObject* args ) + { + cdebug_log(30,0) << "PyRoutingGauge_getPWireWidth()" << endl; + + DbU::Unit wireWidth = 0; + HTRY + METHOD_HEAD("RoutingGauge.getPWireWidth()") + PyObject* pyLayer = NULL; + + if (PyArg_ParseTuple( args, "O:RoutingGauge.getPWireWidth", &pyLayer)) { + if ( not PyObject_IsInstance(pyLayer,(PyObject*)&PyTypeLayer) ) { + PyErr_SetString ( ConstructorError, "Bad type for layer argument of RoutingGauge.getPWireWidth()." ); + return NULL; + } + wireWidth = rg->getPWireWidth( PYLAYER_O(pyLayer) ); + } else { + PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingGauge.getPWireWidth()." ); + return NULL; + } + HCATCH + return Py_BuildValue("I",wireWidth); + } + + static PyObject* PyRoutingGauge_getViaWidth ( PyRoutingGauge* self, PyObject* args ) { cdebug_log(30,0) << "PyRoutingGauge_getViaWidth()" << endl; diff --git a/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp b/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp index 9f5ef06e..190dc3a7 100644 --- a/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp @@ -74,14 +74,15 @@ extern "C" { int type; int depth; double density; - PyObject* pyOffset = NULL; - PyObject* pyPitch = NULL; - PyObject* pyWireWidth = NULL; - PyObject* pyViaWidth = NULL; - PyObject* pyObsDw = NULL; + PyObject* pyOffset = NULL; + PyObject* pyPitch = NULL; + PyObject* pyWireWidth = NULL; + PyObject* pyPWireWidth = NULL; + PyObject* pyViaWidth = NULL; + PyObject* pyObsDw = NULL; if (PyArg_ParseTuple( args - , "OIIIdOOOOO:RoutingLayerGauge.create" + , "OIIIdOOOOOO:RoutingLayerGauge.create" , &pyLayer , &direction , &type @@ -90,6 +91,7 @@ extern "C" { , &pyOffset , &pyPitch , &pyWireWidth + , &pyPWireWidth , &pyViaWidth , &pyObsDw )) { @@ -120,6 +122,7 @@ extern "C" { , PyAny_AsLong(pyOffset) , PyAny_AsLong(pyPitch) , PyAny_AsLong(pyWireWidth) + , PyAny_AsLong(pyPWireWidth) , PyAny_AsLong(pyViaWidth) , PyAny_AsLong(pyObsDw) ); @@ -265,10 +268,12 @@ extern "C" { DirectGetLongAttribute (PyRoutingLayerGauge_getPitch ,getPitch ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getHalfPitch ,getHalfPitch ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getWireWidth ,getWireWidth ,PyRoutingLayerGauge,RoutingLayerGauge) + DirectGetLongAttribute (PyRoutingLayerGauge_getPWireWidth ,getPWireWidth ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getHalfWireWidth,getHalfWireWidth,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getViaWidth ,getViaWidth ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getHalfViaWidth ,getHalfViaWidth ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getObstacleDw ,getObstacleDw ,PyRoutingLayerGauge,RoutingLayerGauge) + DirectSetLongAttribute (PyRoutingLayerGauge_setPWireWidth ,setPWireWidth ,PyRoutingLayerGauge,RoutingLayerGauge) // Standart Destroy (Attribute). @@ -297,6 +302,8 @@ extern "C" { , "Returns the half track pitch (center to center)." } , { "getWireWidth" , (PyCFunction)PyRoutingLayerGauge_getWireWidth , METH_NOARGS , "Returns the wire width." } + , { "getPWireWidth" , (PyCFunction)PyRoutingLayerGauge_getPWireWidth , METH_NOARGS + , "Returns the perpandicular wire width (same layer)." } , { "getHalfWireWidth" , (PyCFunction)PyRoutingLayerGauge_getHalfWireWidth, METH_NOARGS , "Returns the half wire width." } , { "getViaWidth" , (PyCFunction)PyRoutingLayerGauge_getViaWidth , METH_NOARGS @@ -311,6 +318,8 @@ extern "C" { , "Returns the index of track at the given position (with rounding)." } , { "getTrackPosition" , (PyCFunction)PyRoutingLayerGauge_getTrackPosition, METH_VARARGS , "Compute the position of track number ." } + , { "setPWireWidth" , (PyCFunction)PyRoutingLayerGauge_setPWireWidth , METH_VARARGS + , "Sets the perpandicular wire width (same layer)." } //, { "destroy" , (PyCFunction)PyRoutingLayerGauge_destroy , METH_VARARGS // , "Destroy the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/cumulus/src/plugins/alpha/block/bigvia.py b/cumulus/src/plugins/alpha/block/bigvia.py index 52ca0e8d..738b92e2 100644 --- a/cumulus/src/plugins/alpha/block/bigvia.py +++ b/cumulus/src/plugins/alpha/block/bigvia.py @@ -70,9 +70,14 @@ class BigVia ( object ): global rg if rg is None: rg = CRL.AllianceFramework.get().getRoutingGauge() for depth in range(self.bottomDepth,self.topDepth+1): - print( 'Create plate @{} {} {}'.format(DbU.getValueString(self.x) - ,DbU.getValueString(self.y) - ,rg.getRoutingLayer(depth)) ) + minArea = rg.getRoutingLayer( depth ).getMinimalArea() + minLength = DbU.fromPhysical( minArea / DbU.toPhysical( self.width, DbU.UnitPowerMicro ) + , DbU.UnitPowerMicro ) + #minLength = toFoundryGrid( minLength, DbU.SnapModeSuperior ) + plateArea = DbU.toPhysical( self.width , DbU.UnitPowerMicro ) \ + * DbU.toPhysical( self.height, DbU.UnitPowerMicro ) + if plateArea < minArea: + print( WarningMessage( 'BigVia::doLayout(): Area too small for {}'.format(self.net) )) self.plates[ depth ] = Contact.create( self.net , rg.getRoutingLayer(depth) , self.x , self.y @@ -115,9 +120,6 @@ class BigVia ( object ): x = cutArea.getXMin() self.vias[ depth ].append( [] ) while x <= cutArea.getXMax(): - print( 'Create cut @{} {} {}'.format(DbU.getValueString(x) - ,DbU.getValueString(y) - ,cutLayer) ) cut = Contact.create( self.net, cutLayer, x, y, cutSide, cutSide ) self.vias[ depth ][ -1 ].append( cut ) x += cutSide + cutSpacing diff --git a/cumulus/src/plugins/alpha/block/block.py b/cumulus/src/plugins/alpha/block/block.py index 4adcd5cd..fcad4051 100644 --- a/cumulus/src/plugins/alpha/block/block.py +++ b/cumulus/src/plugins/alpha/block/block.py @@ -376,6 +376,8 @@ class Block ( object ): trace( 550, '\tCORE AB is {}\n'.format(self.conf.cell.getAbutmentBox()) ) if self.conf.isCoreBlock: self.conf.setupICore() + else: + self.conf.setRoutingBb( self.conf.cell.getAbutmentBox() ) def addClockTrees ( self ): """Create the trunk of all the clock trees (recursive H-Tree).""" diff --git a/cumulus/src/plugins/alpha/block/clocktree.py b/cumulus/src/plugins/alpha/block/clocktree.py index c693dfbd..6b93c18e 100644 --- a/cumulus/src/plugins/alpha/block/clocktree.py +++ b/cumulus/src/plugins/alpha/block/clocktree.py @@ -97,11 +97,13 @@ class ClockTree ( object ): if qt.isLeaf(): trace( 550, '-' ) return False - gaugeConf = self.spares.conf bufferConf = self.spares.conf.bufferConf ckNet = qt.bOutputPlug.getNet() self.subNets.append( ckNet ) + hLeafDepth = gaugeConf.horizontalDepth + if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth): + hLeafDepth = gaugeConf.horizontalDepth - 2 leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer , bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer , bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffer, bufferConf.input , ckNet ) @@ -110,14 +112,17 @@ class ClockTree ( object ): trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffer, bufferConf.input , ckNet ) leftContact = gaugeConf.createContact( ckNet, blContact.getX(), leftSourceContact.getY(), 0 ) rightContact = gaugeConf.createContact( ckNet, brContact.getX(), rightSourceContact.getY(), 0 ) - leftSourceX = gaugeConf.getNearestVerticalTrack ( qt.root.area, leftSourceContact.getX(), 0 ) - leftSourceY = gaugeConf.getNearestHorizontalTrack( qt.root.area, leftSourceContact.getY(), 0 ) - rightSourceX = gaugeConf.getNearestVerticalTrack ( qt.root.area, rightSourceContact.getX(), 0 ) - rightSourceY = gaugeConf.getNearestHorizontalTrack( qt.root.area, rightSourceContact.getY(), 0 ) - leftX = gaugeConf.getNearestVerticalTrack ( qt.root.area, leftContact.getX(), 0 ) - rightX = gaugeConf.getNearestVerticalTrack ( qt.root.area, rightContact.getX(), 0 ) - tlY = gaugeConf.getNearestHorizontalTrack( qt.root.area, tlContact.getY(), 0 ) - blY = gaugeConf.getNearestHorizontalTrack( qt.root.area, blContact.getY(), 0 ) + leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0 ) + leftSourceY = gaugeConf.getNearestHorizontalTrack( leftSourceContact.getY(), 0 ) + rightSourceX = gaugeConf.getNearestVerticalTrack ( rightSourceContact.getX(), 0 ) + rightSourceY = gaugeConf.getNearestHorizontalTrack( rightSourceContact.getY(), 0 ) + leftX = gaugeConf.getNearestVerticalTrack ( leftContact.getX(), 0 ) + rightX = gaugeConf.getNearestVerticalTrack ( rightContact.getX(), 0 ) + tlY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, 0 ) + blY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, 0 ) + #tlY = gaugeConf.getNearestHorizontalTrack( tlContact.getY(), 0 ) + #blY = gaugeConf.getNearestHorizontalTrack( blContact.getY(), 0 ) + trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) )) gaugeConf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY ) gaugeConf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY ) gaugeConf.setStackPosition( tlContact, leftX, tlY ) diff --git a/cumulus/src/plugins/alpha/block/configuration.py b/cumulus/src/plugins/alpha/block/configuration.py index 2e017a83..dce9e6a9 100644 --- a/cumulus/src/plugins/alpha/block/configuration.py +++ b/cumulus/src/plugins/alpha/block/configuration.py @@ -59,6 +59,12 @@ def findCellOutput ( cell, callerName, parameterId ): , ' please check that the Nets directions are set.' ] ) +def toFoundryGrid ( u, mode ): + """Snap the DbU ``u`` to the foundry grid, according to ``mode``.""" + oneGrid = DbU.fromGrid( 1.0 ) + return DbU.getOnCustomGrid( u, oneGrid, mode ) + + # ---------------------------------------------------------------------------- # Class : "configuration.GaugeConf". @@ -87,6 +93,7 @@ class GaugeConf ( object ): self._plugToRp = { } self._rpToAccess = { } self._loadRoutingGauge() + self._routingBb = Box() return @property @@ -122,8 +129,15 @@ class GaugeConf ( object ): @property def vDeepRG ( self ): return self._routingGauge.getLayerGauge( self.verticalDeepDepth ) + @property + def routingBb ( self ): return self._routingBb + def getPitch ( self, layer ): return self._routingGauge.getPitch( layer ) + def setRoutingBb ( self, bb ): + trace( 550, '\tGaugeConf.setRoutingBb(): {}\n'.format(bb) ) + self._routingBb = bb + def _loadRoutingGauge ( self ): trace( 550, ',+', '\tGaugeConf._loadRoutingGauge()\n' ) gaugeName = Cfg.getParamString('anabatic.routingGauge').asString() @@ -206,25 +220,34 @@ class GaugeConf ( object ): , self._routingGauge.getLayerGauge(depth).getViaWidth() ) - def getNearestHorizontalTrack ( self, bb, y, flags ): + def getTrack ( self, u, depth, offset ): + """ + Returns the y/x axis position of the H/V track nearest to ``u`` (y/x) + with an offset of ``offset`` tracks applied. + """ + trace( 550, '\tGaugeConf.getTrack(): u={}, depth={}, offset={}' \ + .format( DbU.getValueString(u), depth, offset )) + rg = self._routingGauge.getLayerGauge( depth ) + if rg.getDirection() == RoutingLayerGauge.Horizontal: + bbMin = self.routingBb.getYMin() + bbMax = self.routingBb.getYMax() + else: + bbMin = self.routingBb.getXMin() + bbMax = self.routingBb.getXMax() + index = rg.getTrackIndex( bbMin, bbMax, u, RoutingLayerGauge.Nearest ) + utrack = rg.getTrackPosition( bbMin, index ) + trace( 550, ' -> utrack={}\n'.format( DbU.getValueString(utrack) )) + return utrack + offset*rg.getPitch() + + def getNearestHorizontalTrack ( self, y, flags ): if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth else: depth = self.horizontalDepth - - index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getYMin() - , bb.getYMax() - , y - , RoutingLayerGauge.Nearest ) - return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getYMin(), index ) + return self.getTrack( y, depth, 0 ) - def getNearestVerticalTrack ( self, bb, x, flags ): + def getNearestVerticalTrack ( self, x, flags ): if flags & GaugeConf.DeepDepth: depth = self.verticalDeepDepth else: depth = self.verticalDepth - - index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getXMin() - , bb.getXMax() - , x - , RoutingLayerGauge.Nearest ) - return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getXMin(), index ) + return self.getTrack( x, depth, 0 ) def createHorizontal ( self, source, target, y, flags ): if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth @@ -273,17 +296,27 @@ class GaugeConf ( object ): else: hdepth = self.horizontalDepth vdepth = self.verticalDepth - - hpitch = self._routingGauge.getLayerGauge(hdepth).getPitch() - hoffset = self._routingGauge.getLayerGauge(hdepth).getOffset() + + #hpitch = self._routingGauge.getLayerGauge(hdepth).getPitch() + #hoffset = self._routingGauge.getLayerGauge(hdepth).getOffset() + #contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 ) + #midSliceY = contact1.getY() - (contact1.getY() % self._cellGauge.getSliceHeight()) \ + # + self._cellGauge.getSliceHeight() / 2 + #midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch) + #dy = midSliceY - contact1.getY() + # + #if flags & GaugeConf.OffsetBottom1: dy += hpitch + #if flags & GaugeConf.OffsetTop1: dy -= hpitch + #contact1.setDy( dy ) + + yoffset = 0 + if flags & GaugeConf.OffsetBottom1: yoffset = 1 + if flags & GaugeConf.OffsetTop1: yoffset = -1 contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 ) midSliceY = contact1.getY() - (contact1.getY() % self._cellGauge.getSliceHeight()) \ + self._cellGauge.getSliceHeight() / 2 - midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch) - dy = midSliceY - contact1.getY() - - if flags & GaugeConf.OffsetBottom1: dy += hpitch - if flags & GaugeConf.OffsetTop1: dy -= hpitch + ytrack = self.getTrack( contact1.getY(), self.horizontalDeepDepth, yoffset ) + dy = ytrack - contact1.getY() contact1.setDy( dy ) trace( 550, contact1 ) @@ -293,13 +326,20 @@ class GaugeConf ( object ): trace( 550, '\tstopDepth:%d\n' % stopDepth ) for depth in range(1,stopDepth): + rg = self._routingGauge.getLayerGauge(depth) xoffset = 0 if flags & GaugeConf.OffsetRight1 and depth == 1: - xoffset = self._routingGauge.getLayerGauge(depth+1).getPitch() + xoffset = 1 + if rg.getDirection() == RoutingLayerGauge.Horizontal: + xtrack = self.getTrack( contact1.getX(), depth+1, xoffset ) + ytrack = self.getTrack( contact1.getY(), depth , 0 ) + else: + xtrack = self.getTrack( contact1.getX(), depth , xoffset ) + ytrack = self.getTrack( contact1.getY(), depth+1, 0 ) contact2 = Contact.create( rp.getNet() , self._routingGauge.getContactLayer(depth) - , contact1.getX() + xoffset - , contact1.getY() + , xtrack + , ytrack , self._routingGauge.getLayerGauge(depth).getViaWidth() , self._routingGauge.getLayerGauge(depth).getViaWidth() ) @@ -307,17 +347,17 @@ class GaugeConf ( object ): if self._routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal: segment = Horizontal.create( contact1 , contact2 - , self._routingGauge.getRoutingLayer(depth) + , rg.getLayer() , contact1.getY() - , self._routingGauge.getLayerGauge(depth).getWireWidth() + , rg.getWireWidth() ) trace( 550, segment ) else: segment = Vertical.create( contact1 , contact2 - , self._routingGauge.getRoutingLayer(depth) + , rg.getLayer() , contact1.getX() - , self._routingGauge.getLayerGauge(depth).getWireWidth() + , rg.getWireWidth() ) trace( 550, segment ) contact1 = contact2 @@ -385,8 +425,55 @@ class GaugeConf ( object ): elif isinstance(segment,Vertical): segment.setX( x ) segment.getOppositeAnchor( topContact ).setX( x ) + self.expandMinArea( topContact ) return + def expandMinArea ( self, topContact ): + segments = [] + contacts = [ topContact ] + i = 0 + while i < len(contacts): + for component in contacts[i].getSlaveComponents(): + if not isinstance(component,Horizontal) and not isinstance(component,Vertical): + continue + if component not in segments: + segments.append( component ) + if component.getSource() not in contacts: + contacts.append( component.getSource() ) + if component.getTarget() not in contacts: + contacts.append( component.getTarget() ) + i += 1 + for segment in segments: + layer = segment.getLayer() + wireWidth = segment.getWidth() + depth = self._routingGauge.getLayerDepth( layer ) + minArea = self._routingGauge.getRoutingLayer( depth ).getMinimalArea() + extension = 0 + if minArea: + minLength = DbU.fromPhysical( minArea / DbU.toPhysical( wireWidth, DbU.UnitPowerMicro ) + , DbU.UnitPowerMicro ) + minLength = toFoundryGrid( minLength, DbU.SnapModeSuperior ); + if isinstance(segment,Horizontal): + uMin = segment.getSource().getX() + uMax = segment.getTarget().getX() + segLength = abs( uMax - uMin ) + if segLength < minLength: + extension = toFoundryGrid( (minLength - segLength)/2, DbU.SnapModeSuperior ) + if uMin > uMax: + extension = - extension + segment.setDxSource( -extension ) + segment.setDxTarget( extension ) + if isinstance(segment,Vertical): + uMin = segment.getSource().getY() + uMax = segment.getTarget().getY() + segLength = abs( uMax - uMin ) + if segLength < minLength: + extension = toFoundryGrid( (minLength - segLength)/2, DbU.SnapModeSuperior ) + if uMin > uMax: + extension = - extension + segment.setDySource( -extension ) + segment.setDyTarget( extension ) + # ------------------------------------------------------------------- # Class : "IoPadConf". @@ -1004,8 +1091,8 @@ class BlockConf ( GaugeConf ): @property def coreAb ( self ): if not hasattr(self,'coreSize'): return Box() - trace( 550, '\tcoreAb:[{} {}]\n'.format( DbU.getValueString(self.coreSize[0]) - , DbU.getValueString(self.coreSize[1]) )) + #trace( 550, '\tcoreAb:[{} {}]\n'.format( DbU.getValueString(self.coreSize[0]) + # , DbU.getValueString(self.coreSize[1]) )) return Box( 0, 0, self.coreSize[0], self.coreSize[1] ) @property diff --git a/cumulus/src/plugins/alpha/chip/chip.py b/cumulus/src/plugins/alpha/chip/chip.py index ed550947..0d1af207 100644 --- a/cumulus/src/plugins/alpha/chip/chip.py +++ b/cumulus/src/plugins/alpha/chip/chip.py @@ -105,7 +105,10 @@ class Chip ( Block ): self.conf.core.setAbutmentBox( self.conf.coreAb ) x = (coronaAb.getWidth () - self.conf.coreAb.getWidth ()) / 2 y = (coronaAb.getHeight() - self.conf.coreAb.getHeight()) / 2 + trace( 550, '\tCore X, {} '.format(DbU.getValueString(x)) ) x = x - (x % self.conf.sliceHeight) + trace( 550, ' adjusted on {}, {}\n'.format( DbU.getValueString(self.conf.sliceHeight) + , DbU.getValueString(x)) ) y = y - (y % self.conf.sliceHeight) self.conf.icore.setTransformation ( Transformation(x,y,Transformation.Orientation.ID) ) self.conf.icore.setPlacementStatus( Instance.PlacementStatus.FIXED ) diff --git a/cumulus/src/plugins/alpha/chip/configuration.py b/cumulus/src/plugins/alpha/chip/configuration.py index 0c43ec37..100aa8cd 100644 --- a/cumulus/src/plugins/alpha/chip/configuration.py +++ b/cumulus/src/plugins/alpha/chip/configuration.py @@ -190,8 +190,11 @@ class ChipConf ( BlockConf ): self.core.setAbutmentBox( Box( 0, 0, ab.getWidth(), ab.getHeight() ) ) trace( 550, '\tCORE ab:{}\n'.format(self.coreAb) ) coreX = (self.coronaAb.getWidth () - self.coreAb.getWidth ()) / 2 + trace( 550, '\tCore X, {} '.format(DbU.getValueString(coreX)) ) + coreX = coreX - (coreX % self.sliceHeight) + trace( 550, ' adjusted on {}, {}\n'.format( DbU.getValueString(self.sliceHeight) + , DbU.getValueString(coreX)) ) coreY = (self.coronaAb.getHeight() - self.coreAb.getHeight()) / 2 - coreX = coreX - (coreX % self.sliceStep) coreY = coreY - (coreY % self.sliceHeight) self.icore.setTransformation( Transformation( coreX, coreY, Transformation.Orientation.ID ) ) self.icore.setPlacementStatus( Instance.PlacementStatus.FIXED ) @@ -668,6 +671,7 @@ class ChipConf ( BlockConf ): , self.toSymbolic( self.ioPadHeight + ab.getYMin(), Superior ) , Transformation.Orientation.ID ) ) self.icorona.setPlacementStatus( Instance.PlacementStatus.FIXED ) + self.setRoutingBb( self.corona.getAbutmentBox() ) def setupCore ( self, gapX1, gapY1, gapX2, gapY2 ): trace( 550, ',+', '\tChipConf.setupCore()\n' ) diff --git a/cumulus/src/plugins/alpha/chip/corona.py b/cumulus/src/plugins/alpha/chip/corona.py index 7251f6ce..c86fc70a 100644 --- a/cumulus/src/plugins/alpha/chip/corona.py +++ b/cumulus/src/plugins/alpha/chip/corona.py @@ -115,6 +115,7 @@ class HorizontalRail ( Rail ): def connect ( self, contact ): trace( 550, ',+', '\tTry to connect to: {}\n'.format(self) ) + trace( 550, '\tContact {}\n'.format(contact) ) contactBb = contact.getBoundingBox() if contactBb.getXMin() < self.side.innerBb.getXMin() \ or contactBb.getXMax() > self.side.innerBb.getXMax(): @@ -167,8 +168,8 @@ class HorizontalRail ( Rail ): def doLayout ( self ): trace( 550, ',+', '\tHorizontalRail.doLayout() order:{} @{}\n' \ .format( self.order,DbU.getValueString(self.axis ))) - railVias = [ self.side.corner0(self.order) - , self.side.corner1(self.order) ] + railVias = [ self.side.corner0(self.order).getPlate( self.side.getHLayer() ) + , self.side.corner1(self.order).getPlate( self.side.getHLayer() ) ] for via in self.vias.values(): if via[1].getNet() != via[2].getNet(): continue via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) ) @@ -206,8 +207,8 @@ class VerticalRail ( Rail ): , DbU.getValueString(self.axis) ) def doLayout ( self ): - railVias = [ self.side.corner0(self.order) - , self.side.corner1(self.order) ] + railVias = [ self.side.corner0(self.order).getPlate( self.side.getVLayer() ) + , self.side.corner1(self.order).getPlate( self.side.getVLayer() ) ] for via in self.vias.values(): if via[1].getNet() != via[2].getNet(): continue via[1].doLayout() @@ -465,8 +466,6 @@ class VerticalSide ( Side ): if via[1].getNet() != via[2].getNet(): continue spans.merge( via[1].y - via[1].height/2, via[1].y + via[1].height/2 ) routingGauge = self.corona.routingGauge - print( self.getOuterRail(0) ) - print( self.getOuterRail(0).vias.values() ) for depth in range(self.getOuterRail(0).vias.values()[0][1].bottomDepth ,self.getOuterRail(0).vias.values()[0][1].topDepth ): blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer() @@ -645,33 +644,21 @@ class Builder ( object ): trBox.merge( xTR, yTR ) self.routingGauge.getContactLayer(contactDepth) self.corners[SouthWest].append( - Contact.create( net - , self.routingGauge.getContactLayer(contactDepth) - , xBL, yBL - , self.hRailWidth - , self.vRailWidth - ) ) + BigVia( net, contactDepth, xBL, yBL, self.hRailWidth, self.vRailWidth ) ) + self.corners[SouthWest][-1].mergeDepth( contactDepth+1 ) + self.corners[SouthWest][-1].doLayout() self.corners[NorthWest].append( - Contact.create( net - , self.routingGauge.getContactLayer(contactDepth) - , xBL, yTR - , self.hRailWidth - , self.vRailWidth - ) ) + BigVia( net, contactDepth, xBL, yTR, self.hRailWidth, self.vRailWidth ) ) + self.corners[NorthWest][-1].mergeDepth( contactDepth+1 ) + self.corners[NorthWest][-1].doLayout() self.corners[SouthEast].append( - Contact.create( net - , self.routingGauge.getContactLayer(contactDepth) - , xTR, yBL - , self.hRailWidth - , self.vRailWidth - ) ) + BigVia( net, contactDepth, xTR, yBL, self.hRailWidth, self.vRailWidth ) ) + self.corners[SouthEast][-1].mergeDepth( contactDepth+1 ) + self.corners[SouthEast][-1].doLayout() self.corners[NorthEast].append( - Contact.create( net - , self.routingGauge.getContactLayer(contactDepth) - , xTR, yTR - , self.hRailWidth - , self.vRailWidth - ) ) + BigVia( net, contactDepth, xTR, yTR, self.hRailWidth, self.vRailWidth ) ) + self.corners[NorthEast][-1].mergeDepth( contactDepth+1 ) + self.corners[NorthEast][-1].doLayout() self.southSide.doLayout() self.northSide.doLayout() self.westSide .doLayout() diff --git a/cumulus/src/plugins/alpha/chip/pads.py b/cumulus/src/plugins/alpha/chip/pads.py index 175ee101..bab34ca1 100644 --- a/cumulus/src/plugins/alpha/chip/pads.py +++ b/cumulus/src/plugins/alpha/chip/pads.py @@ -946,6 +946,12 @@ class Corona ( object ): bb = component.getBoundingBox() padInstance.getTransformation().applyOn( bb ) trace( 550, '\t| External:{} bb:{}\n'.format(component,bb) ) + if self.conf.chipConf.ioPadGauge == 'LibreSOCIO': + if chipIntNet.isPower() or chipIntNet.isGround(): + if side.type == North or side.type == South: + bb.inflate( -DbU.fromPhysical( 0.6, DbU.UnitPowerMicro ), 0 ) + else: + bb.inflate( 0, -DbU.fromPhysical( 0.6, DbU.UnitPowerMicro ) ) if bb.intersect(innerBb): trace( 550, '\t| Accepted.\n' ) lg = rg.getLayerGauge( component.getLayer() ) diff --git a/cumulus/src/plugins/alpha/chip/power.py b/cumulus/src/plugins/alpha/chip/power.py index 65e35525..3132a6b4 100644 --- a/cumulus/src/plugins/alpha/chip/power.py +++ b/cumulus/src/plugins/alpha/chip/power.py @@ -225,6 +225,7 @@ class Builder ( object ): return with UpdateSession(): bufferRp = self.conf.rpAccessByOccurrence( Occurrence(htPlugs[0], Path()), ck, 0 ) + self.conf.expandMinArea( bufferRp ) blockAb = self.block.getAbutmentBox() self.path.getTransformation().applyOn( blockAb ) layerGauge = self.conf.routingGauge.getLayerGauge(self.conf.verticalDepth) diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index dec9f5e7..4739ded0 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -806,6 +806,14 @@ namespace Katana { cdebug_tabw(155,1); + openSession(); + for ( RoutingPlane* plane : _routingPlanes ) { + for ( Track* track : plane->getTracks() ) { + track->expandMinArea(); + } + } + Session::close(); + setState( Anabatic::EngineDriving ); _gutKatana(); diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index a5132673..f893db7e 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -383,11 +383,11 @@ namespace { void merge ( const Box&, Net* ); void doLayout (); private: - const Layer* _layer; - RoutingPlane* _routingPlane; - RailsMap _horizontalRails; - RailsMap _verticalRails; - Flags _powerDirection; + const Layer* _layer; + RoutingPlane* _routingPlane; + RailsMap _horizontalRails; + RailsMap _verticalRails; + Flags _powerDirection; }; public: @@ -404,7 +404,7 @@ namespace { void merge ( const Box&, Net* ); void doLayout (); private: - KatanaEngine* _katana; + KatanaEngine* _katana; GlobalNetTable _globalNets; PlanesMap _planes; Plane* _activePlane; @@ -504,7 +504,8 @@ namespace { //DbU::Unit delta = plane->getLayerGauge()->getPitch() // - plane->getLayerGauge()->getHalfWireWidth() // - DbU::fromLambda(0.1); - DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1); + //DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1); + DbU::Unit delta = 0; DbU::Unit extension = layer->getExtentionCap(); //DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2; //DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getHalfPitch() + getHalfWireWidth(); @@ -515,6 +516,12 @@ namespace { DbU::Unit axisMin = 0; DbU::Unit axisMax = 0; + if (AllianceFramework::get()->getCellGauge()->getName() == Name("FlexLib")) { + if (_width >= DbU::fromPhysical( 10.0, DbU::UnitPower::Micro )) { + delta = 2 * plane->getLayerGauge()->getPitch(); + } + } + cdebug_log(159,0) << " delta:" << DbU::getValueString(delta) << " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch()) << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index e83df655..2eb93b9e 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -18,10 +18,12 @@ #include #include #include +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/Bug.h" #include "hurricane/Layer.h" #include "hurricane/Net.h" +#include "anabatic/AutoContact.h" #include "katana/RoutingPlane.h" #include "katana/Track.h" #include "katana/TrackMarker.h" @@ -31,6 +33,7 @@ namespace { using namespace std; + using Hurricane::DebugSession; using namespace CRL; using namespace Katana; @@ -44,6 +47,81 @@ namespace { // { return (*(v.begin()+i))->getSourceU(); } + bool hasSameLayerTurn ( const Layer* layer, TrackElement* segment, Flags flags ) + { + if (not segment or not segment->base()) return false; + AutoContact* contact = (flags & Flags::Source) ? segment->base()->getAutoSource() + : segment->base()->getAutoTarget() ; + if (contact->getLayer() != layer) return false; + if (not contact->isTurn()) return false; + AutoSegment* pp = contact->getPerpandicular( segment->base() ); + return contact->getPerpandicular(segment->base())->getLength(); + } + + + DbU::Unit toFoundryGrid ( DbU::Unit u, DbU::SnapMode mode ) + { + DbU::Unit oneGrid = DbU::fromGrid( 1.0 ); + return DbU::getOnCustomGrid( u, oneGrid, mode ); + } + + + void expandToMinArea ( TrackElement* minSegment + , TrackElement* maxSegment + , const Interval& segSpan + , DbU::Unit minFree + , DbU::Unit maxFree ) + { + DebugSession::open( minSegment->getNet(), 150, 160 ); + cdebug_log(155,1) << "Track::expandMinArea() for:" << endl; + cdebug_log(155,0) << "minSegment:" << minSegment << endl; + cdebug_log(155,0) << "maxSegment:" << maxSegment << endl; + + const Layer* layer = minSegment->getLayer(); + double minArea = layer->getMinimalArea(); + DbU::Unit minSpacing = layer->getMinimalSpacing(); + DbU::Unit minLength + = DbU::fromPhysical( minArea / DbU::toPhysical( minSegment->getWidth(), DbU::UnitPower::Micro ) + , DbU::UnitPower::Micro ); + minLength = toFoundryGrid( minLength, DbU::Superior ); + DbU::Unit segLength = segSpan.getSize() - minSpacing; + cdebug_log(155,0) << "minSpacing:" << DbU::getValueString(minSpacing) << endl; + cdebug_log(155,0) << " minLength:" << DbU::getValueString(minLength) << endl; + cdebug_log(155,0) << " segLenght:" << DbU::getValueString(segLength) << endl; + + DbU::Unit sourceECap = minSegment->base()->getExtensionCap( Flags::Source|Flags::LayerCapOnly ); + DbU::Unit targetECap = maxSegment->base()->getExtensionCap( Flags::Target|Flags::LayerCapOnly ); + cdebug_log(155,0) << "sourceECap:" << DbU::getValueString(sourceECap) << endl; + cdebug_log(155,0) << "targetECap:" << DbU::getValueString(targetECap) << endl; + + if (segLength < minLength) { + DbU::Unit marginLeft = segSpan.getVMin() - minFree; + DbU::Unit marginRight = maxFree - segSpan.getVMax(); + DbU::Unit expandLeft = toFoundryGrid( (minLength - segLength)/2 + sourceECap, DbU::Inferior ); + DbU::Unit expandRight = toFoundryGrid( (minLength - segLength)/2 + targetECap, DbU::Superior ); + if ((marginLeft >= expandLeft) and (marginRight >= expandRight)) { + minSegment->base()->setDuSource( minSegment->base()->getDuSource() - expandLeft ); + maxSegment->base()->setDuTarget( maxSegment->base()->getDuTarget() + expandRight ); + } else { + if (marginLeft + marginRight >= expandLeft + expandRight) { + DbU::Unit shiftLeft = 0; + if (marginLeft >= expandLeft + expandRight) + shiftLeft = - expandRight; + else + shiftLeft = - marginLeft + expandLeft; + minSegment->base()->setDuSource( minSegment->base()->getDuSource() - expandLeft + shiftLeft ); + maxSegment->base()->setDuTarget( maxSegment->base()->getDuTarget() + expandRight + shiftLeft ); + } else { + cerr << Error( "::expandToMinArea(): Cannot expand %s." + , getString(minSegment).c_str() ) << endl; + } + } + } + cdebug_tabw(155,-1); + DebugSession::close(); + } + + } // Anonymous namespace. @@ -54,6 +132,7 @@ namespace Katana { using std::sort; using Hurricane::dbo_ptr; using Hurricane::tab; + using Hurricane::DebugSession; using Hurricane::Warning; using Hurricane::Bug; using Hurricane::Layer; @@ -786,6 +865,58 @@ namespace Katana { } + void Track::expandMinArea () + { + if (_segments.empty()) return; + + double minArea = getLayer()->getMinimalArea(); + if (minArea == 0.0) return; + + DbU::Unit prevSpanMin = getMin(); + TrackElement* minSegment = NULL; + TrackElement* maxSegment = NULL; + Interval span; + bool hasTurn = false; + for ( size_t j=0 ; j<_segments.size() ; ) { + if (not _segments[j]->base() or not (_segments[j]->getDirection() & getDirection())) { + ++j; + continue; + } + + if (not minSegment) { + minSegment = _segments[j]; + maxSegment = _segments[j]; + if (not span.isEmpty()) prevSpanMin = span.getVMax(); + span.makeEmpty(); + span = _segments[j]->getCanonicalInterval(); + hasTurn = hasSameLayerTurn( getLayer(), _segments[j], Flags::Source ) + or hasSameLayerTurn( getLayer(), _segments[j], Flags::Target ); + ++j; + continue; + } + + if ( (_segments[j]->getNet() == minSegment->getNet()) + and (span.getVMax() >= _segments[j]->getSourceU()) ) { + if (_segments[j]->getTargetU() > span.getVMax()) { + maxSegment = _segments[j]; + span.merge( _segments[j]->getTargetU() ); + hasTurn = hasTurn or hasSameLayerTurn( getLayer(), _segments[j], Flags::Target ); + } + ++j; + continue; + } + + if (not hasTurn and minSegment->base()) + expandToMinArea( minSegment, maxSegment, span, prevSpanMin, _segments[j]->getSourceU() ); + + minSegment = NULL; + } + + if (not hasTurn and minSegment and minSegment->base()) + expandToMinArea( minSegment, maxSegment, span, prevSpanMin, getMax() ); + } + + string Track::_getString () const { return "<" + _getTypeName() + " " diff --git a/katana/src/katana/RoutingPlane.h b/katana/src/katana/RoutingPlane.h index 7cda121b..d276c7fb 100644 --- a/katana/src/katana/RoutingPlane.h +++ b/katana/src/katana/RoutingPlane.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef KATANA_ROUTING_PLANE_H -#define KATANA_ROUTING_PLANE_H - +#pragma once #include "crlcore/RoutingLayerGauge.h" #include "katana/Track.h" @@ -33,31 +31,32 @@ namespace Katana { class RoutingPlane { public: - static RoutingPlane* create ( KatanaEngine*, size_t depth ); - void destroy (); - inline bool isHorizontal () const; - inline bool isVertical () const; - inline KatanaEngine* getKatanaEngine () const; - inline RoutingLayerGauge* getLayerGauge () const; - inline Flags getDirection () const; - inline size_t getDepth () const; - inline DbU::Unit getAxisMin () const; - inline DbU::Unit getAxisMax () const; - inline DbU::Unit getTrackMin () const; - inline DbU::Unit getTrackMax () const; - RoutingPlane* getTop () const; - RoutingPlane* getBottom () const; - inline const Layer* getLayer () const; - inline const Layer* getBlockageLayer () const; - inline size_t getTracksSize () const; - inline size_t computeTracksSize () const; - inline DbU::Unit getTrackPosition ( size_t index ) const; - Track* getTrackByIndex ( size_t index ) const; - Track* getTrackByPosition ( DbU::Unit axis, uint32_t mode=Constant::Nearest ) const; - bool _check ( uint32_t& overlaps ) const; - Record* _getRecord () const; - string _getString () const; - inline string _getTypeName () const; + static RoutingPlane* create ( KatanaEngine*, size_t depth ); + void destroy (); + inline bool isHorizontal () const; + inline bool isVertical () const; + inline KatanaEngine* getKatanaEngine () const; + inline RoutingLayerGauge* getLayerGauge () const; + inline Flags getDirection () const; + inline size_t getDepth () const; + inline DbU::Unit getAxisMin () const; + inline DbU::Unit getAxisMax () const; + inline DbU::Unit getTrackMin () const; + inline DbU::Unit getTrackMax () const; + RoutingPlane* getTop () const; + RoutingPlane* getBottom () const; + inline const Layer* getLayer () const; + inline const Layer* getBlockageLayer () const; + inline const vector getTracks () const; + inline size_t getTracksSize () const; + inline size_t computeTracksSize () const; + inline DbU::Unit getTrackPosition ( size_t index ) const; + Track* getTrackByIndex ( size_t index ) const; + Track* getTrackByPosition ( DbU::Unit axis, uint32_t mode=Constant::Nearest ) const; + bool _check ( uint32_t& overlaps ) const; + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; protected: // Sub-Class: TrackCompare. @@ -91,18 +90,19 @@ namespace Katana { inline bool RoutingPlane::TrackCompare::operator() ( Track* lhs, Track* rhs ) { return lhs->getAxis() > rhs->getAxis(); }; - inline KatanaEngine* RoutingPlane::getKatanaEngine () const { return _katana; } - inline RoutingLayerGauge* RoutingPlane::getLayerGauge () const { return _layerGauge; } - inline Flags RoutingPlane::getDirection () const { return _flags & Flags::DirectionMask; } - inline size_t RoutingPlane::getDepth () const { return _depth; } - inline DbU::Unit RoutingPlane::getAxisMin () const { return _axisMin; } - inline DbU::Unit RoutingPlane::getAxisMax () const { return _axisMax; } - inline DbU::Unit RoutingPlane::getTrackMin () const { return _trackMin; } - inline DbU::Unit RoutingPlane::getTrackMax () const { return _trackMax; } - inline const Layer* RoutingPlane::getLayer () const { return getLayerGauge()->getLayer(); } - inline const Layer* RoutingPlane::getBlockageLayer () const { return getLayerGauge()->getBlockageLayer(); } - inline size_t RoutingPlane::getTracksSize () const { return _tracks.size(); } - inline string RoutingPlane::_getTypeName () const { return "RoutingPlane"; } + inline KatanaEngine* RoutingPlane::getKatanaEngine () const { return _katana; } + inline RoutingLayerGauge* RoutingPlane::getLayerGauge () const { return _layerGauge; } + inline Flags RoutingPlane::getDirection () const { return _flags & Flags::DirectionMask; } + inline size_t RoutingPlane::getDepth () const { return _depth; } + inline DbU::Unit RoutingPlane::getAxisMin () const { return _axisMin; } + inline DbU::Unit RoutingPlane::getAxisMax () const { return _axisMax; } + inline DbU::Unit RoutingPlane::getTrackMin () const { return _trackMin; } + inline DbU::Unit RoutingPlane::getTrackMax () const { return _trackMax; } + inline const Layer* RoutingPlane::getLayer () const { return getLayerGauge()->getLayer(); } + inline const Layer* RoutingPlane::getBlockageLayer () const { return getLayerGauge()->getBlockageLayer(); } + inline const vector RoutingPlane::getTracks () const { return _tracks; } + inline size_t RoutingPlane::getTracksSize () const { return _tracks.size(); } + inline string RoutingPlane::_getTypeName () const { return "RoutingPlane"; } inline size_t RoutingPlane::computeTracksSize () const { return _layerGauge->getTrackNumber(_axisMin,_axisMax); } @@ -121,6 +121,3 @@ namespace Katana { INSPECTOR_P_SUPPORT(Katana::RoutingPlane); - - -#endif // KATANA_ROUTING_PLANE_H diff --git a/katana/src/katana/Track.h b/katana/src/katana/Track.h index d14be33d..c9c5977f 100644 --- a/katana/src/katana/Track.h +++ b/katana/src/katana/Track.h @@ -14,16 +14,13 @@ // +-----------------------------------------------------------------+ -#ifndef KATANA_TRACK_H -#define KATANA_TRACK_H - -#include "hurricane/Point.h" +#pragma once +#include "hurricane/Point.h" namespace Hurricane { class Layer; } - -#include "katana/TrackCost.h" -#include "katana/TrackElement.h" +#include "katana/TrackCost.h" +#include "katana/TrackElement.h" namespace Katana { @@ -102,6 +99,7 @@ namespace Katana { DbU::Unit getSourcePosition ( size_t index ) const; bool check ( uint32_t& overlaps, const char* message=NULL ) const; uint32_t checkOverlap ( uint32_t& overlaps ) const; + void expandMinArea (); inline void setLocalAssigned ( bool ); void invalidate (); void insert ( TrackElement* ); @@ -231,5 +229,3 @@ namespace Katana { INSPECTOR_P_SUPPORT(Katana::Track); - -#endif // KATANA_TRACK_H