diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index b265663a..bb524f92 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -25,6 +25,7 @@ #include "hurricane/BasicLayer.h" #include "hurricane/RegularLayer.h" #include "hurricane/RoutingPad.h" +#include "hurricane/Pin.h" #include "hurricane/NetExternalComponents.h" #include "hurricane/Cell.h" #include "crlcore/Utilities.h" @@ -55,6 +56,7 @@ namespace Anabatic { using Hurricane::BasicLayer; using Hurricane::RegularLayer; using Hurricane::Segment; + using Hurricane::Pin; using Hurricane::Plug; using Hurricane::Path; using Hurricane::Occurrence; @@ -458,13 +460,18 @@ namespace Anabatic { cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl; for ( Component* component : masterNet->getComponents() ) { cdebug_log(112,0) << "@ " << component << endl; - if (not NetExternalComponents::isExternal(component)) continue; + if (not NetExternalComponents::isExternal(component)) { + cdebug_log(112,0) << " Not an external component, skip." << endl; + continue; + } - Segment* segment = dynamic_cast(component); - if (not segment) continue; - if (segment->getLayer()->getMask() != metal1->getMask()) continue; + Component* candidate = dynamic_cast(component); + if (not candidate + or (candidate->getLayer()->getMask() != metal1->getMask()) ) + candidate = dynamic_cast(component); + if (not candidate) continue; - Box bb = transformation.getBox( component->getBoundingBox() ); + Box bb = transformation.getBox( candidate->getBoundingBox() ); DbU::Unit trackPos = 0; DbU::Unit minPos = DbU::Max; DbU::Unit maxPos = DbU::Min; @@ -497,7 +504,7 @@ namespace Anabatic { cdebug_log(112,0) << "| " << occurrence.getPath() << endl; cdebug_log(112,0) << "| " << transformation << endl; - cdebug_log(112,0) << "| " << bb << " of:" << segment << endl; + cdebug_log(112,0) << "| " << bb << " of:" << candidate << endl; cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 33ede5ce..6138f904 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -401,14 +401,14 @@ namespace Anabatic { for ( Hook* hook : fromHook->getHooks() ) { cdebug_log(145,0) << "Hook: " << hook << endl; cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = " - << "[" << (int)_connexity.fields.globals - << "+" << (int)_connexity.fields.M1 - << "+" << (int)_connexity.fields.M2 - << "+" << (int)_connexity.fields.M3 - << "+" << (int)_connexity.fields.Pin - << "+" << (int)_connexity.fields.Pad - << "] " << _gcell - << endl; + << "[" << (int)_connexity.fields.globals + << "+" << (int)_connexity.fields.M1 + << "+" << (int)_connexity.fields.M2 + << "+" << (int)_connexity.fields.M3 + << "+" << (int)_connexity.fields.Pin + << "+" << (int)_connexity.fields.Pad + << "] " << _gcell + << endl; Segment* toSegment = dynamic_cast( hook->getComponent() ); if (toSegment) { @@ -507,6 +507,16 @@ namespace Anabatic { if (_gcell == NULL) throw Error( missingGCell ); + cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = " + << "[" << (int)_connexity.fields.globals + << "+" << (int)_connexity.fields.M1 + << "+" << (int)_connexity.fields.M2 + << "+" << (int)_connexity.fields.M3 + << "+" << (int)_connexity.fields.Pin + << "+" << (int)_connexity.fields.Pad + << "] " << _gcell + << endl; + return *this; } @@ -543,6 +553,15 @@ namespace Anabatic { void NetBuilder::construct () { cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl; + cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = " + << "[" << (int)_connexity.fields.globals + << "+" << (int)_connexity.fields.M1 + << "+" << (int)_connexity.fields.M2 + << "+" << (int)_connexity.fields.M3 + << "+" << (int)_connexity.fields.Pin + << "+" << (int)_connexity.fields.Pad + << "] " << _gcell + << endl; if (not isTwoMetals()) { _southWestContact = NULL; @@ -617,17 +636,22 @@ namespace Anabatic { case Conn_4G: _do_xG(); break; // End xG cascaded cases. // Optimized specific cases. - case Conn_1G_1PinM1: _do_1G_1PinM1 (); break; - case Conn_2G_1PinM1: _do_2G_1PinM1 (); break; - case Conn_1G_1PinM2: _do_1G_1PinM2 (); break; - case Conn_2G_1PinM2: - case Conn_3G_1PinM2: _do_xG_1PinM2 (); break; - case Conn_1G_1PinM3: _do_1G_1PinM3 (); break; - case Conn_2G_1PinM3: - case Conn_3G_1PinM3: _do_xG_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; + case Conn_1G_1PinM1: _do_1G_1PinM1 (); break; + case Conn_2G_1PinM1: _do_2G_1PinM1 (); break; + case Conn_1G_1PinM2: _do_1G_1PinM2 (); break; + case Conn_2G_1PinM2: + case Conn_3G_1PinM2: _do_xG_1PinM2 (); break; + case Conn_1G_1PinM3: _do_1G_1PinM3 (); break; + case Conn_2G_1PinM3: + case Conn_3G_1PinM3: _do_xG_1PinM3 (); break; + case Conn_1G_1M1_1PinM3: _do_1G_1M1_1PinM3(); break; + case Conn_1G_1M1_1PinM2: + 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_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; default: if (not isTwoMetals()) throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" @@ -1069,7 +1093,28 @@ namespace Anabatic { return false; } + + bool NetBuilder::_do_1G_1M1_1PinM3 () + { + throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() ); + return false; + } + + + bool NetBuilder::_do_1G_xM1_1PinM2 () + { + throw Error ( "%s::_do_1G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() ); + return false; + } + + + bool NetBuilder::_do_2G_xM1_1PinM2 () + { + throw Error ( "%s::_do_2G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() ); + return false; + } + bool NetBuilder::_do_globalSegment () { throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() ); diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 17ce88b3..d46dc31b 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -251,6 +251,45 @@ namespace Anabatic { } + AutoContact* NetBuilderHV::doRp_AccessNorthPin ( GCell* gcell, RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl; + + AutoContact* rpSourceContact = NULL; + AutoContact* rpContactTarget = NULL; + AutoContact* turn = NULL; + + doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect ); + + Net* net = rp->getNet(); + Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + if (pinDir == Pin::AccessDirection::NORTH) { + turn = AutoContactTurn::create( gcell, net, Session::getRoutingLayer(1) ); + AutoSegment* segment = AutoSegment::create( rpSourceContact, turn, Flags::Vertical ); + segment->setAxis( rp->getX(), Flags::Force ); + segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis ); + rpSourceContact = turn; + + turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(1) ); + segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal ); + rpSourceContact = turn; + + DbU::Unit axis = gcell->getYMax() - Session::getDHorizontalPitch(); + cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl; + + segment->setAxis( axis, Flags::Force ); + //segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis ); + cdebug_log(145,0) << segment << endl; + } else { + turn = rpSourceContact; + } + + cdebug_tabw(145,-1); + return turn; + } + + bool NetBuilderHV::_do_1G_1M1 () { cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; @@ -744,9 +783,8 @@ namespace Anabatic { cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl; AutoContact* rpSourceContact = NULL; - AutoContact* rpContactTarget = NULL; - doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoFlags ); + rpSourceContact = doRp_AccessNorthPin( getGCell(), getRoutingPads()[0] ); AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); AutoSegment::create( rpSourceContact, turn1, Flags::Vertical ); @@ -804,15 +842,19 @@ namespace Anabatic { setSouthWestContact( turn1 ); setNorthEastContact( htee1 ); - } else { - AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); - AutoSegment::create( rpSourceContact, vtee1, Flags::Vertical ); - + } else if (north() and south()) { AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); - AutoSegment::create( vtee1, turn1, Flags::Vertical ); + AutoSegment::create( rpSourceContact, turn1, Flags::Vertical ); - setSouthWestContact( vtee1 ); - setNorthEastContact( turn1 ); + AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( turn1, vtee1, Flags::Horizontal ); + + setBothCornerContacts( vtee1 ); + } else { // Remaining case is East & West. + AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpSourceContact, htee1, Flags::Vertical ); + + setBothCornerContacts( htee1 ); } } else { AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); @@ -830,6 +872,144 @@ namespace Anabatic { } + bool NetBuilderHV::_do_1G_xM1_1PinM2 () + { + cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl; + + sortRpByX( getRoutingPads(), NoFlags ); // increasing X. + + vector rpsM1; + RoutingPad* pinM2 = NULL; + for ( RoutingPad* rp : getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) pinM2 = rp; + else rpsM1.push_back( rp ); + } + + AutoContact* turn = NULL; + AutoContact* tee = NULL; + AutoContact* pinM2Contact = NULL; + AutoContact* rpM1Contact = NULL; + doRp_AutoContacts( getGCell(), pinM2, pinM2Contact, rpM1Contact, NoProtect ); + rpM1Contact = doRp_Access( getGCell(), rpsM1[0], HAccess ); + + if (north() or south()) { + turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( rpM1Contact , tee , Flags::Horizontal ); + AutoSegment::create( pinM2Contact, turn, Flags::Horizontal ); + AutoSegment::create( tee , turn, Flags::Vertical ); + } else { + turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + tee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( rpM1Contact , turn, Flags::Horizontal ); + AutoSegment::create( pinM2Contact, tee , Flags::Horizontal ); + AutoSegment::create( tee , turn, Flags::Vertical ); + } + setBothCornerContacts( tee ); + + for ( size_t i=1 ; i rpsM1; + RoutingPad* pinM2 = NULL; + for ( RoutingPad* rp : getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) pinM2 = rp; + else rpsM1.push_back( rp ); + } + + AutoContact* pinM2Contact = NULL; + AutoContact* rpM1Contact = NULL; + doRp_AutoContacts( getGCell(), pinM2, pinM2Contact, rpM1Contact, NoFlags ); + rpM1Contact = doRp_Access( getGCell(), rpsM1[0], NoFlags ); + + if (north() and south()) { + AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoContact* vtee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( pinM2Contact, htee, Flags::Horizontal ); + AutoSegment::create( rpM1Contact , htee, Flags::Vertical ); + AutoSegment::create( htee , vtee, Flags::Horizontal ); + setBothCornerContacts( vtee ); + } else if (east() and west()) { + AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( pinM2Contact, htee1, Flags::Horizontal ); + AutoSegment::create( rpM1Contact , htee1, Flags::Vertical ); + AutoSegment::create( htee1 , turn , Flags::Horizontal ); + AutoSegment::create( htee2 , turn , Flags::Vertical ); + setBothCornerContacts( htee2 ); + } else { + AutoContact* htee1 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoContact* htee2 = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( pinM2Contact, htee1, Flags::Horizontal ); + AutoSegment::create( rpM1Contact , htee1, Flags::Vertical ); + AutoSegment::create( htee1 , htee2, Flags::Horizontal ); + AutoSegment::create( htee2 , turn , Flags::Vertical ); + setNorthEastContact( htee2 ); + setSouthWestContact( turn ); + } + + for ( size_t i=1 ; i(rpM1->getOccurrence().getEntity())) std::swap( rpM1, pinM3 ); + + AutoContact* contact1 = doRp_Access( getGCell(), rpM1, HAccess ); + AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( contact1, htee, Flags::Horizontal ); + + rpSourceContact = doRp_AccessNorthPin( getGCell(), pinM3 ); + + if (north() or south()) { + AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpSourceContact, turn, Flags::Vertical ); + AutoSegment::create( turn , htee, Flags::Horizontal ); + } else { + AutoSegment::create( rpSourceContact, htee, Flags::Vertical ); + } + setBothCornerContacts( htee ); + + cdebug_tabw(145,-1); + return true; + } + + bool NetBuilderHV::_do_2G_1M1 () { return _do_xG_1M1(); @@ -1349,6 +1529,120 @@ namespace Anabatic { } + void NetBuilderHV::singleGCell ( AnabaticEngine* anbt, Net* net ) + { + cdebug_log(145,1) << "NetBuilderHV::singleGCell() " << net << endl; + + vector rpM1s; + Component* rpM2 = NULL; + RoutingPad* rpPin = NULL; + + for ( RoutingPad* rp : net->getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) { + rpPin = rp; + continue; + } + + if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 1) + rpM2 = rp; + else + rpM1s.push_back( rp ); + } + + if ( (rpM1s.size() < 2) and not (rpM2 or rpPin) ) { + cerr << Error( "For %s, less than two Plugs/Pins (%d)." + , getString(net).c_str() + , rpM1s.size() ) << endl; + cdebug_tabw(145,-1); + return; + } + + if (rpM1s.empty()) { + cerr << Error( "No METAL1 in Single GCell for Net \"%s\".", getString(net->getName()).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + + sortRpByX( rpM1s, NetBuilder::NoFlags ); // increasing X. + + GCell* gcell1 = anbt->getGCellUnder( (*rpM1s.begin ())->getCenter() ); + GCell* gcell2 = anbt->getGCellUnder( (*rpM1s.rbegin())->getCenter() ); + + if (not gcell1) { + cerr << Error( "No GCell under %s.", getString(*(rpM1s.begin())).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + if (gcell1 != gcell2) { + cerr << Error( "Not under a single GCell %s.", getString(*(rpM1s.rbegin())).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + + cdebug_log(145,0) << "singleGCell " << gcell1 << endl; + + AutoContact* turn1 = NULL; + AutoContact* turn2 = NULL; + AutoContact* source = NULL; + AutoContact* target = NULL; + + for ( size_t irp=1 ; irpgetUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) { + uint64_t flags = checkRoutingPadSize( rpM1s[irp-1] ); + if ((flags & VSmall) or Session::getConfiguration()->isVH()) { + if (Session::getConfiguration()->isHV()) { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( source, turn1, Flags::Horizontal ); + source = turn1; + } + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( source, turn1 , Flags::Vertical ); + source = turn1; + } + flags = checkRoutingPadSize( rpM1s[irp] ); + if ((flags & VSmall) or Session::getConfiguration()->isVH()) { + if (Session::getConfiguration()->isHV()) { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( target, turn1, Flags::Horizontal ); + target = turn1; + } + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( target, turn1 , Flags::Vertical ); + target = turn1; + } + AutoSegment::create( source, target, Flags::Horizontal ); + } else { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + turn2 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( source, turn1 , Flags::Horizontal ); + AutoSegment::create( turn1 , turn2 , Flags::Vertical ); + AutoSegment::create( turn2 , target, Flags::Horizontal ); + } + } + + if (rpM2) { + doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact ); + doRp_AutoContacts( gcell1, rpM2 , target, turn1, DoSourceContact ); + turn1 = AutoContactTurn::create( gcell1, rpM2->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( source, turn1 , Flags::Horizontal ); + AutoSegment::create( turn1 , target, Flags::Vertical ); + } + + 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 ); + } + + cdebug_tabw(145,-1); + } + + string NetBuilderHV::getTypeName () const { return "NetBuilderHV"; } diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index 6bb01d9e..ec060849 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -221,6 +221,9 @@ namespace Anabatic { 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* ); AutoContact* _doHChannel (); @@ -242,74 +245,79 @@ namespace Anabatic { + ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \ + ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize)) - // Connexity Name | G|M1|M2|M3|Pad|Pin| - enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 ) - , Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 ) - , Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 ) - , Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 ) - , Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 ) - , Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 ) - , Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 ) - , Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 ) - , Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 ) - , Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 ) - , Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 ) - , Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 ) - , Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 ) - , Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 ) - , Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 ) - , Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 ) - , Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 ) - , Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 ) - , Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 ) - , Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 ) - , Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 ) - , Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 ) - // Connexity Name | G|M1|M2|M3|Pad|Pin| - , Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 ) - , Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 ) - , Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 ) - , Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 ) - , Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 ) - , Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 ) - , Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 ) - , Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 ) - , Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 ) - , Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 ) - , Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 ) - , Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 ) - , Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 ) - , Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 ) - // Connexity Name | G|M1|M2|M3|Pad|Pin| - , Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 ) - , Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 ) - , Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 ) - , Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 ) - , Conn_3G_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 ) - , Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 ) - , Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 ) - , Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 ) - , Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 ) - , Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 ) - , Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 ) - // Connexity Name | G|M1|M2|M3|Pad|Pin| - , Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 ) - , Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 ) - , Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 ) - , Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 ) - , Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 ) - , Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 ) - , Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 ) - , Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 ) - , Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 ) - , Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 ) - , Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 ) - , Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 ) - , Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 ) - , Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 ) - , Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 ) - , Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 ) - , Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 ) + // Connexity Name | G|M1|M2|M3|Pad|Pin| + enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 ) + , Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 ) + , Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 ) + , Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 ) + , Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 ) + , Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 ) + , Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 ) + , Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 ) + , Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 ) + , Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 ) + , Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 ) + , Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 ) + , Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 ) + , Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 ) + , Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 ) + , Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 ) + , Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 ) + , Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 ) + , Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 ) + , Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 ) + , Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 ) + , Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 ) + // Connexity Name | G|M1|M2|M3|Pad|Pin| + , Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 ) + , Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 ) + , Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 ) + , Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 ) + , Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 ) + , Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 ) + , Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 ) + , Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 ) + , Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 ) + , Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 ) + , Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 ) + , Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 ) + , Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 ) + , Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 ) + // Connexity Name | G|M1|M2|M3|Pad|Pin| + , Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 ) + , Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 ) + , Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 ) + , Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 ) + , Conn_3G_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 ) + , Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 ) + , Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 ) + , Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 ) + , Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 ) + , Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 ) + , Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 ) + // Connexity Name | G|M1|M2|M3|Pad|Pin| + , Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 ) + , Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 ) + , Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 ) + , Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 ) + , Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 ) + , Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 ) + , Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 ) + , Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 ) + , Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 ) + , Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 ) + , Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 ) + , Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 ) + , Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 ) + , Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 ) + , Conn_1G_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 ) + , Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 ) + , Conn_2G_1M1_1PinM2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 1 ) + , Conn_2G_2M1_1PinM2 = CONNEXITY_VALUE( 2, 2, 1, 0, 0 , 1 ) + , Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 ) + , 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 ) }; #undef CONNEXITY_VALUE diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index 59f79fda..b4442ea7 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -28,33 +28,38 @@ 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 ); + 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* ); 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_globalSegment (); - 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_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + public: + virtual string getTypeName () const; }; diff --git a/etesian/src/AddFeeds.cpp b/etesian/src/AddFeeds.cpp index e031d260..928eef8e 100644 --- a/etesian/src/AddFeeds.cpp +++ b/etesian/src/AddFeeds.cpp @@ -370,6 +370,8 @@ namespace Etesian { sliceHoles.setSpinSlice0( _yspinSlice0 ); + Cell::setFlattenLeafMode( true ); + for ( Occurrence occurrence : getBlockCell()->getLeafInstanceOccurrences() ) { Instance* instance = static_cast(occurrence.getEntity()); @@ -397,6 +399,8 @@ namespace Etesian { sliceHoles.addFeeds(); + Cell::setFlattenLeafMode( false ); + UpdateSession::close(); if (_viewer) _viewer->getCellWidget()->refresh(); diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 95f27d4c..cc6150ef 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -432,7 +432,6 @@ namespace Etesian { { //cerr << "EtesianEngine::resetPlacement()" << endl; - if (not getBlockCell()->isPlaced()) return; _flatDesign = true; Dots dots ( cmess2, " ", 80, 1000 ); @@ -461,10 +460,11 @@ namespace Etesian { Instance* instance = static_cast(ioccurrence.getEntity()); instance->destroy(); } - if (not getBlockCell()->getAbutmentBox().isEmpty() ) - setFixedAbHeight( getBlockCell()->getAbutmentBox().getHeight() ); - getBlockCell()->setAbutmentBox( Box() ); - getBlockCell()->resetFlags( Cell::Flags::Placed ); + + // if (not getBlockCell()->getAbutmentBox().isEmpty() ) + // setFixedAbHeight( getBlockCell()->getAbutmentBox().getHeight() ); + // getBlockCell()->setAbutmentBox( Box() ); + // getBlockCell()->resetFlags( Cell::Flags::Placed ); UpdateSession::close(); dots.finish( Dots::Reset ); @@ -483,40 +483,42 @@ namespace Etesian { cmess1 << ::Dots::asString(" - H-pitch" , DbU::getValueString(hpitch)) << endl; cmess1 << ::Dots::asString(" - V-pitch" , DbU::getValueString(vpitch)) << endl; - resetPlacement(); - Dots dots ( cmess2, " ", 80, 1000 ); if (not cmess2.enabled()) dots.disable(); - - size_t instancesNb = getCell()->getLeafInstanceOccurrences(getBlockInstance()).getSize() + 1; // One dummy fixed instance at the end - - // Coloquinte circuit description data-structures. - vector idsToTransf ( instancesNb ); - vector instances ( instancesNb ); - vector< point > positions ( instancesNb ); - vector< point > orientations( instancesNb, point(true, true) ); - - cmess1 << " - Converting " << instancesNb << " instances" << endl; - cout.flush(); Box topAb = getBlockCell()->getAbutmentBox(); Transformation topTransformation; if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation(); topTransformation.applyOn( topAb ); + Cell::setFlattenLeafMode( true ); + UpdateSession::open(); for ( Occurrence occurrence : getBlockCell()->getNonLeafInstanceOccurrences() ) { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); - if (not masterCell->getAbutmentBox().isEmpty() - and (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED) - and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED ) ) { - throw Error( "EtesianEngine::toColoquinte(): Non-leaf instance \"%s\" of \"%s\" has an abutment box but is *not* placed." - , getString(instance ->getName()).c_str() - , getString(masterCell->getName()).c_str() - ); + if (not masterCell->getAbutmentBox().isEmpty()) { + if ( (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED) + and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED ) ) { + throw Error( "EtesianEngine::toColoquinte(): Non-leaf instance \"%s\" of \"%s\" has an abutment box but is *not* placed." + , getString(instance ->getName()).c_str() + , getString(masterCell->getName()).c_str() + ); + } else { + bool isFullyPlaced = true; + for ( Instance* subInstance : masterCell->getInstances() ) { + if ( (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED) + and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED ) ) { + isFullyPlaced = false; + break; + } + } + if (isFullyPlaced) { + masterCell->setFlattenLeaf( true ); + } + } } if ( masterCell->getAbutmentBox().isEmpty() @@ -532,13 +534,35 @@ namespace Etesian { } UpdateSession::close(); + size_t instancesNb = getCell()->getLeafInstanceOccurrences(getBlockInstance()).getSize(); + if (not instancesNb) { + cerr << Error( "EtesianEngine::toColoquinte(): No instance to place. We're gonna crash..." ) << endl; + } + + // Coloquinte circuit description data-structures. + // One dummy fixed instance at the end + vector idsToTransf ( instancesNb+1 ); + vector instances ( instancesNb+1 ); + vector< point > positions ( instancesNb+1 ); + vector< point > orientations( instancesNb+1, point(true, true) ); + + cmess1 << " - Converting " << instancesNb << " instances" << endl; + cout.flush(); + cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); getCell()->flattenNets( getBlockInstance(), Cell::Flags::NoClockFlatten ); - index_t instanceId = 0; + bool tooManyInstances = false; + index_t instanceId = 0; for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { + if (tooManyInstances or (instanceId == instancesNb)) { + tooManyInstances = true; + ++instanceId; + continue; + } + Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); string instanceName = occurrence.getCompactString(); @@ -547,8 +571,8 @@ namespace Etesian { instanceName.erase( instanceName.size()-1 ); if (CatalogExtension::isFeed(masterCell)) { - cerr << Warning("Feed instance found and skipped.") << endl; - continue; + throw Error( "EtesianEngine::toColoquinte(): Feed instance \"%s\" found." + , instanceName.c_str() ); } Box instanceAb = _bloatCells.getAb( occurrence ); @@ -596,6 +620,19 @@ namespace Etesian { dots.dot(); } + if (tooManyInstances) { + throw Error( "EtesianEngine::toColoquinte(): Too many leaf instances, %d (expected: %d)\n" + " maybe a virtual flattening problem." + , instanceId, instancesNb + ); + } + if (instanceId < instancesNb) { + throw Error( "EtesianEngine::toColoquinte(): Too little leaf instances, %d (expected: %d)\n" + " maybe a virtual flattening problem." + , instanceId, instancesNb + ); + } + // Dummy fixed instance at the end instances[instanceId].size = point( 0, 0 ); instances[instanceId].list_index = instanceId; @@ -605,7 +642,23 @@ namespace Etesian { dots.finish( Dots::Reset|Dots::FirstDot ); - size_t netsNb = getCell()->getNets().getSize(); + size_t netsNb = 0; + for ( Net* net : getCell()->getNets() ) + { + const char* excludedType = NULL; + if (net->getType() == Net::Type::POWER ) excludedType = "POWER"; + if (net->getType() == Net::Type::GROUND) excludedType = "GROUND"; + if (net->getType() == Net::Type::CLOCK ) excludedType = "CLOCK"; + if (excludedType) { + cparanoid << Warning( "%s is not a routable net (%s,excluded)." + , getString(net).c_str(), excludedType ) << endl; + continue; + } + if (af->isBLOCKAGE(net->getName())) continue; + + ++netsNb; + } + cmess1 << " - Converting " << netsNb << " nets" << endl; vector nets ( netsNb ); @@ -618,11 +671,7 @@ namespace Etesian { if (net->getType() == Net::Type::POWER ) excludedType = "POWER"; if (net->getType() == Net::Type::GROUND) excludedType = "GROUND"; if (net->getType() == Net::Type::CLOCK ) excludedType = "CLOCK"; - if (excludedType) { - cparanoid << Warning( "%s is not a routable net (%s,excluded)." - , getString(net).c_str(), excludedType ) << endl; - continue; - } + if (excludedType) continue; if (af->isBLOCKAGE(net->getName())) continue; dots.dot(); @@ -664,8 +713,9 @@ namespace Etesian { auto iid = _cellsToIds.find( insName ); if (iid == _cellsToIds.end()) { - if (insName != topCellInstancePin) + if (insName != topCellInstancePin) { cerr << Error( "Unable to lookup instance \"%s\".", insName.c_str() ) << endl; + } } else { pins.push_back( temporary_pin( point(xpin,ypin), (*iid).second, netId ) ); } @@ -687,6 +737,8 @@ namespace Etesian { _placementLB.positions_ = positions; _placementLB.orientations_ = orientations; _placementUB = _placementLB; + + Cell::setFlattenLeafMode( false ); } @@ -928,6 +980,7 @@ namespace Etesian { getConfiguration()->print( getCell() ); adjustSliceHeight(); + resetPlacement(); if (getBlockCell()->getAbutmentBox().isEmpty()) setDefaultAb(); findYSpin(); @@ -1060,6 +1113,7 @@ namespace Etesian { if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation(); topTransformation.invert(); + Cell::setFlattenLeafMode( true ); for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { DbU::Unit hpitch = getHorizontalPitch(); @@ -1094,6 +1148,7 @@ namespace Etesian { instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); } } + Cell::setFlattenLeafMode( false ); UpdateSession::close(); diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 4d160e93..4a0ec90b 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -524,6 +524,10 @@ namespace Hurricane { // Cell implementation // **************************************************************************************************** + +bool Cell::_useFlattenLeaf = false; + + Cell::Cell(Library* library, const Name& name) // ******************************************* : Inherit(), @@ -601,7 +605,7 @@ Box Cell::getBoundingBox() const bool Cell::isLeaf() const // ********************** { - return _instanceMap.isEmpty(); + return _instanceMap.isEmpty() or (_useFlattenLeaf and isFlattenLeaf()); } bool Cell::isCalledBy ( Cell* cell ) const diff --git a/hurricane/src/hurricane/CellCollections.cpp b/hurricane/src/hurricane/CellCollections.cpp index a398124b..d403177d 100644 --- a/hurricane/src/hurricane/CellCollections.cpp +++ b/hurricane/src/hurricane/CellCollections.cpp @@ -1007,7 +1007,8 @@ class Cell_LeafInstanceOccurrences : public Collection { public: typedef Hurricane::Locator Inherit; public: - Locator ( const Cell* cell=NULL, const Instance* topInstance=NULL ); + Locator ( const Cell* cell =NULL + , const Instance* topInstance=NULL ); Locator ( const Locator& ); Locator& operator= ( const Locator& ); virtual Occurrence getElement () const; @@ -1025,7 +1026,8 @@ class Cell_LeafInstanceOccurrences : public Collection { }; public: - Cell_LeafInstanceOccurrences ( const Cell* cell=NULL, const Instance* topInstance=NULL ); + Cell_LeafInstanceOccurrences ( const Cell* cell =NULL + , const Instance* topInstance=NULL ); Cell_LeafInstanceOccurrences ( const Cell_LeafInstanceOccurrences& ); Cell_LeafInstanceOccurrences& operator= ( const Cell_LeafInstanceOccurrences& ); virtual Collection* getClone () const; @@ -1740,7 +1742,7 @@ Instances Cell::getTerminalInstances() const } Instances Cell::getLeafInstances() const -// ************************************* +// *************************************************** { return getInstances().getSubSet(Instance::getIsLeafFilter()); } @@ -1820,7 +1822,7 @@ Instances Cell::getLeafInstancesUnder(const Box& area) const Instances Cell::getNonLeafInstances() const // **************************************** { - return getInstances().getSubSet(!Instance::getIsLeafFilter()); + return getInstances().getSubSet(not Instance::getIsLeafFilter()); } Instances Cell::getNonLeafInstancesUnder(const Box& area) const @@ -3222,7 +3224,7 @@ Cell_LeafInstanceOccurrences::Locator::Locator ( const Cell* cell, const Instanc if (not _topInstance or (nonLeaf == _topInstance)) { Cell* masterCell = nonLeaf->getMasterCell(); - _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); + _occurrenceLocator = masterCell->getLeafInstanceOccurrences(NULL).getLocator(); if (_occurrenceLocator.isValid()) { _state = 2; break; @@ -3293,7 +3295,7 @@ void Cell_LeafInstanceOccurrences::Locator::progress () _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); while (!_state && _nonLeafInstanceLocator.isValid()) { Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); - _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); + _occurrenceLocator = masterCell->getLeafInstanceOccurrences(NULL).getLocator(); if (_occurrenceLocator.isValid()) _state = 2; else @@ -3314,7 +3316,7 @@ void Cell_LeafInstanceOccurrences::Locator::progress () if (not _topInstance or (nonLeaf == _topInstance)) { Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); - _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); + _occurrenceLocator = masterCell->getLeafInstanceOccurrences(NULL).getLocator(); if (_occurrenceLocator.isValid()) { _state = 2; break; @@ -4744,9 +4746,9 @@ bool Cell_HyperNetRootNetOccurrences::Locator::isValid() const void Cell_HyperNetRootNetOccurrences::Locator::progress() // ****************************************************** { - if (_netLocator.isValid()) - { + if (_netLocator.isValid()) { _netLocator.progress(); + while ( _netLocator.isValid() ) { if ( not dynamic_cast(_netLocator.getElement()) and not _netLocator.getElement()->isAutomatic() @@ -4754,18 +4756,18 @@ void Cell_HyperNetRootNetOccurrences::Locator::progress() _netLocator.progress(); } - } - else if (_hyperNetRootNetOccurrenceLocator.isValid()) - _hyperNetRootNetOccurrenceLocator.progress(); + } else if (_hyperNetRootNetOccurrenceLocator.isValid()) + _hyperNetRootNetOccurrenceLocator.progress(); - if (!_netLocator.isValid()) - while (!_hyperNetRootNetOccurrenceLocator.isValid() && _instanceLocator.isValid()) - { - Instance* instance = _instanceLocator.getElement(); - _hyperNetRootNetOccurrenceLocator=Locator(instance->getMasterCell(),Path(_path,instance)); - _instanceLocator.progress(); + if (not _netLocator.isValid()) { + while (not _hyperNetRootNetOccurrenceLocator.isValid() and _instanceLocator.isValid()) { + Instance* instance = _instanceLocator.getElement(); + if (not instance->isLeaf()) { + _hyperNetRootNetOccurrenceLocator=Locator(instance->getMasterCell(),Path(_path,instance)); } - + _instanceLocator.progress(); + } + } } string Cell_HyperNetRootNetOccurrences::Locator::_getString() const diff --git a/hurricane/src/hurricane/HyperNet.cpp b/hurricane/src/hurricane/HyperNet.cpp index 547f7d08..a7282e84 100644 --- a/hurricane/src/hurricane/HyperNet.cpp +++ b/hurricane/src/hurricane/HyperNet.cpp @@ -365,7 +365,7 @@ Occurrences HyperNet::getLeafPlugOccurrences(bool doExtraction, bool allowInterr Occurrences HyperNet::getComponentOccurrences(bool doExtraction, bool allowInterruption) const // ******************************************************************************************* { - return HyperNet_ComponentOccurrences(this, doExtraction, allowInterruption); + return HyperNet_ComponentOccurrences(this, false, doExtraction, allowInterruption); } string HyperNet::_getString() const @@ -637,12 +637,14 @@ void HyperNet_NetOccurrences::Locator::progress() } // for component*. } - for ( Plug* plug : net->getPlugs() ) { - Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) ); + if (not net->getCell()->isLeaf()) { + for ( Plug* plug : net->getPlugs() ) { + Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) ); - if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { - _netOccurrenceSet.insert(occurrence); - _netOccurrenceStack.push(occurrence); + if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { + _netOccurrenceSet.insert(occurrence); + _netOccurrenceStack.push(occurrence); + } } } @@ -991,91 +993,81 @@ string HyperNet_LeafPlugOccurrences::_getString() const // HyperNet_LeafPlugOccurrences::Locator implementation // **************************************************************************************************** -HyperNet_LeafPlugOccurrences::Locator::Locator() -// *************************************** -: Inherit(), - _netOccurrenceLocator(), - _plugOccurrence() - +HyperNet_LeafPlugOccurrences::Locator::Locator () + : Inherit() + , _netOccurrenceLocator() + , _plugOccurrence() +{ } + + +HyperNet_LeafPlugOccurrences::Locator::Locator ( const HyperNet* hyperNet + , bool doExtraction + , bool allowInterruption ) + : Inherit() + , _netOccurrenceLocator() + , _plugOccurrence() { + if (hyperNet) { + _netOccurrenceLocator = hyperNet->getNetOccurrences( doExtraction + , allowInterruption ).getLocator(); + progress(); + } } -HyperNet_LeafPlugOccurrences::Locator::Locator(const HyperNet* hyperNet, bool doExtraction, bool allowInterruption) -// **************************************************************************************************** -: Inherit(), - _netOccurrenceLocator(), - _plugOccurrence() + +HyperNet_LeafPlugOccurrences::Locator::Locator ( const Locator& locator ) + : Inherit() + , _netOccurrenceLocator() + , _plugOccurrence() +{ } + + +HyperNet_LeafPlugOccurrences::Locator& HyperNet_LeafPlugOccurrences::Locator::operator= ( const Locator& locator ) { - if (hyperNet) { - _netOccurrenceLocator = hyperNet->getNetOccurrences(doExtraction,allowInterruption).getLocator(); - progress(); + _netOccurrenceLocator = locator._netOccurrenceLocator; + _plugOccurrence = locator._plugOccurrence; + return *this; +} + + +Occurrence HyperNet_LeafPlugOccurrences::Locator::getElement () const +{ return _plugOccurrence; } + + +Locator* HyperNet_LeafPlugOccurrences::Locator::getClone () const +{ return new Locator( *this ); } + + +bool HyperNet_LeafPlugOccurrences::Locator::isValid () const +{ return _plugOccurrence.isValid(); } + + +void HyperNet_LeafPlugOccurrences::Locator::progress () +{ + _plugOccurrence = Occurrence(); + while(_netOccurrenceLocator.isValid() and not _plugOccurrence.isValid()) { + Occurrence netOccurrence = _netOccurrenceLocator.getElement(); + + _netOccurrenceLocator.progress(); + Net* net = static_cast( netOccurrence.getEntity() ); + Path path = netOccurrence.getPath(); + + if (not path.isEmpty() and net->getCell()->isLeaf()) { + Instance* instance = path.getTailInstance(); + Plug* plug = instance->getPlug(net); + if (plug) + _plugOccurrence = Occurrence( plug,path.getHeadPath() ); } -} - -HyperNet_LeafPlugOccurrences::Locator::Locator(const Locator& locator) -// ************************************************************* -: Inherit(), - _netOccurrenceLocator(), - _plugOccurrence() -{ -} - -HyperNet_LeafPlugOccurrences::Locator& HyperNet_LeafPlugOccurrences::Locator::operator=(const Locator& locator) -// ************************************************************************************************ -{ - _netOccurrenceLocator = locator._netOccurrenceLocator; - _plugOccurrence = locator._plugOccurrence; - return *this; -} - -Occurrence HyperNet_LeafPlugOccurrences::Locator::getElement() const -// ********************************************************** -{ - return _plugOccurrence; -} - -Locator* HyperNet_LeafPlugOccurrences::Locator::getClone() const -// ****************************************************************** -{ - return new Locator(*this); -} - -bool HyperNet_LeafPlugOccurrences::Locator::isValid() const -// ************************************************** -{ - return _plugOccurrence.isValid(); + } } -void HyperNet_LeafPlugOccurrences::Locator::progress() -// ********************************************* +string HyperNet_LeafPlugOccurrences::Locator::_getString () const { - _plugOccurrence = Occurrence(); - while(_netOccurrenceLocator.isValid() && !_plugOccurrence.isValid()) - { - Occurrence netOccurrence = _netOccurrenceLocator.getElement(); - - _netOccurrenceLocator.progress(); - Net* net = (Net*)netOccurrence.getEntity(); - Path path = netOccurrence.getPath(); - - if (!path.isEmpty() && net->getCell()->isTerminal()) - { - Instance *instance = path.getTailInstance(); - Plug *plug=instance->getPlug(net); - if (plug) - _plugOccurrence=Occurrence(plug,path.getHeadPath()); - } - } -} - -string HyperNet_LeafPlugOccurrences::Locator::_getString() const -// ******************************************************* -{ - string s = "<" + _TName("HyperNet::LeafPlugOccurrences::Locator"); - s += " " + getString(_netOccurrenceLocator); - s += ">"; - return s; + string s = "<" + _TName("HyperNet::LeafPlugOccurrences::Locator"); + s += " " + getString(_netOccurrenceLocator); + s += ">"; + return s; } @@ -1239,7 +1231,8 @@ void HyperNet_ComponentOccurrences::Locator::progress() _netOccurrenceLocator.progress(); Net* net = static_cast( netOccurrence.getEntity() ); - if (_withLeafCells or not net->getCell()->isTerminal()) { + //if (_withLeafCells or not net->getCell()->isTerminal()) { + if (not net->getCell()->isLeaf()) { _componentLocator = net->getComponents().getLocator(); } } else diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index f7413ce6..24095a26 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -96,20 +96,21 @@ class Instance_IsTerminalFilter : public Filter { }; -class Instance_IsLeafFilter : public Filter { -// ******************************************************* - - public: Instance_IsLeafFilter() {}; - - public: Instance_IsLeafFilter(const Instance_IsLeafFilter& filter) {}; - - public: Instance_IsLeafFilter& operator=(const Instance_IsLeafFilter& filter) {return *this;}; - - public: virtual Filter* getClone() const {return new Instance_IsLeafFilter(*this);}; - - public: virtual bool accept(Instance* instance) const {return instance->isLeaf();}; - - public: virtual string _getString() const {return "<" + _TName("Instance::IsLeafFilter") + ">";}; +class Instance_IsLeafFilter : public Filter +{ + public: + Instance_IsLeafFilter () {}; + Instance_IsLeafFilter ( const Instance_IsLeafFilter& filter ) {}; + Instance_IsLeafFilter& operator= ( const Instance_IsLeafFilter& filter ) + { return *this; }; + virtual Filter* getClone () const + { return new Instance_IsLeafFilter( *this ); }; + virtual bool accept ( Instance* instance ) const + { return instance->isLeaf(); }; + virtual string _getString () const + { return "<" + _TName("Instance::IsLeafFilter") + ">"; }; + private: + uint32_t _flags; }; @@ -315,7 +316,7 @@ InstanceFilter Instance::getIsTerminalFilter() } InstanceFilter Instance::getIsLeafFilter() -// ******************************************* +// *************************************** { return Instance_IsLeafFilter(); } diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 9ae8a517..c9698df4 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -342,6 +342,7 @@ class Cell : public Entity { private: AliasNameSet _netAliasSet; private: Observable _observers; private: Flags _flags; + private: static bool _useFlattenLeaf; // Constructors // ************ @@ -521,6 +522,7 @@ class Cell : public Entity { public: void addObserver(BaseObserver*); public: void removeObserver(BaseObserver*); public: void notify(unsigned flags); + public: static void setFlattenLeafMode(bool state) { _useFlattenLeaf=state; }; }; diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 40abcd12..36e2a549 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -570,10 +570,10 @@ namespace { TrackElement* element = TrackFixedSegment::create ( track, segment ); cdebug_log(159,0) << " Insert in " << track << "+" << element << endl; - if (segment->getId() == 51904) { - cerr << " Insert in " << track << endl; - cerr << " +" << element << endl; - } + // if (segment->getId() == 51904) { + // cerr << " Insert in " << track << endl; + // cerr << " +" << element << endl; + // } } // if (segment->getId() == 51904) { // DebugSession::close(); diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index d9942b74..a2ff7a99 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -56,16 +56,13 @@ namespace Katana { // Class : "TrackFixedSegment". - Net* TrackFixedSegment::_blockageNet = NULL; - - TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment ) : TrackElement (NULL) , _segment (segment) { Box boundingBox = segment->getBoundingBox(); - uint32_t flags = TElemFixed | ((segment->getNet() == _blockageNet) ? TElemBlockage : 0); + uint32_t flags = TElemFixed | ((segment->getNet() == Session::getBlockageNet()) ? TElemBlockage : 0); setFlags( flags ); if (track) { @@ -123,8 +120,6 @@ namespace Katana { TrackElement* TrackFixedSegment::create ( Track* track, Segment* segment ) { - if ( not _blockageNet ) _blockageNet = Session::getBlockageNet(); - TrackFixedSegment* trackFixedSegment = NULL; if (track) { trackFixedSegment = new TrackFixedSegment ( track, segment ); @@ -189,7 +184,7 @@ namespace Katana { { Net* realNet = _segment->getNet(); if (realNet->isSupply() or realNet->isClock()) - return _blockageNet; + return Session::getBlockageNet(); return realNet; } diff --git a/katana/src/katana/TrackFixedSegment.h b/katana/src/katana/TrackFixedSegment.h index 51cdfb6a..37622d13 100644 --- a/katana/src/katana/TrackFixedSegment.h +++ b/katana/src/katana/TrackFixedSegment.h @@ -71,8 +71,7 @@ namespace Katana { virtual string _getTypeName () const; protected: // Attributes. - static Net* _blockageNet; - Segment* _segment; + Segment* _segment; protected: // Constructors & Destructors. TrackFixedSegment ( Track*, Segment* ) ;