Complete the modularization of the detail routing converter.
* New: In Anabatic::NetBuilder, set all the attributes as private and create accessors and mutators. Finish virtualising all GCell build methods and transfer them into the NetBuilderHV class. Build methods now return a boolean to tell if the GCell was processed or not, to allow cascading in the "big switch". Reorganise the "big switch" in separate sections only partially cascading. Truly fuse the *big switch* for channel routing and over-the-cells. Create a new method "_do_globalSegment()" to delagate the drawing of global segments between two GCell to the derived classes.
This commit is contained in:
parent
e17a50ca0b
commit
f87bcf717c
|
@ -29,6 +29,7 @@
|
|||
#include "crlcore/RoutingGauge.h"
|
||||
#include "crlcore/Measures.h"
|
||||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/NetBuilderM2.h"
|
||||
#include "anabatic/NetBuilderHV.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
||||
|
@ -729,24 +730,42 @@ namespace Anabatic {
|
|||
startMeasures();
|
||||
openSession();
|
||||
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
DebugSession::open( net, 144, 160 );
|
||||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
NetBuilder::load<NetBuilderHV>( this, net );
|
||||
Session::revalidate();
|
||||
DebugSession::close();
|
||||
int gaugeKind = 3;
|
||||
if (getConfiguration()->isTwoMetals()) gaugeKind = 0;
|
||||
if (getConfiguration()->isHV ()) gaugeKind = 1;
|
||||
if (getConfiguration()->isVH ()) gaugeKind = 2;
|
||||
|
||||
if (gaugeKind < 2) {
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
DebugSession::open( net, 144, 160 );
|
||||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
||||
switch ( gaugeKind ) {
|
||||
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break;
|
||||
//case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
DebugSession::close();
|
||||
}
|
||||
}
|
||||
AutoSegment::setAnalogMode( false );
|
||||
}
|
||||
AutoSegment::setAnalogMode( false );
|
||||
|
||||
#if defined(CHECK_DATABASE)
|
||||
_check ( "after Anabatic loading" );
|
||||
#endif
|
||||
|
||||
Session::close();
|
||||
|
||||
stopMeasures();
|
||||
|
||||
if (gaugeKind > 1) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"."
|
||||
, getString(getConfiguration()->getRoutingGauge()->getName()).c_str() );
|
||||
}
|
||||
|
||||
printMeasures( "load" );
|
||||
|
||||
addMeasure<size_t>( getCell(), "Globals", AutoSegment::getGlobalsCount() );
|
||||
|
|
|
@ -30,6 +30,7 @@ endif ( CHECK_DETERMINISM )
|
|||
anabatic/AutoVertical.h
|
||||
anabatic/Session.h
|
||||
anabatic/NetBuilder.h
|
||||
anabatic/NetBuilderM2.h
|
||||
anabatic/NetBuilderHV.h
|
||||
anabatic/ChipTools.h
|
||||
)
|
||||
|
@ -53,6 +54,7 @@ endif ( CHECK_DETERMINISM )
|
|||
NetConstraints.cpp
|
||||
NetOptimals.cpp
|
||||
NetBuilder.cpp
|
||||
NetBuilderM2.cpp
|
||||
NetBuilderHV.cpp
|
||||
ChipTools.cpp
|
||||
LayerAssign.cpp
|
||||
|
|
|
@ -173,6 +173,14 @@ namespace Anabatic {
|
|||
Configuration* Configuration::clone () const
|
||||
{ return new Configuration(*this); }
|
||||
|
||||
bool Configuration::isTwoMetals () const
|
||||
{ return _rg->isTwoMetals(); }
|
||||
|
||||
bool Configuration::isHV () const
|
||||
{ return _rg->isHV(); }
|
||||
|
||||
bool Configuration::isVH () const
|
||||
{ return _rg->isVH(); }
|
||||
|
||||
bool Configuration::isGMetal ( const Layer* layer ) const
|
||||
{ return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@
|
|||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./LoadGlobalRouting.cpp" |
|
||||
// | C++ Module : "./NetBuilderHV.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
|
@ -52,6 +52,8 @@
|
|||
namespace Anabatic {
|
||||
|
||||
using std::swap;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Warning;
|
||||
|
||||
|
||||
NetBuilderHV::NetBuilderHV ()
|
||||
|
@ -69,7 +71,7 @@ namespace Anabatic {
|
|||
, uint64_t flags
|
||||
)
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilderHV::doRp_AutoContacts()" << endl;
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AutoContacts()" << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
|
||||
source = target = NULL;
|
||||
|
@ -154,7 +156,7 @@ namespace Anabatic {
|
|||
|
||||
AutoContact* NetBuilderHV::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilderHV::doRp_Access() - flags:" << flags << endl;
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||
|
||||
AutoContact* rpContactSource;
|
||||
AutoContact* rpContactTarget;
|
||||
|
@ -185,9 +187,9 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void NetBuilderHV::_do_1G_1M1 ()
|
||||
bool NetBuilderHV::_do_1G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilderHV::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
uint64_t flags = NoFlags;
|
||||
if (east() ) { flags |= HAccess; }
|
||||
|
@ -198,12 +200,13 @@ namespace Anabatic {
|
|||
setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void NetBuilderHV::_do_1G_xM1 ()
|
||||
bool NetBuilderHV::_do_1G_xM1 ()
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilderHV::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Managed Configuration]" << endl;
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Managed Configuration]" << endl;
|
||||
|
||||
sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByX(NoFlags) ); // increasing X.
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
|
||||
|
@ -238,7 +241,581 @@ namespace Anabatic {
|
|||
setBothCornerContacts( globalContact );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
} else if (getConnexity().fields.globals == 3) {
|
||||
if (east() and west()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (south()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
||||
} else {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (west()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
||||
}
|
||||
} else { // fields.globals == 4.
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_2G ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G()" << endl;
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
|
||||
if (east() and west()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
||||
} else if (south() and north()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
||||
} else {
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_1Pad ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_1Pad() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
cdebug_log(145,0) << "getConnexity().globals:" << (int)getConnexity().fields.globals << endl;
|
||||
|
||||
uint64_t flags = NoFlags;
|
||||
bool eastPad = false;
|
||||
bool westPad = false;
|
||||
bool northPad = false;
|
||||
bool southPad = false;
|
||||
Instance* padInstance = getRoutingPads()[0]->getOccurrence().getPath().getHeadInstance();
|
||||
|
||||
switch ( padInstance->getTransformation().getOrientation() ) {
|
||||
case Transformation::Orientation::ID: northPad = true; break;
|
||||
case Transformation::Orientation::MY: southPad = true; break;
|
||||
case Transformation::Orientation::YR:
|
||||
case Transformation::Orientation::R3: eastPad = true; flags |= HAccess; break;
|
||||
case Transformation::Orientation::R1: westPad = true; flags |= HAccess; break;
|
||||
default:
|
||||
cerr << Warning( "Unmanaged orientation %s for pad <%s>."
|
||||
, getString(padInstance->getTransformation().getOrientation()).c_str()
|
||||
, getString(padInstance).c_str() ) << endl;
|
||||
break;
|
||||
}
|
||||
cdebug_log(145,0) << "eastPad:" << eastPad << ", "
|
||||
<< "westPad:" << westPad << ", "
|
||||
<< "northPad:" << northPad << ", "
|
||||
<< "southPad:" << southPad
|
||||
<< endl;
|
||||
|
||||
AutoContact* source = doRp_AccessPad( getRoutingPads()[0], flags );
|
||||
// Point position = getRoutingPads()[0]->getCenter();
|
||||
// AutoContact* source = NULL;
|
||||
// GCell* gcell = Session::getAnabatic()->getGCellGrid()->getGCell(position);
|
||||
|
||||
// source = AutoContactTerminal::create ( gcell
|
||||
// , getRoutingPads()[0]
|
||||
// , Session::getContactLayer(3)
|
||||
// , position
|
||||
// , Session::getViaWidth(3), Session::getViaWidth(3)
|
||||
// );
|
||||
// source->setFlags( CntFixed );
|
||||
|
||||
// if (northPad or eastPad) {
|
||||
// getSouthWestContact() = getNorthEastContact() = source;
|
||||
// cdebug_tabw(145,-1);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Check for straight lines, which are not managed by _do_xG().
|
||||
if (getConnexity().fields.globals == 1) {
|
||||
if ( (westPad and (east() != NULL))
|
||||
or (eastPad and (west() != NULL)) ) {
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ) );
|
||||
AutoSegment::create( source, turn, Flags::Horizontal );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
} else if ( (southPad and (north() != NULL))
|
||||
or (northPad and (south() != NULL)) ) {
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ) );
|
||||
AutoSegment::create( source, turn, Flags::Vertical );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Horizontal );
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
++getConnexity().fields.globals;
|
||||
--getConnexity().fields.Pad;
|
||||
|
||||
if (westPad ) addToWests ( source->getBodyHook() );
|
||||
if (eastPad ) addToEasts ( source->getBodyHook() );
|
||||
if (southPad) addToSouths( source->getBodyHook() );
|
||||
if (northPad) addToNorths( source->getBodyHook() );
|
||||
|
||||
_do_xG();
|
||||
|
||||
if (westPad) {
|
||||
AutoSegment::create( source, getSouthWestContact(), Flags::Horizontal );
|
||||
clearWests();
|
||||
}
|
||||
if (eastPad) {
|
||||
AutoSegment::create( source, getNorthEastContact(), Flags::Horizontal );
|
||||
clearEasts();
|
||||
}
|
||||
if (southPad) {
|
||||
AutoSegment::create( source, getSouthWestContact(), Flags::Vertical );
|
||||
clearSouths();
|
||||
}
|
||||
if (northPad) {
|
||||
AutoSegment::create( source, getNorthEastContact(), Flags::Vertical );
|
||||
clearNorths();
|
||||
}
|
||||
--(getConnexity().fields.globals);
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_1G_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpContact, turn1, Flags::Vertical );
|
||||
|
||||
if (north() or south()) {
|
||||
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( turn1, turn2, Flags::Horizontal );
|
||||
turn1 = turn2;
|
||||
}
|
||||
setBothCornerContacts( turn1 );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_1M1_1M2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_1M1_1M2() [Managed Configuration]" << endl;
|
||||
|
||||
Component* rpL1;
|
||||
Component* rpL2;
|
||||
if (getRoutingPads()[0]->getLayer() == Session::getRoutingLayer(0)) {
|
||||
rpL1 = getRoutingPads()[0];
|
||||
rpL2 = getRoutingPads()[1];
|
||||
} else {
|
||||
rpL1 = getRoutingPads()[1];
|
||||
rpL2 = getRoutingPads()[0];
|
||||
}
|
||||
cdebug_log(145,0) << "rpL1 := " << rpL1 << endl;
|
||||
cdebug_log(145,0) << "rpL2 := " << rpL2 << endl;
|
||||
|
||||
AutoContact* rpL1ContactSource = NULL;
|
||||
AutoContact* rpL1ContactTarget = NULL;
|
||||
AutoContact* rpL2ContactSource = NULL;
|
||||
AutoContact* rpL2ContactTarget = NULL;
|
||||
|
||||
doRp_AutoContacts( getGCell(), rpL1, rpL1ContactSource, rpL1ContactTarget, NoFlags );
|
||||
doRp_AutoContacts( getGCell(), rpL2, rpL2ContactSource, rpL2ContactTarget, NoFlags );
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
const Layer* viaLayer2 = Session::getContactLayer(2);
|
||||
|
||||
AutoContact* subContact = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( rpL1ContactSource, subContact, Flags::Horizontal );
|
||||
AutoSegment::create( rpL2ContactSource, subContact, Flags::Vertical );
|
||||
|
||||
if (south() or west()) {
|
||||
doRp_AutoContacts( getGCell(), rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact );
|
||||
if (south() and west()) {
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer2 ) );
|
||||
AutoSegment::create( rpL2ContactSource, getSouthWestContact(), Flags::Horizontal );
|
||||
} else {
|
||||
if (south()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer2 ) );
|
||||
AutoSegment::create( rpL2ContactSource, getSouthWestContact(), Flags::Horizontal );
|
||||
} else {
|
||||
setSouthWestContact( rpL2ContactSource );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (north() or east()) {
|
||||
doRp_AutoContacts( getGCell(), rpL2, rpL2ContactSource, rpL2ContactTarget, DoTargetContact );
|
||||
if (north() and east()) {
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer2 ) );
|
||||
AutoSegment::create( rpL2ContactTarget, getNorthEastContact(), Flags::Horizontal );
|
||||
} else {
|
||||
if (north()) {
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer2 ) );
|
||||
AutoSegment::create( rpL2ContactTarget, getNorthEastContact(), Flags::Horizontal );
|
||||
} else {
|
||||
setNorthEastContact( rpL2ContactTarget );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_xM1_xM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName()
|
||||
<< "::_do_xG_" << (int)getConnexity().fields.M1
|
||||
<< "M1_" << (int)getConnexity().fields.M3
|
||||
<< "M3() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl;
|
||||
cdebug_log(145,0) << "north: " << north() << endl;
|
||||
cdebug_log(145,0) << "south: " << south() << endl;
|
||||
cdebug_log(145,0) << "east: " << east() << endl;
|
||||
cdebug_log(145,0) << "west: " << west() << endl;
|
||||
|
||||
Component* rpM3 = NULL;
|
||||
if (getRoutingPads()[0]->getLayer() == Session::getRoutingLayer(2))
|
||||
rpM3 = getRoutingPads()[0];
|
||||
|
||||
sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByX(NoFlags) ); // increasing X.
|
||||
for ( size_t i=1 ; i<getRoutingPads().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 );
|
||||
|
||||
if (not rpM3 and (getRoutingPads()[i]->getLayer() == Session::getRoutingLayer(2)))
|
||||
rpM3 = getRoutingPads()[i];
|
||||
}
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
AutoContact* unusedContact = NULL;
|
||||
|
||||
if (rpM3) {
|
||||
// At least one M3 RoutingPad is present: use it.
|
||||
if (west() and not south()) {
|
||||
setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
|
||||
} else if (not west() and south()) {
|
||||
doRp_AutoContacts( getGCell(), rpM3, getSouthWestContact(), unusedContact, DoSourceContact );
|
||||
} else if (west() and south()) {
|
||||
AutoContact* rpContact = NULL;
|
||||
doRp_AutoContacts( getGCell(), rpM3, rpContact, unusedContact, DoSourceContact );
|
||||
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
|
||||
}
|
||||
|
||||
if (east() and not north()) {
|
||||
setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
|
||||
} else if (not east() and north()) {
|
||||
doRp_AutoContacts( getGCell(), rpM3, unusedContact, getNorthEastContact(), DoTargetContact );
|
||||
} else if (east() and north()) {
|
||||
AutoContact* rpContact = NULL;
|
||||
doRp_AutoContacts( getGCell(), rpM3, unusedContact, rpContact, DoTargetContact );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
|
||||
}
|
||||
} else {
|
||||
// All RoutingPad are M1.
|
||||
Component* southWestRp = getRoutingPads()[0];
|
||||
cdebug_log(145,0) << "| Initial S-W Global RP: " << southWestRp << endl;
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
|
||||
if (southWestRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break;
|
||||
if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) {
|
||||
cdebug_log(145,0) << "| Better RP: " << southWestRp << endl;
|
||||
southWestRp = getRoutingPads()[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (west() and not south()) {
|
||||
setSouthWestContact( doRp_Access( getGCell(), southWestRp, HAccess ) );
|
||||
} else if (not west() and south()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), southWestRp, HAccess );
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Horizontal );
|
||||
} else if (west() and south()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), southWestRp, HAccess );
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Horizontal );
|
||||
}
|
||||
|
||||
Component* northEastRp = getRoutingPads()[getRoutingPads().size()-1];
|
||||
cdebug_log(145,0) << "| Initial N-E Global RP: " << northEastRp << endl;
|
||||
|
||||
if (getRoutingPads().size() > 1) {
|
||||
for ( size_t i=getRoutingPads().size()-1; i != 0 ; ) {
|
||||
i -= 1;
|
||||
if (northEastRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break;
|
||||
if (getRoutingPads()[i]->getBoundingBox().getHeight() > northEastRp->getBoundingBox().getHeight()) {
|
||||
cdebug_log(145,0) << "| Better RP: " << northEastRp << endl;
|
||||
northEastRp = getRoutingPads()[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (east() and not north()) {
|
||||
setNorthEastContact( doRp_Access( getGCell(), northEastRp, HAccess ) );
|
||||
} else if (not east() and north()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), northEastRp, HAccess );
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Horizontal );
|
||||
} else if (east() and north()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), northEastRp, HAccess );
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Horizontal );
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_4G_1M2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_4G_1M2() [Managed Configuration]" << endl;
|
||||
|
||||
Component* rpL2 = getRoutingPads()[0];
|
||||
cdebug_log(145,0) << "rpL2 := " << rpL2 << endl;
|
||||
|
||||
AutoContact* rpL2ContactSource = NULL;
|
||||
AutoContact* rpL2ContactTarget = NULL;
|
||||
|
||||
doRp_AutoContacts( getGCell(), rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact|DoTargetContact );
|
||||
|
||||
const Layer* viaLayer2 = Session::getContactLayer(2);
|
||||
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer2 ) );
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer2 ) );
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), rpL2ContactSource, Flags::Horizontal );
|
||||
AutoSegment::create( rpL2ContactTarget, getNorthEastContact(), Flags::Horizontal );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_xM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_"
|
||||
<< (int)getConnexity().fields.globals << "G_"
|
||||
<< (int)getConnexity().fields.M2 << "M2() [Managed Configuration - x]" << endl;
|
||||
|
||||
Component* biggestRp = getRoutingPads()[0];
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
|
||||
doRp_StairCaseH( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
||||
if (getRoutingPads()[i]->getBoundingBox().getWidth() > biggestRp->getBoundingBox().getWidth())
|
||||
biggestRp = getRoutingPads()[i];
|
||||
}
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
AutoContact* unusedContact = NULL;
|
||||
|
||||
if (west() and not south()) {
|
||||
doRp_AutoContacts( getGCell(), getRoutingPads()[0], getSouthWestContact(), unusedContact, DoSourceContact );
|
||||
} else if (not west() and south()) {
|
||||
setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
||||
} else if (west() and south()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
||||
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
|
||||
}
|
||||
|
||||
if (east() and not north()) {
|
||||
doRp_AutoContacts( getGCell(), getRoutingPads()[getRoutingPads().size()-1], getNorthEastContact(), unusedContact, DoSourceContact );
|
||||
} else if (not east() and north()) {
|
||||
setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
||||
} else if (east() and north()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_1G_1M3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M3() [Optimised Configuration]" << endl;
|
||||
|
||||
uint64_t flags = (east() or west()) ? HAccess : NoFlags;
|
||||
flags |= (north()) ? DoTargetContact : NoFlags;
|
||||
flags |= (south()) ? DoSourceContact : NoFlags;
|
||||
|
||||
doRp_AutoContacts( getGCell()
|
||||
, getRoutingPads()[0]
|
||||
, getSouthWestContact()
|
||||
, getNorthEastContact()
|
||||
, flags
|
||||
);
|
||||
if (not getSouthWestContact()) setSouthWestContact( getNorthEastContact() );
|
||||
if (not getNorthEastContact()) setNorthEastContact( getSouthWestContact() );
|
||||
|
||||
cdebug_log(145,0) << "_southWest: " << getSouthWestContact() << endl;
|
||||
cdebug_log(145,0) << "_northEast: " << getNorthEastContact() << endl;
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
|
||||
if (flags & HAccess) {
|
||||
// HARDCODED VALUE.
|
||||
if (getRoutingPads()[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) {
|
||||
AutoContact* subContact = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getSouthWestContact(), subContact, Flags::Vertical );
|
||||
|
||||
setBothCornerContacts( subContact );
|
||||
}
|
||||
} else {
|
||||
if (getSourceContact()) {
|
||||
if (getSourceContact()->getX() != getSouthWestContact()->getX()) {
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
||||
setBothCornerContacts( turn2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_xM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName()
|
||||
<< "::_do_xG_" << (int)getConnexity().fields.M3
|
||||
<< "M3() [Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "west:" << west() << endl;
|
||||
cdebug_log(145,0) << "east:" << east() << endl;
|
||||
cdebug_log(145,0) << "south:" << south() << endl;
|
||||
cdebug_log(145,0) << "north:" << north() << endl;
|
||||
|
||||
sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByY(NoFlags) ); // increasing Y.
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; i++ ) {
|
||||
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
||||
}
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
AutoContact* unusedContact = NULL;
|
||||
Component* rp = getRoutingPads()[0];
|
||||
|
||||
if (west() and not south()) {
|
||||
setSouthWestContact( doRp_Access( getGCell(), rp, HAccess ) );
|
||||
} else if (not west() and south()) {
|
||||
doRp_AutoContacts( getGCell(), rp, getSouthWestContact(), unusedContact, DoSourceContact );
|
||||
if (getSourceContact()) {
|
||||
if (getSourceContact()->getX() != getSouthWestContact()->getX()) {
|
||||
cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(getSourceContact()->getX())
|
||||
<< "_southWest:" << DbU::getValueString(getSouthWestContact()->getX()) << endl;
|
||||
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
||||
setSouthWestContact( turn2 );
|
||||
}
|
||||
}
|
||||
} else if (west() and south()) {
|
||||
AutoContact* rpContact = NULL;
|
||||
doRp_AutoContacts( getGCell(), rp, rpContact, unusedContact, DoSourceContact );
|
||||
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
|
||||
}
|
||||
|
||||
rp = getRoutingPads()[getRoutingPads().size()-1];
|
||||
if (east() and not north()) {
|
||||
setNorthEastContact( doRp_Access( getGCell(), rp, HAccess ) );
|
||||
} else if (not east() and north()) {
|
||||
doRp_AutoContacts( getGCell(), rp, unusedContact, getNorthEastContact(), DoTargetContact );
|
||||
if (getSourceContact()) {
|
||||
if (getSourceContact()->getX() != getNorthEastContact()->getX()) {
|
||||
cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(getSourceContact()->getX())
|
||||
<< "_southWest:" << DbU::getValueString(getNorthEastContact()->getX()) << endl;
|
||||
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
||||
setNorthEastContact( turn2 );
|
||||
}
|
||||
}
|
||||
} else if (east() and north()) {
|
||||
AutoContact* rpContact = NULL;
|
||||
doRp_AutoContacts( getGCell(), rp, unusedContact, rpContact, DoTargetContact );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_globalSegment ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
||||
|
||||
if (getSourceContact()) {
|
||||
AutoContact* targetContact
|
||||
= ( getSegmentHookType(getFromHook()) & (NorthBound|EastBound) )
|
||||
? getNorthEastContact() : getSouthWestContact() ;
|
||||
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
|
||||
, targetContact
|
||||
, static_cast<Segment*>( getFromHook()->getComponent() )
|
||||
);
|
||||
globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 );
|
||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) return false;
|
||||
} else
|
||||
setFromHook( NULL );
|
||||
|
||||
push( east (), getNorthEastContact() );
|
||||
push( west (), getSouthWestContact() );
|
||||
push( north(), getNorthEastContact() );
|
||||
push( south(), getSouthWestContact() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string NetBuilderHV::getTypeName () const
|
||||
{ return "NetBuilderHV"; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -0,0 +1,348 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2016, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./NetBuilderM2.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/NetRoutingProperty.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/RoutingPads.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "crlcore/Measures.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
#include "anabatic/AutoContactTurn.h"
|
||||
#include "anabatic/AutoContactHTee.h"
|
||||
#include "anabatic/AutoContactVTee.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
#include "anabatic/NetBuilderM2.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::swap;
|
||||
|
||||
|
||||
NetBuilderM2::NetBuilderM2 ()
|
||||
: NetBuilder()
|
||||
{ }
|
||||
|
||||
|
||||
NetBuilderM2::~NetBuilderM2 () { }
|
||||
|
||||
|
||||
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
, AutoContact*& target
|
||||
, uint64_t flags
|
||||
)
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilderM2::doRp_AutoContacts()" << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
|
||||
source = target = NULL;
|
||||
|
||||
Point sourcePosition;
|
||||
Point targetPosition;
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
Flags direction = Session::getDirection ( rpDepth );
|
||||
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
|
||||
|
||||
getPositions( rp, sourcePosition, targetPosition );
|
||||
|
||||
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
|
||||
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
|
||||
|
||||
GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition );
|
||||
GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition );
|
||||
|
||||
if (rpDepth == 0) {
|
||||
rpLayer = Session::getContactLayer(0);
|
||||
direction = Flags::Horizontal;
|
||||
viaSide = Session::getViaWidth( rpDepth );
|
||||
}
|
||||
|
||||
// Non-M1 terminal or punctual M1 protections.
|
||||
if ((rpDepth != 0) or (sourcePosition == targetPosition)) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, sourcePosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
AutoContact* targetProtect = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, targetPosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
sourceProtect->setFlags( CntFixed );
|
||||
targetProtect->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
|
||||
segment->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
getRpLookup().insert( make_pair(rp,segment) );
|
||||
}
|
||||
}
|
||||
|
||||
if (sourcePosition != targetPosition) {
|
||||
if (flags & DoSourceContact)
|
||||
source = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, sourcePosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
if (flags & DoTargetContact)
|
||||
target = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, targetPosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
}
|
||||
|
||||
if (not source and not target) {
|
||||
source = target = AutoContactTerminal::create( gcell
|
||||
, rp
|
||||
, rpLayer
|
||||
, rp->getCenter()
|
||||
, viaSide, viaSide
|
||||
);
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderM2::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
|
||||
Point sourcePosition;
|
||||
Point targetPosition;
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
DbU::Unit viaSide = Session::getDContactWidth();
|
||||
DbU::Unit ypitch = Session::getDVerticalPitch();
|
||||
|
||||
getPositions( rp, sourcePosition, targetPosition );
|
||||
|
||||
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
|
||||
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
|
||||
|
||||
Point position = rp->getCenter();
|
||||
if (not (flags & Middle)) {
|
||||
if (flags & NorthBound) position = targetPosition;
|
||||
if (flags & SouthBound) position = sourcePosition;
|
||||
}
|
||||
|
||||
DbU::Unit ycontact = (flags & SouthBound) ? gcell->getYMin() : gcell->getYMax()-ypitch;
|
||||
|
||||
AutoContact* rpContact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide );
|
||||
AutoContact* contact1 = AutoContactTurn::create( gcell, getNet(), viaLayer );
|
||||
AutoContact* contact2 = AutoContactTurn::create( gcell, getNet(), viaLayer );
|
||||
contact1->setPosition( position.getX(), ycontact );
|
||||
contact2->setPosition( position.getX(), ycontact );
|
||||
rpContact->setFlags( CntFixed );
|
||||
contact1 ->setFlags( CntFixed );
|
||||
contact2 ->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal );
|
||||
fixed ->setFlags( AutoSegment::SegFixed );
|
||||
dogleg->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return contact2;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderM2::_do_1G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1()" << endl;
|
||||
|
||||
uint64_t flags = NoFlags;
|
||||
if (north()) flags |= NorthBound;
|
||||
else if (south()) flags |= SouthBound;
|
||||
|
||||
AutoContact* contact = NULL;
|
||||
contact = doRp_Access( getGCell(), getRoutingPads()[0], flags );
|
||||
setNorthEastContact( contact );
|
||||
push( north(), contact, SouthWest );
|
||||
push( south(), contact, SouthWest );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderM2::_do_2G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1()" << endl;
|
||||
|
||||
AutoContact* contact = NULL;
|
||||
contact = doRp_Access( getGCell(), getRoutingPads()[0], SouthBound|NorthBound );
|
||||
push( north(), contact, SouthWest|Middle );
|
||||
|
||||
contact = doRp_Access( getGCell(), getRoutingPads()[0], SouthBound|NorthBound );
|
||||
push( south(), contact, SouthWest|Middle );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderM2::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
||||
vector<Hook*> hooksNS = getNorths();
|
||||
hooksNS.insert( hooksNS.end(), getSouths().begin(), getSouths().end() );
|
||||
sort( hooksNS.begin(), hooksNS.end(), SortHookByX(NoFlags) );
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
AutoContact* contactW = NULL;
|
||||
AutoContact* contactE = NULL;
|
||||
|
||||
// Simple turn.
|
||||
if ( (west() and not east() and (hooksNS.size() == 1))
|
||||
or (east() and not west() and (hooksNS.size() == 1)) ) {
|
||||
contactW = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
push( west() , contactW, SouthWest );
|
||||
push( east() , contactW, SouthWest );
|
||||
push( hooksNS[0], contactW, SouthWest );
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Simple HTee.
|
||||
if (west() and east() and (hooksNS.size() == 1)) {
|
||||
contactW = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
|
||||
push( west() , contactW, SouthWest );
|
||||
push( east() , contactW, SouthWest );
|
||||
push( hooksNS[0], contactW, SouthWest );
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "West side processing." << endl;
|
||||
// West side processing.
|
||||
if (west()) {
|
||||
contactW = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
|
||||
push( west() , contactW, SouthWest );
|
||||
push( hooksNS[0], contactW, SouthWest );
|
||||
} else {
|
||||
contactW = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
push( hooksNS[0], contactW, SouthWest );
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "Middle processing." << endl;
|
||||
// Middle (North & South) processing.
|
||||
if (hooksNS.size() > 2) {
|
||||
for ( size_t i=1 ; i<hooksNS.size()-1 ; ++i ) {
|
||||
AutoContact* current = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
|
||||
AutoSegment::create( contactW, current, Flags::Horizontal );
|
||||
push( hooksNS[i], current, SouthWest );
|
||||
|
||||
contactW = current;
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "East side processing." << endl;
|
||||
// East side processing.
|
||||
if (east()) {
|
||||
contactE = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
|
||||
push( east(), contactE, SouthWest );
|
||||
if (hooksNS.size() > 1)
|
||||
push( hooksNS[hooksNS.size()-1], contactE, SouthWest );
|
||||
} else {
|
||||
contactE = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
push( hooksNS[hooksNS.size()-1], contactE, SouthWest );
|
||||
}
|
||||
|
||||
AutoSegment::create( contactW, contactE, Flags::Horizontal );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderM2::_do_globalSegment ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
||||
|
||||
if (getSourceContact()) {
|
||||
Segment* segment = static_cast <Segment*> ( getFromHook()->getComponent() );
|
||||
AutoSegment* globalSegment = AutoSegment::create( getSourceContact(), getSouthWestContact(), segment );
|
||||
|
||||
globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 );
|
||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) return false;
|
||||
} else
|
||||
setFromHook( NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderM2::_do_1G_xM1 () { return false; }
|
||||
bool NetBuilderM2::_do_xG_1Pad () { return false; }
|
||||
bool NetBuilderM2::_do_1G_1PinM2 () { return false; }
|
||||
bool NetBuilderM2::_do_xG_xM2 () { return false; }
|
||||
bool NetBuilderM2::_do_1G_1M3 () { return false; }
|
||||
bool NetBuilderM2::_do_xG_xM3 () { return false; }
|
||||
bool NetBuilderM2::_do_xG_1M1_1M2 () { return false; }
|
||||
bool NetBuilderM2::_do_xG_xM1_xM3 () { return false; }
|
||||
bool NetBuilderM2::_do_4G_1M2 () { return false; }
|
||||
bool NetBuilderM2::_do_2G () { return false; }
|
||||
|
||||
|
||||
string NetBuilderM2::getTypeName () const
|
||||
{ return "NetBuilderM2"; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -64,6 +64,9 @@ namespace Anabatic {
|
|||
// Methods.
|
||||
bool isGMetal ( const Layer* ) const;
|
||||
bool isGContact ( const Layer* ) const;
|
||||
bool isTwoMetals () const;
|
||||
bool isHV () const;
|
||||
bool isVH () const;
|
||||
const Layer* getGContactLayer () const;
|
||||
const Layer* getGHorizontalLayer () const;
|
||||
const Layer* getGVerticalLayer () const;
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Hurricane {
|
|||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::endl;
|
||||
|
@ -99,6 +100,16 @@ namespace Anabatic {
|
|||
, SouthWest = SouthBound|WestBound
|
||||
, NorthEast = NorthBound|EastBound
|
||||
};
|
||||
enum TopologyFlag { Global_Vertical_End = 0x00000001
|
||||
, Global_Horizontal_End = 0x00000002
|
||||
, Global_Horizontal = 0x00000004
|
||||
, Global_Vertical = 0x00000008
|
||||
, Global_Turn = 0x00000010
|
||||
, Global_Fork = 0x00000020
|
||||
, Global_Fixed = 0x00000040
|
||||
, Global_End = Global_Vertical_End | Global_Horizontal_End
|
||||
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
|
||||
};
|
||||
|
||||
// Connexity Union Type.
|
||||
enum ConnexityBits { GlobalBSize = 8
|
||||
|
@ -130,6 +141,7 @@ namespace Anabatic {
|
|||
NetBuilder ();
|
||||
virtual ~NetBuilder ();
|
||||
void clear ();
|
||||
inline unsigned int getDegree () const;
|
||||
inline void setDegree ( unsigned int degree );
|
||||
void fixSegments ();
|
||||
NetBuilder& startFrom ( AnabaticEngine*
|
||||
|
@ -138,43 +150,63 @@ namespace Anabatic {
|
|||
void construct ();
|
||||
inline unsigned int getStateG () const;
|
||||
inline UConnexity getConnexity () const;
|
||||
inline UConnexity& getConnexity ();
|
||||
inline Net* getNet () const;
|
||||
inline GCell* getGCell () const;
|
||||
inline AutoContact* getSourceContact () const;
|
||||
inline AutoContact* getSouthWestContact () const;
|
||||
inline AutoContact*& getSouthWestContact ();
|
||||
inline AutoContact* getNorthEastContact () const;
|
||||
inline AutoContact*& getNorthEastContact ();
|
||||
inline Hook* getFromHook () const;
|
||||
inline ForkStack& getForks ();
|
||||
inline vector<RoutingPad*>& getRoutingPads ();
|
||||
inline map<Component*,AutoSegment*>& getRpLookup ();
|
||||
inline unsigned int getTopology () const;
|
||||
inline vector<Hook*>& getNorths ();
|
||||
inline vector<Hook*>& getSouths ();
|
||||
inline Hook* north ( size_t i=0 ) const;
|
||||
inline Hook* south ( size_t i=0 ) const;
|
||||
inline Hook* east ( size_t i=0 ) const;
|
||||
inline Hook* west ( size_t i=0 ) const;
|
||||
inline void addToNorths ( Hook* );
|
||||
inline void addToSouths ( Hook* );
|
||||
inline void addToEasts ( Hook* );
|
||||
inline void addToWests ( Hook* );
|
||||
inline void clearNorths ();
|
||||
inline void clearSouths ();
|
||||
inline void clearEasts ();
|
||||
inline void clearWests ();
|
||||
inline void setFromHook ( Hook* );
|
||||
inline void setSouthWestContact ( AutoContact* );
|
||||
inline void setNorthEastContact ( AutoContact* );
|
||||
inline void setBothCornerContacts ( AutoContact* );
|
||||
inline void swapCornerContacts ();
|
||||
inline void addToFixSegments ( AutoSegment* );
|
||||
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 );
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0;
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0;
|
||||
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
|
||||
virtual AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, uint64_t flags );
|
||||
AutoContact* doRp_2m_Access ( GCell*, RoutingPad*, uint64_t flags );
|
||||
void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 );
|
||||
void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 );
|
||||
void singleGCell ( AnabaticEngine*, Net* );
|
||||
void _load ( AnabaticEngine*, Net* );
|
||||
private:
|
||||
void _do_2m_1G_1M1 ();
|
||||
void _do_2m_2G_1M1 ();
|
||||
void _do_2m_xG ();
|
||||
void _do_xG ();
|
||||
void _do_2G ();
|
||||
virtual void _do_xG_1Pad ();
|
||||
virtual void _do_1G_1PinM2 ();
|
||||
virtual void _do_1G_1M1 () = 0;
|
||||
virtual void _do_1G_xM1 () = 0;
|
||||
virtual void _do_xG_xM1_xM3 ();
|
||||
virtual void _do_xG_1M1_1M2 ();
|
||||
virtual void _do_4G_1M2 ();
|
||||
virtual void _do_xG_xM2 ();
|
||||
virtual void _do_1G_1M3 ();
|
||||
virtual void _do_xG_xM3 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
AutoContact* _doHChannel ();
|
||||
AutoContact* _doVChannel ();
|
||||
AutoContact* _doStrut ();
|
||||
|
@ -184,6 +216,7 @@ namespace Anabatic {
|
|||
void _doIoPad ();
|
||||
unsigned int getNumberGlobals ();
|
||||
unsigned int getDeviceNeighbourBound();
|
||||
virtual string getTypeName () const;
|
||||
private:
|
||||
|
||||
#define CONNEXITY_VALUE( Gs, M1s, M2s, M3s, pads, pins ) \
|
||||
|
@ -256,17 +289,6 @@ namespace Anabatic {
|
|||
|
||||
#undef CONNEXITY_VALUE
|
||||
|
||||
enum TopologyFlag { Global_Vertical_End = 0x00000001
|
||||
, Global_Horizontal_End = 0x00000002
|
||||
, Global_Horizontal = 0x00000004
|
||||
, Global_Vertical = 0x00000008
|
||||
, Global_Turn = 0x00000010
|
||||
, Global_Fork = 0x00000020
|
||||
, Global_Fixed = 0x00000040
|
||||
, Global_End = Global_Vertical_End | Global_Horizontal_End
|
||||
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
|
||||
};
|
||||
|
||||
// Attributes.
|
||||
private:
|
||||
ForkStack _forks;
|
||||
|
@ -323,20 +345,43 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline unsigned int NetBuilder::getDegree () const { return _degree; }
|
||||
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; }
|
||||
inline NetBuilder::UConnexity& NetBuilder::getConnexity () { return _connexity; }
|
||||
inline ForkStack& NetBuilder::getForks () { return _forks; }
|
||||
inline unsigned int NetBuilder::getStateG () const { return _connexity.fields.globals; }
|
||||
inline GCell* NetBuilder::getGCell () const { return _gcell; }
|
||||
inline Net* NetBuilder::getNet () const { return _net; }
|
||||
inline AutoContact* NetBuilder::getSourceContact () const { return _sourceContact; }
|
||||
inline AutoContact* NetBuilder::getSouthWestContact () const { return _southWestContact; }
|
||||
inline AutoContact*& NetBuilder::getSouthWestContact () { return _southWestContact; }
|
||||
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
|
||||
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
|
||||
inline Hook* NetBuilder::getFromHook () const { return _fromHook; }
|
||||
inline unsigned int NetBuilder::getTopology () const { return _topology; }
|
||||
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
|
||||
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; }
|
||||
inline vector<Hook*>& NetBuilder::getNorths () { return _norths; }
|
||||
inline vector<Hook*>& NetBuilder::getSouths () { return _souths; }
|
||||
inline Hook* NetBuilder::north ( size_t i ) const { return (i<_norths.size()) ? _norths[i] : NULL; }
|
||||
inline Hook* NetBuilder::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; }
|
||||
inline Hook* NetBuilder::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; }
|
||||
inline Hook* NetBuilder::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; }
|
||||
inline void NetBuilder::setDegree ( unsigned int degree ) { _degree = degree; }
|
||||
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
|
||||
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }
|
||||
inline void NetBuilder::setSouthWestContact ( AutoContact* ac ) { _southWestContact = ac; }
|
||||
inline void NetBuilder::setNorthEastContact ( AutoContact* ac ) { _northEastContact = ac; }
|
||||
inline void NetBuilder::swapCornerContacts () { std::swap( _southWestContact, _northEastContact ); }
|
||||
inline void NetBuilder::addToFixSegments ( AutoSegment* as ) { _toFixSegments.push_back(as); }
|
||||
inline void NetBuilder::addToNorths ( Hook* hook ) { _norths.push_back(hook); }
|
||||
inline void NetBuilder::addToSouths ( Hook* hook ) { _souths.push_back(hook); }
|
||||
inline void NetBuilder::addToEasts ( Hook* hook ) { _easts .push_back(hook); }
|
||||
inline void NetBuilder::addToWests ( Hook* hook ) { _wests .push_back(hook); }
|
||||
inline void NetBuilder::clearNorths () { _norths.clear(); }
|
||||
inline void NetBuilder::clearSouths () { _souths.clear(); }
|
||||
inline void NetBuilder::clearEasts () { _easts .clear(); }
|
||||
inline void NetBuilder::clearWests () { _wests .clear(); }
|
||||
|
||||
template< typename BuilderT >
|
||||
void NetBuilder::load ( AnabaticEngine* engine, Net* net ) { BuilderT()._load(engine,net); }
|
||||
|
|
|
@ -32,8 +32,21 @@ namespace Anabatic {
|
|||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
virtual void _do_1G_1M1 ();
|
||||
virtual void _do_1G_xM1 ();
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2016, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./anabatic/NetBuilderM2.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_M2_H
|
||||
#define ANABATIC_NET_BUILDER_M2_H
|
||||
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "NetBuilderM2".
|
||||
|
||||
class NetBuilderM2 : public NetBuilder {
|
||||
public:
|
||||
NetBuilderM2 ();
|
||||
virtual ~NetBuilderM2 ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_globalSegment ();
|
||||
// Should never occur, so just return false.
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_2G ();
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_M2_H
|
|
@ -46,6 +46,11 @@ routingGaugesTable['msxlib'] = \
|
|||
, ( 'METAL5' , ( Gauge.Vertical , Gauge.Default, 4, 0.0, 0, 10, 3, 2, 8 ) )
|
||||
#, ( 'METAL6' , ( Gauge.Horizontal, Gauge.Default, 5, 0.0, 0, 10, 5, 2, 8 ) )
|
||||
)
|
||||
|
||||
routingGaugesTable['msxlib-2M'] = \
|
||||
( ( 'METAL1', ( Gauge.Horizontal, Gauge.Default, 0, 0.0, 0, 10, 2, 2, 7 ) )
|
||||
, ( 'METAL2', ( Gauge.Vertical , Gauge.Default, 1, 0.0, 0, 10, 3, 2, 8 ) )
|
||||
)
|
||||
|
||||
|
||||
# Format of cellGaugesTable (dictionary):
|
||||
|
|
|
@ -53,6 +53,10 @@ namespace CRL {
|
|||
// Constructors & Destructors.
|
||||
static RoutingGauge* create ( const char* name );
|
||||
virtual void destroy ();
|
||||
// Predicates.
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isHV () const;
|
||||
inline bool isVH () const;
|
||||
// Accessors.
|
||||
RoutingGauge* getClone () const;
|
||||
inline const Name getName () const;
|
||||
|
@ -103,6 +107,9 @@ namespace CRL {
|
|||
};
|
||||
|
||||
|
||||
inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
|
||||
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
||||
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
||||
inline const Name RoutingGauge::getName () const { return _name; }
|
||||
inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); }
|
||||
inline Technology* RoutingGauge::getTechnology () const { return _technology; }
|
||||
|
|
|
@ -285,6 +285,7 @@ namespace Katana {
|
|||
_routingPlanes.reserve( maxDepth );
|
||||
for ( size_t depth=0 ; depth < maxDepth ; depth++ ) {
|
||||
_routingPlanes.push_back( RoutingPlane::create( this, depth ) );
|
||||
cdebug_log(155,0) << _routingPlanes.back() << endl;
|
||||
}
|
||||
|
||||
if (not sessionReUse) Session::close();
|
||||
|
@ -524,6 +525,7 @@ namespace Katana {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void KatanaEngine::printCompletion () const
|
||||
{
|
||||
size_t routeds = 0;
|
||||
|
@ -683,7 +685,6 @@ namespace Katana {
|
|||
|
||||
void KatanaEngine::finalizeLayout ()
|
||||
{
|
||||
|
||||
cdebug_log(155,0) << "KatanaEngine::finalizeLayout()" << endl;
|
||||
if (getState() > Anabatic::EngineDriving) return;
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ namespace Katana {
|
|||
{
|
||||
_gcells = gcells;
|
||||
|
||||
loadRoutingPads( this );
|
||||
if (not Session::getKatanaEngine()->isChannelMode()) loadRoutingPads( this );
|
||||
Session::revalidate();
|
||||
|
||||
for ( auto element : Session::getKatanaEngine()->_getAutoSegmentLut() ) {
|
||||
|
|
Loading…
Reference in New Issue