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.
This commit is contained in:
Jean-Paul Chaput 2021-02-17 23:34:17 +01:00
parent d942f3cb59
commit db0ad6bf07
2 changed files with 45 additions and 17 deletions

View File

@ -168,9 +168,9 @@ namespace Anabatic {
{ {
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
AutoContact* rpSourceContact; AutoContact* rpSourceContact = NULL;
AutoContact* rpContactTarget; AutoContact* rpContactTarget = NULL;
Flags useNonPref = Flags::NoFlags; Flags useNonPref = Flags::NoFlags;
if (flags & UseNonPref) useNonPref |= Flags::UseNonPref; if (flags & UseNonPref) useNonPref |= Flags::UseNonPref;
@ -239,6 +239,22 @@ namespace Anabatic {
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical ); AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
} else { } 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) ); subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
} }
@ -1549,6 +1565,20 @@ namespace Anabatic {
const Layer* viaLayer1 = Session::getContactLayer(1); 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) { if (flags & HAccess) {
// HARDCODED VALUE. // HARDCODED VALUE.
if (getRoutingPads()[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) { if (getRoutingPads()[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) {
@ -1558,14 +1588,15 @@ namespace Anabatic {
setBothCornerContacts( subContact ); setBothCornerContacts( subContact );
} }
} else { } else {
if (getSourceContact()) { if (getSourceContact() and (getSourceContact()->getX() != getSouthWestContact()->getX())) {
if (getSourceContact()->getX() != getSouthWestContact()->getX()) { cdebug_log(145,0) << "On grid, Misaligned M3, add dogleg" << endl;
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical ); AutoSegment* v1 = AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
AutoSegment::create( turn1 , turn2, Flags::Horizontal ); AutoSegment::create( turn1, turn2, Flags::Horizontal );
setBothCornerContacts( turn2 ); v1->setAxis( getSouthWestContact()->getX(), Flags::Force );
} v1->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
setBothCornerContacts( turn2 );
} }
} }
cdebug_tabw(145,-1); cdebug_tabw(145,-1);

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef ANABATIC_SESSION_H #pragma once
#define ANABATIC_SESSION_H
#include <string> #include <string>
#include <vector> #include <vector>
#include <set> #include <set>
@ -115,6 +113,7 @@ namespace Anabatic {
static inline bool isGMetal ( const Layer* ); static inline bool isGMetal ( const Layer* );
static inline bool isGContact ( const Layer* ); static inline bool isGContact ( const Layer* );
static inline bool isGaugeLayer ( const Layer* ); static inline bool isGaugeLayer ( const Layer* );
static inline RoutingLayerGauge* getLayerGauge ( const Layer* );
static inline RoutingLayerGauge* getLayerGauge ( size_t depth ); static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
static inline size_t getDepth (); static inline size_t getDepth ();
static inline size_t getViaDepth ( const Layer* layer ); 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::isGMetal ( const Layer* layer ) { return getConfiguration()->isGMetal(layer); }
inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); } inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); }
inline bool Session::isGaugeLayer ( const Layer* layer ) { return getRoutingGauge()->hasLayer(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 RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); } inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); } inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }
@ -290,6 +290,3 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::Session); INSPECTOR_P_SUPPORT(Anabatic::Session);
#endif // ANABATIC_SESSION_H