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:
Jean-Paul Chaput 2017-12-18 18:15:14 +01:00
parent e17a50ca0b
commit f87bcf717c
14 changed files with 1291 additions and 833 deletions

View File

@ -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() );

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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); }

View File

@ -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;
};

View File

@ -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

View File

@ -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):

View File

@ -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; }

View File

@ -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;

View File

@ -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() ) {