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.
This commit is contained in:
Jean-Paul Chaput 2020-03-04 00:50:18 +01:00
parent 757b95343b
commit 59ee8358ca
15 changed files with 708 additions and 294 deletions

View File

@ -25,6 +25,7 @@
#include "hurricane/BasicLayer.h" #include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h" #include "hurricane/RegularLayer.h"
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
#include "hurricane/Pin.h"
#include "hurricane/NetExternalComponents.h" #include "hurricane/NetExternalComponents.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
@ -55,6 +56,7 @@ namespace Anabatic {
using Hurricane::BasicLayer; using Hurricane::BasicLayer;
using Hurricane::RegularLayer; using Hurricane::RegularLayer;
using Hurricane::Segment; using Hurricane::Segment;
using Hurricane::Pin;
using Hurricane::Plug; using Hurricane::Plug;
using Hurricane::Path; using Hurricane::Path;
using Hurricane::Occurrence; using Hurricane::Occurrence;
@ -458,13 +460,18 @@ namespace Anabatic {
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl; cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
for ( Component* component : masterNet->getComponents() ) { for ( Component* component : masterNet->getComponents() ) {
cdebug_log(112,0) << "@ " << component << endl; 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<Segment*>(component); Component* candidate = dynamic_cast<Segment*>(component);
if (not segment) continue; if (not candidate
if (segment->getLayer()->getMask() != metal1->getMask()) continue; or (candidate->getLayer()->getMask() != metal1->getMask()) )
candidate = dynamic_cast<Pin*>(component);
if (not candidate) continue;
Box bb = transformation.getBox( component->getBoundingBox() ); Box bb = transformation.getBox( candidate->getBoundingBox() );
DbU::Unit trackPos = 0; DbU::Unit trackPos = 0;
DbU::Unit minPos = DbU::Max; DbU::Unit minPos = DbU::Max;
DbU::Unit maxPos = DbU::Min; DbU::Unit maxPos = DbU::Min;
@ -497,7 +504,7 @@ namespace Anabatic {
cdebug_log(112,0) << "| " << occurrence.getPath() << endl; cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
cdebug_log(112,0) << "| " << transformation << 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; cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {

View File

@ -507,6 +507,16 @@ namespace Anabatic {
if (_gcell == NULL) throw Error( missingGCell ); 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; return *this;
} }
@ -543,6 +553,15 @@ namespace Anabatic {
void NetBuilder::construct () void NetBuilder::construct ()
{ {
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl; 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()) { if (not isTwoMetals()) {
_southWestContact = NULL; _southWestContact = NULL;
@ -625,6 +644,11 @@ namespace Anabatic {
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break; case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
case Conn_2G_1PinM3: case Conn_2G_1PinM3:
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break; 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_1M2: _do_xG_1M1_1M2 (); break;
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break; case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
@ -1070,6 +1094,27 @@ namespace Anabatic {
} }
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 () bool NetBuilder::_do_globalSegment ()
{ {
throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() ); throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() );

View File

@ -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<Pin*>( 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 () bool NetBuilderHV::_do_1G_1M1 ()
{ {
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; 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; cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpSourceContact = NULL; 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) ); AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, turn1, Flags::Vertical ); AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
@ -804,15 +842,19 @@ namespace Anabatic {
setSouthWestContact( turn1 ); setSouthWestContact( turn1 );
setNorthEastContact( htee1 ); setNorthEastContact( htee1 );
} else { } else if (north() and south()) {
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, vtee1, Flags::Vertical );
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
AutoSegment::create( vtee1, turn1, Flags::Vertical ); AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
setSouthWestContact( vtee1 ); AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
setNorthEastContact( turn1 ); 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 { } else {
AutoContact* vtee1 = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) ); 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<RoutingPad*> rpsM1;
RoutingPad* pinM2 = NULL;
for ( RoutingPad* rp : getRoutingPads() ) {
if (dynamic_cast<Pin*>(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.size() ; ++i ) {
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHV::_do_2G_xM1_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_2G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
vector<RoutingPad*> rpsM1;
RoutingPad* pinM2 = NULL;
for ( RoutingPad* rp : getRoutingPads() ) {
if (dynamic_cast<Pin*>(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<rpsM1.size() ; ++i ) {
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHV::_do_1G_1M1_1PinM3 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpSourceContact = NULL;
RoutingPad* pinM3 = getRoutingPads()[0];
RoutingPad* rpM1 = getRoutingPads()[1];
if (dynamic_cast<Pin*>(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 () bool NetBuilderHV::_do_2G_1M1 ()
{ {
return _do_xG_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<RoutingPad*> rpM1s;
Component* rpM2 = NULL;
RoutingPad* rpPin = NULL;
for ( RoutingPad* rp : net->getRoutingPads() ) {
if (dynamic_cast<Pin*>(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 ; irp<rpM1s.size() ; ++irp ) {
doRp_AutoContacts( gcell1, rpM1s[irp-1], source, turn1, DoSourceContact );
doRp_AutoContacts( gcell1, rpM1s[irp ], target, turn1, DoSourceContact );
if (source->getUConstraints(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 string NetBuilderHV::getTypeName () const
{ return "NetBuilderHV"; } { return "NetBuilderHV"; }

View File

@ -221,6 +221,9 @@ namespace Anabatic {
virtual bool _do_xG_xM2 (); virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 (); virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 (); 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 bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* ); virtual void singleGCell ( AnabaticEngine*, Net* );
AutoContact* _doHChannel (); AutoContact* _doHChannel ();
@ -307,9 +310,14 @@ namespace Anabatic {
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 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_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 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_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 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_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 #undef CONNEXITY_VALUE

View File

@ -32,6 +32,7 @@ namespace Anabatic {
virtual ~NetBuilderHV (); virtual ~NetBuilderHV ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
private: private:
virtual bool _do_1G_1M1 (); virtual bool _do_1G_1M1 ();
virtual bool _do_1G_xM1 (); virtual bool _do_1G_xM1 ();
@ -52,7 +53,11 @@ namespace Anabatic {
virtual bool _do_xG_xM2 (); virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 (); virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 (); 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 bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public: public:
virtual string getTypeName () const; virtual string getTypeName () const;
}; };

View File

@ -370,6 +370,8 @@ namespace Etesian {
sliceHoles.setSpinSlice0( _yspinSlice0 ); sliceHoles.setSpinSlice0( _yspinSlice0 );
Cell::setFlattenLeafMode( true );
for ( Occurrence occurrence : getBlockCell()->getLeafInstanceOccurrences() ) for ( Occurrence occurrence : getBlockCell()->getLeafInstanceOccurrences() )
{ {
Instance* instance = static_cast<Instance*>(occurrence.getEntity()); Instance* instance = static_cast<Instance*>(occurrence.getEntity());
@ -397,6 +399,8 @@ namespace Etesian {
sliceHoles.addFeeds(); sliceHoles.addFeeds();
Cell::setFlattenLeafMode( false );
UpdateSession::close(); UpdateSession::close();
if (_viewer) _viewer->getCellWidget()->refresh(); if (_viewer) _viewer->getCellWidget()->refresh();

View File

@ -432,7 +432,6 @@ namespace Etesian {
{ {
//cerr << "EtesianEngine::resetPlacement()" << endl; //cerr << "EtesianEngine::resetPlacement()" << endl;
if (not getBlockCell()->isPlaced()) return;
_flatDesign = true; _flatDesign = true;
Dots dots ( cmess2, " ", 80, 1000 ); Dots dots ( cmess2, " ", 80, 1000 );
@ -461,10 +460,11 @@ namespace Etesian {
Instance* instance = static_cast<Instance*>(ioccurrence.getEntity()); Instance* instance = static_cast<Instance*>(ioccurrence.getEntity());
instance->destroy(); instance->destroy();
} }
if (not getBlockCell()->getAbutmentBox().isEmpty() )
setFixedAbHeight( getBlockCell()->getAbutmentBox().getHeight() ); // if (not getBlockCell()->getAbutmentBox().isEmpty() )
getBlockCell()->setAbutmentBox( Box() ); // setFixedAbHeight( getBlockCell()->getAbutmentBox().getHeight() );
getBlockCell()->resetFlags( Cell::Flags::Placed ); // getBlockCell()->setAbutmentBox( Box() );
// getBlockCell()->resetFlags( Cell::Flags::Placed );
UpdateSession::close(); UpdateSession::close();
dots.finish( Dots::Reset ); dots.finish( Dots::Reset );
@ -483,40 +483,42 @@ namespace Etesian {
cmess1 << ::Dots::asString(" - H-pitch" , DbU::getValueString(hpitch)) << endl; cmess1 << ::Dots::asString(" - H-pitch" , DbU::getValueString(hpitch)) << endl;
cmess1 << ::Dots::asString(" - V-pitch" , DbU::getValueString(vpitch)) << endl; cmess1 << ::Dots::asString(" - V-pitch" , DbU::getValueString(vpitch)) << endl;
resetPlacement();
Dots dots ( cmess2, " ", 80, 1000 ); Dots dots ( cmess2, " ", 80, 1000 );
if (not cmess2.enabled()) dots.disable(); 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<Transformation> idsToTransf ( instancesNb );
vector<temporary_cell> instances ( instancesNb );
vector< point<int_t> > positions ( instancesNb );
vector< point<bool> > orientations( instancesNb, point<bool>(true, true) );
cmess1 << " - Converting " << instancesNb << " instances" << endl;
cout.flush();
Box topAb = getBlockCell()->getAbutmentBox(); Box topAb = getBlockCell()->getAbutmentBox();
Transformation topTransformation; Transformation topTransformation;
if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation(); if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation();
topTransformation.applyOn( topAb ); topTransformation.applyOn( topAb );
Cell::setFlattenLeafMode( true );
UpdateSession::open(); UpdateSession::open();
for ( Occurrence occurrence : getBlockCell()->getNonLeafInstanceOccurrences() ) for ( Occurrence occurrence : getBlockCell()->getNonLeafInstanceOccurrences() )
{ {
Instance* instance = static_cast<Instance*>(occurrence.getEntity()); Instance* instance = static_cast<Instance*>(occurrence.getEntity());
Cell* masterCell = instance->getMasterCell(); Cell* masterCell = instance->getMasterCell();
if (not masterCell->getAbutmentBox().isEmpty() if (not masterCell->getAbutmentBox().isEmpty()) {
and (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED) if ( (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED)
and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED ) ) { and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED ) ) {
throw Error( "EtesianEngine::toColoquinte(): Non-leaf instance \"%s\" of \"%s\" has an abutment box but is *not* placed." throw Error( "EtesianEngine::toColoquinte(): Non-leaf instance \"%s\" of \"%s\" has an abutment box but is *not* placed."
, getString(instance ->getName()).c_str() , getString(instance ->getName()).c_str()
, getString(masterCell->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() if ( masterCell->getAbutmentBox().isEmpty()
@ -532,13 +534,35 @@ namespace Etesian {
} }
UpdateSession::close(); 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<Transformation> idsToTransf ( instancesNb+1 );
vector<temporary_cell> instances ( instancesNb+1 );
vector< point<int_t> > positions ( instancesNb+1 );
vector< point<bool> > orientations( instancesNb+1, point<bool>(true, true) );
cmess1 << " - Converting " << instancesNb << " instances" << endl;
cout.flush();
cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl;
//getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten );
getCell()->flattenNets( getBlockInstance(), Cell::Flags::NoClockFlatten ); getCell()->flattenNets( getBlockInstance(), Cell::Flags::NoClockFlatten );
bool tooManyInstances = false;
index_t instanceId = 0; index_t instanceId = 0;
for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) )
{ {
if (tooManyInstances or (instanceId == instancesNb)) {
tooManyInstances = true;
++instanceId;
continue;
}
Instance* instance = static_cast<Instance*>(occurrence.getEntity()); Instance* instance = static_cast<Instance*>(occurrence.getEntity());
Cell* masterCell = instance->getMasterCell(); Cell* masterCell = instance->getMasterCell();
string instanceName = occurrence.getCompactString(); string instanceName = occurrence.getCompactString();
@ -547,8 +571,8 @@ namespace Etesian {
instanceName.erase( instanceName.size()-1 ); instanceName.erase( instanceName.size()-1 );
if (CatalogExtension::isFeed(masterCell)) { if (CatalogExtension::isFeed(masterCell)) {
cerr << Warning("Feed instance found and skipped.") << endl; throw Error( "EtesianEngine::toColoquinte(): Feed instance \"%s\" found."
continue; , instanceName.c_str() );
} }
Box instanceAb = _bloatCells.getAb( occurrence ); Box instanceAb = _bloatCells.getAb( occurrence );
@ -596,6 +620,19 @@ namespace Etesian {
dots.dot(); 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 // Dummy fixed instance at the end
instances[instanceId].size = point<int_t>( 0, 0 ); instances[instanceId].size = point<int_t>( 0, 0 );
instances[instanceId].list_index = instanceId; instances[instanceId].list_index = instanceId;
@ -605,7 +642,23 @@ namespace Etesian {
dots.finish( Dots::Reset|Dots::FirstDot ); 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; cmess1 << " - Converting " << netsNb << " nets" << endl;
vector<temporary_net> nets ( netsNb ); vector<temporary_net> nets ( netsNb );
@ -618,11 +671,7 @@ namespace Etesian {
if (net->getType() == Net::Type::POWER ) excludedType = "POWER"; if (net->getType() == Net::Type::POWER ) excludedType = "POWER";
if (net->getType() == Net::Type::GROUND) excludedType = "GROUND"; if (net->getType() == Net::Type::GROUND) excludedType = "GROUND";
if (net->getType() == Net::Type::CLOCK ) excludedType = "CLOCK"; if (net->getType() == Net::Type::CLOCK ) excludedType = "CLOCK";
if (excludedType) { if (excludedType) continue;
cparanoid << Warning( "%s is not a routable net (%s,excluded)."
, getString(net).c_str(), excludedType ) << endl;
continue;
}
if (af->isBLOCKAGE(net->getName())) continue; if (af->isBLOCKAGE(net->getName())) continue;
dots.dot(); dots.dot();
@ -664,8 +713,9 @@ namespace Etesian {
auto iid = _cellsToIds.find( insName ); auto iid = _cellsToIds.find( insName );
if (iid == _cellsToIds.end()) { if (iid == _cellsToIds.end()) {
if (insName != topCellInstancePin) if (insName != topCellInstancePin) {
cerr << Error( "Unable to lookup instance \"%s\".", insName.c_str() ) << endl; cerr << Error( "Unable to lookup instance \"%s\".", insName.c_str() ) << endl;
}
} else { } else {
pins.push_back( temporary_pin( point<int_t>(xpin,ypin), (*iid).second, netId ) ); pins.push_back( temporary_pin( point<int_t>(xpin,ypin), (*iid).second, netId ) );
} }
@ -687,6 +737,8 @@ namespace Etesian {
_placementLB.positions_ = positions; _placementLB.positions_ = positions;
_placementLB.orientations_ = orientations; _placementLB.orientations_ = orientations;
_placementUB = _placementLB; _placementUB = _placementLB;
Cell::setFlattenLeafMode( false );
} }
@ -928,6 +980,7 @@ namespace Etesian {
getConfiguration()->print( getCell() ); getConfiguration()->print( getCell() );
adjustSliceHeight(); adjustSliceHeight();
resetPlacement();
if (getBlockCell()->getAbutmentBox().isEmpty()) setDefaultAb(); if (getBlockCell()->getAbutmentBox().isEmpty()) setDefaultAb();
findYSpin(); findYSpin();
@ -1060,6 +1113,7 @@ namespace Etesian {
if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation(); if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation();
topTransformation.invert(); topTransformation.invert();
Cell::setFlattenLeafMode( true );
for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) )
{ {
DbU::Unit hpitch = getHorizontalPitch(); DbU::Unit hpitch = getHorizontalPitch();
@ -1094,6 +1148,7 @@ namespace Etesian {
instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); instance->setPlacementStatus( Instance::PlacementStatus::PLACED );
} }
} }
Cell::setFlattenLeafMode( false );
UpdateSession::close(); UpdateSession::close();

View File

@ -524,6 +524,10 @@ namespace Hurricane {
// Cell implementation // Cell implementation
// **************************************************************************************************** // ****************************************************************************************************
bool Cell::_useFlattenLeaf = false;
Cell::Cell(Library* library, const Name& name) Cell::Cell(Library* library, const Name& name)
// ******************************************* // *******************************************
: Inherit(), : Inherit(),
@ -601,7 +605,7 @@ Box Cell::getBoundingBox() const
bool Cell::isLeaf() const bool Cell::isLeaf() const
// ********************** // **********************
{ {
return _instanceMap.isEmpty(); return _instanceMap.isEmpty() or (_useFlattenLeaf and isFlattenLeaf());
} }
bool Cell::isCalledBy ( Cell* cell ) const bool Cell::isCalledBy ( Cell* cell ) const

View File

@ -1007,7 +1007,8 @@ class Cell_LeafInstanceOccurrences : public Collection<Occurrence> {
public: public:
typedef Hurricane::Locator<Occurrence> Inherit; typedef Hurricane::Locator<Occurrence> Inherit;
public: public:
Locator ( const Cell* cell=NULL, const Instance* topInstance=NULL ); Locator ( const Cell* cell =NULL
, const Instance* topInstance=NULL );
Locator ( const Locator& ); Locator ( const Locator& );
Locator& operator= ( const Locator& ); Locator& operator= ( const Locator& );
virtual Occurrence getElement () const; virtual Occurrence getElement () const;
@ -1025,7 +1026,8 @@ class Cell_LeafInstanceOccurrences : public Collection<Occurrence> {
}; };
public: 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 ( const Cell_LeafInstanceOccurrences& );
Cell_LeafInstanceOccurrences& operator= ( const Cell_LeafInstanceOccurrences& ); Cell_LeafInstanceOccurrences& operator= ( const Cell_LeafInstanceOccurrences& );
virtual Collection<Occurrence>* getClone () const; virtual Collection<Occurrence>* getClone () const;
@ -1740,7 +1742,7 @@ Instances Cell::getTerminalInstances() const
} }
Instances Cell::getLeafInstances() const Instances Cell::getLeafInstances() const
// ************************************* // ***************************************************
{ {
return getInstances().getSubSet(Instance::getIsLeafFilter()); return getInstances().getSubSet(Instance::getIsLeafFilter());
} }
@ -1820,7 +1822,7 @@ Instances Cell::getLeafInstancesUnder(const Box& area) const
Instances Cell::getNonLeafInstances() const Instances Cell::getNonLeafInstances() const
// **************************************** // ****************************************
{ {
return getInstances().getSubSet(!Instance::getIsLeafFilter()); return getInstances().getSubSet(not Instance::getIsLeafFilter());
} }
Instances Cell::getNonLeafInstancesUnder(const Box& area) const 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)) { if (not _topInstance or (nonLeaf == _topInstance)) {
Cell* masterCell = nonLeaf->getMasterCell(); Cell* masterCell = nonLeaf->getMasterCell();
_occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); _occurrenceLocator = masterCell->getLeafInstanceOccurrences(NULL).getLocator();
if (_occurrenceLocator.isValid()) { if (_occurrenceLocator.isValid()) {
_state = 2; _state = 2;
break; break;
@ -3293,7 +3295,7 @@ void Cell_LeafInstanceOccurrences::Locator::progress ()
_nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator();
while (!_state && _nonLeafInstanceLocator.isValid()) { while (!_state && _nonLeafInstanceLocator.isValid()) {
Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell();
_occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); _occurrenceLocator = masterCell->getLeafInstanceOccurrences(NULL).getLocator();
if (_occurrenceLocator.isValid()) if (_occurrenceLocator.isValid())
_state = 2; _state = 2;
else else
@ -3314,7 +3316,7 @@ void Cell_LeafInstanceOccurrences::Locator::progress ()
if (not _topInstance or (nonLeaf == _topInstance)) { if (not _topInstance or (nonLeaf == _topInstance)) {
Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell();
_occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); _occurrenceLocator = masterCell->getLeafInstanceOccurrences(NULL).getLocator();
if (_occurrenceLocator.isValid()) { if (_occurrenceLocator.isValid()) {
_state = 2; _state = 2;
break; break;
@ -4744,9 +4746,9 @@ bool Cell_HyperNetRootNetOccurrences::Locator::isValid() const
void Cell_HyperNetRootNetOccurrences::Locator::progress() void Cell_HyperNetRootNetOccurrences::Locator::progress()
// ****************************************************** // ******************************************************
{ {
if (_netLocator.isValid()) if (_netLocator.isValid()) {
{
_netLocator.progress(); _netLocator.progress();
while ( _netLocator.isValid() ) { while ( _netLocator.isValid() ) {
if ( not dynamic_cast<DeepNet*>(_netLocator.getElement()) if ( not dynamic_cast<DeepNet*>(_netLocator.getElement())
and not _netLocator.getElement()->isAutomatic() and not _netLocator.getElement()->isAutomatic()
@ -4754,18 +4756,18 @@ void Cell_HyperNetRootNetOccurrences::Locator::progress()
_netLocator.progress(); _netLocator.progress();
} }
} } else if (_hyperNetRootNetOccurrenceLocator.isValid())
else if (_hyperNetRootNetOccurrenceLocator.isValid())
_hyperNetRootNetOccurrenceLocator.progress(); _hyperNetRootNetOccurrenceLocator.progress();
if (!_netLocator.isValid()) if (not _netLocator.isValid()) {
while (!_hyperNetRootNetOccurrenceLocator.isValid() && _instanceLocator.isValid()) while (not _hyperNetRootNetOccurrenceLocator.isValid() and _instanceLocator.isValid()) {
{
Instance* instance = _instanceLocator.getElement(); Instance* instance = _instanceLocator.getElement();
if (not instance->isLeaf()) {
_hyperNetRootNetOccurrenceLocator=Locator(instance->getMasterCell(),Path(_path,instance)); _hyperNetRootNetOccurrenceLocator=Locator(instance->getMasterCell(),Path(_path,instance));
}
_instanceLocator.progress(); _instanceLocator.progress();
} }
}
} }
string Cell_HyperNetRootNetOccurrences::Locator::_getString() const string Cell_HyperNetRootNetOccurrences::Locator::_getString() const

View File

@ -365,7 +365,7 @@ Occurrences HyperNet::getLeafPlugOccurrences(bool doExtraction, bool allowInterr
Occurrences HyperNet::getComponentOccurrences(bool doExtraction, bool allowInterruption) const 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 string HyperNet::_getString() const
@ -637,6 +637,7 @@ void HyperNet_NetOccurrences::Locator::progress()
} // for component*. } // for component*.
} }
if (not net->getCell()->isLeaf()) {
for ( Plug* plug : net->getPlugs() ) { for ( Plug* plug : net->getPlugs() ) {
Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) ); Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) );
@ -645,6 +646,7 @@ void HyperNet_NetOccurrences::Locator::progress()
_netOccurrenceStack.push(occurrence); _netOccurrenceStack.push(occurrence);
} }
} }
}
if (net->isExternal()) { if (net->isExternal()) {
Instance* instance = path.getTailInstance(); Instance* instance = path.getTailInstance();
@ -992,75 +994,65 @@ string HyperNet_LeafPlugOccurrences::_getString() const
// **************************************************************************************************** // ****************************************************************************************************
HyperNet_LeafPlugOccurrences::Locator::Locator () HyperNet_LeafPlugOccurrences::Locator::Locator ()
// *************************************** : Inherit()
: Inherit(), , _netOccurrenceLocator()
_netOccurrenceLocator(), , _plugOccurrence()
_plugOccurrence() { }
{
}
HyperNet_LeafPlugOccurrences::Locator::Locator(const HyperNet* hyperNet, bool doExtraction, bool allowInterruption) HyperNet_LeafPlugOccurrences::Locator::Locator ( const HyperNet* hyperNet
// **************************************************************************************************** , bool doExtraction
: Inherit(), , bool allowInterruption )
_netOccurrenceLocator(), : Inherit()
_plugOccurrence() , _netOccurrenceLocator()
, _plugOccurrence()
{ {
if (hyperNet) { if (hyperNet) {
_netOccurrenceLocator = hyperNet->getNetOccurrences(doExtraction,allowInterruption).getLocator(); _netOccurrenceLocator = hyperNet->getNetOccurrences( doExtraction
, allowInterruption ).getLocator();
progress(); progress();
} }
} }
HyperNet_LeafPlugOccurrences::Locator::Locator ( const Locator& locator ) HyperNet_LeafPlugOccurrences::Locator::Locator ( const Locator& locator )
// ************************************************************* : Inherit()
: Inherit(), , _netOccurrenceLocator()
_netOccurrenceLocator(), , _plugOccurrence()
_plugOccurrence() { }
{
}
HyperNet_LeafPlugOccurrences::Locator& HyperNet_LeafPlugOccurrences::Locator::operator= ( const Locator& locator ) HyperNet_LeafPlugOccurrences::Locator& HyperNet_LeafPlugOccurrences::Locator::operator= ( const Locator& locator )
// ************************************************************************************************
{ {
_netOccurrenceLocator = locator._netOccurrenceLocator; _netOccurrenceLocator = locator._netOccurrenceLocator;
_plugOccurrence = locator._plugOccurrence; _plugOccurrence = locator._plugOccurrence;
return *this; return *this;
} }
Occurrence HyperNet_LeafPlugOccurrences::Locator::getElement () const Occurrence HyperNet_LeafPlugOccurrences::Locator::getElement () const
// ********************************************************** { return _plugOccurrence; }
{
return _plugOccurrence;
}
Locator<Occurrence>* HyperNet_LeafPlugOccurrences::Locator::getClone () const Locator<Occurrence>* HyperNet_LeafPlugOccurrences::Locator::getClone () const
// ****************************************************************** { return new Locator( *this ); }
{
return new Locator(*this);
}
bool HyperNet_LeafPlugOccurrences::Locator::isValid () const bool HyperNet_LeafPlugOccurrences::Locator::isValid () const
// ************************************************** { return _plugOccurrence.isValid(); }
{
return _plugOccurrence.isValid();
}
void HyperNet_LeafPlugOccurrences::Locator::progress () void HyperNet_LeafPlugOccurrences::Locator::progress ()
// *********************************************
{ {
_plugOccurrence = Occurrence(); _plugOccurrence = Occurrence();
while(_netOccurrenceLocator.isValid() && !_plugOccurrence.isValid()) while(_netOccurrenceLocator.isValid() and not _plugOccurrence.isValid()) {
{
Occurrence netOccurrence = _netOccurrenceLocator.getElement(); Occurrence netOccurrence = _netOccurrenceLocator.getElement();
_netOccurrenceLocator.progress(); _netOccurrenceLocator.progress();
Net* net = (Net*)netOccurrence.getEntity(); Net* net = static_cast<Net*>( netOccurrence.getEntity() );
Path path = netOccurrence.getPath(); Path path = netOccurrence.getPath();
if (!path.isEmpty() && net->getCell()->isTerminal()) if (not path.isEmpty() and net->getCell()->isLeaf()) {
{
Instance* instance = path.getTailInstance(); Instance* instance = path.getTailInstance();
Plug* plug = instance->getPlug(net); Plug* plug = instance->getPlug(net);
if (plug) if (plug)
@ -1069,8 +1061,8 @@ void HyperNet_LeafPlugOccurrences::Locator::progress()
} }
} }
string HyperNet_LeafPlugOccurrences::Locator::_getString () const string HyperNet_LeafPlugOccurrences::Locator::_getString () const
// *******************************************************
{ {
string s = "<" + _TName("HyperNet::LeafPlugOccurrences::Locator"); string s = "<" + _TName("HyperNet::LeafPlugOccurrences::Locator");
s += " " + getString(_netOccurrenceLocator); s += " " + getString(_netOccurrenceLocator);
@ -1239,7 +1231,8 @@ void HyperNet_ComponentOccurrences::Locator::progress()
_netOccurrenceLocator.progress(); _netOccurrenceLocator.progress();
Net* net = static_cast<Net*>( netOccurrence.getEntity() ); Net* net = static_cast<Net*>( 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(); _componentLocator = net->getComponents().getLocator();
} }
} else } else

View File

@ -96,20 +96,21 @@ class Instance_IsTerminalFilter : public Filter<Instance*> {
}; };
class Instance_IsLeafFilter : public Filter<Instance*> { class Instance_IsLeafFilter : public Filter<Instance*>
// ******************************************************* {
public:
public: Instance_IsLeafFilter() {}; Instance_IsLeafFilter () {};
Instance_IsLeafFilter ( const Instance_IsLeafFilter& filter ) {};
public: Instance_IsLeafFilter(const Instance_IsLeafFilter& filter) {}; Instance_IsLeafFilter& operator= ( const Instance_IsLeafFilter& filter )
{ return *this; };
public: Instance_IsLeafFilter& operator=(const Instance_IsLeafFilter& filter) {return *this;}; virtual Filter<Instance*>* getClone () const
{ return new Instance_IsLeafFilter( *this ); };
public: virtual Filter<Instance*>* getClone() const {return new Instance_IsLeafFilter(*this);}; virtual bool accept ( Instance* instance ) const
{ return instance->isLeaf(); };
public: virtual bool accept(Instance* instance) const {return instance->isLeaf();}; virtual string _getString () const
{ return "<" + _TName("Instance::IsLeafFilter") + ">"; };
public: virtual string _getString() const {return "<" + _TName("Instance::IsLeafFilter") + ">";}; private:
uint32_t _flags;
}; };
@ -315,7 +316,7 @@ InstanceFilter Instance::getIsTerminalFilter()
} }
InstanceFilter Instance::getIsLeafFilter() InstanceFilter Instance::getIsLeafFilter()
// ******************************************* // ***************************************
{ {
return Instance_IsLeafFilter(); return Instance_IsLeafFilter();
} }

View File

@ -342,6 +342,7 @@ class Cell : public Entity {
private: AliasNameSet _netAliasSet; private: AliasNameSet _netAliasSet;
private: Observable _observers; private: Observable _observers;
private: Flags _flags; private: Flags _flags;
private: static bool _useFlattenLeaf;
// Constructors // Constructors
// ************ // ************
@ -521,6 +522,7 @@ class Cell : public Entity {
public: void addObserver(BaseObserver*); public: void addObserver(BaseObserver*);
public: void removeObserver(BaseObserver*); public: void removeObserver(BaseObserver*);
public: void notify(unsigned flags); public: void notify(unsigned flags);
public: static void setFlattenLeafMode(bool state) { _useFlattenLeaf=state; };
}; };

View File

@ -570,10 +570,10 @@ namespace {
TrackElement* element = TrackFixedSegment::create ( track, segment ); TrackElement* element = TrackFixedSegment::create ( track, segment );
cdebug_log(159,0) << " Insert in " << track << "+" << element << endl; cdebug_log(159,0) << " Insert in " << track << "+" << element << endl;
if (segment->getId() == 51904) { // if (segment->getId() == 51904) {
cerr << " Insert in " << track << endl; // cerr << " Insert in " << track << endl;
cerr << " +" << element << endl; // cerr << " +" << element << endl;
} // }
} }
// if (segment->getId() == 51904) { // if (segment->getId() == 51904) {
// DebugSession::close(); // DebugSession::close();

View File

@ -56,16 +56,13 @@ namespace Katana {
// Class : "TrackFixedSegment". // Class : "TrackFixedSegment".
Net* TrackFixedSegment::_blockageNet = NULL;
TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment ) TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment )
: TrackElement (NULL) : TrackElement (NULL)
, _segment (segment) , _segment (segment)
{ {
Box boundingBox = segment->getBoundingBox(); 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 ); setFlags( flags );
if (track) { if (track) {
@ -123,8 +120,6 @@ namespace Katana {
TrackElement* TrackFixedSegment::create ( Track* track, Segment* segment ) TrackElement* TrackFixedSegment::create ( Track* track, Segment* segment )
{ {
if ( not _blockageNet ) _blockageNet = Session::getBlockageNet();
TrackFixedSegment* trackFixedSegment = NULL; TrackFixedSegment* trackFixedSegment = NULL;
if (track) { if (track) {
trackFixedSegment = new TrackFixedSegment ( track, segment ); trackFixedSegment = new TrackFixedSegment ( track, segment );
@ -189,7 +184,7 @@ namespace Katana {
{ {
Net* realNet = _segment->getNet(); Net* realNet = _segment->getNet();
if (realNet->isSupply() or realNet->isClock()) if (realNet->isSupply() or realNet->isClock())
return _blockageNet; return Session::getBlockageNet();
return realNet; return realNet;
} }

View File

@ -71,7 +71,6 @@ namespace Katana {
virtual string _getTypeName () const; virtual string _getTypeName () const;
protected: protected:
// Attributes. // Attributes.
static Net* _blockageNet;
Segment* _segment; Segment* _segment;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.