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/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) ) {
|
||||||
|
|
|
@ -401,14 +401,14 @@ namespace Anabatic {
|
||||||
for ( Hook* hook : fromHook->getHooks() ) {
|
for ( Hook* hook : fromHook->getHooks() ) {
|
||||||
cdebug_log(145,0) << "Hook: " << hook << endl;
|
cdebug_log(145,0) << "Hook: " << hook << endl;
|
||||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||||
<< "[" << (int)_connexity.fields.globals
|
<< "[" << (int)_connexity.fields.globals
|
||||||
<< "+" << (int)_connexity.fields.M1
|
<< "+" << (int)_connexity.fields.M1
|
||||||
<< "+" << (int)_connexity.fields.M2
|
<< "+" << (int)_connexity.fields.M2
|
||||||
<< "+" << (int)_connexity.fields.M3
|
<< "+" << (int)_connexity.fields.M3
|
||||||
<< "+" << (int)_connexity.fields.Pin
|
<< "+" << (int)_connexity.fields.Pin
|
||||||
<< "+" << (int)_connexity.fields.Pad
|
<< "+" << (int)_connexity.fields.Pad
|
||||||
<< "] " << _gcell
|
<< "] " << _gcell
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
|
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
|
||||||
if (toSegment) {
|
if (toSegment) {
|
||||||
|
@ -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;
|
||||||
|
@ -617,17 +636,22 @@ namespace Anabatic {
|
||||||
case Conn_4G: _do_xG(); break;
|
case Conn_4G: _do_xG(); break;
|
||||||
// End xG cascaded cases.
|
// End xG cascaded cases.
|
||||||
// Optimized specific cases.
|
// Optimized specific cases.
|
||||||
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
|
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
|
||||||
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
|
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
|
||||||
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
||||||
case Conn_2G_1PinM2:
|
case Conn_2G_1PinM2:
|
||||||
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
||||||
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_1M2: _do_xG_1M1_1M2(); break;
|
case Conn_1G_1M1_1PinM3: _do_1G_1M1_1PinM3(); break;
|
||||||
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
|
case Conn_1G_1M1_1PinM2:
|
||||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break;
|
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:
|
default:
|
||||||
if (not isTwoMetals())
|
if (not isTwoMetals())
|
||||||
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
||||||
|
@ -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() );
|
||||||
|
|
|
@ -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"; }
|
||||||
|
|
||||||
|
|
|
@ -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 ();
|
||||||
|
@ -242,74 +245,79 @@ namespace Anabatic {
|
||||||
+ ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \
|
+ ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \
|
||||||
+ ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize))
|
+ ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize))
|
||||||
|
|
||||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||||
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
|
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
|
||||||
, Conn_2G = CONNEXITY_VALUE( 2, 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_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
|
||||||
, Conn_4G = CONNEXITY_VALUE( 4, 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_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 )
|
||||||
, Conn_6G = CONNEXITY_VALUE( 6, 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_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
|
||||||
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 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_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
|
||||||
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 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_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
|
||||||
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 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_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
|
||||||
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 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_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
|
||||||
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 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_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
|
||||||
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 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_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
|
||||||
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 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_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
|
||||||
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
|
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
|
||||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||||
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
|
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
|
||||||
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 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_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
|
||||||
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 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_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
|
||||||
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 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_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
|
||||||
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 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_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
|
||||||
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 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_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
|
||||||
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 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_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
|
||||||
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
|
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
|
||||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||||
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
|
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
|
||||||
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 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_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
|
||||||
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 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_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 )
|
||||||
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 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_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
|
||||||
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 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_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
|
||||||
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
|
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
|
||||||
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
|
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
|
||||||
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
// Connexity Name | G|M1|M2|M3|Pad|Pin|
|
||||||
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
|
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
|
||||||
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 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_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
|
||||||
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 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_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
|
||||||
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 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_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
|
||||||
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 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_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
|
||||||
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
||||||
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 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_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_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
|
, Conn_1G_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 )
|
||||||
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
|
, Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 )
|
||||||
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 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
|
#undef CONNEXITY_VALUE
|
||||||
|
|
|
@ -28,33 +28,38 @@ namespace Anabatic {
|
||||||
|
|
||||||
class NetBuilderHV : public NetBuilder {
|
class NetBuilderHV : public NetBuilder {
|
||||||
public:
|
public:
|
||||||
NetBuilderHV ();
|
NetBuilderHV ();
|
||||||
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 ();
|
||||||
virtual bool _do_xG ();
|
virtual bool _do_xG ();
|
||||||
virtual bool _do_2G ();
|
virtual bool _do_2G ();
|
||||||
virtual bool _do_2G_1M1 ();
|
virtual bool _do_2G_1M1 ();
|
||||||
virtual bool _do_xG_1Pad ();
|
virtual bool _do_xG_1Pad ();
|
||||||
virtual bool _do_1G_1PinM1 ();
|
virtual bool _do_1G_1PinM1 ();
|
||||||
virtual bool _do_2G_1PinM1 ();
|
virtual bool _do_2G_1PinM1 ();
|
||||||
virtual bool _do_1G_1PinM2 ();
|
virtual bool _do_1G_1PinM2 ();
|
||||||
virtual bool _do_xG_1PinM2 ();
|
virtual bool _do_xG_1PinM2 ();
|
||||||
virtual bool _do_1G_1PinM3 ();
|
virtual bool _do_1G_1PinM3 ();
|
||||||
virtual bool _do_xG_1PinM3 ();
|
virtual bool _do_xG_1PinM3 ();
|
||||||
virtual bool _do_xG_1M1 ();
|
virtual bool _do_xG_1M1 ();
|
||||||
virtual bool _do_xG_1M1_1M2 ();
|
virtual bool _do_xG_1M1_1M2 ();
|
||||||
virtual bool _do_xG_xM1_xM3 ();
|
virtual bool _do_xG_xM1_xM3 ();
|
||||||
virtual bool _do_4G_1M2 ();
|
virtual bool _do_4G_1M2 ();
|
||||||
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_globalSegment ();
|
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:
|
public:
|
||||||
virtual string getTypeName () const;
|
virtual string getTypeName () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
index_t instanceId = 0;
|
bool tooManyInstances = false;
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,12 +637,14 @@ void HyperNet_NetOccurrences::Locator::progress()
|
||||||
} // for component*.
|
} // for component*.
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( Plug* plug : net->getPlugs() ) {
|
if (not net->getCell()->isLeaf()) {
|
||||||
Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) );
|
for ( Plug* plug : net->getPlugs() ) {
|
||||||
|
Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) );
|
||||||
|
|
||||||
if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) {
|
if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) {
|
||||||
_netOccurrenceSet.insert(occurrence);
|
_netOccurrenceSet.insert(occurrence);
|
||||||
_netOccurrenceStack.push(occurrence);
|
_netOccurrenceStack.push(occurrence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -991,91 +993,81 @@ string HyperNet_LeafPlugOccurrences::_getString() const
|
||||||
// HyperNet_LeafPlugOccurrences::Locator implementation
|
// HyperNet_LeafPlugOccurrences::Locator implementation
|
||||||
// ****************************************************************************************************
|
// ****************************************************************************************************
|
||||||
|
|
||||||
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 )
|
||||||
|
: Inherit()
|
||||||
|
, _netOccurrenceLocator()
|
||||||
|
, _plugOccurrence()
|
||||||
{
|
{
|
||||||
|
if (hyperNet) {
|
||||||
|
_netOccurrenceLocator = hyperNet->getNetOccurrences( doExtraction
|
||||||
|
, allowInterruption ).getLocator();
|
||||||
|
progress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HyperNet_LeafPlugOccurrences::Locator::Locator(const HyperNet* hyperNet, bool doExtraction, bool allowInterruption)
|
|
||||||
// ****************************************************************************************************
|
HyperNet_LeafPlugOccurrences::Locator::Locator ( const Locator& locator )
|
||||||
: Inherit(),
|
: Inherit()
|
||||||
_netOccurrenceLocator(),
|
, _netOccurrenceLocator()
|
||||||
_plugOccurrence()
|
, _plugOccurrence()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
HyperNet_LeafPlugOccurrences::Locator& HyperNet_LeafPlugOccurrences::Locator::operator= ( const Locator& locator )
|
||||||
{
|
{
|
||||||
if (hyperNet) {
|
_netOccurrenceLocator = locator._netOccurrenceLocator;
|
||||||
_netOccurrenceLocator = hyperNet->getNetOccurrences(doExtraction,allowInterruption).getLocator();
|
_plugOccurrence = locator._plugOccurrence;
|
||||||
progress();
|
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();
|
string s = "<" + _TName("HyperNet::LeafPlugOccurrences::Locator");
|
||||||
while(_netOccurrenceLocator.isValid() && !_plugOccurrence.isValid())
|
s += " " + getString(_netOccurrenceLocator);
|
||||||
{
|
s += ">";
|
||||||
Occurrence netOccurrence = _netOccurrenceLocator.getElement();
|
return s;
|
||||||
|
|
||||||
_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,7 @@ 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.
|
||||||
TrackFixedSegment ( Track*, Segment* ) ;
|
TrackFixedSegment ( Track*, Segment* ) ;
|
||||||
|
|
Loading…
Reference in New Issue