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:
parent
757b95343b
commit
59ee8358ca
|
@ -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<Segment*>(component);
|
||||
if (not segment) continue;
|
||||
if (segment->getLayer()->getMask() != metal1->getMask()) continue;
|
||||
Component* candidate = dynamic_cast<Segment*>(component);
|
||||
if (not candidate
|
||||
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 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) ) {
|
||||
|
|
|
@ -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<Segment*>( 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() );
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
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<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 ()
|
||||
{
|
||||
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
|
||||
{ return "NetBuilderHV"; }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -370,6 +370,8 @@ namespace Etesian {
|
|||
|
||||
sliceHoles.setSpinSlice0( _yspinSlice0 );
|
||||
|
||||
Cell::setFlattenLeafMode( true );
|
||||
|
||||
for ( Occurrence occurrence : getBlockCell()->getLeafInstanceOccurrences() )
|
||||
{
|
||||
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
||||
|
@ -397,6 +399,8 @@ namespace Etesian {
|
|||
|
||||
sliceHoles.addFeeds();
|
||||
|
||||
Cell::setFlattenLeafMode( false );
|
||||
|
||||
UpdateSession::close();
|
||||
|
||||
if (_viewer) _viewer->getCellWidget()->refresh();
|
||||
|
|
|
@ -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<Instance*>(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<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();
|
||||
Transformation topTransformation;
|
||||
if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation();
|
||||
topTransformation.applyOn( topAb );
|
||||
|
||||
Cell::setFlattenLeafMode( true );
|
||||
|
||||
UpdateSession::open();
|
||||
for ( Occurrence occurrence : getBlockCell()->getNonLeafInstanceOccurrences() )
|
||||
{
|
||||
Instance* instance = static_cast<Instance*>(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<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;
|
||||
//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<Instance*>(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<int_t>( 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<temporary_net> 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<int_t>(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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1007,7 +1007,8 @@ class Cell_LeafInstanceOccurrences : public Collection<Occurrence> {
|
|||
public:
|
||||
typedef Hurricane::Locator<Occurrence> 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<Occurrence> {
|
|||
};
|
||||
|
||||
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<Occurrence>* 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<DeepNet*>(_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
|
||||
|
|
|
@ -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<Occurrence>* 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<Net*>( 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<Occurrence>* 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<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();
|
||||
}
|
||||
} else
|
||||
|
|
|
@ -96,20 +96,21 @@ class Instance_IsTerminalFilter : public Filter<Instance*> {
|
|||
|
||||
};
|
||||
|
||||
class Instance_IsLeafFilter : public Filter<Instance*> {
|
||||
// *******************************************************
|
||||
|
||||
public: Instance_IsLeafFilter() {};
|
||||
|
||||
public: Instance_IsLeafFilter(const Instance_IsLeafFilter& filter) {};
|
||||
|
||||
public: Instance_IsLeafFilter& operator=(const Instance_IsLeafFilter& filter) {return *this;};
|
||||
|
||||
public: virtual Filter<Instance*>* 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<Instance*>
|
||||
{
|
||||
public:
|
||||
Instance_IsLeafFilter () {};
|
||||
Instance_IsLeafFilter ( const Instance_IsLeafFilter& filter ) {};
|
||||
Instance_IsLeafFilter& operator= ( const Instance_IsLeafFilter& filter )
|
||||
{ return *this; };
|
||||
virtual Filter<Instance*>* 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();
|
||||
}
|
||||
|
|
|
@ -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; };
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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* ) ;
|
||||
|
|
Loading…
Reference in New Issue