From 8978074fe72acb90b94a6c3b20ba820a1b753b69 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 20 Apr 2020 12:53:07 +0200 Subject: [PATCH] Added new configuration in NetBuilderHV (for M3 Pins). * New: In Anabatic::NetBuilderHV(), added configurations to manage one Pin M3 + one M1 terminal plus 2 & 3 globals: * _do_2G_1M1_1PinM3() * _do_3G_1M1_1PinM3() They were occuring for the first time in soclayout/experiment7 in the "flat" approach. * New: In Katana::runNegociate(), mark the newly routed netlist as "NetlistTerminal" so it is not placed and routed *again* when reused as an instance (mostly interract with Etesian). --- anabatic/src/NetBuilder.cpp | 16 +++ anabatic/src/NetBuilderHV.cpp | 145 ++++++++++++++++++++++++++- anabatic/src/anabatic/NetBuilder.h | 4 + anabatic/src/anabatic/NetBuilderHV.h | 65 ++++++------ katana/src/KatanaEngine.cpp | 1 + katana/src/NegociateWindow.cpp | 10 +- 6 files changed, 202 insertions(+), 39 deletions(-) diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 6138f904..7d53cc08 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -649,6 +649,8 @@ namespace Anabatic { case Conn_1G_2M1_1PinM2: _do_1G_xM1_1PinM2(); break; case Conn_2G_1M1_1PinM2: case Conn_2G_2M1_1PinM2: _do_2G_xM1_1PinM2(); break; + case Conn_2G_1M1_1PinM3: _do_2G_1M1_1PinM3(); break; + case Conn_3G_1M1_1PinM3: _do_3G_1M1_1PinM3(); break; case Conn_1G_1M1_1M2: _do_xG_1M1_1M2 (); break; case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break; @@ -1113,6 +1115,20 @@ namespace Anabatic { throw Error ( "%s::_do_2G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() ); return false; } + + + bool NetBuilder::_do_2G_1M1_1PinM3 () + { + throw Error ( "%s::_do_2G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() ); + return false; + } + + + bool NetBuilder::_do_3G_1M1_1PinM3 () + { + throw Error ( "%s::_do_3G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() ); + return false; + } bool NetBuilder::_do_globalSegment () diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index d46dc31b..f8f9583e 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -290,6 +290,40 @@ namespace Anabatic { } + AutoContact* NetBuilderHV::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl; + + Net* net = rp->getNet(); + Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + AutoContact* rpSourceContact = NULL; + AutoContact* rpContactTarget = NULL; + AutoContact* turn = NULL; + AutoSegment* segment = NULL; + + doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect ); + + turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) ); + segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal ); + segment->setAxis( pin->getCenter().getY(), Flags::Force ); + + rpSourceContact = turn; + turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) ); + segment = AutoSegment::create( rpSourceContact, turn, Flags::Vertical ); + + DbU::Unit axis = 0; + if (pinDir == Pin::AccessDirection::EAST) + axis = gcell->getXMax() - Session::getDVerticalPitch(); + else + axis = gcell->getXMin() + Session::getDVerticalPitch(); + segment->setAxis( axis ); + + cdebug_tabw(145,-1); + return turn; + } + + bool NetBuilderHV::_do_1G_1M1 () { cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; @@ -872,6 +906,92 @@ namespace Anabatic { } + bool NetBuilderHV::_do_3G_1M1_1PinM3 () + { + cdebug_log(145,1) << getTypeName() << "::_do_3G_1M1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl; + + RoutingPad* rpM1 = NULL; + RoutingPad* pinM3 = NULL; + AutoContact* pinContact = NULL; + AutoContact* dummy = NULL; + + for ( RoutingPad* rp : getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) pinM3 = rp; + else rpM1 = rp; + } + + doRp_AutoContacts( getGCell(), pinM3, pinContact, dummy, NoFlags ); + + AutoContact* m1contact = doRp_Access( getGCell(), rpM1, HAccess ); + + AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( m1contact , vtee1, Flags::Horizontal ); + + AutoContact* vtee2 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( vtee1, vtee2, Flags::Vertical ); + + AutoContact* vtee3 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( vtee2, vtee3, Flags::Vertical ); + + if (not south() or not north()) { + AutoSegment::create( pinContact, vtee1, Flags::Vertical ); + } + + if (not east() or not west()) { + AutoSegment::create( pinContact, vtee2, Flags::Horizontal ); + } + + if (not south()) { + setSouthWestContact( vtee2 ); + setNorthEastContact( vtee3 ); + } else if (not north()) { + setSouthWestContact( vtee3 ); + setNorthEastContact( vtee2 ); + } else if (not east()) { + setSouthWestContact( vtee3 ); + setNorthEastContact( vtee1 ); + } else if (not west()) { + setSouthWestContact( vtee1 ); + setNorthEastContact( vtee3 ); + } + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderHV::_do_2G_1M1_1PinM3 () + { + cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl; + + RoutingPad* rpM1 = NULL; + RoutingPad* pinM3 = NULL; + AutoContact* pinContact = NULL; + AutoContact* dummy = NULL; + + for ( RoutingPad* rp : getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) pinM3 = rp; + else rpM1 = rp; + } + + doRp_AutoContacts( getGCell(), pinM3, pinContact, dummy, NoFlags ); + + AutoContact* m1contact = doRp_Access( getGCell(), rpM1, HAccess ); + + AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( m1contact , vtee1, Flags::Horizontal ); + AutoSegment::create( pinContact, vtee1, Flags::Vertical ); + + AutoContact* vtee2 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( vtee1, vtee2, Flags::Vertical ); + + setBothCornerContacts( vtee2 ); + + cdebug_tabw(145,-1); + return true; + } + + bool NetBuilderHV::_do_1G_xM1_1PinM2 () { cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl; @@ -1632,11 +1752,26 @@ namespace Anabatic { } if (rpPin) { - doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact ); - target = doRp_AccessNorthPin( gcell1, rpPin ); - turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( source, turn1 , Flags::Horizontal ); - AutoSegment::create( turn1 , target, Flags::Vertical ); + Pin* pin = dynamic_cast( rpPin->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + + if ( (pinDir == Pin::AccessDirection::NORTH) + or (pinDir == Pin::AccessDirection::SOUTH) ) { + doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact ); + target = doRp_AccessNorthPin( gcell1, rpPin ); + turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( source, turn1 , Flags::Horizontal ); + AutoSegment::create( turn1 , target, Flags::Vertical ); + } else { + RoutingPad* closest = NULL; + + if (pinDir == Pin::AccessDirection::EAST) closest = rpM1s.back(); + else closest = rpM1s.front(); + + doRp_AutoContacts( gcell1, closest, source, turn1, DoSourceContact ); + target = doRp_AccessEastWestPin( gcell1, rpPin ); + AutoSegment::create( source, target , Flags::Horizontal ); + } } cdebug_tabw(145,-1); diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index ec060849..c72b7ca6 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -224,6 +224,8 @@ namespace Anabatic { virtual bool _do_1G_xM1_1PinM2 (); virtual bool _do_2G_xM1_1PinM2 (); virtual bool _do_1G_1M1_1PinM3 (); + virtual bool _do_2G_1M1_1PinM3 (); + virtual bool _do_3G_1M1_1PinM3 (); virtual bool _do_globalSegment (); virtual void singleGCell ( AnabaticEngine*, Net* ); AutoContact* _doHChannel (); @@ -318,6 +320,8 @@ namespace Anabatic { , Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 ) , Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 ) , Conn_1G_1M1_1PinM3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 1 ) + , Conn_2G_1M1_1PinM3 = CONNEXITY_VALUE( 2, 1, 0, 1, 0 , 1 ) + , Conn_3G_1M1_1PinM3 = CONNEXITY_VALUE( 3, 1, 0, 1, 0 , 1 ) }; #undef CONNEXITY_VALUE diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index b4442ea7..f2c44655 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -28,38 +28,41 @@ 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* ); + 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_globalSegment (); - virtual void singleGCell ( AnabaticEngine*, Net* ); - public: - virtual string getTypeName () const; + 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_1M1_1PinM3 (); + virtual bool _do_3G_1M1_1PinM3 (); + virtual bool _do_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + public: + virtual string getTypeName () const; }; diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index bd647bcb..7eb94921 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -559,6 +559,7 @@ namespace Katana { _negociateWindow->run( flags ); _negociateWindow->destroy(); _negociateWindow = NULL; + getCell()->setTerminalNetlist( true ); Session::close(); stopMeasures(); diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 1e673070..d0d16115 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -318,6 +318,8 @@ namespace Katana { TrackElement* NegociateWindow::createTrackSegment ( AutoSegment* autoSegment, Flags flags ) { + DebugSession::open( autoSegment->getNet(), 159, 160 ); + cdebug_log(159,1) << "NegociateWindow::createTrackSegment() - " << autoSegment << endl; // Special case: fixed AutoSegments must not interfere with blockages. @@ -374,7 +376,7 @@ namespace Katana { if (trackSegment->isNonPref()) { _segments.push_back( trackSegment ); - cdebug_log(159,0) << "Non-preferred diection, do not attempt to set on track." << endl; + cdebug_log(159,0) << "Non-preferred direction, do not attempt to set on track." << endl; cdebug_tabw(159,-1); return trackSegment; } @@ -385,9 +387,10 @@ namespace Katana { Interval constraints; autoSegment->getConstraints( constraints ); - uside.intersection( constraints ); - cdebug_log(159,0) << "* Constraints " << constraints << endl; + + uside.intersection( constraints ); + cdebug_log(159,0) << "* Constraints+U-side " << constraints << endl; cdebug_log(159,0) << "* Nearest " << track << endl; if (not track) @@ -420,6 +423,7 @@ namespace Katana { } cdebug_tabw(159,-1); + DebugSession::close(); return trackSegment; }