From 59ee8358cac8254dcd999a945e07ef717573e32e Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 4 Mar 2020 00:50:18 +0100 Subject: [PATCH] First working recursive place & route (Libre-SOC ALU16 benchmark). * New: In Hurricane::Cell::isLeaf(), a leaf cell was defined as one without instances. Now it can be software defined with the "FlattenLeaf" state. If it is flagged "flatten leaf" is will be considered as a leaf by the trans-hierarchical walkthrough. This flag is also set for Cells in the Alliance CATAL. * New: In Hurricane::Cell_LeafInstanceOccurrences::progress(), add a test to prune leaf cells. * Bug: In Hurricane::getComponentOccurrences(), when calling the locator constructor, the "withLeafCells" argument was forgotten and was getting the value of "doExtraction" (wich, fortunately, was the same). * Change: In Hurricane::HypreNet_LeafPlugOccurrences::progress(), prune the leaf cells instead of the terminal ones. * Change: In Hurricane::HypreNet_ComponentOccurrences::progress(), prune the leaf cells instead of the terminal ones. * New: In Hurricane::Cell, add a "useFlattenLeaf" mode to take into account or ignore the "FlattenLeaf" flag when doing trans- hierarchical walkthrough. Not sure if it shouldn't be systematic. * New: In Etesian::toColoquinte() and other, activate the "FlattenLeaf" mode for all walkthough. So we can stop at already placed sub-blocks. * Bug: In Etesian::toColoquinte(), when placed sub-block where present, the number of instances was under estimated, so the instance array was oversized and the end went unitialized. So we were getting all kind of strange behavior from Coloquinte... Now throw an exception if the number of instances differs from the computed size. * Bug: In Etesian::toColoquinte(), as for the instance array, now correctly compute the size with the ecluded nets (supplies, clocks). * Bug: In Etesian::resetPlacement(), event if the Cell is unplaced, go through the instance list to remove the potential feed cells. The netlist is written back after placement *with* the feed cells added. So, when loading again, they where cluttering the netlist and giving feed redefintions warning. They also generated erratic behaviors. * New: In Anabatic::NetBuilderHV, added configurations for: * 1G_1M1_1PinM3 * 1G_xM1_1PinM2 * 2G_xM1_1PinM2 * doRp_AccessNorthPin * New: In Anabatic::NetBuilderHV, added Pin management in SingleGCell. * Bug: In Anabatic::NetBuilderHV::_do_xG_1PinM3(), the North/South global routing configuration was forgotten (only East/West). * Bug: In Katana::TrackFixedSegment, the blockage net was a static variable initialized at the first run. So we were getting stuck with the blockage net of the first cell to be routed. Of course, it did show only when Katana was run multiple times in the same process. --- anabatic/src/Configuration.cpp | 19 +- anabatic/src/NetBuilder.cpp | 83 ++++-- anabatic/src/NetBuilderHV.cpp | 312 +++++++++++++++++++- anabatic/src/anabatic/NetBuilder.h | 144 ++++----- anabatic/src/anabatic/NetBuilderHV.h | 57 ++-- etesian/src/AddFeeds.cpp | 4 + etesian/src/EtesianEngine.cpp | 125 +++++--- hurricane/src/hurricane/Cell.cpp | 6 +- hurricane/src/hurricane/CellCollections.cpp | 40 +-- hurricane/src/hurricane/HyperNet.cpp | 159 +++++----- hurricane/src/hurricane/Instance.cpp | 31 +- hurricane/src/hurricane/hurricane/Cell.h | 2 + katana/src/PowerRails.cpp | 8 +- katana/src/TrackFixedSegment.cpp | 9 +- katana/src/katana/TrackFixedSegment.h | 3 +- 15 files changed, 708 insertions(+), 294 deletions(-) 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* ) ;