diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index d98a94e2..409bf669 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -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( 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( this, net ); break; + case 1: NetBuilder::load( this, net ); break; + //case 2: NetBuilder::load( 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( getCell(), "Globals", AutoSegment::getGlobalsCount() ); diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt index 6ff7d7b7..f9660907 100644 --- a/anabatic/src/CMakeLists.txt +++ b/anabatic/src/CMakeLists.txt @@ -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 diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index aa379cf4..211f335e 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.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))); } diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 2ff8cb42..b2001da3 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -195,6 +195,10 @@ namespace Anabatic { { } + NetBuilder::~NetBuilder () + { } + + void NetBuilder::clear () { _connexity.connexity = 0; @@ -342,10 +346,6 @@ namespace Anabatic { return *this; } - - - NetBuilder::~NetBuilder () - { } bool NetBuilder::push ( Hook* toHook, AutoContact* contact, uint64_t flags ) @@ -381,154 +381,105 @@ namespace Anabatic { { cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl; - _southWestContact = NULL; - _northEastContact = NULL; + if (_gcell->isMatrix()) { + _southWestContact = NULL; + _northEastContact = NULL; + } if (not _gcell->isAnalog()) { - if (_gcell->isMatrix()) { - switch ( _connexity.connexity ) { - case Conn_1G_1Pad: - case Conn_2G_1Pad: - case Conn_3G_1Pad: _do_xG_1Pad (); break; - case Conn_1G_1PinM2: _do_1G_1PinM2(); break; - case Conn_1G_1M1: _do_1G_1M1 (); break; - case Conn_1G_2M1: - case Conn_1G_3M1: - case Conn_1G_4M1: - case Conn_1G_5M1: _do_1G_xM1(); break; - case Conn_1G_1M2: - case Conn_1G_2M2: - case Conn_1G_3M2: - case Conn_1G_4M2: _do_xG_xM2(); break; - case Conn_1G_1M3: _do_1G_1M3(); break; - case Conn_1G_2M3: - case Conn_1G_3M3: - case Conn_1G_4M3: _do_xG_xM3 (); break; - case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break; - case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; - case Conn_2G_1M1: - case Conn_2G_2M1: - case Conn_2G_3M1: - case Conn_2G_4M1: - case Conn_2G_5M1: - case Conn_3G_1M1: - case Conn_3G_2M1: - case Conn_3G_3M1: - case Conn_3G_4M1: - case Conn_3G_2M3: - case Conn_3G_3M3: - case Conn_3G_4M3: - case Conn_4G_1M1: - case Conn_4G_2M1: - case Conn_4G_3M1: - case Conn_4G_4M1: _do_xG_xM1_xM3(); break; - case Conn_4G_1M2: _do_4G_1M2 (); break; - case Conn_2G_1M2: - case Conn_2G_2M2: - case Conn_2G_3M2: - case Conn_2G_4M2: - case Conn_3G_1M2: - case Conn_3G_2M2: _do_xG_xM2(); break; - case Conn_2G_1M3: - case Conn_2G_2M3: - case Conn_2G_3M3: - case Conn_2G_4M3: - case Conn_3G_1M3: _do_xG_xM3 (); break; - case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; - case Conn_2G_1PinM2: _do_xG_xM2 (); break; - case Conn_2G: _do_2G (); break; - case Conn_3G: - case Conn_4G: - _do_xG(); - break; - default: - throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" - " The global routing seems to be defective." - , _connexity.connexity - , _connexity.fields.globals - , _connexity.fields.M1 - , _connexity.fields.M2 - , _connexity.fields.M3 - , _connexity.fields.Pin - , _connexity.fields.Pad - , _net->_getString().c_str() - , getString(_gcell).c_str() - ); - _do_xG(); - } - - if (_sourceContact) { - AutoContact* targetContact - = ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ) - ? _northEastContact : _southWestContact ; - AutoSegment* globalSegment = AutoSegment::create( _sourceContact - , targetContact - , static_cast( _fromHook->getComponent() ) - ); - globalSegment->setFlags( (_degree == 2) ? AutoSegment::SegBipoint : 0 ); - cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; - - // HARDCODED VALUE. - if ( (_topology & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) ) - _toFixSegments.push_back( globalSegment ); - - if (_connexity.fields.globals < 2) { - cdebug_tabw(145,-1); - return; - } - } else - _fromHook = NULL; - - push( east (), _northEastContact ); - push( west (), _southWestContact ); - push( north(), _northEastContact ); - push( south(), _southWestContact ); - } else { - if (not _sourceContact) _fromHook = NULL; + if (not _gcell->isMatrix() and not _sourceContact) _fromHook = NULL; + + switch ( _connexity.connexity ) { + case Conn_1G_1Pad: + case Conn_2G_1Pad: + case Conn_3G_1Pad: _do_xG_1Pad (); break; + // End xG_1Pad cascaded cases. - switch ( _connexity.connexity ) { - case Conn_1G_1M1: _do_2m_1G_1M1(); break; - case Conn_2G_1M1: _do_2m_2G_1M1(); break; - default: - if ( _connexity.fields.M1 - or _connexity.fields.M2 - or _connexity.fields.M3 - or _connexity.fields.Pin - or _connexity.fields.Pad ) - throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" - " The global routing seems to be defective." - , _connexity.connexity - , _connexity.fields.globals - , _connexity.fields.M1 - , _connexity.fields.M2 - , _connexity.fields.M3 - , _connexity.fields.Pin - , _connexity.fields.Pad - , _net->_getString().c_str() - , getString(_gcell).c_str() - ); - _do_2m_xG(); - } - - if (_sourceContact) { - Segment* segment = static_cast ( _fromHook->getComponent() ); - AutoSegment* globalSegment = AutoSegment::create( _sourceContact, _southWestContact, segment ); + case Conn_1G_1M1: if (_do_1G_1M1()) break; + case Conn_1G_2M1: + case Conn_1G_3M1: + case Conn_1G_4M1: + case Conn_1G_5M1: _do_1G_xM1(); break; + // End 1G_xM1 cascaded cases. - globalSegment->setFlags( (_degree == 2) ? AutoSegment::SegBipoint : 0 ); - cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; - - // HARDCODED VALUE. - if ( (_topology & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) ) - _toFixSegments.push_back( globalSegment ); - - if (_connexity.fields.globals < 2) { - cdebug_tabw(145,-1); - return; - } - } else - _fromHook = NULL; - + case Conn_1G_1M2: + case Conn_1G_2M2: + case Conn_1G_3M2: + case Conn_1G_4M2: _do_xG_xM2(); break; + // End 1G_xM2 cascaded cases. + + case Conn_1G_1M3: if (_do_1G_1M3()) break; + case Conn_1G_2M3: + case Conn_1G_3M3: + case Conn_1G_4M3: _do_xG_xM3(); break; + // End 1G_xM3 cascaded cases. + + case Conn_2G_1M1: if (_do_2G_1M1()) break; + case Conn_2G_2M1: + case Conn_2G_3M1: + case Conn_2G_4M1: + case Conn_2G_5M1: + case Conn_3G_1M1: + case Conn_3G_2M1: + case Conn_3G_3M1: + case Conn_3G_4M1: + case Conn_3G_2M3: + case Conn_3G_3M3: + case Conn_3G_4M3: + case Conn_4G_1M1: + case Conn_4G_2M1: + case Conn_4G_3M1: + case Conn_4G_4M1: _do_xG_xM1_xM3(); break; + // End xG_xM1_xM3 cascaded cases. + + case Conn_4G_1M2: if (_do_4G_1M2()) break; + case Conn_2G_1M2: + case Conn_2G_2M2: + case Conn_2G_3M2: + case Conn_2G_4M2: + case Conn_3G_1M2: + case Conn_3G_2M2: _do_xG_xM2(); break; + // End xG_xM2 cascaded cases. + + case Conn_2G_1M3: + case Conn_2G_2M3: + case Conn_2G_3M3: + case Conn_2G_4M3: + case Conn_3G_1M3: _do_xG_xM3(); break; + // End xG_xM3 cascaded cases. + + case Conn_2G: if (_do_2G()) break; + case Conn_3G: + case Conn_4G: _do_xG(); break; + // End xG cascaded cases. + // Optimized specific cases. + case Conn_1G_1PinM2: _do_1G_1PinM2 (); break; + case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break; + case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; + case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; + case Conn_2G_1PinM2: _do_xG_xM2 (); break; + default: + throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" + " The global routing seems to be defective." + , _connexity.connexity + , _connexity.fields.globals + , _connexity.fields.M1 + , _connexity.fields.M2 + , _connexity.fields.M3 + , _connexity.fields.Pin + , _connexity.fields.Pad + , _net->_getString().c_str() + , getString(_gcell).c_str() + ); + _do_xG(); } + + if (not _do_globalSegment()) { + cdebug_log(145,0) << "No global generated, finish." << endl; + cdebug_tabw(145,-1); + return; + } + cdebug_log(145,0) << "Proceed to next GCell." << endl; } else { AutoContact* targetContact = NULL; if (not _sourceContact) _fromHook = NULL; @@ -744,50 +695,6 @@ namespace Anabatic { } - AutoContact* NetBuilder::doRp_2m_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) - { - cdebug_log(145,1) << "doRp_2m_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, _net, viaLayer ); - AutoContact* contact2 = AutoContactTurn::create( gcell, _net, 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; - } - - void NetBuilder::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 ) { cdebug_log(145,0) << "doRp_StairCaseH()" << endl; @@ -856,639 +763,101 @@ namespace Anabatic { } - void NetBuilder::_do_2m_1G_1M1 () + bool NetBuilder::_do_xG () { - cdebug_log(145,1) << "_do_2m_1G_1M1()" << endl; - - uint64_t flags = NoFlags; - if (north()) flags |= NorthBound; - else if (south()) flags |= SouthBound; - - AutoContact* contact = NULL; - contact = _northEastContact = doRp_2m_Access( _gcell, _routingPads[0], flags ); - push( north(), contact, SouthWest ); - push( south(), contact, SouthWest ); - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_2m_2G_1M1 () + + bool NetBuilder::_do_2G () { - cdebug_log(145,1) << "_do_2m_2G_1M1()" << endl; - - AutoContact* contact = NULL; - contact = doRp_2m_Access( _gcell, _routingPads[0], SouthBound|NorthBound ); - push( north(), contact, SouthWest|Middle ); - - contact = doRp_2m_Access( _gcell, _routingPads[0], SouthBound|NorthBound ); - push( south(), contact, SouthWest|Middle ); - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_2m_xG () + + bool NetBuilder::_do_xG_1Pad () { - cdebug_log(145,1) << "_do_2m_xG()" << endl; - - vector hooksNS = _norths; - hooksNS.insert( hooksNS.end(), _souths.begin(), _souths.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( _gcell, _net, viaLayer ); - push( west() , contactW, SouthWest ); - push( east() , contactW, SouthWest ); - push( hooksNS[0], contactW, SouthWest ); - cdebug_tabw(145,-1); - return; - } - - // Simple HTee. - if (west() and east() and (hooksNS.size() == 1)) { - contactW = AutoContactHTee::create( _gcell, _net, viaLayer ); - push( west() , contactW, SouthWest ); - push( east() , contactW, SouthWest ); - push( hooksNS[0], contactW, SouthWest ); - cdebug_tabw(145,-1); - return; - } - - cdebug_log(145,0) << "West side processing." << endl; - // West side processing. - if (west()) { - contactW = AutoContactHTee::create( _gcell, _net, viaLayer ); - push( west() , contactW, SouthWest ); - push( hooksNS[0], contactW, SouthWest ); - } else { - contactW = AutoContactTurn::create( _gcell, _net, 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 1) - push( hooksNS[hooksNS.size()-1], contactE, SouthWest ); - } else { - contactE = AutoContactTurn::create( _gcell, _net, viaLayer ); - push( hooksNS[hooksNS.size()-1], contactE, SouthWest ); - } - - AutoSegment::create( contactW, contactE, Flags::Horizontal ); - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_xG () + + bool NetBuilder::_do_1G_1PinM2 () { - cdebug_log(145,1) << "_do_xG()" << endl; - - const Layer* viaLayer = Session::getDContactLayer(); - - if (_connexity.fields.globals == 2) { - _southWestContact = _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - } else if (_connexity.fields.globals == 3) { - if (east() and west()) { - _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer ); - if (south()) swap( _southWestContact, _northEastContact ); - - AutoSegment::create( _southWestContact, _northEastContact, Flags::Vertical ); - } else { - _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer ); - if (west()) swap( _southWestContact, _northEastContact ); - - AutoSegment::create( _southWestContact, _northEastContact, Flags::Horizontal ); - } - } else { // fields.globals == 4. - AutoContact* turn = AutoContactTurn::create( _gcell, _net, viaLayer ); - _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer ); - _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer ); - AutoSegment::create( _southWestContact, turn, Flags::Horizontal ); - AutoSegment::create( turn, _northEastContact, Flags::Vertical ); - } - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_2G () + + bool NetBuilder::_do_1G_1M1 () { - cdebug_log(145,1) << "_do_2G()" << endl; - - const Layer* viaLayer = Session::getDContactLayer(); - - if (east() and west()) { - _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - AutoSegment::create( _southWestContact, _northEastContact, Flags::Vertical ); - } else if (south() and north()) { - _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - AutoSegment::create( _southWestContact, _northEastContact, Flags::Horizontal ); - } else { - _southWestContact = _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); - } - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_xG_1Pad () + + bool NetBuilder::_do_2G_1M1 () { - cdebug_log(145,1) << "_do_xG_1Pad() [Managed Configuration - Optimized] " << _topology << endl; - cdebug_log(145,0) << "_connexity.globals:" << (int)_connexity.fields.globals << endl; - - uint64_t flags = NoFlags; - bool eastPad = false; - bool westPad = false; - bool northPad = false; - bool southPad = false; - Instance* padInstance = _routingPads[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( _routingPads[0], flags ); - // Point position = _routingPads[0]->getCenter(); - // AutoContact* source = NULL; - // GCell* gcell = Session::getAnabatic()->getGCellGrid()->getGCell(position); - - // source = AutoContactTerminal::create ( gcell - // , _routingPads[0] - // , Session::getContactLayer(3) - // , position - // , Session::getViaWidth(3), Session::getViaWidth(3) - // ); - // source->setFlags( CntFixed ); - - // if (northPad or eastPad) { - // _southWestContact = _northEastContact = source; - // cdebug_tabw(145,-1); - // return; - // } - - // Check for straight lines, which are not managed by _do_xG(). - if (_connexity.fields.globals == 1) { - if ( (westPad and (east() != NULL)) - or (eastPad and (west() != NULL)) ) { - AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = _southWestContact - = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoSegment::create( source, turn, Flags::Horizontal ); - AutoSegment::create( turn, _northEastContact, Flags::Vertical ); - cdebug_tabw(145,-1); - return; - } else if ( (southPad and (north() != NULL)) - or (northPad and (south() != NULL)) ) { - AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = _southWestContact - = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoSegment::create( source, turn, Flags::Vertical ); - AutoSegment::create( turn, _northEastContact, Flags::Horizontal ); - cdebug_tabw(145,-1); - return; - } - } - - ++_connexity.fields.globals; - --_connexity.fields.Pad; - - if (westPad ) _wests .push_back( source->getBodyHook() ); - if (eastPad ) _easts .push_back( source->getBodyHook() ); - if (southPad) _souths.push_back( source->getBodyHook() ); - if (northPad) _norths.push_back( source->getBodyHook() ); - - _do_xG(); - - if (westPad) { - AutoSegment::create( source, _southWestContact, Flags::Horizontal ); - _wests.clear(); - } - if (eastPad) { - AutoSegment::create( source, _northEastContact, Flags::Horizontal ); - _easts.clear(); - } - if (southPad) { - AutoSegment::create( source, _southWestContact, Flags::Vertical ); - _souths.clear(); - } - if (northPad) { - AutoSegment::create( source, _northEastContact, Flags::Vertical ); - _norths.clear(); - } - --_connexity.fields.globals; - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_1G_1PinM2 () + + bool NetBuilder::_do_1G_xM1 () { - cdebug_log(145,1) << "_do_1G_1PinM2() [Managed Configuration - Optimized] " << _topology << endl; - - AutoContact* rpContact = doRp_Access( _gcell, _routingPads[0], NoFlags ); - AutoContact* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoSegment::create( rpContact, turn1, Flags::Vertical ); - - if (north() or south()) { - AutoContact* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoSegment::create( turn1, turn2, Flags::Horizontal ); - turn1 = turn2; - } - _southWestContact = _northEastContact = turn1; - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_xG_1M1_1M2 () + + bool NetBuilder::_do_xG_xM1_xM3 () { - cdebug_log(145,1) << "_do_xG_1M1_1M2() [Managed Configuration]" << endl; - - Component* rpL1; - Component* rpL2; - if (_routingPads[0]->getLayer() == Session::getRoutingLayer(0)) { - rpL1 = _routingPads[0]; - rpL2 = _routingPads[1]; - } else { - rpL1 = _routingPads[1]; - rpL2 = _routingPads[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( _gcell, rpL1, rpL1ContactSource, rpL1ContactTarget, NoFlags ); - doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, NoFlags ); - - const Layer* viaLayer1 = Session::getContactLayer(1); - const Layer* viaLayer2 = Session::getContactLayer(2); - - AutoContact* subContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpL1ContactSource, subContact, Flags::Horizontal ); - AutoSegment::create( rpL2ContactSource, subContact, Flags::Vertical ); - - if (south() or west()) { - doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact ); - if (south() and west()) { - _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); - AutoSegment::create( rpL2ContactSource, _southWestContact, Flags::Horizontal ); - } else { - if (south()) { - _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer2 ); - AutoSegment::create( rpL2ContactSource, _southWestContact, Flags::Horizontal ); - } else { - _southWestContact = rpL2ContactSource; - } - } - } - - if (north() or east()) { - doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoTargetContact ); - if (north() and east()) { - _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); - AutoSegment::create( rpL2ContactTarget, _northEastContact, Flags::Horizontal ); - } else { - if (north()) { - _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer2 ); - AutoSegment::create( rpL2ContactTarget, _northEastContact, Flags::Horizontal ); - } else { - _northEastContact = rpL2ContactTarget; - } - } - } - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_xG_xM1_xM3 () + + bool NetBuilder::_do_xG_1M1_1M2 () { - cdebug_log(145,1) << "_do_xG_" << (int)_connexity.fields.M1 - << "M1_" << (int)_connexity.fields.M3 - << "M3() [G:" << (int)_connexity.fields.globals << " Managed Configuration]" << endl; - cdebug_log(145,0) << "_connexity: " << _connexity.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; - - if (Session::getAllowedDepth() < 2) { - } - - Component* rpM3 = NULL; - if (_routingPads[0]->getLayer() == Session::getRoutingLayer(2)) - rpM3 = _routingPads[0]; - - sort( _routingPads.begin(), _routingPads.end(), SortRpByX(NoFlags) ); // increasing X. - for ( size_t i=1 ; i<_routingPads.size() ; ++i ) { - AutoContact* leftContact = doRp_Access( _gcell, _routingPads[i-1], HAccess ); - AutoContact* rightContact = doRp_Access( _gcell, _routingPads[i ], HAccess ); - AutoSegment::create( leftContact, rightContact, Flags::Horizontal ); - - if (not rpM3 and (_routingPads[i]->getLayer() == Session::getRoutingLayer(2))) - rpM3 = _routingPads[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()) { - _southWestContact = doRp_Access( _gcell, _routingPads[0], HAccess ); - } else if (not west() and south()) { - doRp_AutoContacts( _gcell, rpM3, _southWestContact, unusedContact, DoSourceContact ); - } else if (west() and south()) { - AutoContact* rpContact = NULL; - doRp_AutoContacts( _gcell, rpM3, rpContact, unusedContact, DoSourceContact ); - _southWestContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _southWestContact, Flags::Vertical ); - } - - if (east() and not north()) { - _northEastContact = doRp_Access( _gcell, _routingPads[_routingPads.size()-1], HAccess ); - } else if (not east() and north()) { - doRp_AutoContacts( _gcell, rpM3, unusedContact, _northEastContact, DoTargetContact ); - } else if (east() and north()) { - AutoContact* rpContact = NULL; - doRp_AutoContacts( _gcell, rpM3, unusedContact, rpContact, DoTargetContact ); - _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _northEastContact, Flags::Vertical ); - } - } else { - // All RoutingPad are M1. - Component* southWestRp = _routingPads[0]; - cdebug_log(145,0) << "| Initial S-W Global RP: " << southWestRp << endl; - for ( size_t i=1 ; i<_routingPads.size() ; ++i ) { - if (southWestRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; - if (_routingPads[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { - cdebug_log(145,0) << "| Better RP: " << southWestRp << endl; - southWestRp = _routingPads[i]; - } - } - - if (west() and not south()) { - _southWestContact = doRp_Access( _gcell, southWestRp, HAccess ); - } else if (not west() and south()) { - AutoContact* rpContact = doRp_Access( _gcell, southWestRp, HAccess ); - _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _southWestContact, Flags::Horizontal ); - } else if (west() and south()) { - AutoContact* rpContact = doRp_Access( _gcell, southWestRp, HAccess ); - _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _southWestContact, Flags::Horizontal ); - } - - Component* northEastRp = _routingPads[_routingPads.size()-1]; - cdebug_log(145,0) << "| Initial N-E Global RP: " << northEastRp << endl; - - if (_routingPads.size() > 1) { - for ( size_t i=_routingPads.size()-1; i != 0 ; ) { - i -= 1; - if (northEastRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; - if (_routingPads[i]->getBoundingBox().getHeight() > northEastRp->getBoundingBox().getHeight()) { - cdebug_log(145,0) << "| Better RP: " << northEastRp << endl; - northEastRp = _routingPads[i]; - } - } - } - - if (east() and not north()) { - _northEastContact = doRp_Access( _gcell, northEastRp, HAccess ); - } else if (not east() and north()) { - AutoContact* rpContact = doRp_Access( _gcell, northEastRp, HAccess ); - _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _northEastContact, Flags::Horizontal ); - } else if (east() and north()) { - AutoContact* rpContact = doRp_Access( _gcell, northEastRp, HAccess ); - _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _northEastContact, Flags::Horizontal ); - } - } - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_4G_1M2 () + + bool NetBuilder::_do_4G_1M2 () { - cdebug_log(145,1) << "_do_4G_1M2() [Managed Configuration]" << endl; - - Component* rpL2 = _routingPads[0]; - cdebug_log(145,0) << "rpL2 := " << rpL2 << endl; - - AutoContact* rpL2ContactSource = NULL; - AutoContact* rpL2ContactTarget = NULL; - - doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact|DoTargetContact ); - - const Layer* viaLayer2 = Session::getContactLayer(2); - - _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); - _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); - - AutoSegment::create( _southWestContact, rpL2ContactSource, Flags::Horizontal ); - AutoSegment::create( rpL2ContactTarget, _northEastContact, Flags::Horizontal ); - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_xG_xM2 () + + bool NetBuilder::_do_xG_xM2 () { - cdebug_log(145,1) << "_do_" - << (int)_connexity.fields.globals << "G_" - << (int)_connexity.fields.M2 << "M2() [Managed Configuration - x]" << endl; - - Component* biggestRp = _routingPads[0]; - for ( size_t i=1 ; i<_routingPads.size() ; ++i ) { - doRp_StairCaseH( _gcell, _routingPads[i-1], _routingPads[i] ); - if (_routingPads[i]->getBoundingBox().getWidth() > biggestRp->getBoundingBox().getWidth()) - biggestRp = _routingPads[i]; - } - - const Layer* viaLayer1 = Session::getContactLayer(1); - AutoContact* unusedContact = NULL; - - if (west() and not south()) { - doRp_AutoContacts( _gcell, _routingPads[0], _southWestContact, unusedContact, DoSourceContact ); - } else if (not west() and south()) { - _southWestContact = doRp_Access( _gcell, biggestRp, NoFlags ); - } else if (west() and south()) { - AutoContact* rpContact = doRp_Access( _gcell, biggestRp, NoFlags ); - _southWestContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _southWestContact, Flags::Vertical ); - } - - if (east() and not north()) { - doRp_AutoContacts( _gcell, _routingPads[_routingPads.size()-1], _northEastContact, unusedContact, DoSourceContact ); - } else if (not east() and north()) { - _northEastContact = doRp_Access( _gcell, biggestRp, NoFlags ); - } else if (east() and north()) { - AutoContact* rpContact = doRp_Access( _gcell, biggestRp, NoFlags ); - _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _northEastContact, Flags::Vertical ); - } - - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_1G_1M3 () + + bool NetBuilder::_do_1G_1M3 () { - cdebug_log(145,1) << "_do_1G_1M3() [Optimised Configuration]" << endl; - - uint64_t flags = (east() or west()) ? HAccess : NoFlags; - flags |= (north()) ? DoTargetContact : NoFlags; - flags |= (south()) ? DoSourceContact : NoFlags; - - doRp_AutoContacts( _gcell - , _routingPads[0] - , _southWestContact - , _northEastContact - , flags - ); - if (not _southWestContact) _southWestContact = _northEastContact; - if (not _northEastContact) _northEastContact = _southWestContact; - - cdebug_log(145,0) << "_southWest: " << _southWestContact << endl; - cdebug_log(145,0) << "_northEast: " << _northEastContact << endl; - - const Layer* viaLayer1 = Session::getContactLayer(1); - - if (flags & HAccess) { - // HARDCODED VALUE. - if (_routingPads[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) { - AutoContact* subContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( _southWestContact, subContact, Flags::Vertical ); - - _southWestContact = _northEastContact = subContact; - } - } else { - if (_sourceContact) { - if (_sourceContact->getX() != _southWestContact->getX()) { - AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( _southWestContact, turn1, Flags::Vertical ); - AutoSegment::create( turn1 , turn2, Flags::Horizontal ); - _southWestContact = _northEastContact = turn2; - } - } - } - cdebug_tabw(145,-1); + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } - - void NetBuilder::_do_xG_xM3 () + + bool NetBuilder::_do_xG_xM3 () { - cdebug_log(145,1) << "_do_xG_" << (int)_connexity.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; + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; + } - sort( _routingPads.begin(), _routingPads.end(), SortRpByY(NoFlags) ); // increasing Y. - for ( size_t i=1 ; i<_routingPads.size() ; i++ ) { - doRp_StairCaseV( _gcell, _routingPads[i-1], _routingPads[i] ); - } - - const Layer* viaLayer1 = Session::getContactLayer(1); - AutoContact* unusedContact = NULL; - Component* rp = _routingPads[0]; - - if (west() and not south()) { - _southWestContact = doRp_Access( _gcell, rp, HAccess ); - } else if (not west() and south()) { - doRp_AutoContacts( _gcell, rp, _southWestContact, unusedContact, DoSourceContact ); - if (_sourceContact) { - if (_sourceContact->getX() != _southWestContact->getX()) { - cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(_sourceContact->getX()) - << "_southWest:" << DbU::getValueString(_southWestContact->getX()) << endl; - - AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( _southWestContact, turn1, Flags::Vertical ); - AutoSegment::create( turn1 , turn2, Flags::Horizontal ); - _southWestContact = turn2; - } - } - } else if (west() and south()) { - AutoContact* rpContact = NULL; - doRp_AutoContacts( _gcell, rp, rpContact, unusedContact, DoSourceContact ); - _southWestContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _southWestContact, Flags::Vertical ); - } - - rp = _routingPads[_routingPads.size()-1]; - if (east() and not north()) { - _northEastContact = doRp_Access( _gcell, rp, HAccess ); - } else if (not east() and north()) { - doRp_AutoContacts( _gcell, rp, unusedContact, _northEastContact, DoTargetContact ); - if (_sourceContact) { - if (_sourceContact->getX() != _northEastContact->getX()) { - cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(_sourceContact->getX()) - << "_southWest:" << DbU::getValueString(_northEastContact->getX()) << endl; - - AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( _northEastContact, turn1, Flags::Vertical ); - AutoSegment::create( turn1 , turn2, Flags::Horizontal ); - _northEastContact = turn2; - } - } - } else if (east() and north()) { - AutoContact* rpContact = NULL; - doRp_AutoContacts( _gcell, rp, unusedContact, rpContact, DoTargetContact ); - _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); - AutoSegment::create( rpContact, _northEastContact, Flags::Vertical ); - } - - cdebug_tabw(145,-1); + + bool NetBuilder::_do_globalSegment () + { + cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + return false; } @@ -2746,4 +2115,8 @@ namespace Anabatic { } + string NetBuilder::getTypeName () const + { return "NetBuilder"; } + + } // Anabatic namespace. diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 5e76d1c9..8fa50e5a 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -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 ; igetOccurrence().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 ; igetLayer() == 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 ; igetBoundingBox().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 ; igetBoundingBox().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 ; igetX() != 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( 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. diff --git a/anabatic/src/NetBuilderM2.cpp b/anabatic/src/NetBuilderM2.cpp new file mode 100644 index 00000000..918ae4df --- /dev/null +++ b/anabatic/src/NetBuilderM2.cpp @@ -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 +#include +#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::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 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 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 ( 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. diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index 2f15d1b2..01d08072 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -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; diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index b251f61b..b9d4c054 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -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& getRoutingPads (); inline map& getRpLookup (); inline unsigned int getTopology () const; + inline vector& getNorths (); + inline vector& 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& NetBuilder::getRoutingPads () { return _routingPads; } inline map& NetBuilder::getRpLookup () { return _routingPadAutoSegments; } + inline vector& NetBuilder::getNorths () { return _norths; } + inline vector& 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); } diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index f7c906ca..d6bbd51f 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -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; }; diff --git a/anabatic/src/anabatic/NetBuilderM2.h b/anabatic/src/anabatic/NetBuilderM2.h new file mode 100644 index 00000000..de0ff6a0 --- /dev/null +++ b/anabatic/src/anabatic/NetBuilderM2.h @@ -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 diff --git a/crlcore/etc/180/scn6m_deep_09/kite.conf b/crlcore/etc/180/scn6m_deep_09/kite.conf index 8c5f2b61..88d6800b 100644 --- a/crlcore/etc/180/scn6m_deep_09/kite.conf +++ b/crlcore/etc/180/scn6m_deep_09/kite.conf @@ -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): diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index 48a57b10..d70abb39 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -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; } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index c6811c40..74b34d37 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -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; diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 7cebd503..501a0d69 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -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() ) {