diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 92b2fe88..df7d7b74 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -34,6 +34,7 @@ #include "crlcore/Histogram.h" #include "anabatic/GCell.h" #include "anabatic/AutoContactTerminal.h" +#include "anabatic/NetBuilderHybridVH.h" #include "anabatic/NetBuilderM2.h" #include "anabatic/NetBuilderHV.h" #include "anabatic/NetBuilderVH.h" @@ -383,25 +384,27 @@ namespace Anabatic { , _edgeCapacitiesLut() , _blockageNet (cell->getNet("blockagenet")) , _diodeCell (NULL) - { - _matrix.setCell( cell, _configuration->getSliceHeight() ); - Edge::unity = _configuration->getSliceHeight(); - - if (not _blockageNet) { - _blockageNet = Net::create( cell, "blockagenet" ); - _blockageNet->setType( Net::Type::BLOCKAGE ); - } - } + { } void AnabaticEngine::_postCreate () { Super::_postCreate(); - _diodeCell = DataBase::getDB()->getCell( getConfiguration()->getDiodeName() );; + _configuration = _createConfiguration(); + setupNetBuilder(); + _matrix.setCell( getCell(), _configuration->getSliceHeight() ); + Edge::unity = _configuration->getSliceHeight(); + + if (not _blockageNet) { + _blockageNet = Net::create( getCell(), "blockagenet" ); + _blockageNet->setType( Net::Type::BLOCKAGE ); + } + + _diodeCell = DataBase::getDB()->getCell( _configuration->getDiodeName() );; if (not _diodeCell) { cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell." - , getConfiguration()->getDiodeName().c_str() + , _configuration->getDiodeName().c_str() ) << endl; } @@ -412,6 +415,10 @@ namespace Anabatic { } + Configuration* AnabaticEngine::_createConfiguration () + { return new Configuration(); } + + AnabaticEngine* AnabaticEngine::create ( Cell* cell ) { if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." ); @@ -623,7 +630,7 @@ namespace Anabatic { } } - RoutingGauge* rg = getConfiguration()->getRoutingGauge(); + RoutingGauge* rg = _configuration->getRoutingGauge(); size_t errorCount = 0; ostringstream errors; errors << "AnabaticEngine::checkPlacement():\n"; @@ -852,7 +859,7 @@ namespace Anabatic { if (horizontal) { splitted = Horizontal::create( breakContact , targetContact - , getConfiguration()->getGHorizontalLayer() + , _configuration->getGHorizontalLayer() , horizontal->getY() , DbU::fromLambda(2.0) ); @@ -861,7 +868,7 @@ namespace Anabatic { if (vertical) { splitted = Vertical::create( breakContact , targetContact - , getConfiguration()->getGVerticalLayer() + , _configuration->getGVerticalLayer() , vertical->getX() , DbU::fromLambda(2.0) ); @@ -1097,7 +1104,7 @@ namespace Anabatic { for ( Net* net : getCell()->getNets() ) { for ( Component* component : net->getComponents() ) { - if (getConfiguration()->isGLayer(component->getLayer())) { + if (_configuration->isGLayer(component->getLayer())) { cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n" " %s" , getString(component).c_str() @@ -1124,7 +1131,7 @@ namespace Anabatic { } cleanupGlobal(); - if (not getConfiguration()->isTwoMetals()) relaxOverConstraineds(); + if (not _configuration->isTwoMetals()) relaxOverConstraineds(); _state = EngineActive; } @@ -1241,6 +1248,64 @@ namespace Anabatic { } + void AnabaticEngine::setupNetBuilder () + { + uint32_t gaugeKind = 4; + if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0; + else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1; + else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2; + else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3; + + if (gaugeKind == 0) { + if (not _configuration->isVH()) + throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"." + , getString(_configuration->getRoutingGauge()->getName()).c_str() + , getNetBuilderStyle().c_str() ); + if (getRoutingStyle() == StyleFlags::NoStyle) { + _configuration->setRoutingStyle( StyleFlags::VH + | StyleFlags::Channel + | StyleFlags::Hybrid ); + } + } + else if (gaugeKind == 1) { + if (getRoutingStyle() == StyleFlags::NoStyle) { + _configuration->setRoutingStyle( StyleFlags::Channel ); + } + } + else if (gaugeKind == 2) { + if (not _configuration->isVH()) + throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"." + , getString(_configuration->getRoutingGauge()->getName()).c_str() + , getNetBuilderStyle().c_str() ); + if (_configuration->getRoutingGauge()->getUsableLayers() < 3) + throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"." + , getString(_configuration->getRoutingGauge()->getName()).c_str() + , getNetBuilderStyle().c_str() ); + if (getRoutingStyle() == StyleFlags::NoStyle) { + _configuration->setRoutingStyle( StyleFlags::VH + | StyleFlags::OTH ); + } + } + else if (gaugeKind == 3) { + if (not _configuration->isHV()) + throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"." + , getString(_configuration->getRoutingGauge()->getName()).c_str() + , getNetBuilderStyle().c_str() ); + if (_configuration->getRoutingGauge()->getUsableLayers() < 3) + throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"." + , getString(_configuration->getRoutingGauge()->getName()).c_str() + , getNetBuilderStyle().c_str() ); + if (getRoutingStyle() == StyleFlags::NoStyle) { + _configuration->setRoutingStyle( StyleFlags::HV + | StyleFlags::OTH ); + } + } + if (gaugeKind == 4) { + throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing auge style \"%s\"." + , getNetBuilderStyle().c_str() ); + } + } + void AnabaticEngine::_loadGrByNet () { cmess1 << " o Building detailed routing from global. " << endl; @@ -1250,12 +1315,13 @@ namespace Anabatic { startMeasures(); openSession(); - int gaugeKind = 3; - if (getConfiguration()->isTwoMetals()) gaugeKind = 0; - if (getConfiguration()->isHV ()) gaugeKind = 1; - if (getConfiguration()->isVH ()) gaugeKind = 2; + uint32_t gaugeKind = 4; + if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0; + else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1; + else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2; + else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3; - if (gaugeKind < 3) { + if (gaugeKind < 4) { for ( Net* net : getCell()->getNets() ) { if (NetRoutingExtension::isShortNet(net)) { //AutoSegment::setShortNetMode( true ); @@ -1269,9 +1335,10 @@ namespace Anabatic { 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; + case 0: NetBuilder::load( this, net ); break; + case 1: NetBuilder::load ( this, net ); break; + case 2: NetBuilder::load ( this, net ); break; + case 3: NetBuilder::load ( this, net ); break; } Session::revalidate(); @@ -1290,11 +1357,6 @@ namespace Anabatic { stopMeasures(); cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl; - - if (gaugeKind > 2) { - throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"." - , getString(getConfiguration()->getRoutingGauge()->getName()).c_str() ); - } printMeasures( "load" ); @@ -1626,7 +1688,7 @@ namespace Anabatic { EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span ) { - size_t depth = getConfiguration()->getAllowedDepth(); + size_t depth = _configuration->getAllowedDepth(); EdgeCapacity* edgeCapacity = NULL; flags &= Flags::EdgeCapacityMask; @@ -1668,7 +1730,7 @@ namespace Anabatic { UpdateSession::open(); for ( auto rp : rps ) { - if (not getConfiguration()->selectRpComponent(rp)) + if (not _configuration->selectRpComponent(rp)) cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl; Point center = rp->getBoundingBox().getCenter(); diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index 65e2587b..c3a96fc4 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -406,8 +406,8 @@ namespace Anabatic { if (horizontals[1] != NULL) ++count; if (verticals [0] != NULL) ++count; if (verticals [1] != NULL) ++count; - if (count > 1) { - showTopologyError( "Terminal has more than one segment." ); + if (count != 1) { + showTopologyError( "Terminal has not *exactly* one segment." ); } if (horizontals[0] != NULL ) { _segment = Session::lookup( horizontals[0] ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 60ef6f7f..53527aa9 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -1808,7 +1808,7 @@ namespace Anabatic { return false; } - if (not Session::getAnabatic()->isChannelMode() + if (not Session::getAnabatic()->isChannelStyle() and (getDepth() == 1) and isSpinBottom()) return false; if ((flags & Flags::WithPerpands) and _reduceds) return false; @@ -3284,7 +3284,7 @@ namespace Anabatic { Flags perpandFlags = (currentSegment->getAutoSource() == sourceContact) ? Flags::Source : Flags::Target; perpandiculars.push_back( make_tuple( currentSegment, perpandFlags )); - if (Session::getAnabatic()->isChannelMode()) { + if (Session::getAnabatic()->isChannelStyle()) { if (currentSegment->isNonPref() and currentSegment->isFixed()) { if (perpandFlags & Flags::Source) isSourceBoundToChannel = true; else isTargetBoundToChannel = true; diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt index 966b2db8..fca8d790 100644 --- a/anabatic/src/CMakeLists.txt +++ b/anabatic/src/CMakeLists.txt @@ -36,9 +36,10 @@ endif ( CHECK_DETERMINISM ) anabatic/NetBuilderM2.h anabatic/NetBuilderHV.h anabatic/NetBuilderVH.h + anabatic/NetBuilderHybridVH.h anabatic/ChipTools.h ) - set( pyIncludes ) + set( pyIncludes anabatic/PyStyleFlags.h ) set( cpps Constants.cpp Configuration.cpp Matrix.cpp @@ -62,13 +63,15 @@ endif ( CHECK_DETERMINISM ) NetBuilderM2.cpp NetBuilderHV.cpp NetBuilderVH.cpp + NetBuilderHybridVH.cpp ChipTools.cpp LayerAssign.cpp AntennaProtect.cpp PreRouteds.cpp AnabaticEngine.cpp ) - set( pyCpps PyAnabatic.cpp + set( pyCpps PyStyleFlags.cpp + PyAnabatic.cpp ) set( depLibs ${ETESIAN_LIBRARIES} diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 9857062b..81d10971 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -1,7 +1,7 @@ // -*- mode: C++; explicit-buffer-name: "Configuration.cpp" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2016-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -78,6 +78,8 @@ namespace Anabatic { , _ddepthv (ndepth) , _ddepthh (ndepth) , _ddepthc (ndepth) + , _netBuilderStyle (Cfg::getParamString("anabatic.netBuilderStyle","HV,3RL+")->asString() ) + , _routingStyle (Cfg::getParamInt ("anabatic.routingStyle" ,StyleFlags::NoStyle)->asInt() ) , _cg (NULL) , _rg (NULL) , _extensionCaps () @@ -187,6 +189,8 @@ namespace Anabatic { , _ddepthv (other._ddepthv) , _ddepthh (other._ddepthh) , _ddepthc (other._ddepthc) + , _netBuilderStyle (other._netBuilderStyle) + , _routingStyle (other._routingStyle) , _cg (NULL) , _rg (NULL) , _extensionCaps (other._extensionCaps) @@ -223,6 +227,10 @@ namespace Anabatic { bool Configuration::isTwoMetals () const { return _rg->isTwoMetals(); } + + + bool Configuration::isHybrid () const + { return _routingStyle & StyleFlags::Hybrid; } bool Configuration::isHV () const diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 29d88a11..3a08772c 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -14,16 +14,22 @@ // +-----------------------------------------------------------------+ +#include "hurricane/Error.h" #include "anabatic/Constants.h" namespace Anabatic { + using std::hex; using std::string; using std::ostringstream; using Hurricane::BaseFlags; + using Hurricane::Error; +// ------------------------------------------------------------------- +// Class : "Anabatic::Flags". + const BaseFlags Flags::NoFlags = 0; // Flags used for both objects states & functions arguments. const BaseFlags Flags::Horizontal = (1L << 0); @@ -211,4 +217,69 @@ namespace Anabatic { } +// ------------------------------------------------------------------- +// Class : "Anabatic::StyleFlags". + + + const BaseFlags StyleFlags::NoStyle = 0; + const BaseFlags StyleFlags::HV = (1L << 0); + const BaseFlags StyleFlags::VH = (1L << 1); + const BaseFlags StyleFlags::OTH = (1L << 2); + const BaseFlags StyleFlags::Channel = (1L << 3); + const BaseFlags StyleFlags::Hybrid = (1L << 4); + + + StyleFlags::~StyleFlags () + { } + + + StyleFlags StyleFlags::toFlag ( std::string textFlag ) + { + if (textFlag == "HV") return HV; + if (textFlag == "VH") return VH; + if (textFlag == "OTH") return OTH; + if (textFlag == "Channel") return Channel; + if (textFlag == "Hybrid") return Hybrid; + if (textFlag == "NoStyle") return NoStyle; + std::cerr << Error( "StyleFlags::toFlag(): Unknown flag value \"%s\"", textFlag.c_str() ) << std::endl; + return NoStyle; + } + + + StyleFlags StyleFlags::from ( std::string textFlags ) + { + size_t start = 0; + size_t stop = textFlags.find( '|' ); + while ( stop != string::npos ) { + *this |= toFlag( textFlags.substr( start, stop-start-1 )); + start = stop + 1; + stop = textFlags.find( '|', start ); + } + *this |= toFlag( textFlags.substr( stop+1 )); + return *this; + } + + + string StyleFlags::asString () const + { + ostringstream s; + + if (_flags & (uint64_t)HV) { s << (s.tellp() ? "|" : "") << "HV"; } + if (_flags & (uint64_t)VH) { s << (s.tellp() ? "|" : "") << "VH"; } + if (_flags & (uint64_t)OTH) { s << (s.tellp() ? "|" : "") << "OTH"; } + if (_flags & (uint64_t)Channel) { s << (s.tellp() ? "|" : "") << "Channel"; } + if (_flags & (uint64_t)Hybrid ) { s << (s.tellp() ? "|" : "") << "Hybrid"; } + s << " (0x" << hex << _flags << ")"; + return s.str(); + } + + + string StyleFlags::_getTypeName () const + { return "Anabatic::StyleFlags"; } + + + string StyleFlags::_getString () const + { return asString(); } + + } // Anabatic namespace. diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index dc8fdc93..fe567666 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -285,7 +285,7 @@ namespace Anabatic { : Super(anabatic->getCell()) , _observable () , _anabatic (anabatic) - , _flags (Flags::HChannelGCell|Flags::Invalidated) + , _flags (Flags::Invalidated) , _westEdges () , _eastEdges () , _southEdges () @@ -1557,7 +1557,8 @@ namespace Anabatic { int contiguousNonSaturated = 0; for ( size_t i=0 ; i<_depth ; i++ ) { uLengths2[i] += _blockages[i]; - if (not i) continue; + if (Session::getLayerGauge(i)->getType() & Constant::PinOnly) + continue; if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply) continue; if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height)) diff --git a/anabatic/src/LayerAssign.cpp b/anabatic/src/LayerAssign.cpp index ed375a49..b17c39ca 100644 --- a/anabatic/src/LayerAssign.cpp +++ b/anabatic/src/LayerAssign.cpp @@ -218,9 +218,10 @@ namespace { cdebug_log(149,0) << "Slacken from: " << rp << endl; if (rp->getLayer()) { - if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1) + if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1) { cdebug_log(149,0) << "In METAL2, skiping" << endl; continue; + } } for ( Component* component : rp->getSlaveComponents() ) { diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 67e94c5c..d375ac61 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -227,7 +227,7 @@ namespace Anabatic { // ------------------------------------------------------------------- // Class : "NetBuilder". - + void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target ) { Segment* segment = dynamic_cast( anchor ); @@ -368,7 +368,7 @@ namespace Anabatic { , _routingPadAutoSegments() , _toFixSegments () , _degree (0) - , _isTwoMetals (false) + , _isStrictChannel (false) , _sourceFlags (0) , _flags (0) { } @@ -396,8 +396,8 @@ namespace Anabatic { _norths .clear(); _souths .clear(); _routingPads .clear(); - _toFixSegments .clear(); _routingPadAutoSegments.clear(); + _toFixSegments .clear(); } @@ -416,14 +416,15 @@ namespace Anabatic { { clear(); - _isTwoMetals = anbt->getConfiguration()->isTwoMetals(); - _sourceFlags = sourceFlags; - _sourceContact = sourceContact; - _fromHook = fromHook; + _isStrictChannel = anbt->isChannelStyle() and not anbt->isHybridStyle(); + _sourceFlags = sourceFlags; + _sourceContact = sourceContact; + _fromHook = fromHook; cdebug_log(145,1) << "NetBuilder::setStartHook()" << endl; cdebug_log(145,0) << "* _fromHook: " << fromHook << endl; cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl; + cdebug_log(145,0) << "_isStrictChannel:" << _isStrictChannel << endl; if (not _fromHook) { cdebug_tabw(145,-1); @@ -573,7 +574,6 @@ namespace Anabatic { << "+" << (int)_connexity.fields.Pad << "] " << _gcell << endl; - return *this; } @@ -671,13 +671,16 @@ namespace Anabatic { cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags() << " getFlags():" << getFlags() << endl; - if (not isTwoMetals()) { + if (not isStrictChannel()) { _southWestContact = NULL; _northEastContact = NULL; } if (not _gcell->isAnalog()) { - if (isTwoMetals() and not _sourceContact) _fromHook = NULL; + if (isStrictChannel() and not _sourceContact) { + cdebug_log(145,0) << "No _sourceContact, resetting _fromHook" << endl; + _fromHook = NULL; + } switch ( _connexity.connexity ) { case Conn_1G_1Pad: @@ -787,7 +790,7 @@ namespace Anabatic { case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break; default: - if (not isTwoMetals()) + //if (not isStrictChannel()) throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" " The global routing seems to be defective." , _connexity.connexity @@ -803,6 +806,9 @@ namespace Anabatic { _do_xG(); } + cdebug_log(145,0) << "SouthWest: " << _southWestContact << endl; + cdebug_log(145,0) << "NorthEast: " << _northEastContact << endl; + if (not _do_globalSegment()) { cdebug_log(145,0) << "No global generated, finish." << endl; cdebug_tabw(145,-1); @@ -1143,7 +1149,9 @@ namespace Anabatic { bool NetBuilder::_do_xG_1PinM2 () { - throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() ); + throw Error( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.\n" + " On %s" + , getTypeName().c_str(), getString(getNet()).c_str() ); return false; } diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 80fa722e..4ebd94bd 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -66,6 +66,10 @@ namespace Anabatic { NetBuilderHV::~NetBuilderHV () { } + + string NetBuilderHV::getStyle () + { return "HV,3RL+"; } + void NetBuilderHV::doRp_AutoContacts ( GCell* gcell , Component* rp @@ -348,9 +352,9 @@ namespace Anabatic { } - AutoContact* NetBuilderHV::doRp_AccessNorthPin ( GCell* gcell, RoutingPad* rp ) + AutoContact* NetBuilderHV::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp ) { - cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl; + cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl; AutoContact* rpSourceContact = NULL; AutoContact* rpContactTarget = NULL; @@ -389,7 +393,7 @@ namespace Anabatic { AutoContact* NetBuilderHV::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp ) { - cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl; + cdebug_log(145,1) << getTypeName() << "::doRp_AccessEastWestPin() " << rp << endl; Net* net = rp->getNet(); Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); @@ -942,9 +946,9 @@ namespace Anabatic { AutoContact* rpSourceContact = NULL; - rpSourceContact = doRp_AccessNorthPin( getGCell(), getRoutingPads()[0] ); + rpSourceContact = doRp_AccessNorthSouthPin( getGCell(), getRoutingPads()[0] ); - AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) ); + AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) ); AutoSegment::create( rpSourceContact, turn1, Flags::Vertical ); if (north() or south()) { @@ -1182,12 +1186,6 @@ namespace Anabatic { setBothCornerContacts( turn ); } - - for ( size_t i=1 ; igetNet(), Session::getContactLayer(1) ); AutoSegment::create( source, turn1 , Flags::Horizontal ); AutoSegment::create( turn1 , target, Flags::Vertical ); diff --git a/anabatic/src/NetBuilderHybridVH.cpp b/anabatic/src/NetBuilderHybridVH.cpp new file mode 100644 index 00000000..f41af8d4 --- /dev/null +++ b/anabatic/src/NetBuilderHybridVH.cpp @@ -0,0 +1,604 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, 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 : "./NetBuilderHybridVH.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/Pin.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/NetBuilderHybridVH.h" +#include "anabatic/AnabaticEngine.h" + + +namespace Anabatic { + + using std::swap; + using Hurricane::Error; + using Hurricane::Pin; + + + NetBuilderHybridVH::NetBuilderHybridVH () + : NetBuilder() + { } + + + NetBuilderHybridVH::~NetBuilderHybridVH () { } + + + string NetBuilderHybridVH::getStyle () + { return "VH,2RL"; } + + + void NetBuilderHybridVH::doRp_AutoContacts ( GCell* gcell + , Component* rp + , AutoContact*& source + , AutoContact*& target + , uint64_t flags + ) + { + throw Error ( "%s::dpRp_AutoContacts() method must never be called.", getTypeName().c_str() ); + } + + + AutoContact* NetBuilderHybridVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl; + cdebug_log(145,0) << rp << endl; + + const Layer* rpLayer = rp->getLayer(); + const Layer* viaLayer = Session::getDContactLayer(); + DbU::Unit viaSide = Session::getDContactWidth(); + Point position = rp->getCenter(); + AutoContact* rpContact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide ); + + cdebug_tabw(145,-1); + return rpContact; + } + + + AutoContact* NetBuilderHybridVH::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl; + + AutoContact* rpContact = doRp_Access( gcell, rp, NoFlags ); + AutoContact* turn = NULL; + + Net* net = rp->getNet(); + Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + if (pinDir == Pin::AccessDirection::NORTH) { + turn = AutoContactTurn::create( gcell, net, Session::getRoutingLayer(0) ); + AutoSegment* segment = AutoSegment::create( rpContact, turn, Flags::Vertical ); + segment->setAxis( rp->getX(), Flags::Force ); + segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis ); + rpContact = turn; + + turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(0) ); + segment = AutoSegment::create( rpContact, turn, Flags::Horizontal ); + rpContact = turn; + + DbU::Unit axis = gcell->getYMax() - Session::getDHorizontalPitch(); + cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl; + + segment->setAxis( axis, Flags::Force ); + //segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis ); + cdebug_log(145,0) << segment << endl; + } else { + turn = rpContact; + } + + cdebug_tabw(145,-1); + return turn; + } + + + AutoContact* NetBuilderHybridVH::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessEastWestPin() " << rp << endl; + + Net* net = rp->getNet(); + Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + AutoContact* rpContact = doRp_Access( gcell, rp, NoFlags ); + AutoContact* turn = NULL; + AutoSegment* segment = NULL; + + turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(0) ); + segment = AutoSegment::create( rpContact, turn, Flags::Horizontal ); + segment->setAxis( pin->getCenter().getY(), Flags::Force ); + + rpContact = turn; + turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(0) ); + segment = AutoSegment::create( rpContact, turn, Flags::Vertical ); + + DbU::Unit axis = 0; + if (pinDir == Pin::AccessDirection::EAST) + axis = gcell->getXMax() - Session::getDVerticalPitch(); + else + axis = gcell->getXMin() + Session::getDVerticalPitch(); + segment->setAxis( axis ); + + cdebug_tabw(145,-1); + return turn; + } + + + bool NetBuilderHybridVH::doRp_xG_1M1 ( RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_xG_1M1()" << endl; + + AutoContact* swContact = nullptr; + if (west() or south()) { + AutoContact* termContact = doRp_Access( getGCell(), rp, NoFlags ); + if (west() and south()) { + swContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( termContact, swContact, Flags::Vertical ); + } else { + if (west()) { + swContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( termContact, swContact, Flags::Vertical ); + } else + swContact = termContact; + } + setSouthWestContact( swContact ); + } + + AutoContact* neContact = nullptr; + if (east() or north()) { + AutoContact* termContact = doRp_Access( getGCell(), rp, NoFlags ); + if (east() and north()) { + neContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( termContact, neContact, Flags::Vertical ); + } else { + if (east()) { + neContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( termContact, neContact, Flags::Vertical ); + } else + neContact = termContact; + } + setNorthEastContact( neContact ); + } + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderHybridVH::_do_xG_1M1 () + { + cdebug_log(145,1) << getTypeName() << "::_do_xG_1M1()" << endl; + + doRp_xG_1M1( getRoutingPads()[0] ); + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderHybridVH::doRp_xG_xM1_xM3 ( const vector& rps ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_xG_xM1()" << endl; + + AutoContact* prevContact = nullptr; + AutoContact* currContact = nullptr; + + for ( size_t i=0 ; i rpsM1; + RoutingPad* rpM2 = nullptr; + for ( RoutingPad* rp : getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) rpM2 = rp; + else rpsM1.push_back( rp ); + } + if (rpsM1.size() > 1) + doRp_xG_xM1_xM3( rpsM1 ); + else + doRp_xG_1M1( rpsM1[0] ); + + + Pin* pin = dynamic_cast( rpM2->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), rpM2 ); + AutoContact* rpM1Contact = nullptr; + if (pinDir == Pin::AccessDirection::EAST) + rpM1Contact = doRp_Access( getGCell(), rpsM1.back(), NoFlags ); + else + rpM1Contact = doRp_Access( getGCell(), rpsM1.front(), NoFlags ); + AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( rpM1Contact, turn, Flags::Vertical ); + AutoSegment::create( rpContact , turn, Flags::Horizontal ); + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderHybridVH::_do_1G_1M1 () { return false; } + bool NetBuilderHybridVH::_do_2G_1M1 () { return false; } + // bool NetBuilderHybridVH::_do_xG_1Pad () { return false; } + // bool NetBuilderHybridVH::_do_xG_xM2 () { return false; } + // bool NetBuilderHybridVH::_do_1G_1M3 () { return false; } + // bool NetBuilderHybridVH::_do_xG_xM3 () { return false; } + // bool NetBuilderHybridVH::_do_xG_1M1_1M2 () { return false; } + // bool NetBuilderHybridVH::_do_4G_1M2 () { return false; } + bool NetBuilderHybridVH::_do_2G () { return false; } + + + bool NetBuilderHybridVH::_do_globalSegment () + { + cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl; + cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags() + << " getFlags():" << getFlags() << endl; + + if (getSourceContact()) { + uint64_t segmentBound = getSegmentHookType( getFromHook() ); + AutoContact* targetContact + = (segmentBound & (NorthBound|EastBound)) ? getNorthEastContact() : getSouthWestContact() ; + if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl; + + AutoContact* sourceContact = getSourceContact(); + if (segmentBound & (NorthBound|SouthBound)) { + AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( sourceContact, turn, Flags::Vertical ); + sourceContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) ); + AutoSegment::create( sourceContact, turn, Flags::Horizontal ); + } + Segment* baseSegment = static_cast( getFromHook()->getComponent() ); + AutoSegment* globalSegment = AutoSegment::create( sourceContact + , targetContact + , baseSegment + ); + globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 ); + cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; + + // HARDCODED VALUE. + if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) ) + addToFixSegments( globalSegment ); + + if (getConnexity().fields.globals < 2) { + cdebug_tabw(145,-1); + return false; + } + } else + setFromHook( NULL ); + + push( east (), getNorthEastContact() ); + push( west (), getSouthWestContact() ); + push( north(), getNorthEastContact() ); + push( south(), getSouthWestContact() ); + + cdebug_tabw(145,-1); + return true; + } + + + void NetBuilderHybridVH::singleGCell ( AnabaticEngine* anbt, Net* net ) + { + cdebug_log(145,1) << getTypeName() << "::singleGCell() " << net << endl; + + vector rps; + for ( RoutingPad* irp : net->getRoutingPads() ) + rps.push_back( irp ); + + if (rps.size() < 2) { + cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d)." + , getTypeName().c_str() + , getString(net).c_str() + , rps.size() ) << endl; + cdebug_tabw(145,-1); + return; + } + + sortRpByX( rps, NetBuilder::NoFlags ); // increasing X. + + GCell* gcell1 = anbt->getGCellUnder( rps.front()->getCenter() ); + GCell* gcell2 = anbt->getGCellUnder( rps.back ()->getCenter() ); + + if (not gcell1) { + cerr << Error( "No GCell under %s.", getString(rps.front()).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + if (gcell1 != gcell2) { + cerr << Error( "Not under a single GCell %s.", getString(rps.back()).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + + AutoContact* prevContact = nullptr; + AutoContact* currContact = nullptr; + + for ( size_t i=0 ; i_anabatic->getRoutingStyle(); } + + bool Session::isInDemoMode () { return get("isInDemoMode()")->_anabatic->isInDemoMode(); } - bool Session::isChannelMode () - { return get("isChannelMode()")->_anabatic->isChannelMode(); } + bool Session::isChannelStyle () + { return get("isChannelStyle()")->_anabatic->isChannelStyle(); } float Session::getSaturateRatio () diff --git a/anabatic/src/anabatic/: b/anabatic/src/anabatic/: deleted file mode 100644 index e4c512cc..00000000 --- a/anabatic/src/anabatic/: +++ /dev/null @@ -1,646 +0,0 @@ -// -*- C++ -*- -// -// This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, 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/AutoSegment.h" | -// +-----------------------------------------------------------------+ - - -#ifndef ANABATIC_AUTOSEGMENT_H -#define ANABATIC_AUTOSEGMENT_H - -#include -#include -#include -#include "hurricane/Interval.h" -#include "hurricane/Segment.h" -#include "hurricane/Components.h" -#include "hurricane/Contact.h" -namespace Hurricane { - class Layer; - class Horizontal; - class Vertical; - class Cell; -} -#include "crlcore/RoutingGauge.h" -#include "anabatic/Constants.h" -#include "anabatic/GCell.h" -#include "anabatic/AutoSegments.h" -#include "anabatic/Session.h" - - -namespace Anabatic { - - using std::array; - using std::set; - using std::cerr; - using std::endl; - using std::binary_function; - using Hurricane::StaticObservable; - using Hurricane::BaseObserver; - using Hurricane::tab; - using Hurricane::Interval; - using Hurricane::Layer; - using Hurricane::Components; - using Hurricane::Horizontal; - using Hurricane::Vertical; - using Hurricane::Cell; - using CRL::RoutingGauge; - - class AutoHorizontal; - class AutoVertical; - -// ------------------------------------------------------------------- -// Class : "AutoSegment". - - - - class AutoSegment { - friend class AutoHorizontal; - friend class AutoVertical; - - public: - static const uint64_t SegNoFlags = 0L; - static const uint64_t SegHorizontal = (1L<< 0); - static const uint64_t SegFixed = (1L<< 1); - static const uint64_t SegFixedAxis = (1L<< 2); - static const uint64_t SegGlobal = (1L<< 3); - static const uint64_t SegWeakGlobal = (1L<< 4); - static const uint64_t SegLongLocal = (1L<< 5); - static const uint64_t SegCanonical = (1L<< 6); - static const uint64_t SegBipoint = (1L<< 7); - static const uint64_t SegDogleg = (1L<< 8); - static const uint64_t SegStrap = (1L<< 9); - static const uint64_t SegSourceTop = (1L<<10); - static const uint64_t SegSourceBottom = (1L<<11); - static const uint64_t SegTargetTop = (1L<<12); - static const uint64_t SegTargetBottom = (1L<<13); - static const uint64_t SegIsReduced = (1L<<14); - static const uint64_t SegDrag = (1L<<15); - static const uint64_t SegLayerChange = (1L<<16); - static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal. - static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal. - static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal; - static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd. - static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd. - static const uint64_t SegNotSourceAligned = (1L<<21); - static const uint64_t SegNotTargetAligned = (1L<<22); - static const uint64_t SegUnbound = (1L<<23); - static const uint64_t SegHalfSlackened = (1L<<24); - static const uint64_t SegSlackened = (1L<<25); - static const uint64_t SegAxisSet = (1L<<26); - static const uint64_t SegInvalidated = (1L<<27); - static const uint64_t SegInvalidatedSource = (1L<<28); - static const uint64_t SegInvalidatedTarget = (1L<<29); - static const uint64_t SegInvalidatedLayer = (1L<<30); - static const uint64_t SegCreated = (1L<<31); - static const uint64_t SegUserDefined = (1L<<32); - static const uint64_t SegAnalog = (1L<<33); - static const uint64_t SegWide = (1L<<34); - // Masks. - static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; - static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; - static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop; - static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom; - static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom; - - public: - class Observable : public StaticObservable<1> { - public: - enum Indexes { TrackSegment = 0 - }; - public: - inline Observable (); - private: - Observable ( const StaticObservable& ); - Observable& operator= ( const StaticObservable& ); - }; - public: - enum ObserverFlag { Create = (1 << 0) - , Destroy = (1 << 1) - , Invalidate = (1 << 2) - , Revalidate = (1 << 3) - , RevalidatePPitch = (1 << 4) - }; - public: - typedef std::function< void(AutoSegment*) > RevalidateCb_t; - public: - static void setAnalogMode ( bool ); - static bool getAnalogMode (); - inline static DbU::Unit getViaToTopCap ( size_t depth ); - inline static DbU::Unit getViaToBottomCap ( size_t depth ); - inline static DbU::Unit getViaToSameCap ( size_t depth ); - static AutoSegment* create ( AutoContact* source - , AutoContact* target - , Segment* hurricaneSegment - ); - static AutoSegment* create ( AutoContact* source - , AutoContact* target - , Flags dir - , size_t depth=RoutingGauge::nlayerdepth - ); - void destroy (); - // Wrapped Segment Functions. - virtual Segment* base () const = 0; - virtual Segment* base () = 0; - virtual Horizontal* getHorizontal () { return NULL; }; - virtual Vertical* getVertical () { return NULL; }; - inline Cell* getCell () const; - inline Net* getNet () const; - inline const Layer* getLayer () const; - inline Box getBoundingBox () const; - inline Hook* getSourceHook (); - inline Hook* getTargetHook (); - inline Contact* getSource () const; - inline Contact* getTarget () const; - inline Component* getOppositeAnchor ( Component* ) const; - inline Components getAnchors () const; - virtual DbU::Unit getX () const; - virtual DbU::Unit getY () const; - inline DbU::Unit getWidth () const; - inline DbU::Unit getContactWidth () const; - inline DbU::Unit getLength () const; - inline DbU::Unit getSourcePosition () const; - inline DbU::Unit getTargetPosition () const; - inline DbU::Unit getSourceX () const; - inline DbU::Unit getSourceY () const; - inline DbU::Unit getTargetX () const; - inline DbU::Unit getTargetY () const; - inline void invert (); - inline void setLayer ( const Layer* ); - // Predicates. - inline bool isHorizontal () const; - inline bool isVertical () const; - inline bool isGlobal () const; - inline bool isWeakGlobal () const; - inline bool isLongLocal () const; - inline bool isLocal () const; - inline bool isFixed () const; - inline bool isFixedAxis () const; - inline bool isBipoint () const; - inline bool isWeakTerminal () const; - inline bool isWeakTerminal1 () const; - inline bool isWeakTerminal2 () const; - inline bool isTerminal () const; - inline bool isDrag () const; - inline bool isNotSourceAligned () const; - inline bool isNotTargetAligned () const; - inline bool isNotAligned () const; - bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; - inline bool isSourceTerminal () const; - inline bool isTargetTerminal () const; - inline bool isLayerChange () const; - inline bool isSpinTop () const; - inline bool isSpinBottom () const; - inline bool isSpinTopOrBottom () const; - inline bool isReduced () const; - inline bool isStrap () const; - inline bool isDogleg () const; - inline bool isUnbound () const; - inline bool isInvalidated () const; - inline bool isInvalidatedLayer () const; - inline bool isCreated () const; - inline bool isCanonical () const; - inline bool isUnsetAxis () const; - inline bool isSlackened () const; - inline bool isUserDefined () const; - bool isReduceCandidate () const; - bool isUTurn () const; - inline bool isAnalog () const; - inline bool isWide () const; - virtual bool _canSlacken () const = 0; - bool canReduce () const; - bool mustRaise () const; - Flags canDogleg ( Interval ); - virtual bool canMoveULeft ( float reserve=0.0 ) const = 0; - virtual bool canMoveURight ( float reserve=0.0 ) const = 0; - bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; - bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; - bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; - bool canSlacken ( Flags flags=Flags::NoFlags ) const; - virtual bool checkPositions () const = 0; - virtual bool checkConstraints () const = 0; - bool checkDepthSpin () const; - // Accessors. - inline unsigned long getId () const; - inline uint64_t getFlags () const; - virtual Flags getDirection () const = 0; - inline GCell* getGCell () const; - virtual bool getGCells ( vector& ) const = 0; - inline AutoContact* getAutoSource () const; - inline AutoContact* getAutoTarget () const; - AutoContact* getOppositeAnchor ( AutoContact* ) const; - size_t getPerpandicularsBound ( set& ); - inline AutoSegment* getParent () const; - inline unsigned int getDepth () const; - inline DbU::Unit getPitch () const; - DbU::Unit getPPitch () const; -#if DISABLED - DbU::Unit getExtensionCap () const; -#endif - DbU::Unit getExtensionCap ( Flags ) const; - inline DbU::Unit getAxis () const; - void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const; - virtual DbU::Unit getSourceU () const = 0; - virtual DbU::Unit getTargetU () const = 0; - virtual DbU::Unit getDuSource () const = 0; - virtual DbU::Unit getDuTarget () const = 0; - inline DbU::Unit getOrigin () const; - inline DbU::Unit getExtremity () const; - virtual Interval getSpanU () const = 0; - Interval getMinSpanU () const; - virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0; - virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0; - virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0; - inline bool getConstraints ( Interval& i ) const; - inline const Interval& getUserConstraints () const; - inline const Interval& getNativeConstraints () const; - virtual DbU::Unit getSlack () const; - inline DbU::Unit getOptimalMin () const; - inline DbU::Unit getOptimalMax () const; - inline DbU::Unit getNativeMin () const; - inline DbU::Unit getNativeMax () const; - Interval& getOptimal ( Interval& i ) const; - virtual DbU::Unit getCost ( DbU::Unit axis ) const; - virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max ); - inline AutoSegment* getCanonical ( Interval& i ); - float getMaxUnderDensity ( Flags flags ); - // Modifiers. - inline void unsetFlags ( uint64_t ); - inline void setFlags ( uint64_t ); - void setFlagsOnAligneds ( uint64_t ); - inline void incReduceds (); - inline void decReduceds (); - virtual void setDuSource ( DbU::Unit du ) = 0; - virtual void setDuTarget ( DbU::Unit du ) = 0; - void computeTerminal (); - virtual void updateOrient () = 0; - virtual void updatePositions () = 0; - virtual void updateNativeConstraints () = 0; - void updateSourceSpin (); - void updateTargetSpin (); - void sourceDetach (); - void targetDetach (); - void sourceAttach ( AutoContact* ); - void targetAttach ( AutoContact* ); - //inline void mergeUserConstraints ( const Interval& ); - void mergeUserConstraints ( const Interval& ); - inline void resetUserConstraints (); - inline void setOptimalMin ( DbU::Unit min ); - inline void setOptimalMax ( DbU::Unit max ); - inline void mergeNativeMin ( DbU::Unit min ); - inline void mergeNativeMax ( DbU::Unit max ); - inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max ); - bool checkNotInvalidated () const; - inline void setParent ( AutoSegment* ); - void revalidate (); - AutoSegment* makeDogleg ( AutoContact* ); - Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags ); - Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags ); - virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0; - virtual bool moveULeft () = 0; - virtual bool moveURight () = 0; - bool slacken ( Flags flags ); - virtual bool _slacken ( Flags flags ) = 0; - void _changeDepth ( unsigned int depth, Flags flags ); - void changeDepth ( unsigned int depth, Flags flags ); - bool moveUp ( Flags flags=Flags::NoFlags ); - bool moveDown ( Flags flags=Flags::NoFlags ); - bool reduceDoglegLayer (); - bool reduce (); - bool raise (); - // Canonical Modifiers. - AutoSegment* canonize ( Flags flags=Flags::NoFlags ); - virtual void invalidate ( Flags flags=Flags::Propagate ); - void invalidate ( AutoContact* ); - void computeOptimal ( set& processeds ); - void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags ); - bool toConstraintAxis ( Flags flags=Flags::Realignate ); - bool toOptimalAxis ( Flags flags=Flags::Realignate ); - // Collections & Filters. - AutoSegments getOnSourceContact ( Flags direction ); - AutoSegments getOnTargetContact ( Flags direction ); - AutoSegments getCachedOnSourceContact ( Flags direction ); - AutoSegments getCachedOnTargetContact ( Flags direction ); - AutoSegments getAligneds ( Flags flags=Flags::NoFlags ); - AutoSegments getConnecteds ( Flags flags=Flags::NoFlags ); - AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags ); - size_t getAlignedContacts ( map& ) const ; - // Observers. - template< typename OwnerT > - inline OwnerT* getObserver ( size_t slot ); - inline void setObserver ( size_t slot, BaseObserver* ); - inline void notify ( unsigned int flags ); - // Inspector Management. - virtual Record* _getRecord () const = 0; - virtual string _getString () const = 0; - virtual string _getTypeName () const = 0; - // Non-reviewed atomic modifiers. - bool _check () const; -#if THIS_IS_DISABLED - virtual void desalignate ( AutoContact* ) = 0; - bool shearUp ( GCell* - , AutoSegment*& movedUp - , float reserve - , Flags flags ); -#endif - - protected: - // Internal: Static Attributes. - static size_t _allocateds; - static size_t _globalsCount; - static bool _analogMode; - static bool _initialized; - static vector< array > _extensionCaps; - // Internal: Attributes. - const unsigned long _id; - GCell* _gcell; - uint64_t _flags; - unsigned int _depth : 8; - unsigned int _optimalMin :16; - unsigned int _optimalMax :16; - unsigned int _reduceds : 2; - DbU::Unit _sourcePosition; - DbU::Unit _targetPosition; - Interval _userConstraints; - Interval _nativeConstraints; - AutoSegment* _parent; - Observable _observers; - - // Internal: Constructors & Destructors. - protected: - AutoSegment ( Segment* segment ); - virtual ~AutoSegment (); - static void _preCreate ( AutoContact* source, AutoContact* target ); - virtual void _postCreate (); - virtual void _preDestroy (); - static void _initialize (); - private: - AutoSegment ( const AutoSegment& ); - AutoSegment& operator= ( const AutoSegment& ); - protected: - void _invalidate (); - inline uint64_t _getFlags () const; - std::string _getStringFlags () const; - virtual void _setAxis ( DbU::Unit ) = 0; - - public: - struct CompareId : public binary_function { - inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const; - }; - public: - struct CompareByDepthLength : public binary_function { - bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; - }; - public: - struct CompareByDepthAxis : public binary_function { - bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; - }; - public: - typedef std::set DepthLengthSet; - typedef std::set IdSet; - - // Static Utilities. - public: - static inline uint64_t swapSourceTargetFlags ( AutoSegment* ); - static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* ); - static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from ); - static bool isTopologicalBound ( AutoSegment* seed, Flags flags ); - static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b ); - static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b ); - static inline bool areAligneds ( AutoSegment* a, AutoSegment* b ); - static Flags getPerpandicularState ( AutoContact* contact - , AutoSegment* source - , AutoSegment* current - , bool isHorizontalMaster - , const Layer* masterLayer=NULL - ); - static inline Flags getPerpandicularState ( AutoContact* contact - , AutoSegment* source - , AutoSegment* current - , AutoSegment* master - ); - static void getTopologicalInfos ( AutoSegment* seed - , vector& collapseds - , vector& perpandiculars - , DbU::Unit& leftBound - , DbU::Unit& rightBound - ); - static int getTerminalCount ( AutoSegment* seed - , vector& collapseds - ); - static inline int getTerminalCount ( AutoSegment* seed ); - static inline size_t getGlobalsCount (); - static inline size_t getAllocateds (); - static inline unsigned long getMaxId (); - }; - - -// Inline Functions. - inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; } - inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; } - inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; } - inline unsigned long AutoSegment::getId () const { return _id; } - inline Cell* AutoSegment::getCell () const { return base()->getCell(); } - inline Net* AutoSegment::getNet () const { return base()->getNet(); } - inline const Layer* AutoSegment::getLayer () const { return base()->getLayer(); } - inline Box AutoSegment::getBoundingBox () const { return base()->getBoundingBox(); } - inline Hook* AutoSegment::getSourceHook () { return base()->getSourceHook(); } - inline Hook* AutoSegment::getTargetHook () { return base()->getTargetHook(); } - inline Contact* AutoSegment::getSource () const { return static_cast(base()->getSource()); } - inline Contact* AutoSegment::getTarget () const { return static_cast(base()->getTarget()); } - inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return base()->getOppositeAnchor(anchor); }; - inline AutoSegment* AutoSegment::getParent () const { return _parent; } - inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; } - inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; } - inline DbU::Unit AutoSegment::getSourceX () const { return base()->getSourceX(); } - inline DbU::Unit AutoSegment::getSourceY () const { return base()->getSourceY(); } - inline DbU::Unit AutoSegment::getTargetX () const { return base()->getTargetX(); } - inline DbU::Unit AutoSegment::getTargetY () const { return base()->getTargetY(); } - inline DbU::Unit AutoSegment::getWidth () const { return base()->getWidth(); } - inline DbU::Unit AutoSegment::getLength () const { return base()->getLength(); } - inline void AutoSegment::invert () { base()->invert(); } - inline GCell* AutoSegment::getGCell () const { return _gcell; } - inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); } - inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); } - inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); } - inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); } - inline unsigned int AutoSegment::getDepth () const { return _depth; } - inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); } - inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); } - inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); } - inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); } - inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); } - inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); } - inline DbU::Unit AutoSegment::getNativeMin () const { return _nativeConstraints.getVMin(); } - inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); } - inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; } - inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; } - - inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; } - inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); } - inline bool AutoSegment::isFixed () const { return _flags & SegFixed; } - inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; } - inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; } - inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; } - inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; } - inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); } - inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; } - inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; } - inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; } - inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; } - inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; } - inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; } - inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; } - inline bool AutoSegment::isDrag () const { return _flags & SegDrag; } - inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; } - inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; } - inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; } - inline bool AutoSegment::isDogleg () const { return _flags & SegDogleg ; } - inline bool AutoSegment::isUnbound () const { return _flags & SegUnbound ; } - inline bool AutoSegment::isStrap () const { return _flags & SegStrap; } - inline bool AutoSegment::isLayerChange () const { return _flags & SegLayerChange; } - inline bool AutoSegment::isSpinTop () const { return ((_flags & SegSpinTop ) == SegSpinTop); } - inline bool AutoSegment::isSpinBottom () const { return ((_flags & SegSpinBottom) == SegSpinBottom); } - inline bool AutoSegment::isSpinTopOrBottom () const { return isSpinTop() or isSpinBottom(); } - inline bool AutoSegment::isReduced () const { return _flags & SegIsReduced; } - inline bool AutoSegment::isSlackened () const { return _flags & SegSlackened; } - inline bool AutoSegment::isCanonical () const { return _flags & SegCanonical; } - inline bool AutoSegment::isUnsetAxis () const { return not (_flags & SegAxisSet); } - inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; } - inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; } - inline bool AutoSegment::isCreated () const { return _flags & SegCreated; } - inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; } - inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; } - inline bool AutoSegment::isWide () const { return _flags & SegWide; } - inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; } - inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; } - - inline uint64_t AutoSegment::getFlags () const { return _flags; } - inline uint64_t AutoSegment::_getFlags () const { return _flags; } - inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; } - inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; } - inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; } - inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); } - inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); } - inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); } - inline void AutoSegment::mergeNativeMax ( DbU::Unit max ) { _nativeConstraints.getVMax() = std::min( max, _nativeConstraints.getVMax() ); } - inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); } -//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } - inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } - - - inline DbU::Unit AutoSegment::getContactWidth () const - { return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); } - - - inline void AutoSegment::setParent ( AutoSegment* parent ) - { - if ( parent == this ) { - cerr << "Parentage Looping: " << parent->_getString() << endl; - } - _parent = parent; - } - - inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const - { return lhs->getId() < rhs->getId(); } - - inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment ) - { - uint64_t segFlags = segment->getFlags(); - uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop - |SegSourceBottom |SegTargetBottom - |SegSourceTerminal |SegTargetTerminal - |SegNotSourceAligned |SegNotTargetAligned - |SegInvalidatedSource|SegInvalidatedTarget - ); - - swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags; - swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags; - swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags; - swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags; - swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags; - - swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags; - swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags; - swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags; - swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags; - swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags; - return swapFlags; - } - - inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 ) - { return s1 and s2 - and (s1->isHorizontal() == s2->isHorizontal()) - and (s1->getLayer() != s2->getLayer()); } - - inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b ) - { return a and b and (a->isHorizontal() != b->isHorizontal()); } - - inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b ) - { return b and (isHorizontalA != b->isHorizontal()); } - - inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b ) - { return a and b and (a->isHorizontal() == b->isHorizontal()); } - - inline Flags AutoSegment::getPerpandicularState ( AutoContact* contact - , AutoSegment* source - , AutoSegment* current - , AutoSegment* master ) - { - return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() ); - } - - - inline int AutoSegment::getTerminalCount ( AutoSegment* seed ) - { - cdebug_log(145,0) << "getTerminalCount() - " << seed << endl; - - vector collapseds; - vector perpandiculars; - DbU::Unit leftBound; - DbU::Unit rightBound; - - getTopologicalInfos ( seed - , collapseds - , perpandiculars - , leftBound - , rightBound - ); - - return getTerminalCount ( seed, collapseds ); - } - - - inline size_t AutoSegment::getGlobalsCount () { return _globalsCount; } - inline size_t AutoSegment::getAllocateds () { return _allocateds; } - - - inline void AutoSegment::setObserver ( size_t slot, BaseObserver* observer ) - { _observers.setObserver( slot, observer ); } - - template - inline OwnerT* AutoSegment::getObserver ( size_t slot ) - { return _observers.getObserver(slot); } - - inline void AutoSegment::notify ( unsigned int flags ) - { _observers.notify( flags ); } - - inline AutoSegment::Observable::Observable () : StaticObservable<1>() { } - - -} // End of Anabatic namespace. - - -INSPECTOR_P_SUPPORT(Anabatic::AutoSegment); - - -# endif // ANABATIC_AUTOSEGMENT_H diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 5b633781..9cc621aa 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -45,6 +45,7 @@ namespace Anabatic { using Hurricane::NetRoutingState; using CRL::ToolEngine; + class NetBuilder; class AnabaticEngine; @@ -194,7 +195,6 @@ namespace Anabatic { static const uint32_t DigitalMode = (1 << 0); static const uint32_t AnalogMode = (1 << 1); static const uint32_t MixedMode = (1 << 2); - static const uint32_t ChannelMode = (1 << 3); static const uint32_t AverageHVDensity = 1; // Average between all densities. static const uint32_t AverageHDensity = 2; // Average between all H densities. static const uint32_t AverageVDensity = 3; // Average between all V densities. @@ -211,11 +211,14 @@ namespace Anabatic { inline bool isDigitalMode () const; inline bool isAnalogMode () const; inline bool isMixedMode () const; - inline bool isChannelMode () const; + inline bool isChannelStyle () const; + inline bool isHybridStyle () const; static const Name& staticGetName (); virtual const Name& getName () const; virtual Configuration* getConfiguration (); virtual const Configuration* getConfiguration () const; + inline std::string getNetBuilderStyle () const; + inline StyleFlags getRoutingStyle () const; inline uint64_t getDensityMode () const; inline CellViewer* getViewer () const; inline void setViewer ( CellViewer* ); @@ -276,6 +279,7 @@ namespace Anabatic { void invalidateRoutingPads (); void updateDensity (); size_t checkGCellDensities (); + void setupNetBuilder (); inline void setRoutingMode ( uint32_t ); inline void resetRoutingMode ( uint32_t ); inline void setGlobalThreshold ( DbU::Unit ); @@ -343,12 +347,15 @@ namespace Anabatic { virtual void _postCreate (); virtual void _preDestroy (); void _gutAnabatic (); + virtual Configuration* _createConfiguration (); private: AnabaticEngine ( const AnabaticEngine& ); AnabaticEngine& operator= ( const AnabaticEngine& ); private: static Name _toolName; + protected: Configuration* _configuration; + private: ChipTools _chipTools; EngineState _state; Matrix _matrix; @@ -369,58 +376,61 @@ namespace Anabatic { }; - inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); }; - inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); }; - inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); }; - inline bool AnabaticEngine::isChannelMode () const { return (_routingMode & ChannelMode); }; - inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; }; - inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; }; - inline EngineState AnabaticEngine::getState () const { return _state; } - inline void AnabaticEngine::setState ( EngineState state ) { _state = state; } - inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } - inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } - inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; } - inline const vector& AnabaticEngine::getGCells () const { return _gcells; } - inline const vector& AnabaticEngine::getOvEdges () const { return _ovEdges; } - inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } - inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } - inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } - inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr( new RawGCellsUnder(this,s) ); } - inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr( new RawGCellsUnder(this,source,target) ); } - inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); } - inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; } - inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; } - inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; } - inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; } - inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; } - inline const Flags& AnabaticEngine::flags () const { return _flags; } - inline Flags& AnabaticEngine::flags () { return _flags; } - inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; } - inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; } - inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; } - inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; } - inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; } - inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; } - inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); } - inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); } - inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return getConfiguration()->getAntennaDiodeMaxWL(); } - inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); } - inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); } - inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); } - inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); } - inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); } - inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; } - inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; } - inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; } - inline const vector& AnabaticEngine::getNetOrdering () const { return _netOrdering; } - inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } - inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; } - inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } - inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); } - inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); } - inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } - inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; } - inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); } + inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); }; + inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); }; + inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); }; + inline bool AnabaticEngine::isChannelStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Channel); }; + inline bool AnabaticEngine::isHybridStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Hybrid); }; + inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; }; + inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; }; + inline EngineState AnabaticEngine::getState () const { return _state; } + inline void AnabaticEngine::setState ( EngineState state ) { _state = state; } + inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } + inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } + inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; } + inline const vector& AnabaticEngine::getGCells () const { return _gcells; } + inline const vector& AnabaticEngine::getOvEdges () const { return _ovEdges; } + inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } + inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } + inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } + inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr( new RawGCellsUnder(this,s) ); } + inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr( new RawGCellsUnder(this,source,target) ); } + inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); } + inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; } + inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; } + inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; } + inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; } + inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; } + inline const Flags& AnabaticEngine::flags () const { return _flags; } + inline Flags& AnabaticEngine::flags () { return _flags; } + inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; } + inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; } + inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; } + inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; } + inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; } + inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; } + inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); } + inline std::string AnabaticEngine::getNetBuilderStyle () const { return _configuration->getNetBuilderStyle(); } + inline StyleFlags AnabaticEngine::getRoutingStyle () const { return _configuration->getRoutingStyle(); } + inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return _configuration->getAntennaGateMaxWL(); } + inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return _configuration->getAntennaDiodeMaxWL(); } + inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); } + inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); } + inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); } + inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); } + inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); } + inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; } + inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; } + inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; } + inline const vector& AnabaticEngine::getNetOrdering () const { return _netOrdering; } + inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } + inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; } + inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } + inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); } + inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); } + inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } + inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; } + inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); } inline void AnabaticEngine::_add ( GCell* gcell ) { diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index f344d225..33e278d6 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -1,7 +1,7 @@ // -*- mode: C++; explicit-buffer-name: "Configuration.h" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2016-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -66,8 +66,11 @@ namespace Anabatic { bool isGMetal ( const Layer* ) const; bool isGContact ( const Layer* ) const; bool isTwoMetals () const; + bool isHybrid () const; bool isHV () const; bool isVH () const; + inline std::string getNetBuilderStyle () const; + inline StyleFlags getRoutingStyle () const; const Layer* getGContactLayer () const; const Layer* getGHorizontalLayer () const; const Layer* getGVerticalLayer () const; @@ -132,6 +135,8 @@ namespace Anabatic { int getGlobalIterations () const; DbU::Unit isOnRoutingGrid ( RoutingPad* ) const; bool selectRpComponent ( RoutingPad* ) const; + inline void setRoutingStyle ( StyleFlags ); + inline void resetRoutingStyle ( StyleFlags ); virtual void print ( Cell* ) const; virtual Record* _getRecord () const; virtual string _getString () const; @@ -146,6 +151,8 @@ namespace Anabatic { size_t _ddepthv; size_t _ddepthh; size_t _ddepthc; + std::string _netBuilderStyle; + StyleFlags _routingStyle; CellGauge* _cg; RoutingGauge* _rg; std::vector _extensionCaps; @@ -169,6 +176,8 @@ namespace Anabatic { }; + inline std::string Configuration::getNetBuilderStyle () const { return _netBuilderStyle; } + inline StyleFlags Configuration::getRoutingStyle () const { return _routingStyle; } inline bool Configuration::isGLayer ( const Layer* layer ) const { return isGMetal(layer) or isGContact(layer); } inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; } inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; } @@ -193,6 +202,8 @@ namespace Anabatic { inline std::string Configuration::getDiodeName () const { return _diodeName; } inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; } inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; } + inline void Configuration::setRoutingStyle ( StyleFlags flags ) { _routingStyle = flags; } + inline void Configuration::resetRoutingStyle ( StyleFlags flags ) { _routingStyle &= ~flags; } } // Anabatic namespace. diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 02e4046d..8624d2fb 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -20,6 +20,9 @@ namespace Anabatic { +// ------------------------------------------------------------------- +// Class : "Anabatic::Flags". + class Flags : public Hurricane::BaseFlags { public: static const BaseFlags NoFlags ; // = 0; @@ -121,6 +124,39 @@ namespace Anabatic { Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { } +// ------------------------------------------------------------------- +// Class : "Anabatic::StyleFlags". + + class StyleFlags : public Hurricane::BaseFlags { + public: + static const BaseFlags NoStyle; // = 0; + static const BaseFlags HV ; // = (1 << 0); + static const BaseFlags VH ; // = (1 << 1); + static const BaseFlags OTH ; // = (1 << 2); + static const BaseFlags Channel; // = (1 << 3); + static const BaseFlags Hybrid ; // = (1 << 4); + public: + inline StyleFlags ( std::string ); + inline StyleFlags ( uint64_t flags = NoStyle ); + inline StyleFlags ( const Hurricane::BaseFlags& ); + virtual ~StyleFlags (); + static StyleFlags toFlag ( std::string ); + StyleFlags from ( std::string ); + virtual std::string asString () const; + virtual std::string _getTypeName () const; + virtual std::string _getString () const; + }; + + + StyleFlags::StyleFlags ( std::string textFlags ) : BaseFlags(NoStyle) { from(textFlags); } + StyleFlags::StyleFlags ( uint64_t flags ) : BaseFlags(flags) { } + StyleFlags::StyleFlags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { } + + +// ------------------------------------------------------------------- +// Misc. enums. + + enum FlagsMode { FlagsFunction = 1 }; diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index 7a36121f..f1f6d5eb 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -112,13 +112,13 @@ 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 + enum TopologyFlag { Global_Vertical_End = (1 << 0) + , Global_Horizontal_End = (1 << 1) + , Global_Horizontal = (1 << 2) + , Global_Vertical = (1 << 3) + , Global_Turn = (1 << 4) + , Global_Fork = (1 << 5) + , Global_Fixed = (1 << 6) , Global_End = Global_Vertical_End | Global_Horizontal_End , Global_Split = Global_Horizontal | Global_Vertical | Global_Fork }; @@ -157,7 +157,7 @@ namespace Anabatic { NetBuilder (); virtual ~NetBuilder (); void clear (); - inline bool isTwoMetals () const; + inline bool isStrictChannel () const; inline bool isUpperMetalRp () const; inline AnabaticEngine* getAnabatic () const; inline unsigned int getDegree () const; @@ -386,13 +386,13 @@ namespace Anabatic { map _routingPadAutoSegments; vector _toFixSegments; unsigned int _degree; - bool _isTwoMetals; + bool _isStrictChannel; uint64_t _sourceFlags; uint64_t _flags; }; - inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; } + inline bool NetBuilder::isStrictChannel () const { return _isStrictChannel; } inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; } inline unsigned int NetBuilder::getDegree () const { return _degree; } inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; } diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index 67981ae7..f25802b7 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -26,43 +26,44 @@ namespace Anabatic { class NetBuilderHV : public NetBuilder { public: - NetBuilderHV (); - virtual ~NetBuilderHV (); - virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); - virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); - AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* ); - AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); + NetBuilderHV (); + virtual ~NetBuilderHV (); + static std::string getStyle (); + virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); + AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* ); + AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); private: - virtual bool _do_1G_1M1 (); - virtual bool _do_1G_xM1 (); - virtual bool _do_xG (); - virtual bool _do_2G (); - virtual bool _do_2G_1M1 (); - virtual bool _do_xG_1Pad (); - virtual bool _do_1G_1PinM1 (); - virtual bool _do_2G_1PinM1 (); - virtual bool _do_1G_1PinM2 (); - virtual bool _do_xG_1PinM2 (); - virtual bool _do_1G_1PinM3 (); - virtual bool _do_xG_1PinM3 (); - virtual bool _do_xG_1M1 (); - virtual bool _do_xG_1M1_1M2 (); - virtual bool _do_xG_xM1_xM3 (); - virtual bool _do_4G_1M2 (); - virtual bool _do_xG_xM2 (); - virtual bool _do_1G_1M3 (); - virtual bool _do_xG_xM3 (); - bool _do_xG_xM3_baseRouting (); - bool _do_xG_xM3_upperRouting (); - virtual bool _do_1G_xM1_1PinM2 (); - virtual bool _do_2G_xM1_1PinM2 (); - virtual bool _do_1G_1M1_1PinM3 (); - virtual bool _do_2G_xM1_1PinM3 (); - virtual bool _do_3G_xM1_1PinM3 (); - virtual bool _do_globalSegment (); - virtual void singleGCell ( AnabaticEngine*, Net* ); - public: - virtual string getTypeName () const; + virtual bool _do_1G_1M1 (); + virtual bool _do_1G_xM1 (); + virtual bool _do_xG (); + virtual bool _do_2G (); + virtual bool _do_2G_1M1 (); + virtual bool _do_xG_1Pad (); + virtual bool _do_1G_1PinM1 (); + virtual bool _do_2G_1PinM1 (); + virtual bool _do_1G_1PinM2 (); + virtual bool _do_xG_1PinM2 (); + virtual bool _do_1G_1PinM3 (); + virtual bool _do_xG_1PinM3 (); + virtual bool _do_xG_1M1 (); + virtual bool _do_xG_1M1_1M2 (); + virtual bool _do_xG_xM1_xM3 (); + virtual bool _do_4G_1M2 (); + virtual bool _do_xG_xM2 (); + virtual bool _do_1G_1M3 (); + virtual bool _do_xG_xM3 (); + bool _do_xG_xM3_baseRouting (); + bool _do_xG_xM3_upperRouting (); + virtual bool _do_1G_xM1_1PinM2 (); + virtual bool _do_2G_xM1_1PinM2 (); + virtual bool _do_1G_1M1_1PinM3 (); + virtual bool _do_2G_xM1_1PinM3 (); + virtual bool _do_3G_xM1_1PinM3 (); + virtual bool _do_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + public: + virtual string getTypeName () const; }; diff --git a/anabatic/src/anabatic/NetBuilderHybridVH.h b/anabatic/src/anabatic/NetBuilderHybridVH.h new file mode 100644 index 00000000..f67c26ba --- /dev/null +++ b/anabatic/src/anabatic/NetBuilderHybridVH.h @@ -0,0 +1,67 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, 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/NetBuilderHybridVH.h" | +// +-----------------------------------------------------------------+ + +#pragma once +#include "anabatic/NetBuilder.h" + + +namespace Anabatic { + + +// ----------------------------------------------------------------- +// Class : "NetBuilderHybridVH". + + class NetBuilderHybridVH : public NetBuilder { + public: + NetBuilderHybridVH (); + virtual ~NetBuilderHybridVH (); + static std::string getStyle (); + virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); + AutoContact* doRp_AccessEastWestPin ( GCell* , RoutingPad* ); + AutoContact* doRp_AccessNorthSouthPin ( GCell* , RoutingPad* ); + private: + bool doRp_xG_1M1 ( RoutingPad* ); + bool doRp_1G_1PinM2 ( RoutingPad* ); + bool doRp_xG_xM1_xM3 ( const std::vector& ); + virtual bool _do_1G_1M1 (); + virtual bool _do_2G_1M1 (); + virtual bool _do_xG_1M1 (); + virtual bool _do_xG (); + bool _do_xG_xM1 (); + 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_1G_xM1_1PinM2 (); + // virtual bool _do_4G_1M2 (); + virtual bool _do_2G (); + virtual bool _do_2G_1PinM1 (); + virtual bool _do_1G_1PinM1 (); + virtual bool _do_1G_1PinM2 (); + virtual bool _do_xG_1PinM2 (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + public: + virtual string getTypeName () const; + }; + + +} // Anabatic namespace. diff --git a/anabatic/src/anabatic/NetBuilderM2.h b/anabatic/src/anabatic/NetBuilderM2.h index 870ecdf9..389459f8 100644 --- a/anabatic/src/anabatic/NetBuilderM2.h +++ b/anabatic/src/anabatic/NetBuilderM2.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -13,9 +13,7 @@ // | C++ Header : "./anabatic/NetBuilderM2.h" | // +-----------------------------------------------------------------+ -#ifndef ANABATIC_NET_BUILDER_M2_H -#define ANABATIC_NET_BUILDER_M2_H - +#pragma once #include "anabatic/NetBuilder.h" @@ -29,6 +27,7 @@ namespace Anabatic { public: NetBuilderM2 (); virtual ~NetBuilderM2 (); + static std::string getStyle (); virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); private: @@ -53,5 +52,3 @@ namespace Anabatic { } // Anabatic namespace. - -#endif // ANABATIC_NET_BUILDER_M2_H diff --git a/anabatic/src/anabatic/NetBuilderVH.h b/anabatic/src/anabatic/NetBuilderVH.h index 9150b569..c2910518 100644 --- a/anabatic/src/anabatic/NetBuilderVH.h +++ b/anabatic/src/anabatic/NetBuilderVH.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2017-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -27,6 +27,7 @@ namespace Anabatic { public: NetBuilderVH (); virtual ~NetBuilderVH (); + static std::string getStyle (); virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); private: diff --git a/anabatic/src/anabatic/PyStyleFlags.h b/anabatic/src/anabatic/PyStyleFlags.h new file mode 100644 index 00000000..d9f133a9 --- /dev/null +++ b/anabatic/src/anabatic/PyStyleFlags.h @@ -0,0 +1,52 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/isobar/PyStyleFlags.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "hurricane/isobar/PyHurricane.h" +#include "anabatic/Constants.h" + + +namespace Anabatic { + + extern "C" { + +// ------------------------------------------------------------------- +// Python Object : "PyStyleFlags". + + typedef struct { + PyObject_HEAD + StyleFlags* _object; + } PyStyleFlags; + + + extern PyTypeObject PyTypeStyleFlags; + extern PyMethodDef PyStyleFlags_Methods[]; + + extern PyObject* PyStyleFlags_Link ( StyleFlags* ); + extern void PyStyleFlags_LinkPyType (); + extern void PyStyleFlags_postModuleInit (); + +#define IsPyStyleFlags(v) ( (v)->ob_type == &PyTypeStyleFlags ) +#define PYSTYLEFLAGS(v) ( (PyStyleFlags*)(v) ) +#define PYSTYLEFLAGS_O(v) ( PYSTYLEFLAGS(v)->_object ) + + } // extern "C". + + + extern Anabatic::StyleFlags PyInt_AsStyleFlags ( PyObject* ); + + +} // Anabatic namespace. diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index 2c76f74b..10f1db20 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -76,11 +76,12 @@ namespace Anabatic { static inline bool doDestroyBaseSegment (); static inline bool doDestroyTool (); static bool isInDemoMode (); - static bool isChannelMode (); + static bool isChannelStyle (); static bool doWarnGCellOverload (); static Session* get ( const char* message=NULL ); static inline Technology* getTechnology (); static inline AnabaticEngine* getAnabatic (); + static StyleFlags getRoutingStyle (); static inline const Configuration* getConfiguration (); static float getSaturateRatio (); static size_t getSaturateRp (); diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 3c6e58c4..dd0aea96 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -143,6 +143,17 @@ namespace CRL { } + RoutingLayerGauge* RoutingGauge::getFirstRoutingGauge () const + { + for ( RoutingLayerGauge* rlg : _layerGauges ) { + if ( (rlg->getType() != Constant::LayerGaugeType::PinOnly) + and (rlg->getType() != Constant::PowerSupply) ) + return rlg; + } + return nullptr; + } + + RoutingLayerGauge* RoutingGauge::getHorizontalGauge () const { RoutingLayerGauge* pinOnly = NULL; diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index ce916ad9..a7c89ffc 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -49,58 +49,59 @@ namespace CRL { // Constants. static const size_t nlayerdepth; // Constructors & Destructors. - static RoutingGauge* create ( const char* name ); - virtual void destroy (); - // Predicates. - inline bool isSymbolic () const; - inline bool isTwoMetals () const; - inline bool isSuperPitched () const; - inline bool isHV () const; - inline bool isVH () const; - inline bool hasPowerSupply () const; - bool hasLayer ( const Layer* ) const; - // Accessors. - RoutingGauge* getClone () const; - inline const Name getName () const; - inline Technology* getTechnology () const; - inline size_t getDepth () const; - inline size_t getUsableLayers () const; - inline DbU::Unit getHorizontalPitch () const; - inline DbU::Unit getVerticalPitch () const; - RoutingLayerGauge* getHorizontalGauge () const; - RoutingLayerGauge* getVerticalGauge () const; - RoutingLayerGauge* getPowerSupplyGauge () const; - RoutingLayerGauge* getLayerGauge ( const Layer* ) const; - size_t getViaDepth ( const Layer* ) const; - size_t getLayerDepth ( const Layer* ) const; - unsigned int getLayerType ( const Layer* ) const; - unsigned int getLayerDirection ( const Layer* ) const; - DbU::Unit getPitch ( const Layer* ) const; - DbU::Unit getOffset ( const Layer* ) const; - DbU::Unit getWireWidth ( const Layer* ) const; - DbU::Unit getPWireWidth ( const Layer* ) const; - DbU::Unit getViaWidth ( const Layer* ) const; - RoutingLayerGauge* getLayerGauge ( size_t depth ) const; - inline unsigned int getLayerDirection ( size_t depth ) const; - inline unsigned int getLayerType ( size_t depth ) const; - inline DbU::Unit getLayerPitch ( size_t depth ) const; - inline DbU::Unit getLayerOffset ( size_t depth ) const; - inline DbU::Unit getLayerWireWidth ( size_t depth ) const; - inline DbU::Unit getLayerPWireWidth ( size_t depth ) const; - inline DbU::Unit getViaWidth ( size_t depth ) const; - const Layer* getRoutingLayer ( size_t depth ) const; - Layer* getContactLayer ( size_t depth ) const; - const vector& - getLayerGauges () const; - // Methods. - void addLayerGauge ( RoutingLayerGauge* layerGauge ); - void checkConnexity () const; - inline void setSymbolic ( bool ); - // Hurricane Managment. - void toJson ( JsonWriter* ) const; - virtual Record* _getRecord ( Record* record=NULL ) const; - virtual string _getString () const; - virtual string _getTypeName () const; + static RoutingGauge* create ( const char* name ); + virtual void destroy (); + // Predicates. + inline bool isSymbolic () const; + inline bool isTwoMetals () const; + inline bool isSuperPitched () const; + inline bool isHV () const; + inline bool isVH () const; + inline bool hasPowerSupply () const; + bool hasLayer ( const Layer* ) const; + // Accessors. + RoutingGauge* getClone () const; + inline const Name getName () const; + inline Technology* getTechnology () const; + inline size_t getDepth () const; + inline size_t getUsableLayers () const; + inline DbU::Unit getHorizontalPitch () const; + inline DbU::Unit getVerticalPitch () const; + RoutingLayerGauge* getFirstRoutingGauge () const; + RoutingLayerGauge* getHorizontalGauge () const; + RoutingLayerGauge* getVerticalGauge () const; + RoutingLayerGauge* getPowerSupplyGauge () const; + RoutingLayerGauge* getLayerGauge ( const Layer* ) const; + size_t getViaDepth ( const Layer* ) const; + size_t getLayerDepth ( const Layer* ) const; + unsigned int getLayerType ( const Layer* ) const; + unsigned int getLayerDirection ( const Layer* ) const; + DbU::Unit getPitch ( const Layer* ) const; + DbU::Unit getOffset ( const Layer* ) const; + DbU::Unit getWireWidth ( const Layer* ) const; + DbU::Unit getPWireWidth ( const Layer* ) const; + DbU::Unit getViaWidth ( const Layer* ) const; + RoutingLayerGauge* getLayerGauge ( size_t depth ) const; + inline unsigned int getLayerDirection ( size_t depth ) const; + inline unsigned int getLayerType ( size_t depth ) const; + inline DbU::Unit getLayerPitch ( size_t depth ) const; + inline DbU::Unit getLayerOffset ( size_t depth ) const; + inline DbU::Unit getLayerWireWidth ( size_t depth ) const; + inline DbU::Unit getLayerPWireWidth ( size_t depth ) const; + inline DbU::Unit getViaWidth ( size_t depth ) const; + const Layer* getRoutingLayer ( size_t depth ) const; + Layer* getContactLayer ( size_t depth ) const; + const vector& + getLayerGauges () const; + // Methods. + void addLayerGauge ( RoutingLayerGauge* layerGauge ); + void checkConnexity () const; + inline void setSymbolic ( bool ); + // Hurricane Managment. + void toJson ( JsonWriter* ) const; + virtual Record* _getRecord ( Record* record=NULL ) const; + virtual string _getString () const; + virtual string _getTypeName () const; protected: // Internal - Attributes. @@ -124,8 +125,8 @@ namespace CRL { inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; } inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; } inline bool RoutingGauge::isTwoMetals () const { return (_usableLayers < 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 bool RoutingGauge::isHV () const { return getFirstRoutingGauge()->isHorizontal(); } + inline bool RoutingGauge::isVH () const { return getFirstRoutingGauge()->isVertical(); } inline bool RoutingGauge::hasPowerSupply () const { return (getPowerSupplyGauge() != NULL); } inline const Name RoutingGauge::getName () const { return _name; } inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); } diff --git a/crlcore/src/pyCRL/PyRoutingGauge.cpp b/crlcore/src/pyCRL/PyRoutingGauge.cpp index 3e9a2bec..21ff3c0b 100644 --- a/crlcore/src/pyCRL/PyRoutingGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingGauge.cpp @@ -1,14 +1,14 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2012-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./PyRoutingGauge.cpp" | // +-----------------------------------------------------------------+ diff --git a/cumulus/src/plugins/alpha/block/block.py b/cumulus/src/plugins/alpha/block/block.py index d8b8a186..a91a2b15 100644 --- a/cumulus/src/plugins/alpha/block/block.py +++ b/cumulus/src/plugins/alpha/block/block.py @@ -768,7 +768,7 @@ class Block ( object ): self.katana.layerAssign ( Anabatic.EngineNoNetLayerAssign ) self.katana.runNegociate ( Katana.Flags.NoFlags ) success = self.katana.isDetailedRoutingSuccess() - Breakpoint.stop( 100, 'Block.route() done, success:{}.'.format(success) ) + Breakpoint.stop( 99, 'Block.route() done, success:{}.'.format(success) ) self.katana.finalizeLayout() if self.conf.cfg.katana.dumpMeasures is True: self.katana.dumpMeasures() diff --git a/cumulus/src/plugins/alpha/block/configuration.py b/cumulus/src/plugins/alpha/block/configuration.py index a7286b93..7d42ddd5 100644 --- a/cumulus/src/plugins/alpha/block/configuration.py +++ b/cumulus/src/plugins/alpha/block/configuration.py @@ -154,7 +154,7 @@ class GaugeConf ( object ): if not self.topLayerDepth: print( WarningMessage( 'Gauge top layer not defined, using top of gauge ({}).' \ .format(self._routingGauge.getDepth()) )) - self._topLayerDepth = self._routingGauge.getDepth() - 1 + self.topLayerDepth = self._routingGauge.getDepth() - 1 self.horizontalDepth = -1 self.verticalDepth = -1 diff --git a/etesian/src/BloatCells.cpp b/etesian/src/BloatCells.cpp index 9bdf343d..8cff2e56 100644 --- a/etesian/src/BloatCells.cpp +++ b/etesian/src/BloatCells.cpp @@ -166,17 +166,19 @@ namespace Etesian { Box ab ( cell->getAbutmentBox() ); DbU::Unit vpitch = etesian->getSliceStep();; int xsize = (ab.getWidth() + vpitch - 1) / vpitch; + int extra = 0; + float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch); + if (termRatio > 0.8) extra += 1; + if (termRatio > 0.5) { + return vpitch * (2*terminals + extra - xsize); + } + return 0; - // float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch); - // if (termRatio > 0.5) { - // return vpitch*6; - // } - - // if (xsize < 4) return vpitch*4; - // if (xsize < 6) return vpitch*2; - // if (xsize < 8) return vpitch*1; - - return vpitch*3; + // if (xsize < 4) return vpitch*4; + // if (xsize < 6) return vpitch*2; + // if (xsize < 8) return vpitch*1; + + // return vpitch*3; } diff --git a/katana/src/Block.cpp b/katana/src/Block.cpp index a165ed69..d454a6f2 100644 --- a/katana/src/Block.cpp +++ b/katana/src/Block.cpp @@ -1,7 +1,7 @@ // -*- mode: C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2017-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -50,6 +50,16 @@ namespace Katana { // Class : "Katana::Row". + Row::Row ( Block* block, DbU::Unit y ) + : _block (block) + , _isHybrid (block->getKatana()->isHybridStyle()) + , _y (y) + , _occurrences () + , _southWest (NULL) + , _channelHeight(1) + { } + + void Row::add ( DbU::Unit x, Occurrence occurrence ) { auto iocc = _occurrences.find( x ); @@ -137,17 +147,21 @@ namespace Katana { } } - southWest->setType( Anabatic::Flags::StdCellRow ); - if (channel) channel->setType( Anabatic::Flags::ChannelRow ); + if (not _isHybrid) { + southWest->setType( Anabatic::Flags::StdCellRow ); + if (channel) channel->setType( Anabatic::Flags::ChannelRow ); + } DbU::Unit xmax = getCell()->getAbutmentBox().getXMax() - sliceHeight; DbU::Unit xcut = _southWest->getXMin() + sliceHeight; for ( ; xcut < xmax ; xcut += sliceHeight ) { southWest = southWest->vcut( xcut ); - southWest->setType( Anabatic::Flags::StdCellRow ); + if (not _isHybrid) + southWest->setType( Anabatic::Flags::StdCellRow ); if (channel) { channel = channel->vcut( xcut ); - channel->setType( Anabatic::Flags::ChannelRow ); + if (not _isHybrid) + channel->setType( Anabatic::Flags::ChannelRow ); channel->getWestEdge()->setFlags( Flags::InfiniteCapacity ); } } @@ -196,17 +210,16 @@ namespace Katana { uint32_t Row::computeChannelHeight () { - _channelHeight = 2; + _channelHeight = 4; GCell* gcell = getSouthWest()->getNorth(); while ( gcell ) { - _channelHeight = std::max( _channelHeight, (uint32_t)gcell->getNetCount() ); - // Edge* east = gcell->getEastEdge(); - // if (east) - // _channelHeight = std::max( _channelHeight, east->getRealOccupancy() ); + //_channelHeight = std::max( _channelHeight, (uint32_t)gcell->getNetCount() ); + Edge* east = gcell->getEastEdge(); + if (east) + _channelHeight = std::max( _channelHeight, east->getRealOccupancy() ); gcell = gcell->getEast(); } - _channelHeight += 2; return _channelHeight; } @@ -233,7 +246,7 @@ namespace Katana { : _katana(katana) , _cell (cell) , _rows () - { + { for ( Occurrence occurrence : _cell->getTerminalNetlistInstanceOccurrences() ) { add( occurrence ); } @@ -312,7 +325,8 @@ namespace Katana { Session::close(); _katana->openSession(); - for ( Row* row : _rows ) row->routingPadsSubBreak(); + if (not _katana->isHybridStyle()) + for ( Row* row : _rows ) row->routingPadsSubBreak(); if (not sessionReUse) Session::close(); } @@ -322,6 +336,8 @@ namespace Katana { { cmess1 << " o Sizing routing channels." << endl; + Breakpoint::stop( 1, "About to compute/resize channel heights." ); + bool sessionReUse = Session::isOpen(); if (not sessionReUse) _katana->openSession(); diff --git a/katana/src/Configuration.cpp b/katana/src/Configuration.cpp index 1d1a6430..c511437c 100644 --- a/katana/src/Configuration.cpp +++ b/katana/src/Configuration.cpp @@ -180,6 +180,8 @@ namespace Katana { if (not cmess1.enabled()) return; cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; + cout << Dots::asString(" - Net builder style" ,getNetBuilderStyle()) << endl; + cout << Dots::asString(" - Routing style" ,getRoutingStyle().asString()) << endl; cout << Dots::asUInt (" - Dijkstra GR search halo" ,getSearchHalo()) << endl; cout << Dots::asBool (" - Use GR density estimate" ,useGlobalEstimate()) << endl; cout << Dots::asBool (" - Use static bloat profile" ,useStaticBloatProfile()) << endl; diff --git a/katana/src/DataNegociate.cpp b/katana/src/DataNegociate.cpp index 20002fae..78684bcb 100644 --- a/katana/src/DataNegociate.cpp +++ b/katana/src/DataNegociate.cpp @@ -126,7 +126,7 @@ namespace Katana { perpandicular = Session::lookup( basePerpand->getCanonical(interval)->base() ); } if (not perpandicular) { - if (not (Session::isChannelMode() + if (not (Session::isChannelStyle() and (basePerpand->isReduced() or basePerpand->isNonPref()))) cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)" //, getString((void*)basePerpand->getCanonical(interval)->base()).c_str() diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index cea65e10..ee953631 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -389,7 +389,7 @@ namespace Katana { startMeasures(); - if (isChannelMode()) createChannels(); + if (isChannelStyle()) createChannels(); if (getGCells().size() == 1) { cmess1 << " o Building regular grid..." << endl; @@ -518,7 +518,7 @@ namespace Katana { , getConfiguration()->getEdgeHScaling() )); const vector& ovEdges = getOvEdges(); - if (isChannelMode()) + if (isChannelStyle()) dijkstra->setSearchAreaHalo( Session::getSliceHeight()*10 ); else dijkstra->setSearchAreaHalo( Session::getSliceHeight()*getSearchHalo() ); @@ -685,7 +685,7 @@ namespace Katana { addMeasure( "H-ovE", hoverflow, 12 ); addMeasure( "V-ovE", voverflow, 12 ); - if (not Session::isChannelMode()) + if (not Session::isChannelStyle()) _buildBloatProfile(); if (flags & Flags::ShowFailedNets ) selectNets ( this, nets ); @@ -706,7 +706,7 @@ namespace Katana { delete dijkstra; Session::close(); - if (isChannelMode()) { + if (isChannelStyle()) { setupRoutingPlanes(); setupPowerRails(); protectRoutingPads(); diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 6a28499d..5e07bcc9 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -188,7 +188,6 @@ namespace Katana { KatanaEngine::KatanaEngine ( Cell* cell ) : Super (cell) , _viewer (NULL) - , _configuration (new Configuration()) , _blocks () , _routingPlanes () , _negociateWindow(NULL) @@ -197,24 +196,29 @@ namespace Katana { , _symmetrics () , _stage (StageNegociate) , _successState (0) - { - //Entity::setMemoryLimit( 1024 ); // 1Gb. - addMeasure( "Gates" - , AllianceFramework::getInstancesCount(cell,AllianceFramework::IgnoreNonLogic - |AllianceFramework::TerminalNetlist - |AllianceFramework::Recursive) ); - } + { } void KatanaEngine::_postCreate () { Super::_postCreate(); + //Entity::setMemoryLimit( 1024 ); // 1Gb. + addMeasure( "Gates" + , AllianceFramework::getInstancesCount(getCell() + ,AllianceFramework::IgnoreNonLogic + |AllianceFramework::TerminalNetlist + |AllianceFramework::Recursive) ); + // Flute: load POWV9.dat & POST9.dat Flute::readLUT( System::getPath( "coriolis_top" ).toString() ); } + Configuration* KatanaEngine::_createConfiguration () + { return new Configuration(); } + + void KatanaEngine::_runKatanaInit () { Utilities::Path pythonSitePackages = System::getPath("pythonSitePackages"); @@ -246,7 +250,7 @@ namespace Katana { setupChannelMode(); setupGlobalGraph( 0 ); - if (not isChannelMode()) { + if (not isChannelStyle()) { setupRoutingPlanes(); } setupSpecialNets(); @@ -254,7 +258,7 @@ namespace Katana { setState( Anabatic::EngineDriving ); throw Error( "KatanaEngine::digitalInit(): All nets are already routed, doing nothing." ); } else { - if (not isChannelMode()) { + if (not isChannelStyle()) { setupPowerRails(); protectRoutingPads(); } @@ -287,6 +291,7 @@ namespace Katana { RoutingGauge* rg = getConfiguration()->getRoutingGauge(); if (rg->isTwoMetals()) { + cmess1 << " - Running in channel mode." << endl; setRoutingMode( ChannelMode ); size_t maxDepth = rg->getDepth(); @@ -361,7 +366,7 @@ namespace Katana { KatanaEngine::~KatanaEngine () - { delete _configuration; } + { } const Name& KatanaEngine::getName () const @@ -369,24 +374,28 @@ namespace Katana { Configuration* KatanaEngine::getConfiguration () - { return _configuration; } + { return static_cast( Super::getConfiguration() ); } + + + const Configuration* KatanaEngine::getConfiguration () const + { return static_cast( Super::getConfiguration() ); } uint32_t KatanaEngine::getRipupLimit ( const TrackElement* segment ) const { if (segment->isBlockage()) return 0; - if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); - if (segment->isUnbreakable()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); - if (segment->isShortNet ()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); + if (segment->isStrap ()) return getConfiguration()->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isUnbreakable()) return getConfiguration()->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isShortNet ()) return getConfiguration()->getRipupLimit( Configuration::ShortNetRipupLimit ); if (segment->isGlobal ()) { vector gcells; segment->getGCells( gcells ); if (gcells.size() > 2) - return _configuration->getRipupLimit( Configuration::LongGlobalRipupLimit ); - return _configuration->getRipupLimit( Configuration::GlobalRipupLimit ); + return getConfiguration()->getRipupLimit( Configuration::LongGlobalRipupLimit ); + return getConfiguration()->getRipupLimit( Configuration::GlobalRipupLimit ); } - return _configuration->getRipupLimit( Configuration::LocalRipupLimit ); + return getConfiguration()->getRipupLimit( Configuration::LocalRipupLimit ); } @@ -553,7 +562,7 @@ namespace Katana { } } - if (Session::isChannelMode()) { + if (Session::isChannelStyle()) { for ( GCell* gcell : getGCells() ) { if (not gcell->isStdCellRow()) continue; @@ -852,7 +861,7 @@ namespace Katana { TrackElement* trackSegment = Session::lookup( segment ); if (not trackSegment) { - if ( isChannelMode() + if ( isChannelStyle() and autoSegment->isFixed() and autoSegment->isHorizontal() and autoSegment->isNonPref()) @@ -998,7 +1007,6 @@ namespace Katana { Record* record = Super::_getRecord (); if (record) { - record->add( getSlot( "_configuration", _configuration ) ); record->add( getSlot( "_blocks" , &_blocks ) ); record->add( getSlot( "_routingPlanes", &_routingPlanes ) ); record->add( getSlot( "_symmetrics" , &_symmetrics ) ); diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 1aed3380..7c3b35ac 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -343,7 +343,7 @@ namespace Katana { // Look for closest enclosing min & max GCells indexes. for ( igcell=0 ; igcellgetSide(_segment->getDirection()); - cdebug_log(159,0) << "| " << setw(3) << igcell << " " << gcells[igcell] << " uside: " << uside << endl; + cdebug_log(159,0) << "| " << igcell << " " << gcells[igcell] << " uside: " << uside << endl; if (uside.contains(interval.getVMin())) { iminconflict = igcell; @@ -437,6 +437,8 @@ namespace Katana { } else if (iminconflict == gcells.size()-1) { dogLegCount--; firstDoglegIsMin = true; + } else { + dogLegCount--; } } break; @@ -724,7 +726,7 @@ namespace Katana { } if ( segment2->isBlockage() or (segment2->isFixed() - and not (segment2->isVertical() and Session::getKatanaEngine()->isChannelMode()))) { + and not (segment2->isVertical() and Session::getKatanaEngine()->isChannelStyle()))) { cdebug_log(159,0) << "Overlap is blockage or fixed." << endl; success = false; continue; diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index fa86d881..227b14fc 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -62,7 +62,7 @@ namespace { if ( segment->isBlockage() or (segment->isFixed() - and not (segment->isVertical() and Session::getKatanaEngine()->isChannelMode()))) { + and not (segment->isVertical() and Session::getKatanaEngine()->isChannelStyle()))) { cdebug_log(159,0) << "Infinite cost from: " << segment << endl; cost.setInfinite (); cost.setOverlap (); @@ -292,7 +292,7 @@ namespace Katana { { _gcells = gcells; - if (not Session::getKatanaEngine()->isChannelMode()) loadRoutingPads( this ); + if (not Session::getKatanaEngine()->isChannelStyle()) loadRoutingPads( this ); Session::revalidate(); for ( auto element : Session::getKatanaEngine()->_getAutoSegmentLut() ) { @@ -331,7 +331,7 @@ namespace Katana { // Special case: fixed AutoSegments must not interfere with blockages. // Ugly: uses of getExtensionCap(). if (autoSegment->isFixed()) { - if (Session::isChannelMode() and autoSegment->isReduced()) { + if (Session::isChannelStyle() and autoSegment->isReduced()) { cdebug_log(159,0) << "* Fixed segment is reduced, ignore " << autoSegment << endl; cdebug_tabw(159,-1); return NULL; @@ -342,7 +342,7 @@ namespace Katana { Interval fixedSpan; Interval blockageSpan; - if (Session::isChannelMode() and autoSegment->isNonPref()) { + if (Session::isChannelStyle() and autoSegment->isNonPref()) { cdebug_log(159,0) << "Fixed in non-preferred direction, do not attempt to set on track." << endl; cdebug_tabw(159,-1); DebugSession::close(); diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index e122db92..4d2b7d41 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -1207,7 +1207,7 @@ namespace Katana { if ( (layer->getMaterial() != BasicLayer::Material::metal) and (layer->getMaterial() != BasicLayer::Material::blockage) ) continue; - if (_configuration->isGMetal(layer)) continue; + if (getConfiguration()->isGMetal(layer)) continue; if (not query.hasBasicLayer(layer)) continue; query.setBasicLayer( layer ); diff --git a/katana/src/PyKatanaEngine.cpp b/katana/src/PyKatanaEngine.cpp index 3383166d..4dfc4d7c 100644 --- a/katana/src/PyKatanaEngine.cpp +++ b/katana/src/PyKatanaEngine.cpp @@ -123,7 +123,7 @@ extern "C" { if (katana == NULL) { katana = KatanaEngine::create(cell); if (cmess1.enabled()) - katana->getKatanaConfiguration()->print(cell); + katana->getConfiguration()->print(cell); } else cerr << Warning("%s already has a Katana engine.",getString(cell).c_str()) << endl; HCATCH diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index c8dad156..41cda40e 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -703,7 +703,8 @@ namespace Katana { } else if ( _segment->base()->getAutoSource()->isFixed() or _segment->base()->getAutoTarget()->isFixed()) { cdebug_log(159,0) << "Not expanding on fixed segments:" << _constraints << endl; - } else if ( Session::getRoutingGauge()->isTwoMetals() + } else if ( ( Session::getKatanaEngine()->isChannelStyle() + and not Session::getKatanaEngine()->isHybridStyle()) and _segment->base()->isHorizontal()) { cdebug_log(159,0) << "Not expanding on horizontal segments in channel mode:" << _constraints << endl; } else { diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 50e031b7..f759b79c 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -1514,10 +1514,12 @@ namespace Katana { _data2->resetRipupCount(); } - if ( segment1->isStrap() - or segment1->isUnbreakable()) { success = _slackenStrap ( segment1, _data1, flags ); } - else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } - else { success = _slackenGlobal( segment1, _data1, flags ); } + if (segment1->isStrap() or segment1->isUnbreakable()) + success = _slackenStrap ( segment1, _data1, flags ); + else if (segment1->isLocal()) + success = _slackenLocal ( segment1, _data1, flags ); + else + success = _slackenGlobal( segment1, _data1, flags ); if (success) { actionFlags |= SegmentAction::ResetRipup; diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 308357f4..a2383d33 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -136,6 +136,7 @@ namespace Katana { bool TrackElement::isFixedAxis () const { return false; } bool TrackElement::isLocal () const { return true; } bool TrackElement::isGlobal () const { return not isLocal(); } + bool TrackElement::isWeakGlobal () const { return false; } bool TrackElement::isBipoint () const { return false; } bool TrackElement::isTerminal () const { return false; } bool TrackElement::isDrag () const { return false; } diff --git a/katana/src/TrackElements.cpp b/katana/src/TrackElements.cpp index 726074ac..9905a19b 100644 --- a/katana/src/TrackElements.cpp +++ b/katana/src/TrackElements.cpp @@ -47,7 +47,7 @@ namespace Katana { _element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() ); if (not _element) { AutoSegment* segment = _locator.getElement()->getCanonical(bounds); - if (Session::isChannelMode() + if (Session::isChannelStyle() and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed())) cerr << Bug( "Canonical segment without TrackElement on %s." , getString(segment).c_str()) << endl; @@ -73,7 +73,7 @@ namespace Katana { _element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() ); if (not _element ) { AutoSegment* segment = _locator.getElement()->getCanonical(bounds); - if (Session::isChannelMode() + if (Session::isChannelStyle() and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed())) cerr << Bug( "Canonical segment without TrackElement on %s." , getString(segment).c_str() ) << endl; diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index e6a5728c..57fddbdc 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -176,14 +176,15 @@ namespace Katana { bool TrackSegment::isFixedAxis () const { return _base->isFixedAxis(); } bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); } bool TrackSegment::isVertical () const { return _base->isVertical(); } - bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); } + bool TrackSegment::isLocal () const { return not _base->isGlobal() and not _base->isWeakGlobal(); } bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); } - bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable(); } + bool TrackSegment::isWeakGlobal () const { return _base->isWeakGlobal(); } + bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable() and not _base->isWeakGlobal(); } bool TrackSegment::isBipoint () const { return _base->isBipoint(); } bool TrackSegment::isTerminal () const { return _base->isTerminal(); } bool TrackSegment::isDrag () const { return _base->isDrag(); } bool TrackSegment::isStrongTerminal ( Flags flags ) const { return _base->isStrongTerminal(flags); } - bool TrackSegment::isStrap () const { return _base->isStrap(); } + bool TrackSegment::isStrap () const { return _base->isStrap() and not _base->isWeakGlobal(); } bool TrackSegment::isSlackened () const { return _base->isSlackened(); } bool TrackSegment::isDogleg () const { return _base->isDogleg(); } bool TrackSegment::isShortDogleg () const { return _flags & TElemShortDogleg; } diff --git a/katana/src/TrackSegmentCost.cpp b/katana/src/TrackSegmentCost.cpp index 6266f92f..58955daf 100644 --- a/katana/src/TrackSegmentCost.cpp +++ b/katana/src/TrackSegmentCost.cpp @@ -105,7 +105,7 @@ namespace Katana { } if ( not perpandicular ) { - if (Session::isChannelMode() + if (Session::isChannelStyle() and not (basePerpand->isReduced() or basePerpand->isNonPref())) cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)" ,getString((void*)basePerpand->getCanonical(interval)->base()).c_str() diff --git a/katana/src/katana/Block.h b/katana/src/katana/Block.h index 24573b27..54b795ed 100644 --- a/katana/src/katana/Block.h +++ b/katana/src/katana/Block.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2017-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -47,7 +47,7 @@ namespace Katana { class Row { public: - inline Row ( Block*, DbU::Unit ); + Row ( Block*, DbU::Unit ); inline Block* getBlock () const; inline Cell* getCell () const; inline DbU::Unit getY () const; @@ -62,6 +62,7 @@ namespace Katana { Record* _getRecord () const; private: Block* _block; + bool _isHybrid; DbU::Unit _y; map _occurrences; GCell* _southWest; @@ -69,9 +70,6 @@ namespace Katana { }; - inline Row::Row ( Block* block, DbU::Unit y ) - : _block(block), _y(y), _occurrences(), _southWest(NULL), _channelHeight(1) { } - inline DbU::Unit Row::getY () const { return _y; } inline Block* Row::getBlock () const { return _block; } inline GCell* Row::getSouthWest () const { return _southWest; } @@ -83,15 +81,16 @@ namespace Katana { class Block { public: - Block ( KatanaEngine*, Cell* ); - ~Block (); - inline Cell* getCell () const; - Row* getAt ( DbU::Unit y ) const; - void add ( Occurrence ); - void createChannels (); - void resizeChannels (); - string _getString () const; - Record* _getRecord () const; + Block ( KatanaEngine*, Cell* ); + ~Block (); + inline KatanaEngine* getKatana () const; + inline Cell* getCell () const; + Row* getAt ( DbU::Unit y ) const; + void add ( Occurrence ); + void createChannels (); + void resizeChannels (); + string _getString () const; + Record* _getRecord () const; private: KatanaEngine* _katana; Cell* _cell; @@ -99,7 +98,8 @@ namespace Katana { }; - inline Cell* Block::getCell () const { return _cell; } + inline KatanaEngine* Block::getKatana () const { return _katana; } + inline Cell* Block::getCell () const { return _cell; } // Deferred Row functions. diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index 02a93646..d67a944a 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -71,8 +71,8 @@ namespace Katana { inline bool useStaticBloatProfile () const; inline CellViewer* getViewer () const; inline AnabaticEngine* base (); - inline Configuration* getKatanaConfiguration (); - virtual Configuration* getConfiguration (); + const Configuration* getConfiguration () const; + Configuration* getConfiguration (); inline uint32_t getSuccessState () const; inline uint32_t getStage () const; inline uint64_t getEventsLimit () const; @@ -152,12 +152,12 @@ namespace Katana { virtual Record* _getRecord () const; virtual string _getString () const; virtual string _getTypeName () const; + virtual Configuration* _createConfiguration (); private: // Attributes. static Name _toolName; protected: CellViewer* _viewer; - Configuration* _configuration; vector _blocks; vector _routingPlanes; NegociateWindow* _negociateWindow; @@ -181,26 +181,25 @@ namespace Katana { // Inline Functions. inline bool KatanaEngine::isGlobalRoutingSuccess () const { return (_successState & GlobalRoutingSuccess); } inline bool KatanaEngine::isDetailedRoutingSuccess() const { return (_successState & DetailedRoutingSuccess); } - inline bool KatanaEngine::useClockTree () const { return _configuration->useClockTree(); } - inline bool KatanaEngine::useGlobalEstimate () const { return _configuration->useGlobalEstimate(); } - inline bool KatanaEngine::useStaticBloatProfile () const { return _configuration->useStaticBloatProfile(); } + inline bool KatanaEngine::useClockTree () const { return getConfiguration()->useClockTree(); } + inline bool KatanaEngine::useGlobalEstimate () const { return getConfiguration()->useGlobalEstimate(); } + inline bool KatanaEngine::useStaticBloatProfile () const { return getConfiguration()->useStaticBloatProfile(); } inline CellViewer* KatanaEngine::getViewer () const { return _viewer; } inline AnabaticEngine* KatanaEngine::base () { return static_cast(this); } - inline Configuration* KatanaEngine::getKatanaConfiguration () { return _configuration; } inline uint32_t KatanaEngine::getStage () const { return _stage; } - inline Configuration::PostEventCb_t& KatanaEngine::getPostEventCb () { return _configuration->getPostEventCb(); } + inline Configuration::PostEventCb_t& KatanaEngine::getPostEventCb () { return getConfiguration()->getPostEventCb(); } inline uint32_t KatanaEngine::getSuccessState () const { return _successState; } - inline uint64_t KatanaEngine::getEventsLimit () const { return _configuration->getEventsLimit(); } - inline uint32_t KatanaEngine::getRipupCost () const { return _configuration->getRipupCost(); } - inline uint32_t KatanaEngine::getSearchHalo () const { return _configuration->getSearchHalo(); } - inline uint32_t KatanaEngine::getBloatOverloadAdd () const { return _configuration->getBloatOverloadAdd(); } - inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); } - inline uint32_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); } - inline uint32_t KatanaEngine::getTermSatReservedLocal () const { return _configuration->getTermSatReservedLocal(); } - inline uint32_t KatanaEngine::getTermSatThreshold () const { return _configuration->getTermSatThreshold(); } - inline uint32_t KatanaEngine::getRipupLimit ( uint32_t type ) const { return _configuration->getRipupLimit(type); } - inline uint32_t KatanaEngine::getTrackFill () const { return _configuration->getTrackFill(); } - inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); } + inline uint64_t KatanaEngine::getEventsLimit () const { return getConfiguration()->getEventsLimit(); } + inline uint32_t KatanaEngine::getRipupCost () const { return getConfiguration()->getRipupCost(); } + inline uint32_t KatanaEngine::getSearchHalo () const { return getConfiguration()->getSearchHalo(); } + inline uint32_t KatanaEngine::getBloatOverloadAdd () const { return getConfiguration()->getBloatOverloadAdd(); } + inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return getConfiguration()->getHTracksReservedLocal(); } + inline uint32_t KatanaEngine::getVTracksReservedLocal () const { return getConfiguration()->getVTracksReservedLocal(); } + inline uint32_t KatanaEngine::getTermSatReservedLocal () const { return getConfiguration()->getTermSatReservedLocal(); } + inline uint32_t KatanaEngine::getTermSatThreshold () const { return getConfiguration()->getTermSatThreshold(); } + inline uint32_t KatanaEngine::getRipupLimit ( uint32_t type ) const { return getConfiguration()->getRipupLimit(type); } + inline uint32_t KatanaEngine::getTrackFill () const { return getConfiguration()->getTrackFill(); } + inline bool KatanaEngine::profileEventCosts () const { return getConfiguration()->profileEventCosts(); } inline const DataSymmetricMap& KatanaEngine::getSymmetrics () const { return _symmetrics; } inline Block* KatanaEngine::getBlock ( size_t i ) const { return (i < _blocks.size()) ? _blocks[i] : NULL; } inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; } @@ -209,16 +208,16 @@ namespace Katana { KatanaEngine::getRoutingPlanes () const { return _routingPlanes; } inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } inline void KatanaEngine::setStage ( uint32_t stage ) { _stage=stage; } - inline void KatanaEngine::setEventLimit ( uint64_t limit ) { _configuration->setEventsLimit(limit); } - inline void KatanaEngine::setRipupLimit ( uint32_t type, uint32_t limit ) { _configuration->setRipupLimit(limit,type); } - inline void KatanaEngine::setRipupCost ( uint32_t cost ) { _configuration->setRipupCost(cost); } - inline void KatanaEngine::setBloatOverloadAdd ( uint32_t add ) { _configuration->setBloatOverloadAdd(add); } - inline void KatanaEngine::setHTracksReservedLocal ( uint32_t reserved ) { _configuration->setHTracksReservedLocal(reserved); } - inline void KatanaEngine::setVTracksReservedLocal ( uint32_t reserved ) { _configuration->setVTracksReservedLocal(reserved); } + inline void KatanaEngine::setEventLimit ( uint64_t limit ) { getConfiguration()->setEventsLimit(limit); } + inline void KatanaEngine::setRipupLimit ( uint32_t type, uint32_t limit ) { getConfiguration()->setRipupLimit(limit,type); } + inline void KatanaEngine::setRipupCost ( uint32_t cost ) { getConfiguration()->setRipupCost(cost); } + inline void KatanaEngine::setBloatOverloadAdd ( uint32_t add ) { getConfiguration()->setBloatOverloadAdd(add); } + inline void KatanaEngine::setHTracksReservedLocal ( uint32_t reserved ) { getConfiguration()->setHTracksReservedLocal(reserved); } + inline void KatanaEngine::setVTracksReservedLocal ( uint32_t reserved ) { getConfiguration()->setVTracksReservedLocal(reserved); } inline void KatanaEngine::addBlock ( Block* block ) { _blocks.push_back(block); } inline void KatanaEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; } - inline void KatanaEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); } - inline void KatanaEngine::printConfiguration () const { _configuration->print(getCell()); } + inline void KatanaEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { getConfiguration()->setPostEventCb(cb); } + inline void KatanaEngine::printConfiguration () const { getConfiguration()->print(getCell()); } inline TrackElement* KatanaEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver(AutoSegment::Observable::TrackSegment); } inline void KatanaEngine::_addShortDogleg ( TrackElement* segmentA, TrackElement* segmentB ) diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 33f4e539..34f67e14 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -109,6 +109,7 @@ namespace Katana { virtual bool isUnbreakable () const; virtual bool isLocal () const; virtual bool isGlobal () const; + virtual bool isWeakGlobal () const; virtual bool isBipoint () const; virtual bool isTerminal () const; virtual bool isDrag () const; diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index d1957100..b552ec60 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef KATANA_TRACK_SEGMENT_H -#define KATANA_TRACK_SEGMENT_H - +#pragma once #include #include #include "katana/TrackElement.h" @@ -68,6 +66,7 @@ namespace Katana { virtual bool isVertical () const; virtual bool isLocal () const; virtual bool isGlobal () const; + virtual bool isWeakGlobal () const; virtual bool isBipoint () const; virtual bool isTerminal () const; virtual bool isDrag () const; @@ -192,5 +191,3 @@ namespace Katana { INSPECTOR_P_SUPPORT(Katana::TrackSegment); - -#endif // KATANA_TRACK_SEGMENT_H