From cd60032d9cc77c82886d7c9c165f51532b407778 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 27 Apr 2022 21:56:41 +0200 Subject: [PATCH] Added direct management of macro blocks I/O pins in METAL2 & METAL3. The decoupling of the cell gauge and the routing gauge implies that the METAL2 & METAL3 terminals of macro blocks cannot be aligned on the routing tracks anymore. That is, an horizontal METAL2 terminal will not be on a track axis, but offgrid, so we no longer can use a METAL2 horizontal segment to connect to it. Making an adjustement between the offgrid terminal and the on-grid segment has proven too complex and generating difficult configuration for the router. Moreover, METLA2 terminal could be fully inside a METAL2 blockage. So now, when the gauges are decoupled, we connect the METAL2 and METAL3 the same way we do for METAL1: *from above* in the perpandicular direction and using a *sliding* VIA. We assume that those kind of terminals in upper metals are quite long. * New: In Hurricane::Rectilinear, export the isNonRectangle() method to the Python interface. * New: In CRL::RoutingGauge, add function isSuperPitched() with the associated boolean attribute. Set to true when each pitch of each layer is independant (not low fractional multiples). * New: In AnabaticEngine, add the ability to temporarily disable the canonize() operation (mainly used in dogleg creation). * New: In AutoSegment::canonize(), do nothing if the operation is disabled by AnabaticEngine. * Bug: In Session::_revalidateTopology(), disable the canonization during the topology updating of a net. Too early canonization was occuring in makeDogleg() leading to incoherencies when performing the later canonization stage over the complete net. Mostly occured in the initial build stage of the net. * New: In GCell, add function postGlobalAnnotate(), if a layer is fully blocked (above 0.9), typically, under a blockage, add a further capacity decrease of 2 on the edges. So we may handle a modicum of doglegs. * Bug; In GCell::addBlockage(), removeContact(), removeHSegment() and removeVSegment(), forgot to set the Invalidated flag. This may have lead to innacurate densities. * Change: In GCell::updateDensity(), more complex setting of the GoStraight flag. This flag is now set if we don't have two *contiguous* below 60% of density. We need free contiguous layers to make doglegs. * New: In NetBuilder, now manage a current state flag along with the state flag of the *source* GCell. This flag is used to tell if the GCell needs it's *global* routing to be done using the upper layers (METAL4 & METAL5) instead of the lower ones. * New: In NetBuilder::setStartHook(), set the state flag of the GCell to ToUpperRouting when processing a global routing articulation and one of the base layer is obstructed above 0.9. In GCell with terminals, also set ToUpperRouting when there are some in METAL2 / METAL3 and the gauge is not super-pitched. * New: In NetBuilder, function isInsideBlockage(), to check if a terminal is completely or partially enclosed in a blockage. * Change: In NetBuilderHV::doRp_AutoContact(), remove support for trying to put on grid misaligned METAL2/METAL3. Instead systematically access them from above. Do not cover with fixed protection terminals that are already enclosed in blockages. * Bug: In NetBuilderHV::doRp_AutoContact(), always add the terminal contact in the requested GCell and not the target/source one, in case the terminal span several GCells. * Change: In NetBuilderHV::doRp_Access(), create the local wiring according to the RoutingPad layer. * Change: In NetBuilderHV::_do_xG(), _do_2G(), create the global wiring in upper layers, according to the ToUpperRouting flag. * Change: In NetBuilderHV::_do_xG_xM3(), now delegate to _do_xG_xM3_baseRouting() and _do_xG_xM3_upperRouting() if the density at terminal level is above 0.5. * New: NetBuilderHV::_do_xG_xM3_baseRouting() and _do_xG_xM3_upperRouting() separated function to manage the local routing. * Change: In NetBuilder::_do_globalSegment(), if the currently processed GCell or it's source is in ToUpperRouting mode, move up the global segment. Do *not* use the moveUp() function which would create doglegs unwanted at this stage. * New: In KatanaEngine::annotateGlobalGraph(), call postGlobalAnnotate() on the GCell after the blockages have been taken into accound to add the penalty. * Bug: In Track::getPrevious(), correctly manage the 0 value for the index argument. Strange it didn't show earlier. Same goes for Track::expandFreeInterval(). --- anabatic/src/AutoContact.cpp | 7 + anabatic/src/AutoContactTerminal.cpp | 6 +- anabatic/src/AutoSegment.cpp | 29 +-- anabatic/src/Constants.cpp | 1 + anabatic/src/GCell.cpp | 45 +++- anabatic/src/NetBuilder.cpp | 114 ++++++++-- anabatic/src/NetBuilderHV.cpp | 255 +++++++++++++++++++---- anabatic/src/NetBuilderVH.cpp | 98 +++------ anabatic/src/Session.cpp | 2 + anabatic/src/anabatic/AnabaticEngine.h | 6 + anabatic/src/anabatic/Constants.h | 1 + anabatic/src/anabatic/GCell.h | 1 + anabatic/src/anabatic/NetBuilder.h | 37 +++- anabatic/src/anabatic/NetBuilderHV.h | 78 ++++--- anabatic/src/anabatic/NetBuilderVH.h | 6 +- crlcore/src/ccore/AllianceFramework.cpp | 4 +- crlcore/src/ccore/RoutingGauge.cpp | 28 ++- crlcore/src/ccore/crlcore/RoutingGauge.h | 9 +- crlcore/src/pyCRL/PyRoutingGauge.cpp | 3 + hurricane/src/hurricane/Contact.cpp | 12 +- hurricane/src/isobar/PyRectilinear.cpp | 6 +- katana/src/KatanaEngine.cpp | 1 + katana/src/RoutingEvent.cpp | 4 +- katana/src/SegmentFsm.cpp | 2 + katana/src/Track.cpp | 16 +- 25 files changed, 541 insertions(+), 230 deletions(-) diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index 10a17681..c81eaa46 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -183,19 +183,26 @@ namespace Anabatic { void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const { + cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl; minDepth = (size_t)-1; maxDepth = 0; Component* anchor = getAnchor (); if (anchor) { + cdebug_log(145,0) << "* Anchor depth: " + << Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl; minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); } for ( AutoSegment* segment : const_cast(this)->getAutoSegments() ) { + cdebug_log(145,0) << "* segment depth: " + << Session::getRoutingGauge()->getLayerDepth(segment->getLayer())<< endl; minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); } + + cdebug_tabw(145,-1); } diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index 9e9aad04..19d989c4 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -559,11 +559,11 @@ namespace Anabatic { if (delta > 1) { //_segment = _segment->makeDogleg( this ); _segment->makeDogleg( this ); - cdebug_log(145,0) << "Update seg: " << _segment << endl; delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) ); + cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl; } - else if (delta == 0) setLayerAndWidth( delta, anchorDepth ); - else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) ); + if (delta == 0) setLayerAndWidth( delta, anchorDepth ); + if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) ); } _segment->invalidate( this ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 8bdafce6..e42cceb4 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -770,16 +770,16 @@ namespace Anabatic { if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth); else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth); else cap = getViaToSameCap (depth); - cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags() - << " VIA cap:" << DbU::getValueString(cap) - << " t:" << (getFlags() & SegSourceBottom) - << " b:" << (getFlags() & SegSourceTop) - << endl; + // cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags() + // << " VIA cap:" << DbU::getValueString(cap) + // << " t:" << (getFlags() & SegSourceBottom) + // << " b:" << (getFlags() & SegSourceTop) + // << endl; if (not (flags & Flags::NoSegExt)) { - cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl; + // cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl; if (-getDuSource() > cap) { cap = -getDuSource(); - cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl; + // cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl; } } } @@ -788,16 +788,16 @@ namespace Anabatic { if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth); else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth); else cap = getViaToSameCap (depth); - cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags() - << " VIA cap:" << DbU::getValueString(cap) - << " t:" << (getFlags() & SegSourceBottom) - << " b:" << (getFlags() & SegSourceTop) - << endl; + // cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags() + // << " VIA cap:" << DbU::getValueString(cap) + // << " t:" << (getFlags() & SegSourceBottom) + // << " b:" << (getFlags() & SegSourceTop) + // << endl; if (not (flags & Flags::NoSegExt)) { - cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl; + // cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl; if (getDuTarget() > cap) { cap = getDuTarget(); - cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl; + // cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl; } } } @@ -1455,6 +1455,7 @@ namespace Anabatic { AutoSegment* AutoSegment::canonize ( Flags flags ) { cdebug_log(149,0) << "canonize() - " << this << endl; + if (Session::getAnabatic()->isCanonizeDisabled()) return this; // if (isCanonical() and isGlobal()) { // cdebug_log(149,0) << "* " << this << " canonical" << endl; diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 5856afd9..29d88a11 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -53,6 +53,7 @@ namespace Anabatic { const BaseFlags Flags::DestroyGCell = (1L << 7); const BaseFlags Flags::DestroyBaseContact = (1L << 8); const BaseFlags Flags::DestroyBaseSegment = (1L << 9); + const BaseFlags Flags::DisableCanonize = (1L << 10); // Flags for NetDatas objects states only. const BaseFlags Flags::GlobalFixed = (1L << 5); const BaseFlags Flags::GlobalEstimated = (1L << 6); diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 04307f85..3c2c6f44 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1343,6 +1343,26 @@ namespace Anabatic { } + void GCell::postGlobalAnnotate () + { + if (isInvalidated()) updateDensity(); + + for ( size_t depth=0 ; depth<_depth ; ++depth ) { + RoutingLayerGauge* rlg = Session::getLayerGauge( depth ); + if (rlg->getType() & Constant::PinOnly) continue; + if (_densities[depth] >= 0.9) { + if (depth+2 < _depth) { + Edge* edge = (rlg->getDirection() == Constant::Vertical) ? getNorthEdge() + : getEastEdge(); + if (edge) { + edge->reserveCapacity( 2 ); + } + } + } + } + } + + void GCell::addBlockage ( size_t depth, DbU::Unit length ) { if (depth >= _depth) return; @@ -1371,6 +1391,7 @@ namespace Anabatic { if (found) { cdebug_log(149,0) << "remove " << ac << " from " << this << endl; _contacts.pop_back(); + _flags |= Flags::Invalidated; } else { cerr << Bug("%p:%s do not belong to %s." ,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl; @@ -1404,6 +1425,7 @@ namespace Anabatic { , _getString().c_str(), getString(segment).c_str() ) << endl; _hsegments.erase( _hsegments.begin() + end, _hsegments.end() ); + _flags |= Flags::Invalidated; } @@ -1429,6 +1451,7 @@ namespace Anabatic { , getString(segment).c_str() ) << endl; _vsegments.erase( _vsegments.begin() + end, _vsegments.end() ); + _flags |= Flags::Invalidated; } @@ -1528,13 +1551,20 @@ namespace Anabatic { } // Add the blockages. + int contiguousNonSaturated = 0; for ( size_t i=0 ; i<_depth ; i++ ) { uLengths2[i] += _blockages[i]; if (not i) continue; - if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) { - flags() |= Flags::GoStraight; - //cerr << "| Set GoStraight on " << this << endl; - } + if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply) + continue; + if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height)) + contiguousNonSaturated = 0; + else + contiguousNonSaturated++; + } + if (contiguousNonSaturated < 2) { + flags() |= Flags::GoStraight; + //cerr << "| Set GoStraight on " << this << endl; } // Compute the number of non pass-through tracks. @@ -1880,6 +1910,13 @@ namespace Anabatic { s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; record->add( getSlot ( s.str(), &_densities[depth] ) ); } + + for ( size_t depth=0 ; depth<_depth ; ++depth ) { + ostringstream s; + const Layer* layer = rg->getRoutingLayer(depth); + s << "_feedthroughs[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; + record->add( getSlot ( s.str(), &_feedthroughs[depth] ) ); + } return record; } diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 4151c70f..845f0824 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -37,6 +37,7 @@ #include "hurricane/Instance.h" #include "hurricane/Vertical.h" #include "hurricane/Horizontal.h" +#include "hurricane/Rectilinear.h" #include "crlcore/AllianceFramework.h" #include "crlcore/RoutingGauge.h" #include "anabatic/AutoContactTerminal.h" @@ -220,6 +221,7 @@ namespace Anabatic { using Hurricane::Error; using Hurricane::Warning; using Hurricane::Bug; + using Hurricane::Rectilinear; // ------------------------------------------------------------------- @@ -367,6 +369,8 @@ namespace Anabatic { , _toFixSegments () , _degree (0) , _isTwoMetals (false) + , _sourceFlags (0) + , _flags (0) { } @@ -377,6 +381,8 @@ namespace Anabatic { void NetBuilder::clear () { _connexity.connexity = 0; + _sourceFlags = 0; + _flags = 0; _topology = 0; _net = NULL; _netData = NULL; @@ -403,11 +409,15 @@ namespace Anabatic { } - NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt, Hook* fromHook, AutoContact* sourceContact ) + NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt + , Hook* fromHook + , AutoContact* sourceContact + , uint64_t sourceFlags ) { clear(); _isTwoMetals = anbt->getConfiguration()->isTwoMetals(); + _sourceFlags = sourceFlags; _sourceContact = sourceContact; _fromHook = fromHook; @@ -470,6 +480,12 @@ namespace Anabatic { throw Error( mismatchGCell ); } + if ( (_gcell->getDensity( Session::getDHorizontalDepth() ) > 0.9) + or (_gcell->getDensity( Session::getDVerticalDepth () ) > 0.9)) { + cdebug_log(145,0) << "Base layers blockeds, moving up" << endl; + _flags |= ToUpperRouting; + } + if (not _gcell->isMatrix()) { cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl; cdebug_log(145,0) << "| " << gcell << endl; @@ -489,11 +505,23 @@ namespace Anabatic { continue; } - if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V - else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H - else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V - else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H - else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V + size_t rpDepth = 0; + for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) { + if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) { + rpDepth = depth; + break; + } + } + if ((rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched()) { + _flags |= ToUpperRouting; + cdebug_log(145,0) << "ToUpperRouting set, getFlags():" << getFlags() << endl; + } + + if (rpDepth == 0) _connexity.fields.M1++; // M1 V + else if (rpDepth == 1) _connexity.fields.M2++; // M2 H + else if (rpDepth == 2) _connexity.fields.M3++; // M3 V + else if (rpDepth == 3) _connexity.fields.M2++; // M4 H + else if (rpDepth == 4) _connexity.fields.M3++; // M5 V else { cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)." , getString(layer->getName()).c_str() @@ -553,6 +581,7 @@ namespace Anabatic { cdebug_log(145,0) << "NetBuilder::push()" << endl; cdebug_log(145,0) << "* toHook: " << toHook << endl; cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl; + cdebug_log(145,0) << "* flags:" << flags << endl; if (not toHook or (toHook == _fromHook)) { if (contact) { @@ -571,12 +600,60 @@ namespace Anabatic { Hook* toHookOpposite = getSegmentOppositeHook( toHook ); cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl; cdebug_log(145,0) << "Pushing (from) " << contact << endl; - _forks.push( toHookOpposite, contact ); + _forks.push( toHookOpposite, contact, getFlags() ); return true; } + bool NetBuilder::isInsideBlockage ( GCell* gcell, Component* rp ) const + { + cdebug_log(145,1) << getTypeName() << "::isInsideBlockage() " << endl; + cdebug_log(145,0) << rp << endl; + cdebug_log(145,0) << rp->getLayer()->getMask() << endl; + + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); + if (gcell->getDensity(rpDepth) < 0.5) { + cdebug_tabw(145,-1); + return false; + } + + Box rpBb = rp->getBoundingBox(); + Layer::Mask rpMask = rp->getLayer()->getBlockageLayer()->getMask(); + cdebug_log(145,0) << "rpBb: " << rpBb << endl; + for ( Occurrence occurrence : getAnabatic()->getCell()->getOccurrencesUnder(rpBb) ) { + cdebug_log(145,0) << "| " << occurrence.getEntity() << endl; + Component* component = dynamic_cast( occurrence.getEntity() ); + if (not component) continue; + + const Layer* blockageLayer = component->getLayer(); + Box blockageBb = component->getBoundingBox(); + cdebug_log(145,0) << " Mask: " << blockageLayer->getMask() << endl; + if ( blockageLayer->isBlockage() + and (blockageLayer->getMask() == rpMask)) { + occurrence.getPath().getTransformation().applyOn( blockageBb ); + cdebug_log(145,0) << " Bb: " << blockageBb << endl; + if (blockageBb.contains(rpBb)) { + cdebug_log(145,-1) << "* Inside " << component << endl; + return true; + } + if (blockageBb.intersect(rpBb)) { + cerr << Warning( "NetBuilder::isInsideBlockage(): RoutingPad is only partially inside blocked area.\n" + " * %s\n" + " * %s" + , getString(rp).c_str() + , getString(component).c_str() + ) << endl; + cdebug_log(145,-1) << "* Partially inside " << component << endl; + return true; + } + } + } + cdebug_tabw(145,-1); + return false; + } + + void NetBuilder::construct () { cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl; @@ -589,6 +666,8 @@ namespace Anabatic { << "+" << (int)_connexity.fields.Pad << "] " << _gcell << endl; + cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags() + << " getFlags():" << getFlags() << endl; if (not isTwoMetals()) { _southWestContact = NULL; @@ -2374,6 +2453,7 @@ namespace Anabatic { Hook* sourceHook = NULL; AutoContact* sourceContact = NULL; + uint64_t sourceFlags = NoFlags; RoutingPads routingPads = net->getRoutingPads(); size_t degree = routingPads.getSize(); @@ -2412,7 +2492,7 @@ namespace Anabatic { ++connecteds; segmentFound = true; - setStartHook( anabatic, hook, NULL ); + setStartHook( anabatic, hook, NULL, NoFlags ); if (getStateG() == 1) { if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) { cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl; @@ -2440,9 +2520,9 @@ namespace Anabatic { } cdebug_tabw(145,-1); - if (startHook == NULL) { setStartHook(anabatic,NULL,NULL).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; } + if (startHook == NULL) { setStartHook(anabatic,NULL,NULL,NoFlags).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; } - setStartHook( anabatic, startHook, NULL ); + setStartHook( anabatic, startHook, NULL, NoFlags ); cdebug_log(145,0) << endl; cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl; cdebug_log(145,0) << endl; @@ -2451,18 +2531,21 @@ namespace Anabatic { sourceHook = _forks.getFrom (); sourceContact = _forks.getContact(); + sourceFlags = _forks.getFlags (); _forks.pop(); while ( sourceHook ) { - setStartHook( anabatic, sourceHook, sourceContact ); + setStartHook( anabatic, sourceHook, sourceContact, sourceFlags ); construct(); - sourceHook = _forks.getFrom(); + sourceHook = _forks.getFrom (); sourceContact = _forks.getContact(); + sourceFlags = _forks.getFlags (); _forks.pop(); - cdebug_log(145,0) << "Popping (from) " << sourceHook << endl; - cdebug_log(145,0) << "Popping (to) " << sourceContact << endl; + cdebug_log(145,0) << "Popping (from) " << sourceHook << endl; + cdebug_log(145,0) << "Popping (to) " << sourceContact << endl; + cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl; } Session::revalidate(); @@ -2473,10 +2556,11 @@ namespace Anabatic { for ( ; iover != overconstraineds.end() ; ++iover ) { (*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true ); } + Session::revalidate(); #endif - Session::revalidate(); fixSegments(); + Session::revalidate(); cdebug_tabw(145,-1); //DebugSession::close(); diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 5565a334..74a25dd3 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -104,6 +104,7 @@ namespace Anabatic { viaSide = Session::getViaWidth( rpDepth ); } +#if THIS_IS_DISABLED // Non-M1 terminal or punctual M1 protections. if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) { map::iterator irp = getRpLookup().find( rp ); @@ -177,17 +178,44 @@ namespace Anabatic { getRpLookup().insert( make_pair(rp,segment) ); } } +#endif + // Non-M1 terminal or punctual M1 protections. + if (isInsideBlockage(gcell,rp)) flags |= NoProtect; + if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) { + map::iterator irp = getRpLookup().find( rp ); + if (irp == getRpLookup().end()) { + AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell + , rp + , rpLayer + , sourcePosition + , viaSide, viaSide + ); + AutoContact* targetProtect = AutoContactTerminal::create( targetGCell + , rp + , rpLayer + , targetPosition + , viaSide, viaSide + ); + sourceProtect->setFlags( CntFixed ); + targetProtect->setFlags( CntFixed ); + + AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction ); + segment->setFlags( AutoSegment::SegFixed ); + + getRpLookup().insert( make_pair(rp,segment) ); + } + } if (sourcePosition != targetPosition) { if (flags & DoSourceContact) - source = AutoContactTerminal::create( sourceGCell + source = AutoContactTerminal::create( gcell , rp , rpLayer , sourcePosition , viaSide, viaSide ); if (flags & DoTargetContact) - target = AutoContactTerminal::create( targetGCell + target = AutoContactTerminal::create( gcell , rp , rpLayer , targetPosition @@ -245,7 +273,7 @@ namespace Anabatic { if (flags & (VSmall|UseNonPref)) { cdebug_log(145,0) << "case: UseNonPref" << endl; - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref ); rpSourceContact = subContact1; } @@ -254,19 +282,19 @@ namespace Anabatic { cdebug_log(145,0) << "case: HSmall" << endl; AutoContact* subContact1 = rpSourceContact; - AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); rpSourceContact = subContact2; if (flags & Punctual) { cdebug_log(145,0) << "case: HSmall + Punctual" << endl; subContact1 = subContact2; - subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( subContact1, subContact2, Flags::Vertical ); + subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + AutoSegment::create( subContact1, subContact2, Flags::Vertical, rpDepth+2 ); subContact1 = subContact2; - subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); + subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 ); rpSourceContact = subContact2; } @@ -277,12 +305,14 @@ namespace Anabatic { AutoContact* subContact1 = NULL; if (flags & HAccess) { - if (flags & HAccessEW) - subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - else - subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + cdebug_log(145,0) << "HAccess" << endl; + if (flags & HAccessEW) { + cdebug_log(145,0) << "HAccessEW" << endl; + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + } else + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); - AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical, rpDepth+1 ); } else { #if OFFGRID_M2_DISABLED Box cellAb = getAnabatic()->getCell()->getAbutmentBox(); @@ -299,9 +329,14 @@ namespace Anabatic { rpSourceContact = subContact1; } #endif - - subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); + if (Session::getRoutingGauge()->isSuperPitched()) { + cdebug_log(145,0) << "Vertical access & super-pitched" << endl; + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); + } else { + cdebug_log(145,0) << "Vertical access" << endl; + subContact1 = rpSourceContact; + } } rpSourceContact = subContact1; } @@ -456,7 +491,15 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl; - const Layer* viaLayer = Session::getDContactLayer(); + size_t hDepth = Session::getDHorizontalDepth(); + size_t vDepth = Session::getDVerticalDepth(); + size_t cDepth = Session::getDContactDepth(); + if (getFlags() & ToUpperRouting) { + hDepth += 2; + vDepth += 2; + cDepth += 2; + } + const Layer* viaLayer = Session::getContactLayer( cDepth ); if (getConnexity().fields.globals == 2) { setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); @@ -466,20 +509,20 @@ namespace Anabatic { setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) ); if (south()) swapCornerContacts(); - AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical ); + AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth ); } else { setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) ); if (west()) swapCornerContacts(); - AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal ); + AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth ); } } else { // fields.globals == 4. AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer ); setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) ); setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) ); - AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal ); - AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical ); + AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal, hDepth ); + AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical , vDepth ); } cdebug_tabw(145,-1); return true; @@ -490,16 +533,24 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_2G()" << endl; - const Layer* viaLayer = Session::getDContactLayer(); + size_t hDepth = Session::getDHorizontalDepth(); + size_t vDepth = Session::getDVerticalDepth(); + size_t cDepth = Session::getDContactDepth(); + if (getFlags() & ToUpperRouting) { + hDepth += 2; + vDepth += 2; + cDepth += 2; + } + const Layer* viaLayer = Session::getContactLayer( cDepth ); if (east() and west()) { setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); - AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical ); + AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth ); } else if (south() and north()) { setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); - AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal ); + AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth ); } else { setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) ); } @@ -1568,7 +1619,7 @@ namespace Anabatic { biggestRp = getRoutingPads()[i]; } - const Layer* viaLayer1 = Session::getContactLayer(1); + const Layer* viaLayer1 = Session::getContactLayer(1); if (east() and west() and not south() and not north()) { AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess ); @@ -1580,6 +1631,7 @@ namespace Anabatic { if (west() and not south()) { setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) ); } else if (not west() and south()) { + cdebug_log(145,1) << "case: not west and south" << endl; setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); } else if (west() and south()) { AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags ); @@ -1590,6 +1642,7 @@ namespace Anabatic { if (east() and not north()) { setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) ); } else if (not east() and north()) { + cdebug_log(145,1) << "case: not east and north" << endl; setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); } else if (east() and north()) { AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags ); @@ -1605,6 +1658,7 @@ namespace Anabatic { bool NetBuilderHV::_do_1G_1M3 () { cdebug_log(145,1) << getTypeName() << "::_do_1G_1M3() [Optimised Configuration]" << endl; + size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() ); uint64_t flags = (east() or west()) ? HAccess : NoFlags; flags |= (north()) ? DoTargetContact : NoFlags; @@ -1622,6 +1676,13 @@ namespace Anabatic { cdebug_log(145,0) << "_southWest: " << getSouthWestContact() << endl; cdebug_log(145,0) << "_northEast: " << getNorthEastContact() << endl; + if (not (east() or west())) { + AutoContact* subContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer((rpDepth)) ); + AutoSegment::create( getSouthWestContact(), subContact, Flags::Horizontal, rpDepth+1 ); + setBothCornerContacts( subContact ); + } + +#if THIS_IS_DISABLED const Layer* viaLayer1 = Session::getContactLayer(1); Box cellAb = getAnabatic()->getCell()->getAbutmentBox(); @@ -1658,6 +1719,7 @@ namespace Anabatic { setBothCornerContacts( turn2 ); } } +#endif cdebug_tabw(145,-1); return true; } @@ -1665,9 +1727,28 @@ namespace Anabatic { bool NetBuilderHV::_do_xG_xM3 () { + size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() ); + if (getGCell()->getDensity(rpDepth) > 0.5) + return _do_xG_xM3_upperRouting(); + return _do_xG_xM3_baseRouting(); + } + + + bool NetBuilderHV::_do_xG_xM3_baseRouting () + { + size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() ); + size_t vDepth = rpDepth + 2; + size_t hDepth = rpDepth + 1; + const Layer* viaLayer = Session::getContactLayer( rpDepth ); + if (Session::getRoutingGauge()->isSuperPitched()) { + viaLayer = Session::getContactLayer( 1 ); + vDepth = 2; + hDepth = 1; + } + cdebug_log(145,1) << getTypeName() << "::_do_xG_" << (int)getConnexity().fields.M3 - << "M3() [Managed Configuration]" << endl; + << "M3_baseRouting() [Managed Configuration]" << endl; cdebug_log(145,0) << "west:" << west() << endl; cdebug_log(145,0) << "east:" << east() << endl; cdebug_log(145,0) << "south:" << south() << endl; @@ -1678,7 +1759,6 @@ namespace Anabatic { doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] ); } - const Layer* viaLayer1 = Session::getContactLayer(1); AutoContact* unusedContact = NULL; Component* rp = getRoutingPads()[0]; @@ -1691,18 +1771,18 @@ namespace Anabatic { cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(getSourceContact()->getX()) << "_southWest:" << DbU::getValueString(getSouthWestContact()->getX()) << endl; - AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); - AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); - AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical ); - AutoSegment::create( turn1 , turn2, Flags::Horizontal ); + AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer ); + AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer ); + AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical , vDepth ); + AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth ); setSouthWestContact( turn2 ); } } } else if (west() and south()) { AutoContact* rpContact = NULL; doRp_AutoContacts( getGCell(), rp, rpContact, unusedContact, DoSourceContact ); - setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) ); - AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical ); + setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) ); + AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical, vDepth ); } rp = getRoutingPads()[getRoutingPads().size()-1]; @@ -1715,18 +1795,102 @@ namespace Anabatic { cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(getSourceContact()->getX()) << "_southWest:" << DbU::getValueString(getNorthEastContact()->getX()) << endl; - AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); - AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); - AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical ); - AutoSegment::create( turn1 , turn2, Flags::Horizontal ); + AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer ); + AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer ); + AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical , vDepth ); + AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth ); setNorthEastContact( turn2 ); } } } else if (east() and north()) { AutoContact* rpContact = NULL; doRp_AutoContacts( getGCell(), rp, unusedContact, rpContact, DoTargetContact ); - setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) ); - AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical ); + setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) ); + AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical, vDepth ); + } + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderHV::_do_xG_xM3_upperRouting () + { + cdebug_log(145,1) << getTypeName() + << "::_do_xG_" << (int)getConnexity().fields.M3 + << "M3_upperRouting() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl; + cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl; + cdebug_log(145,0) << "north: " << north() << endl; + cdebug_log(145,0) << "south: " << south() << endl; + cdebug_log(145,0) << "east: " << east () << endl; + cdebug_log(145,0) << "west: " << west () << endl; + size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() ); + + sortRpByY( getRoutingPads(), NoFlags ); // increasing Y. + for ( size_t i=1 ; i( getFromHook()->getComponent() ); + Segment* baseSegment = static_cast( getFromHook()->getComponent() ); + if ( (getSourceFlags() | getFlags()) & ToUpperRouting) { + cdebug_log(145,0) << "Moving up global" << endl; + size_t gdepth = Session::getGHorizontalDepth(); + if (dynamic_cast(baseSegment)) + gdepth = Session::getGVerticalDepth(); + baseSegment->setLayer( Session::getRoutingLayer( gdepth+2 )); + baseSegment->setWidth( Session::getWireWidth( gdepth+2 )); + } + AutoSegment* globalSegment = AutoSegment::create( getSourceContact() , targetContact , baseSegment diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp index a7539618..3fa6266e 100644 --- a/anabatic/src/NetBuilderVH.cpp +++ b/anabatic/src/NetBuilderVH.cpp @@ -85,7 +85,6 @@ namespace Anabatic { size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); Flags direction = Session::getDirection ( rpDepth ); DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); - DbU::Unit gridPosition = 0; getPositions( rp, sourcePosition, targetPosition ); @@ -114,56 +113,8 @@ namespace Anabatic { } } -#if 0 - // Quasi-punctual M1 terminal. - if (flags & VSmall) { - Box ab = rp->getCell()->getBoundingBox(); - RoutingLayerGauge* gaugeMetal3 = Session::getLayerGauge( 2 ); - DbU::Unit metal3axis = gaugeMetal3->getTrackPosition( ab.getYMin() - , ab.getYMax() - , sourcePosition.getY() - , Constant::Nearest ); - DbU::Unit viaSideProtect = Session::getViaWidth((size_t)0); - - AutoContact* sourceVia12 = AutoContactTerminal::create( sourceGCell - , rp - , Session::getContactLayer(0) - , sourcePosition - , viaSideProtect, viaSideProtect - ); - AutoContact* targetVia12 = AutoContactTerminal::create( targetGCell - , rp - , Session::getContactLayer(0) - , targetPosition - , viaSideProtect, viaSideProtect - ); - AutoContact* sourceVia23 = AutoContactTurn::create( sourceGCell, net, Session::getContactLayer(1) ); - AutoContact* targetVia23 = AutoContactTurn::create( targetGCell, net, Session::getContactLayer(1) ); - sourceVia23->setY( metal3axis ); - targetVia23->setY( metal3axis ); - sourceVia23->setX( sourcePosition.getX() ); - targetVia23->setX( targetPosition.getX() ); - - AutoSegment* segmentS = AutoSegment::create( sourceVia12, sourceVia23, Flags::Vertical ); - AutoSegment* segmentT = AutoSegment::create( targetVia12, targetVia23, Flags::Vertical ); - AutoSegment* segmentM = AutoSegment::create( sourceVia23, targetVia23, Flags::Horizontal ); - - sourceVia12->setFlags( CntFixed ); - sourceVia23->setFlags( CntFixed ); - targetVia12->setFlags( CntFixed ); - targetVia23->setFlags( CntFixed ); - segmentS->setFlags( AutoSegment::SegFixed ); - segmentT->setFlags( AutoSegment::SegFixed ); - segmentM->setFlags( AutoSegment::SegFixed ); - - cdebug_log(145,0) << "Hard protect: " << rp << endl; - cdebug_log(145,0) << "X:" << DbU::getValueString(sourcePosition.getX()) - << " Metal3 Track Y:" << DbU::getValueString(metal3axis) << endl; - } -#endif - // Non-M1 terminal or punctual M1 protections. - if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) { + if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) { map::iterator irp = getRpLookup().find( rp ); if (irp == getRpLookup().end()) { AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell @@ -205,6 +156,10 @@ namespace Anabatic { ); } + if ( (rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched() ) { + rpLayer = Session::getContactLayer( rpDepth ); + } + if (not source and not target) { source = target = AutoContactTerminal::create( gcell , rp @@ -223,28 +178,43 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; - AutoContact* rpContactSource; - AutoContact* rpContactTarget; + AutoContact* rpContactSource = NULL; + AutoContact* rpContactTarget = NULL; + const Layer* rpLayer = rp->getLayer(); + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); flags |= checkRoutingPadSize( rp ); doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags ); - if (not (flags & (HAccess|HAccessEW))) { - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); - AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); - rpContactSource = subContact2; - } else { - if (flags & VSmall) { + if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3). + if (not (flags & (HAccess|HAccessEW))) { + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 ); + AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 ); + rpContactSource = subContact2; + } else { + if (flags & VSmall) { + AutoContact* subContact1 = NULL; + if (flags & HAccessEW) + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + else + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + rpContactSource = subContact1; + } + } + } else { // RP should be horizontal (M2). + if (flags & (HAccess|HAccessEW)) { AutoContact* subContact1 = NULL; if (flags & HAccessEW) - subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); else - subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - - AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 ); rpContactSource = subContact1; } } diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index 66e56cc4..fe9cf416 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -215,6 +215,7 @@ namespace Anabatic { { cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl; + _anabatic->disableCanonize(); for ( Net* net : _netInvalidateds ) { cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl; _anabatic->updateNetTopology ( net ); @@ -222,6 +223,7 @@ namespace Anabatic { _anabatic->_computeNetOptimals ( net ); //_anabatic->_computeNetTerminals ( net ); } + _anabatic->enableCanonize(); _canonize (); AutoSegment* segment = NULL; diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 50941164..94523b13 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -204,6 +204,7 @@ namespace Anabatic { public: static AnabaticEngine* create ( Cell* ); static AnabaticEngine* get ( const Cell* ); + inline bool isCanonizeDisabled () const; static const Name& staticGetName (); virtual const Name& getName () const; virtual Configuration* getConfiguration (); @@ -227,6 +228,8 @@ namespace Anabatic { virtual void openSession (); inline void setState ( EngineState state ); inline void setDensityMode ( uint64_t ); + inline void disableCanonize (); + inline void enableCanonize (); inline void addOv ( Edge* ); inline void removeOv ( Edge* ); inline const NetDatas& getNetDatas () const; @@ -380,6 +383,7 @@ namespace Anabatic { inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; } inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; } inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; } + inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; } inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; } inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); } inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); } @@ -399,6 +403,8 @@ namespace Anabatic { inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); } inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); } inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } + inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; } + inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); } inline void AnabaticEngine::_add ( GCell* gcell ) { diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index be4b708b..02e4046d 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -51,6 +51,7 @@ namespace Anabatic { static const BaseFlags DestroyGCell ; // = (1 << 7); static const BaseFlags DestroyBaseContact ; // = (1 << 8); static const BaseFlags DestroyBaseSegment ; // = (1 << 9); + static const BaseFlags DisableCanonize ; // = (1 << 10); // Flags for NetDatas objects states only. static const BaseFlags GlobalFixed ; // = (1 << 5); static const BaseFlags GlobalEstimated ; // = (1 << 6); diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index 38ca8deb..d181161e 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -259,6 +259,7 @@ namespace Anabatic { bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const; void setType ( Flags ); inline void setSatProcessed ( size_t depth ); + void postGlobalAnnotate (); void addBlockage ( size_t depth, DbU::Unit ); inline void addHSegment ( AutoSegment* ); inline void addVSegment ( AutoSegment* ); diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index dce8626f..7a36121f 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -47,31 +47,39 @@ namespace Anabatic { class ForkStack { public: - inline void push ( Hook* from, AutoContact* contact ); + inline void push ( Hook* from, AutoContact* contact, uint64_t flags ); inline void pop (); inline Hook* getFrom () const; inline AutoContact* getContact () const; + inline uint64_t getFlags () const; + inline void setFlags ( uint64_t ); private: struct Element { Hook* _from; AutoContact* _contact; - inline Element ( Hook* from, AutoContact* contact ); + uint64_t _flags; + inline Element ( Hook* from, AutoContact* contact, uint64_t flags ); }; private: list _stack; }; - inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {} + inline ForkStack::Element::Element ( Hook* from, AutoContact* contact, uint64_t flags ) : _from(from), _contact(contact), _flags(flags) {} inline void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); } inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; } inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; } + inline uint64_t ForkStack::getFlags () const { return _stack.empty() ? 0 : _stack.back()._flags; } + inline void ForkStack::setFlags ( uint64_t flags ) { if (not _stack.empty()) _stack.back()._flags |= flags; } - inline void ForkStack::push ( Hook* from, AutoContact* contact ) + inline void ForkStack::push ( Hook* from, AutoContact* contact, uint64_t flags ) { - cdebug_log(145,0) << " Stacking " << from << " + " << contact << endl; - _stack.push_back( Element(from,contact) ); + cdebug_log(145,0) << " Stacking: " << endl; + cdebug_log(145,0) << " + " << from << endl; + cdebug_log(145,0) << " + " << contact << endl; + cdebug_log(145,0) << " + " << flags << endl; + _stack.push_back( Element(from,contact,flags) ); } @@ -99,6 +107,7 @@ namespace Anabatic { , Middle = (1 << 16) , UseNonPref = (1 << 17) , NoProtect = (1 << 18) + , ToUpperRouting = (1 << 19) , HBothAccess = HAccess|HAccessEW , SouthWest = SouthBound|WestBound , NorthEast = NorthBound|EastBound @@ -149,13 +158,15 @@ namespace Anabatic { virtual ~NetBuilder (); void clear (); inline bool isTwoMetals () const; + inline bool isUpperMetalRp () const; inline AnabaticEngine* getAnabatic () const; inline unsigned int getDegree () const; inline void setDegree ( unsigned int degree ); void fixSegments (); NetBuilder& setStartHook ( AnabaticEngine* , Hook* fromHook - , AutoContact* sourceContact=NULL ); + , AutoContact* sourceContact=NULL + , uint64_t sourceFlags=0 ); void construct (); inline unsigned int getStateG () const; inline UConnexity getConnexity () const; @@ -169,6 +180,8 @@ namespace Anabatic { inline AutoContact* getNorthEastContact () const; inline AutoContact*& getNorthEastContact (); inline Hook* getFromHook () const; + inline uint64_t getSourceFlags () const; + inline uint64_t getFlags () const; inline ForkStack& getForks (); inline vector& getRoutingPads (); inline map& getRpLookup (); @@ -187,6 +200,7 @@ namespace Anabatic { inline void clearSouths (); inline void clearEasts (); inline void clearWests (); + inline void setFlags ( uint64_t ); inline void setFromHook ( Hook* ); inline void setSouthWestContact ( AutoContact* ); inline void setNorthEastContact ( AutoContact* ); @@ -194,6 +208,7 @@ namespace Anabatic { inline void swapCornerContacts (); inline void addToFixSegments ( AutoSegment* ); bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 ); + bool isInsideBlockage ( GCell*, Component* ) const; virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0; virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0; virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags ); @@ -372,9 +387,8 @@ namespace Anabatic { vector _toFixSegments; unsigned int _degree; bool _isTwoMetals; - - // Sort classes. - public: + uint64_t _sourceFlags; + uint64_t _flags; }; @@ -394,6 +408,8 @@ namespace Anabatic { inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; } inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; } inline Hook* NetBuilder::getFromHook () const { return _fromHook; } + inline uint64_t NetBuilder::getSourceFlags () const { return _sourceFlags; } + inline uint64_t NetBuilder::getFlags () const { return _flags; } inline unsigned int NetBuilder::getTopology () const { return _topology; } inline vector& NetBuilder::getRoutingPads () { return _routingPads; } inline map& NetBuilder::getRpLookup () { return _routingPadAutoSegments; } @@ -403,6 +419,7 @@ namespace Anabatic { inline Hook* NetBuilder::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; } inline Hook* NetBuilder::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; } inline Hook* NetBuilder::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; } + inline void NetBuilder::setFlags ( uint64_t flags ) { _flags |= flags; } inline void NetBuilder::setDegree ( unsigned int degree ) { _degree = degree; } inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; } inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; } diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index 856e4099..67981ae7 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -13,9 +13,7 @@ // | C++ Header : "./anabatic/NetBuilderHV.h" | // +-----------------------------------------------------------------+ -#ifndef ANABATIC_NET_BUILDER_HV_H -#define ANABATIC_NET_BUILDER_HV_H - +#pragma once #include "anabatic/NetBuilder.h" @@ -28,44 +26,44 @@ namespace Anabatic { class NetBuilderHV : public NetBuilder { public: - NetBuilderHV (); - virtual ~NetBuilderHV (); - virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); - virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); - AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* ); - AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); - private: - virtual bool _do_1G_1M1 (); - virtual bool _do_1G_xM1 (); - virtual bool _do_xG (); - virtual bool _do_2G (); - virtual bool _do_2G_1M1 (); - virtual bool _do_xG_1Pad (); - virtual bool _do_1G_1PinM1 (); - virtual bool _do_2G_1PinM1 (); - virtual bool _do_1G_1PinM2 (); - virtual bool _do_xG_1PinM2 (); - virtual bool _do_1G_1PinM3 (); - virtual bool _do_xG_1PinM3 (); - virtual bool _do_xG_1M1 (); - virtual bool _do_xG_1M1_1M2 (); - virtual bool _do_xG_xM1_xM3 (); - virtual bool _do_4G_1M2 (); - virtual bool _do_xG_xM2 (); - virtual bool _do_1G_1M3 (); - virtual bool _do_xG_xM3 (); - virtual bool _do_1G_xM1_1PinM2 (); - virtual bool _do_2G_xM1_1PinM2 (); - virtual bool _do_1G_1M1_1PinM3 (); - virtual bool _do_2G_xM1_1PinM3 (); - virtual bool _do_3G_xM1_1PinM3 (); - virtual bool _do_globalSegment (); - virtual void singleGCell ( AnabaticEngine*, Net* ); - public: - virtual string getTypeName () const; + NetBuilderHV (); + virtual ~NetBuilderHV (); + virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); + AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* ); + AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); + private: + virtual bool _do_1G_1M1 (); + virtual bool _do_1G_xM1 (); + virtual bool _do_xG (); + virtual bool _do_2G (); + virtual bool _do_2G_1M1 (); + virtual bool _do_xG_1Pad (); + virtual bool _do_1G_1PinM1 (); + virtual bool _do_2G_1PinM1 (); + virtual bool _do_1G_1PinM2 (); + virtual bool _do_xG_1PinM2 (); + virtual bool _do_1G_1PinM3 (); + virtual bool _do_xG_1PinM3 (); + virtual bool _do_xG_1M1 (); + virtual bool _do_xG_1M1_1M2 (); + virtual bool _do_xG_xM1_xM3 (); + virtual bool _do_4G_1M2 (); + virtual bool _do_xG_xM2 (); + virtual bool _do_1G_1M3 (); + virtual bool _do_xG_xM3 (); + bool _do_xG_xM3_baseRouting (); + bool _do_xG_xM3_upperRouting (); + virtual bool _do_1G_xM1_1PinM2 (); + virtual bool _do_2G_xM1_1PinM2 (); + virtual bool _do_1G_1M1_1PinM3 (); + virtual bool _do_2G_xM1_1PinM3 (); + virtual bool _do_3G_xM1_1PinM3 (); + virtual bool _do_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + public: + virtual string getTypeName () const; }; } // Anabatic namespace. - -#endif // ANABATIC_NET_BUILDER_HV_H diff --git a/anabatic/src/anabatic/NetBuilderVH.h b/anabatic/src/anabatic/NetBuilderVH.h index 0c266a52..9150b569 100644 --- a/anabatic/src/anabatic/NetBuilderVH.h +++ b/anabatic/src/anabatic/NetBuilderVH.h @@ -13,9 +13,7 @@ // | C++ Header : "./anabatic/NetBuilderVH.h" | // +-----------------------------------------------------------------+ -#ifndef ANABATIC_NET_BUILDER_VH_H -#define ANABATIC_NET_BUILDER_VH_H - +#pragma once #include "anabatic/NetBuilder.h" @@ -50,5 +48,3 @@ namespace Anabatic { } // Anabatic namespace. - -#endif // ANABATIC_NET_BUILDER_VH_H diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index 18e16f74..af4379cd 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -825,7 +825,7 @@ namespace CRL { CellGauge* AllianceFramework::matchCellGauge ( DbU::Unit width, DbU::Unit height ) const { - for ( const auto item : _cellGauges ) { + for ( const auto& item : _cellGauges ) { CellGauge* cg = item.second; DbU::Unit hcount = width / cg->getSliceStep (); DbU::Unit hremains = width % cg->getSliceStep (); @@ -842,7 +842,7 @@ namespace CRL { CellGauge* AllianceFramework::matchCellGaugeByHeight ( DbU::Unit height ) const { - for ( const auto item : _cellGauges ) { + for ( const auto& item : _cellGauges ) { CellGauge* cg = item.second; DbU::Unit vcount = height / cg->getSliceHeight(); DbU::Unit vremains = height % cg->getSliceHeight(); diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 07eb5e83..21455101 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -56,20 +56,22 @@ namespace CRL { RoutingGauge::RoutingGauge ( const char* name ) - : _name (name) - , _layerGauges() - , _viaLayers () - , _technology (DataBase::getDB()->getTechnology()) - , _isSymbolic (true) + : _name (name) + , _layerGauges () + , _viaLayers () + , _technology (DataBase::getDB()->getTechnology()) + , _isSymbolic (true) + , _isSuperPitched(true) { } RoutingGauge::RoutingGauge ( const RoutingGauge& gauge ) - : _name (gauge._name) - , _layerGauges() - , _viaLayers () - , _technology (gauge._technology) - , _isSymbolic (gauge._isSymbolic) + : _name (gauge._name) + , _layerGauges () + , _viaLayers () + , _technology (gauge._technology) + , _isSymbolic (gauge._isSymbolic) + , _isSuperPitched(gauge._isSuperPitched) { // Make a deep copy of the map. for ( size_t i=0 ; i 3) and _isSuperPitched) { + float r = ((float)layerGauge->getPitch() / (float)_layerGauges[gaugeSize-3]->getPitch()); + if (fabsf(roundf(r) - r) > 0.00001f) + _isSuperPitched = false; + } } diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index caf04eaf..4ffdef82 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef CRL_ROUTING_GAUGE_H -#define CRL_ROUTING_GAUGE_H - +#pragma once #include #include #include "hurricane/Name.h" @@ -56,6 +54,7 @@ namespace CRL { // Predicates. inline bool isSymbolic () const; inline bool isTwoMetals () const; + inline bool isSuperPitched () const; inline bool isHV () const; inline bool isVH () const; inline bool hasPowerSupply () const; @@ -109,6 +108,7 @@ namespace CRL { vector _viaLayers; Technology* _technology; bool _isSymbolic; + bool _isSuperPitched; // Internal - Constructors & Destructors. RoutingGauge ( const char* name ); @@ -120,6 +120,7 @@ namespace CRL { inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; } + inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; } inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); } inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); } inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); } @@ -155,5 +156,3 @@ namespace CRL { } // CRL namespace. INSPECTOR_P_SUPPORT(CRL::RoutingGauge); - -#endif diff --git a/crlcore/src/pyCRL/PyRoutingGauge.cpp b/crlcore/src/pyCRL/PyRoutingGauge.cpp index 5ccd1ad9..3e9a2bec 100644 --- a/crlcore/src/pyCRL/PyRoutingGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingGauge.cpp @@ -504,6 +504,7 @@ extern "C" { GetNameMethod(RoutingGauge,rg) accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge) DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge) + DirectGetBoolAttribute(PyRoutingGauge_isSuperPitched,isSuperPitched,PyRoutingGauge,RoutingGauge) DirectSetBoolAttribute(PyRoutingGauge_setSymbolic ,setSymbolic ,PyRoutingGauge,RoutingGauge) DirectGetBoolAttribute(PyRoutingGauge_isHV ,isHV ,PyRoutingGauge,RoutingGauge) DirectGetBoolAttribute(PyRoutingGauge_isVH ,isVH ,PyRoutingGauge,RoutingGauge) @@ -518,6 +519,8 @@ extern "C" { , "Create a new RoutingGauge." } , { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS , "The RoutingGauge is for symbolic technology." } + , { "isSuperPitched" , (PyCFunction)PyRoutingGauge_isSuperPitched , METH_NOARGS + , "The RoutingGauge is super-pitched." } , { "isHV" , (PyCFunction)PyRoutingGauge_isHV , METH_NOARGS , "The first routing layer (metal2) is horizontal." } , { "isVH" , (PyCFunction)PyRoutingGauge_isVH , METH_NOARGS diff --git a/hurricane/src/hurricane/Contact.cpp b/hurricane/src/hurricane/Contact.cpp index e44eb6fb..69e1d5c6 100644 --- a/hurricane/src/hurricane/Contact.cpp +++ b/hurricane/src/hurricane/Contact.cpp @@ -287,13 +287,13 @@ void Contact::translate(const DbU::Unit& dx, const DbU::Unit& dy) void Contact::setLayer(const Layer* layer) // *************************************** { - if (!layer) - throw Error("Can't set layer : null layer"); + if (not layer) + throw Error( "Contact::setLayer(): Invalid NULL layer on %s.", getString(this).c_str() ); - if (layer != _layer) { - invalidate(false); - _layer = layer; - } + if (layer != _layer) { + invalidate( false ); + _layer = layer; + } } void Contact::setWidth(DbU::Unit width) diff --git a/hurricane/src/isobar/PyRectilinear.cpp b/hurricane/src/isobar/PyRectilinear.cpp index b5b5bcb7..0f837ff9 100644 --- a/hurricane/src/isobar/PyRectilinear.cpp +++ b/hurricane/src/isobar/PyRectilinear.cpp @@ -62,8 +62,9 @@ extern "C" { #if defined(__PYTHON_MODULE__) // Standard Accessors (Attributes). - DirectGetLongAttribute(PyRectilinear_getX, getX, PyRectilinear, Rectilinear) - DirectGetLongAttribute(PyRectilinear_getY, getY, PyRectilinear, Rectilinear) + DirectGetLongAttribute(PyRectilinear_getX , getX , PyRectilinear, Rectilinear) + DirectGetLongAttribute(PyRectilinear_getY , getY , PyRectilinear, Rectilinear) + DirectGetBoolAttribute(PyRectilinear_isNonRectangle, isNonRectangle, PyRectilinear, Rectilinear) // Standard Destroy (Attribute). DBoDestroyAttribute(PyRectilinear_destroy, PyRectilinear) @@ -173,6 +174,7 @@ extern "C" { PyMethodDef PyRectilinear_Methods[] = { { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC , "Create a new Rectilinear polygon." } + , { "isNonRectangle", (PyCFunction)PyRectilinear_isNonRectangle, METH_NOARGS , "Tells if the shape is not a rectangle." } , { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." } , { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." } , { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 6f21dd8b..56c688cd 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -594,6 +594,7 @@ namespace Katana { if (edge->getReservedCapacity() < hReservedMin) edge->reserveCapacity( hReservedMin - edge->getReservedCapacity() ); } + gcell->postGlobalAnnotate(); } } } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 0bf5d10c..0d85e57c 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -470,9 +470,9 @@ namespace Katana { queue.repushInvalidateds(); - // if (getProcesseds() == 286892 + 1) { + // if (getProcesseds() == 48172 + 1) { // UpdateSession::close(); - // Breakpoint::stop( 1, "Stopping before revalidating event 286892." ); + // Breakpoint::stop( 0, "Stopping before revalidating event 3107." ); // UpdateSession::open(); // } diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index e0e53e0c..43703308 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -1399,10 +1399,12 @@ namespace Katana { and ( manipulator.getEvent()->getConstraints().isPonctual() or (isFullBlocked() and (_costs.size() > 7))) and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) { + cdebug_log(159,0) << "Next state: MoveUp." << endl; moveUpFlags |= Manipulator::AllowTerminalMoveUp; } else { if ((success = manipulator.slacken(Flags::HalfSlacken))) { nextState = DataNegociate::RipupPerpandiculars; + cdebug_log(159,0) << "Next state: RipupPerpandiculars (half-slacken succeeded)." << endl; break; } } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 210c05a6..95b338ca 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -389,14 +389,14 @@ namespace Katana { TrackElement* Track::getPrevious ( size_t& index, Net* net ) const { - for ( index-- ; index != npos ; index-- ) { - cdebug_log(140,0) << index << ":" << _segments[index] << endl; - - if (_segments[index]->getNet() == net) continue; - return _segments[index]; - } + cdebug_log(155,0) << "Track::getPrevious() " << index << " for " << net << endl; + if ((index == npos) or (index == 0)) return NULL; + do { + --index; + cdebug_log(155,0) << "| " << index << ":" << _segments[index] << endl; + if (_segments[index]->getNet() != net) return _segments[index]; + } while ( index != 0 ); index = npos; - return NULL; } @@ -682,7 +682,7 @@ namespace Katana { DbU::Unit minFree = _min; cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl; - if (not (state & BeginIsTrackMin) ) { + if (not (state & BeginIsTrackMin) and (begin > 0)) { if (_segments[begin]->getNet() == net) getPrevious( begin, net );