From 29b57e86e5d516a3848e3ce7e0c7bfc03e12f528 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 23 Nov 2020 23:07:15 +0100 Subject: [PATCH] DRC correct on Arlet6505 / TSMC C180. Integrate new features and bug fixes so the Arlet 6502 benchs successfully passes real DRC with reference industrial tools. Short summary: * Manage minimum area for VIAs in Katana::Tracks. * Allow different wire width for wires perpandicular to the prefered routing direction. * StackedVIAs used in the clock tree no longer assume an uniform routing grid (same offset & pitch all the way up). * Some hard-coded patches in PowerRails for FlexLib. * New: In CRL/symbolic/cmos/kite.py & cmos45/kite.py, update the RoutingLayerGauges by adding the new PWireWidth parameter. Always zero in case of symbolic layout (too fine tuning). * New: In CRL::RoutingGauge, add accessor to PWireWidth parameter. Modify the clone method. * New: In CRL::RoutingLayerGauge, add new parameter "PWireWidth" to give the width of a wire when it not drawn in the prefered routing direction. If it is set to zero, the normal width is used. * New: In CRL::PyRoutingGauge, export the updated constructor interface. It is *not* backward compatible, one must add the PWireWidth parameter in the various kite.py configuration files (in etc/). * Change: In AnabaticEngine::_gutAnabatic(), disable the minimum area detection mechanism, replaced by a more complete one in Katana::Track. Left commented out for now, but will be removed in the future. * Change: In Anabatic::AutoContact::updateLayer(), now systematically calls setLayerAndWidth() to potentially resize the VIAs. This is needed in real mode as VIAs are *not* macro-generated but have their real final size. * Change: In Anabatic::AutoContact::setLayerAndWidth(), select the width and height of the contact using the gauge wire width *and* perpandicular *wire width*. * Change: In Anabatic::AutoSegment::_initialize(), the "VIA to same cap" to PWireWidth/2, this will be the size of the VIA in the non-preferred direction at the end cap (non-square in real mode). * Change: In Anabatic::AutoSegment::getExtensionCap(), makes different cases for symbolic and real. Use raw length in real, add half the wire width in symbolic. Add a flag to get the extension cap *only*, not increased of half the minimal spacing. * Change: In Anabatic::AutoSegment::bloatStackedStrap(), enhanced, but finally unused... * New: In Anabatic::AutoSegment::create(), use the PWireWidth when the segment is not in the preferred routing direction (and of minimal width). * New: In Anabatic::Configuration, add new getPWirewidth(), DPHorizontalWidth() and DPVerticalWidth() accessors. * Change: In AnabaticEngine::setupPreRouteds(), skip components in in "cut" material. We are only interested in objects containing some metal (happens in real mode when VIAs cuts are really there). * New: In Katana::PowerRailsPlanes::Rail::doLayout(), add an hard-coded patch that artificially enlarge the *wide wire* so the spacing for wide wire is enforced. For now, two pitches on each side for "FlexLib" gauge. * New: In Katana::Track, add support to find and correct small wire chunks so they respect the minimum area rules. Two helper functions: * ::hasSameLayerTurn(), to find if a a TrackElement as non-zero length perpandicular is same layer connected to it. * ::toFoundryGrid(), to ensure that all coordinates will be on the foundry grid (may move in a more shared location). * ::expandToMinArea(), try to expand, *in the routing direction* the too small wire so it respect the minimal area. Check for the free space in the track. Track::minExpandArea() go through all the TrackElements in the track to look for too small ones and correct them. * Change: In Katana::RoutingPlane, add an accessor to get the tracks. * New: In KatanaEngine::finalizeLayout(), add a post-treatment to find for minimal area violations. * Change: In cumulus/plugins.block.configuration.GaugeConf, add a routingBb attribute that will serve as a common reference to all the functions calculation track positions. We must not have two different reference for the core and the corona. The reference is always the corona when we working on a complete chip. * New: In cumulus/plugins.block.configuration.GaugeConf.getTrack(), Simplified and more reliable way of getting tracks positions. Use the routingBb. * New: In cumulus/plugins.block.configuration.GaugeConf.rpAccess(), Make use of getTrack() to get every metal strap on the right X/Y position. * New: In cumulus/plugins.block.configuration.GaugeConf.expandMinArea(), As those wires are left alone by the router, it is our responsability to abide by the minimal area rule here. Hence the code duplication from the router (bad). Mainly wires made for the clock tree, I mean. * Bug: In cumulus/plugins.chip.configuration.ChipConf.setupICore(), the core instance must be placed on the GCell grid, defined by the slice height (X *and* Y). * Bug: In cumulus/plugins.chip.corona.Builder(), forgot to use bigvia for the corners of the inner ring. * Bug: In cumulus/plugins.chip.pads.corona._createCoreWire(), hard-coded patch for LibreSOCIO, the power/ground connectors toward the core are too wide and can create DRC errors when put side by side. Shrink them by the minimal distance. --- anabatic/src/AnabaticEngine.cpp | 2 +- anabatic/src/AutoContact.cpp | 18 ++- anabatic/src/AutoSegment.cpp | 89 ++++++++--- anabatic/src/Configuration.cpp | 7 + anabatic/src/Constants.cpp | 1 + anabatic/src/PreRouteds.cpp | 6 +- anabatic/src/anabatic/AutoSegment.h | 5 + anabatic/src/anabatic/Configuration.h | 6 + anabatic/src/anabatic/Constants.h | 1 + anabatic/src/anabatic/Session.h | 6 + crlcore/etc/symbolic/cmos/kite.py | 7 + crlcore/etc/symbolic/cmos45/kite.py | 18 +++ crlcore/src/ccore/RoutingGauge.cpp | 11 +- crlcore/src/ccore/RoutingLayerGauge.cpp | 9 +- crlcore/src/ccore/crlcore/RoutingGauge.h | 3 + crlcore/src/ccore/crlcore/RoutingLayerGauge.h | 10 +- crlcore/src/pyCRL/PyRoutingGauge.cpp | 24 +++ crlcore/src/pyCRL/PyRoutingLayerGauge.cpp | 21 ++- cumulus/src/plugins/alpha/block/bigvia.py | 14 +- cumulus/src/plugins/alpha/block/block.py | 2 + cumulus/src/plugins/alpha/block/clocktree.py | 23 +-- .../src/plugins/alpha/block/configuration.py | 149 ++++++++++++++---- cumulus/src/plugins/alpha/chip/chip.py | 3 + .../src/plugins/alpha/chip/configuration.py | 6 +- cumulus/src/plugins/alpha/chip/corona.py | 47 ++---- cumulus/src/plugins/alpha/chip/pads.py | 6 + cumulus/src/plugins/alpha/chip/power.py | 1 + katana/src/KatanaEngine.cpp | 8 + katana/src/PowerRails.cpp | 21 ++- katana/src/Track.cpp | 131 +++++++++++++++ katana/src/katana/RoutingPlane.h | 83 +++++----- katana/src/katana/Track.h | 14 +- 32 files changed, 581 insertions(+), 171 deletions(-) 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