From db0ad6bf072403e0701f9b3330c73d36f5e7da31 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 17 Feb 2021 23:34:17 +0100 Subject: [PATCH] Partial support for offgrid METAL3 RoutingPad in Anabatic::NetBuilderHV. * New: In Anabatic::NetBuilder::_do_1G_1M3(), RoutingPad in METAL3 from blocks are most likely to be offgrid in real mode, we must account for that case. When an offgrid METAL3 is found, a strap of METAL2 is added, as it may be less than one pitch, it will be reduced into METAL3 often. * New: In Anabatic::NetBuilder::doRp_Access(), Support for offgrid METAL2 is added but not enabled yet. Seems to need more polishing. --- anabatic/src/NetBuilderHV.cpp | 53 ++++++++++++++++++++++++++------- anabatic/src/anabatic/Session.h | 9 ++---- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index cad28257..dab61af8 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -168,9 +168,9 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; - size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); - AutoContact* rpSourceContact; - AutoContact* rpContactTarget; + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); + AutoContact* rpSourceContact = NULL; + AutoContact* rpContactTarget = NULL; Flags useNonPref = Flags::NoFlags; if (flags & UseNonPref) useNonPref |= Flags::UseNonPref; @@ -239,6 +239,22 @@ namespace Anabatic { AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical ); } else { +#if OFFGRID_M2_DISABLED + Box cellAb = getAnabatic()->getCell()->getAbutmentBox(); + RoutingLayerGauge* lgM2 = Session::getLayerGauge( 1 ); + DbU::Unit trackAxis = lgM2->getTrackPosition( cellAb.getYMin() + , cellAb.getYMax() + , rp->getY() + , Constant::Nearest ); + bool offGrid = (trackAxis != rp->getY()); + if (offGrid) { + cdebug_log(145,0) << "Off grid, Misaligned M2 RoutingPad, add vertical strap" << endl; + subContact1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical ); + rpSourceContact = subContact1; + } +#endif + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); } @@ -1549,6 +1565,20 @@ namespace Anabatic { const Layer* viaLayer1 = Session::getContactLayer(1); + Box cellAb = getAnabatic()->getCell()->getAbutmentBox(); + RoutingLayerGauge* lgM3 = Session::getLayerGauge( 2 ); + DbU::Unit trackAxis = lgM3->getTrackPosition( cellAb.getXMin() + , cellAb.getXMax() + , getRoutingPads()[0]->getX() + , Constant::Nearest ); + bool offGrid = (trackAxis != getRoutingPads()[0]->getX()); + if (offGrid) { + cdebug_log(145,0) << "Off grid, Misaligned M3, add horizontal strap" << endl; + AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); + AutoSegment::create( getSouthWestContact(), turn1, Flags::Horizontal ); + setBothCornerContacts( turn1 ); + } + if (flags & HAccess) { // HARDCODED VALUE. if (getRoutingPads()[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) { @@ -1558,14 +1588,15 @@ namespace Anabatic { setBothCornerContacts( subContact ); } } else { - if (getSourceContact()) { - if (getSourceContact()->getX() != getSouthWestContact()->getX()) { - 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 ); - setBothCornerContacts( turn2 ); - } + if (getSourceContact() and (getSourceContact()->getX() != getSouthWestContact()->getX())) { + cdebug_log(145,0) << "On grid, Misaligned M3, add dogleg" << endl; + AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); + AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); + AutoSegment* v1 = AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical ); + AutoSegment::create( turn1, turn2, Flags::Horizontal ); + v1->setAxis( getSouthWestContact()->getX(), Flags::Force ); + v1->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis ); + setBothCornerContacts( turn2 ); } } cdebug_tabw(145,-1); diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index e031d39a..c87affd9 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef ANABATIC_SESSION_H -#define ANABATIC_SESSION_H - +#pragma once #include #include #include @@ -115,6 +113,7 @@ namespace Anabatic { static inline bool isGMetal ( const Layer* ); static inline bool isGContact ( const Layer* ); static inline bool isGaugeLayer ( const Layer* ); + static inline RoutingLayerGauge* getLayerGauge ( const Layer* ); static inline RoutingLayerGauge* getLayerGauge ( size_t depth ); static inline size_t getDepth (); static inline size_t getViaDepth ( const Layer* layer ); @@ -259,6 +258,7 @@ namespace Anabatic { inline bool Session::isGMetal ( const Layer* layer ) { return getConfiguration()->isGMetal(layer); } inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); } inline bool Session::isGaugeLayer ( const Layer* layer ) { return getRoutingGauge()->hasLayer(layer); } + inline RoutingLayerGauge* Session::getLayerGauge ( const Layer* layer ) { return getRoutingGauge()->getLayerGauge(layer); } inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); } inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); } inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); } @@ -290,6 +290,3 @@ namespace Anabatic { INSPECTOR_P_SUPPORT(Anabatic::Session); - - -#endif // ANABATIC_SESSION_H