From 3265c3ddcb67aa1d5120a1cb150dc9416739b312 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 22 Jul 2016 00:14:17 +0200 Subject: [PATCH] Anabatic transient commit 13. Pre-load wires, imported from Katabatic. --- anabatic/src/AnabaticEngine.cpp | 66 ++- anabatic/src/CMakeLists.txt | 4 + anabatic/src/ChipTools.cpp | 191 +++++++++ anabatic/src/GCell.cpp | 4 +- anabatic/src/GlobalRoute.cpp | 12 +- anabatic/src/GraphicAnabaticEngine.cpp | 1 + anabatic/src/LayerAssign.cpp | 535 +++++++++++++++++++++++++ anabatic/src/PreRouteds.cpp | 173 ++++++++ anabatic/src/anabatic/AnabaticEngine.h | 283 +++++++------ anabatic/src/anabatic/ChipTools.h | 118 ++++++ 10 files changed, 1243 insertions(+), 144 deletions(-) create mode 100644 anabatic/src/ChipTools.cpp create mode 100644 anabatic/src/LayerAssign.cpp create mode 100644 anabatic/src/PreRouteds.cpp create mode 100644 anabatic/src/anabatic/ChipTools.h diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 67e71f73..8cddd236 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -39,6 +39,7 @@ namespace Anabatic { using Hurricane::Component; using Hurricane::Horizontal; using Hurricane::Vertical; + using Hurricane::NetRoutingExtension; using Hurricane::Cell; using Hurricane::DebugSession; using Hurricane::UpdateSession; @@ -82,21 +83,26 @@ namespace Anabatic { AnabaticEngine::AnabaticEngine ( Cell* cell ) : Super(cell) - , _timer () - , _configuration (new ConfigurationConcrete()) - , _state (EngineCreation) - , _matrix () - , _gcells () - , _ovEdges () - , _viewer (NULL) - , _flags (Flags::DestroyBaseContact) - , _stamp (-1) - , _densityMode (MaxDensity) - , _autoSegmentLut() - , _autoContactLut() + , _timer () + , _configuration (new ConfigurationConcrete()) + , _chipTools (cell) + , _state (EngineCreation) + , _matrix () + , _gcells () + , _ovEdges () + , _viewer (NULL) + , _flags (Flags::DestroyBaseContact) + , _stamp (-1) + , _densityMode (MaxDensity) + , _autoSegmentLut () + , _autoContactLut () + , _netRoutingStates() + , _blockageNet (cell->getNet("blockagenet")) { _matrix.setCell( cell, _configuration->getSliceHeight() ); Edge::unity = _configuration->getSliceHeight(); + + if (not _blockageNet) _blockageNet = Net::create( cell, "blockagenet" ); } @@ -279,6 +285,34 @@ namespace Anabatic { } + NetRoutingState* AnabaticEngine::getRoutingState ( Net* net, unsigned int flags ) + { + NetRoutingState* state = NetRoutingExtension::get( net ); + + if (state) { + NetRoutingStates::iterator istate = _netRoutingStates.find( net->getId() ); + if (istate != _netRoutingStates.end()) { + if (istate->second != state) { + cerr << Error( "AnabaticEngine::getRoutingStates() - %s incoherency between property and LUT:\n" + " Property:%x vs. LUT:%x, re-init LUT from property." + , getString(net->getName()).c_str() + , (void*)state + , (void*)(istate->second)) << endl; + _netRoutingStates.insert( make_pair(net->getId(), state) ); + } + return state; + } + } else { + if (not (flags & Flags::Create)) return NULL; + + state = NetRoutingExtension::create( net ); + } + + _netRoutingStates.insert( make_pair(net->getId(), state) ); + return state; + } + + void AnabaticEngine::cleanupGlobal () { UpdateSession::open(); @@ -561,6 +595,14 @@ namespace Anabatic { { for ( GCell* gcell : _gcells ) gcell->updateDensity(); } + size_t AnabaticEngine::checkGCellDensities () + { + size_t saturateds = 0; + for ( GCell* gcell : _gcells ) saturateds += gcell->checkDensity(); + return saturateds; + } + + AutoSegment* AnabaticEngine::_lookup ( Segment* segment ) const { AutoSegmentLut::const_iterator it = _autoSegmentLut.find( segment ); diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt index 59757952..6cdec98c 100644 --- a/anabatic/src/CMakeLists.txt +++ b/anabatic/src/CMakeLists.txt @@ -30,6 +30,7 @@ endif ( CHECK_DETERMINISM ) anabatic/AutoHorizontal.h anabatic/AutoVertical.h anabatic/Session.h + anabatic/ChipTools.h ) set( mocIncludes anabatic/GraphicAnabaticEngine.h ) set( pyIncludes anabatic/PyAnabaticEngine.h @@ -58,6 +59,9 @@ endif ( CHECK_DETERMINISM ) NetConstraints.cpp NetOptimals.cpp LoadGlobalRouting.cpp + ChipTools.cpp + LayerAssign.cpp + PreRouteds.cpp ) set( pyCpps PyAnabaticEngine.cpp PyGraphicAnabaticEngine.cpp diff --git a/anabatic/src/ChipTools.cpp b/anabatic/src/ChipTools.cpp new file mode 100644 index 00000000..2b341058 --- /dev/null +++ b/anabatic/src/ChipTools.cpp @@ -0,0 +1,191 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ChipTools.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Warning.h" +#include "hurricane/Bug.h" +#include "hurricane/Torus.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/AllianceFramework.h" +#include "anabatic/Session.h" +#include "anabatic/AutoContact.h" +#include "anabatic/AutoSegment.h" +#include "anabatic/AutoHorizontal.h" +#include "anabatic/AutoVertical.h" +#include "anabatic/GCell.h" +#include "anabatic/AnabaticEngine.h" + + +namespace { + + using namespace std; + using namespace CRL; + using namespace Hurricane; + using namespace Anabatic; + + + enum SegmentType { LocalSegments=0x10, GlobalSegments=0x20 }; + + + bool isChip ( Cell* cell, Instance*& core, Cell*& referencePad ) + { + AllianceFramework* af = AllianceFramework::get(); + int pads = 0; + int cores = 0; + + core = NULL; + referencePad = NULL; + forEach ( Instance*, iinstance, cell->getInstances() ) { + if ( af->isPad(iinstance->getMasterCell()) ) { + ++pads; + if (not referencePad) + referencePad = iinstance->getMasterCell(); + } else { + ++cores; + core = *iinstance; + } + } + + return (pads > 0) and (cores == 1); + } + + + void reselectPadRp ( Cell* cell ) + { + AllianceFramework* af = AllianceFramework::get(); + + forEach ( Net*, inet, cell->getNets() ) { + if ( inet->getType() == Net::Type::GROUND ) continue; + if ( inet->getType() == Net::Type::POWER ) continue; + if ( inet->getType() == Net::Type::CLOCK ) continue; + + forEach ( RoutingPad*, irp, inet->getRoutingPads() ) { + Instance* instance = irp->getOccurrence().getPath().getTailInstance(); + if ( instance ) { + Cell* masterCell = instance->getMasterCell(); + if ( af->isPad(masterCell) ) + irp->setOnBestComponent(RoutingPad::LowestLayer); + } + } // RoutingPad*. + } // Net*. + } + + +} // End of anonymous namespace. + + +namespace Anabatic { + + + void AnabaticEngine::chipPrep () + { + if (isChip()) { + reselectPadRp( getCell() ); + } + } + + + ChipTools::ChipTools ( Cell* cell ) + : _cell (cell) + , _core (NULL) + , _referencePad (NULL) + , _isChip (false) + , _chipBb (cell->getBoundingBox()) + , _leftPadsBb () + , _rightPadsBb () + , _topPadsBb () + , _bottomPadsBb () + , _chipCorona () + , _padWidth (0) + , _padHeight (0) + , _padPowerWidth(0) + , _padClockWidth(0) + { + _isChip = ::isChip( _cell, _core, _referencePad ); + + if (_isChip) { + _padHeight = _referencePad->getAbutmentBox().getHeight(); + _padWidth = _referencePad->getAbutmentBox().getWidth(); + + Box outer = _cell->getBoundingBox().inflate ( -_padHeight ); + _chipCorona = Torus ( outer, _core->getBoundingBox() ); + _leftPadsBb = Box ( _chipBb.getXMin() , _chipBb.getYMin(), _chipCorona.getOuterBox().getXMin(), _chipBb.getYMax() ); + _rightPadsBb = Box ( _chipCorona.getOuterBox().getXMax(), _chipBb.getYMin(), _chipBb.getXMax(), _chipBb.getYMax() ); + _bottomPadsBb = Box ( _chipBb.getXMin() , _chipBb.getYMin(), _chipBb.getXMax(), _chipCorona.getOuterBox().getYMin() ); + _topPadsBb = Box ( _chipBb.getXMin(), _chipCorona.getOuterBox().getYMax(), _chipBb.getXMax(), _chipBb.getYMax() ); + + Layer* metal3 = DataBase::getDB()->getTechnology()->getLayer( "METAL3" ); + Net* net = _referencePad->getNet( "ck" ); + forEach ( Horizontal*, ihorizontal, net->getHorizontals() ) { + if (ihorizontal->getLayer() == metal3) { + _padClockWidth = ihorizontal->getWidth(); + break; + } + } + net = _referencePad->getNet( "vddi" ); + forEach ( Horizontal*, ihorizontal, net->getHorizontals() ) { + if (ihorizontal->getLayer() == metal3) { + _padPowerWidth = ihorizontal->getWidth(); + break; + } + } + + cmess1 << " o Design is a complete chip." << endl; + cmess1 << " - Core: <" << _core->getName() << ">/<" + << _core->getMasterCell()->getName() << ">." << endl; + cmess1 << " - Reference pad: <" << _referencePad->getName() << ">" << endl; + cmess1 << " - Corona: " << _chipCorona << "." << endl; + } else { + _chipCorona = Torus ( _cell->getBoundingBox(), _cell->getBoundingBox() ); + } + } + + + string ChipTools::_getString () const + { + ostringstream s; + s << "<" << _getTypeName() << " " << _cell->getName() + << " core:" << getString(((_core) ? _core->getName() : "NULL")) + << ">"; + return s.str(); + } + + + Record* ChipTools::_getRecord () const + { + Record* record = new Record ( _getString() ); + + record->add ( getSlot ( "_cell" , _cell ) ); + record->add ( getSlot ( "_core" , _core ) ); + record->add ( getSlot ( "_referencePad", _referencePad ) ); + record->add ( getSlot ( "_isChip" , &_isChip ) ); + record->add ( getSlot ( "_chipBb" , &_chipBb ) ); + record->add ( getSlot ( "_leftPadsBb" , &_leftPadsBb ) ); + record->add ( getSlot ( "_rightPadsBb" , &_rightPadsBb ) ); + record->add ( getSlot ( "_topPadsBb" , &_topPadsBb ) ); + record->add ( getSlot ( "_bottomPadsBb", &_bottomPadsBb ) ); + record->add ( getSlot ( "_chipCorona" , &_chipCorona ) ); + return record; + } + + +} // End of Anabatic namespace. diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index efe2adc1..b124abd8 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1588,8 +1588,8 @@ namespace Anabatic { cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl; - // if (getAnabatic()->moveUpNetTrunk2(*isegment,globalNets,invalidateds)) - // return true; + if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds)) + return true; } return false; diff --git a/anabatic/src/GlobalRoute.cpp b/anabatic/src/GlobalRoute.cpp index e059d583..faf82910 100644 --- a/anabatic/src/GlobalRoute.cpp +++ b/anabatic/src/GlobalRoute.cpp @@ -133,13 +133,23 @@ namespace Anabatic { stopMeasures(); printMeasures( "Anabatic Grid" ); + + Session::open( this ); + setupSpecialNets(); + setupPreRouteds (); + Session::close(); + startMeasures(); cmess1 << " o Running global routing..." << endl; NetSet netsToRoute; for ( Net* net : cell->getNets() ) { - if (net->isSupply() or net->isClock()) continue; + NetRoutingState* state = getRoutingState( net ); + if (state) { + if (state->isMixedPreRoute()) continue; + } + netsToRoute.insert( net ); } diff --git a/anabatic/src/GraphicAnabaticEngine.cpp b/anabatic/src/GraphicAnabaticEngine.cpp index 79ddb035..643ddcaf 100644 --- a/anabatic/src/GraphicAnabaticEngine.cpp +++ b/anabatic/src/GraphicAnabaticEngine.cpp @@ -435,6 +435,7 @@ namespace Anabatic { { AnabaticEngine* engine = getForFramework( CreateEngine ); engine->loadGlobalRouting( EngineLoadGrByNet ); + engine->layerAssign( EngineNoNetLayerAssign ); } diff --git a/anabatic/src/LayerAssign.cpp b/anabatic/src/LayerAssign.cpp new file mode 100644 index 00000000..d08183a9 --- /dev/null +++ b/anabatic/src/LayerAssign.cpp @@ -0,0 +1,535 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./LayerAssign.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/NetRoutingProperty.h" +#include "hurricane/Layer.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Cell.h" +#include "crlcore/RoutingGauge.h" +#include "anabatic/AutoContact.h" +#include "anabatic/AutoSegment.h" +#include "anabatic/AnabaticEngine.h" + + +namespace Anabatic { + + using Hurricane::DebugSession; + using Hurricane::ForEachIterator; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::NetRoutingExtension; + + + void AnabaticEngine::_desaturate ( unsigned int depth + , set& globalNets + , unsigned long& total + , unsigned long& globals ) + { + if (depth+2 > Session::getConfiguration()->getAllowedDepth()) { + cerr << Warning("Anabatic::_desaturate(): %s, no remaining upper layers." + ,getString(Session::getRoutingGauge()->getRoutingLayer(depth)->getName()).c_str() + ) << endl; + return; + } + + cmess1 << " o Desaturate layer " + << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl; + + GCellDensitySet queue ( depth, getGCells() ); + GCell::Set invalidateds; + + bool optimized = true; + while ( optimized ) { + Session::revalidate (); + optimized = false; + queue.requeue (); + + std::set::const_iterator igcell = queue.getGCells().begin(); + size_t i = 0; + for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) { + cdebug_log(149,0) << "_desaturate: [" << depth << "]:" + << (*igcell)->getDensity(depth) << " " << *igcell << endl; + + if (not (*igcell)->isSaturated(depth)) { + cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl; + for ( ; igcell!=queue.getGCells().end() ; ++igcell ) { + if ( (*igcell)->isSaturated( depth ) ) { + cparanoid << "[ERROR] Still saturated: @" << i << " " << *igcell << endl; + break; + } + } + break; + } + + optimized = (*igcell)->stepNetDesaturate( depth, globalNets, invalidateds ); + if ( optimized ) { + for ( GCell::Set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) { + queue.unqueue( *igcell ); + } + break; + } + } + } + } + + + void AnabaticEngine::_layerAssignByLength ( Net* net, unsigned long& total, unsigned long& global, set& globalNets ) + { + DebugSession::open ( net, 140, 150 ); + + cdebug_log(149,0) << "Anabatic::_layerAssignByLength( " << net << " )" << endl; + cdebug_tabw(145,1); + + bool isGlobal = false; + set globalContacts; + + forEach ( Segment*, isegment, net->getSegments() ) { + total++; + if ( (*isegment)->getLength() > getGlobalThreshold() ) { + if (not isGlobal) { + isGlobal = true; + globalNets.insert( net ); + } + + global++; + if ((*isegment)->getLayer() == Session::getRoutingLayer(1)) (*isegment)->setLayer( Session::getRoutingLayer(3) ); + if ((*isegment)->getLayer() == Session::getRoutingLayer(2)) (*isegment)->setLayer( Session::getRoutingLayer(4) ); + } + } + + cdebug_tabw(145,-1); + + DebugSession::close(); + } + + + void AnabaticEngine::_layerAssignByLength ( unsigned long& total, unsigned long& global, set& globalNets ) + { + cmess1 << " o Assign Layer (simple wirelength)." << endl; + + forEach ( Net* , inet , getCell()->getNets() ) { + if (NetRoutingExtension::get(*inet)->isAutomaticGlobalRoute()) { + _layerAssignByLength ( *inet, total, global, globalNets ); + } + } // forEach(Net*) + } + + + void AnabaticEngine::_layerAssignByTrunk ( Net* net, set& globalNets, unsigned long& total, unsigned long& global ) + { + DebugSession::open( net, 140, 150 ); + + cdebug_log(149,0) << "Anabatic::_layerAssignByTrunk ( " << net << " )" << endl; + cdebug_tabw(145,1); + + bool isGlobal = false; + unsigned long netGlobal = 0; + unsigned long netTotal = 0; + set globalContacts; + + forEach ( Segment*, isegment, net->getSegments() ) { + netTotal++; + + if ((*isegment)->getLength() > getGlobalThreshold()) { + isGlobal = true; + netTotal = 0; + globalNets.insert( net ); + break; + } + } + + if (isGlobal) { + forEach ( Segment*, isegment, net->getSegments() ) { + netTotal++; + + AutoSegment* autoSegment = Session::lookup( *isegment ); + if ( autoSegment and not autoSegment->isStrongTerminal() ) { + netGlobal++; + + cdebug_log(145,0) << "Migrate to M4/M5: " << autoSegment << endl; + if (autoSegment->isHorizontal()) autoSegment->setLayer( Session::getRoutingLayer(3) ); + if (autoSegment->isVertical ()) autoSegment->setLayer( Session::getRoutingLayer(4) ); + } + } + } + + total += netTotal; + global += netGlobal; + + cdebug_tabw(145,-1); + + DebugSession::close(); + } + + + void AnabaticEngine::_layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& globalNets ) + { + cmess1 << " o Assign Layer (whole net trunk)." << endl; + + forEach ( Net* , inet , getCell()->getNets() ) { + if (NetRoutingExtension::get(*inet)->isAutomaticGlobalRoute()) { + _layerAssignByTrunk( *inet, globalNets, total, global ); + } + } + } + + +#if THIS_IS_DISABLED + void AnabaticEngine::moveULeft ( AutoSegment* seed, set& globalNets, GCell::Set& invalidateds ) + { + Net* net = seed->getNet(); + DebugSession::open( net, 140, 150 ); + + cdebug_log(9000,0) << "Deter| Move left: " << seed << endl; + + seed->moveULeft(); + globalNets.insert( net ); + + GCell* begin = seed->getAutoSource()->getGCell(); + GCell* end = seed->getAutoTarget()->getGCell(); + + if (seed->isHorizontal()) { + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() ) + invalidateds.insert( gcell ); + + begin = begin->getDown(); + end = end ->getDown(); + + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() ) + invalidateds.insert( gcell ); + } else { + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() ) + invalidateds.insert( gcell ); + + begin = begin->getLeft(); + end = end ->getLeft(); + + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() ) + invalidateds.insert( gcell ); + } + + DebugSession::close(); + } + + + void AnabaticEngine::moveURight ( AutoSegment* seed, set& globalNets, GCell::Set& invalidateds ) + { + Net* net = seed->getNet(); + DebugSession::open( net, 140, 150 ); + + cdebug_log(9000,0) << "Deter| Move right: " << seed << endl; + + seed->moveURight(); + globalNets.insert( net ); + + GCell* begin = seed->getAutoSource()->getGCell(); + GCell* end = seed->getAutoTarget()->getGCell(); + + if (seed->isHorizontal()) { + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() ) + invalidateds.insert( gcell ); + + begin = begin->getUp(); + end = end ->getUp(); + + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() ) + invalidateds.insert( gcell ); + } else { + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() ) + invalidateds.insert( gcell ); + + begin = begin->getRight(); + end = end ->getRight(); + + for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() ) + invalidateds.insert( gcell ); + } + + DebugSession::close(); + } +#endif + + + bool AnabaticEngine::moveUpNetTrunk ( AutoSegment* seed, set& globalNets, GCell::Set& invalidateds ) + { + Net* net = seed->getNet(); + unsigned int seedDepth = Session::getRoutingGauge()->getLayerDepth(seed->getLayer()); + + DebugSession::open( net, 140, 150 ); + cdebug_log(9000,0) << "Deter| moveUpNetTrunk() depth:" << seedDepth << " " << seed << endl; + + if (not seed->canMoveUp( 1.0, Flags::Propagate|Flags::AllowTerminal|Flags::NoCheckLayer) ) { + cdebug_log(9000,0) << "Deter| Reject seed move up, cannot move up." << endl; + DebugSession::close(); + return false; + } + cdebug_tabw(149,1); + + globalNets.insert( net ); + + vector< pair > stack; + vector globals; + vector locals; + + stack.push_back( pair(NULL,seed) ); + while ( not stack.empty() ) { + AutoContact* from = stack.back().first; + AutoSegment* segment = stack.back().second; + stack.pop_back(); + + if (segment->isLocal()) { + if (not segment->isStrongTerminal()) locals.push_back( segment ); + continue; + } + if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) { + locals.push_back( segment ); + continue; + } + + // Do something here. + if (not segment->canMoveUp( 1.0 + , Flags::Propagate + | Flags::AllowTerminal + | Flags::NoCheckLayer + | Flags::CheckLowDensity + ) ) continue; + + globals.push_back( segment ); + + AutoContact* source = segment->getAutoSource(); + if (source != from) { + for ( AutoSegment* connected : source->getAutoSegments() ) { + if (connected != segment) { stack.push_back( make_pair(source,connected) ); } + } + } + AutoContact* target = segment->getAutoTarget(); + if (target != from) { + for ( AutoSegment* connected : target->getAutoSegments() ) { + if (connected != segment) { stack.push_back( make_pair(target,connected) ); } + } + } + } + + for ( size_t i=0 ; igetLayerDepth( globals[i]->getLayer() ); + globals[i]->changeDepth( depth+2, Flags::WithNeighbors ); + + vector gcells; + globals[i]->getGCells( gcells ); + for ( size_t j=0 ; jgetLayerDepth(locals[i]->getLayer()); + if (depth > seedDepth+1) continue; + + if (locals[i]->canPivotUp(2.0,Flags::Propagate|Flags::NoCheckLayer)) { + locals[i]->changeDepth( depth+2, Flags::WithNeighbors ); + + //cdebug_log(9000,0) << "Deter| Trunk move up L:" << locals[i] << endl; + + vector gcells; + locals[i]->getGCells( gcells ); + for ( size_t j=0 ; jgetRoutingLayer(depth)->getName() << endl; + + GCellDensitySet queue ( depth, getGCells()) ); + GCell::Set invalidateds; + + bool optimized = true; + while ( optimized ) { + Session::revalidate(); + optimized = false; + queue.requeue(); + + std::set::const_iterator igcell = queue.getGCells().begin(); + size_t i = 0; + for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) { + cdebug_log(149,0) << "_balance: [" << depth << "]:" + << (*igcell)->getDensity(depth) << " " << *igcell << endl; + + if (not (*igcell)->isSaturated(depth)) { + cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl; + for ( ; igcell!=queue.getGCells().end() ; ++igcell ) { + if ((*igcell)->isSaturated(depth)) { + cparanoid << Error( "Still saturated: @%d %s", i, getString(*igcell).c_str() ) << endl; + break; + } + } + break; + } + + optimized = (*igcell)->stepBalance( depth, invalidateds ); + if (optimized) { + for ( GCell::Set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) { + queue.unqueue( *igcell ); + } + break; + } + } + } + + + Session::close(); + stopMeasures(); + printMeasures( "balance" ); + } + + + void AnabaticEngine::balanceGlobalDensity () + { + cdebug_log(9000,0) << "Deter| Balance Global Density" << endl; + + //_balanceGlobalDensity( 1 ); // metal2 + //_balanceGlobalDensity( 2 ); // metal3 + + set globalNets; + GCell::Set invalidateds; + + Session::open( this ); + + vector segments; + + AutoSegmentLut::iterator ilut = _autoSegmentLut.begin(); + for ( ; ilut!=_autoSegmentLut.end() ; ++ilut ) { + AutoSegment* segment = (*ilut).second; + + if (segment->isLocal() or segment->isFixed()) continue; + if (not segment->isCanonical()) continue; + + segments.push_back( segment ); + } + + // Sort on id before moving to ensure determinism. + sort( segments.begin(), segments.end(), AutoSegment::CompareId() ); + + for ( size_t i=0 ; icanMoveULeft(0.10)) { + moveULeft(segments[i],globalNets,invalidateds); + } else if (segments[i]->canMoveURight(0.10)) { + moveURight(segments[i],globalNets,invalidateds); + } + + for ( GCell::Set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) { + (*igcell)->updateDensity(); + } + invalidateds.clear(); + Session::revalidate(); + } + + Session::close(); + } +#endif + + + void AnabaticEngine::layerAssign ( unsigned int method ) + { + cdebug_log(9000,0) << "Deter| Layer Assignment" << endl; + + set globalNets; + + unsigned long total = 0; + unsigned long global = 0; + + startMeasures(); + Session::open( this ); + + if (Session::getAllowedDepth() >= 3) { + switch ( method ) { + case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break; + case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break; + case EngineNoNetLayerAssign: break; + default: + stopMeasures(); + Session::close(); + throw Error( badMethod + , "Anabatic::layerAssign()" + , method + , getString(_cell).c_str() + ); + } + + globalNets.clear(); + Session::revalidate(); + + if (getConfiguration()->getAllowedDepth() > 2) { + for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) { + _desaturate( depth, globalNets, total, global ); + if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate(); + } + + globalNets.clear (); + Session::revalidate(); + } + +#if defined(CHECK_DATABASE) + _check( "after layer assignment" ); +#endif + + Session::setAnabaticFlags( Flags::WarnOnGCellOverload ); + } + + checkGCellDensities(); + Session::close(); + + stopMeasures(); + printMeasures( "assign" ); + + // cmess2 << " - Total segments : " << total << endl; + // cmess2 << " - Global segments : " << global << endl; + // cmess2 << " - Ratio : " + // << ((float)global/(float)total)*100.0 << "%." << endl; + } + + +} // Anabatic namespace. diff --git a/anabatic/src/PreRouteds.cpp b/anabatic/src/PreRouteds.cpp new file mode 100644 index 00000000..341929c7 --- /dev/null +++ b/anabatic/src/PreRouteds.cpp @@ -0,0 +1,173 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2014-2016, 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++ Module : "./PreRouteds.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Warning.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/DeepNet.h" +#include "hurricane/Pin.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/AllianceFramework.h" +#include "anabatic/AnabaticEngine.h" + + +namespace Anabatic { + + using std::cerr; + using std::cout; + using std::endl; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::BasicLayer; + using Hurricane::RegularLayer; + using Hurricane::Component; + using Hurricane::Pin; + using Hurricane::DeepNet; + using Hurricane::Cell; + using Hurricane::NetRoutingExtension; + using CRL::RoutingGauge; + using CRL::RoutingLayerGauge; + using CRL::AllianceFramework; + + + void AnabaticEngine::setupSpecialNets () + { + AllianceFramework* af = AllianceFramework::get(); + for ( Net* net : _cell->getNets() ) { + const char* excludedType = NULL; + if (net->getType() == Net::Type::POWER ) excludedType = "POWER"; + if (net->getType() == Net::Type::GROUND) excludedType = "GROUND"; + if (excludedType) { + cparanoid << Warning( "%s is not a routable net (%s,excluded)." + , getString(net).c_str(), excludedType ) << endl; + } + if (af->isBLOCKAGE(net->getName())) excludedType = "BLOCKAGE"; + if (excludedType) { + NetRoutingState* state = getRoutingState( net, Flags::Create ); + state->setFlags( NetRoutingState::Fixed ); + } + } + } + + + + void AnabaticEngine::setupPreRouteds () + { + cmess1 << " o Looking for fixed or manually global routed nets." << endl; + + for ( Net* net : getCell()->getNets() ) { + if (net == _blockageNet) continue; + if (net->getType() == Net::Type::POWER ) continue; + if (net->getType() == Net::Type::GROUND) continue; + // Don't skip the clock. + + vector segments; + vector contacts; + + bool isPreRouted = false; + bool isFixed = false; + size_t rpCount = 0; + + if (net->isDeepNet()) { + rpCount = 2; + + Net* rootNet = dynamic_cast( + dynamic_cast(net)->getRootNetOccurrence().getEntity() ); + for( Component* component : rootNet->getComponents() ) { + if (dynamic_cast(component)) { isFixed = true; break; } + if (dynamic_cast (component)) { isFixed = true; break; } + if (dynamic_cast (component)) { isFixed = true; break; } + } + } else { + for( Component* component : net->getComponents() ) { + if (dynamic_cast(component)) continue; + + const RegularLayer* layer = dynamic_cast(component->getLayer()); + if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage)) + continue; + + Horizontal* horizontal = dynamic_cast(component); + if (horizontal) { + segments.push_back( horizontal ); + isPreRouted = true; + if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer())) + isFixed = true; + } else { + Vertical* vertical = dynamic_cast(component); + if (vertical) { + isPreRouted = true; + segments.push_back( vertical ); + if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer())) + isFixed = true; + } else { + Contact* contact = dynamic_cast(component); + if (contact) { + isPreRouted = true; + contacts.push_back( contact ); + if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer())) + or (contact->getHeight() != Session::getViaWidth(contact->getLayer())) ) + isFixed = true; + } else { + RoutingPad* rp = dynamic_cast(component); + if (rp) { + ++rpCount; + } else { + // Plug* plug = dynamic_cast(component); + // if (plug) { + // cerr << "buildPreRouteds(): " << plug << endl; + // ++rpCount; + // } + } + } + } + } + } + } + + if (isFixed or isPreRouted or (rpCount < 2)) { + NetRoutingState* state = getRoutingState( net, Flags::Create ); + state->unsetFlags( NetRoutingState::AutomaticGlobalRoute ); + state->setFlags ( NetRoutingState::ManualGlobalRoute ); + if (rpCount < 2) + state->setFlags ( NetRoutingState::Unconnected ); + + if (isFixed) { + cmess2 << " - <" << net->getName() << "> is fixed." << endl; + state->unsetFlags( NetRoutingState::ManualGlobalRoute ); + state->setFlags ( NetRoutingState::Fixed ); + } else { + if (rpCount > 1) { + cmess2 << " - <" << net->getName() << "> is manually global routed." << endl; + for ( auto icontact : contacts ) { + AutoContact::createFrom( icontact ); + } + + for ( auto isegment : segments ) { + AutoContact* source = Session::lookup( dynamic_cast( isegment->getSource() )); + AutoContact* target = Session::lookup( dynamic_cast( isegment->getTarget() )); + AutoSegment* autoSegment = AutoSegment::create( source, target, isegment ); + autoSegment->setFlags( SegUserDefined|SegAxisSet ); + } + } + } + } + } + + Session::revalidate(); + } + + +} // Anabatic namespace. diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 468accfc..011db3ba 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -22,10 +22,8 @@ #include #include "hurricane/Timer.h" +#include "hurricane/NetRoutingProperty.h" namespace Hurricane { - class Name; - class Net; - class Cell; class Instance; class CellViewer; } @@ -36,6 +34,7 @@ namespace Hurricane { #include "anabatic/GCell.h" #include "anabatic/AutoContact.h" #include "anabatic/AutoSegments.h" +#include "anabatic/ChipTools.h" namespace Anabatic { @@ -48,10 +47,12 @@ namespace Anabatic { using Hurricane::Interval; using Hurricane::Cell; using Hurricane::CellViewer; + using Hurricane::NetRoutingState; using CRL::ToolEngine; - typedef std::set NetSet; + typedef std::set NetSet; + typedef std::map NetRoutingStates; class AnabaticEngine : public ToolEngine { @@ -67,138 +68,159 @@ namespace Anabatic { public: typedef ToolEngine Super; public: - static AnabaticEngine* create ( Cell* ); - static AnabaticEngine* get ( const Cell* ); - static const Name& staticGetName (); - virtual const Name& getName () const; - virtual Configuration* getConfiguration (); - inline unsigned int getDensityMode () const; - inline CellViewer* getViewer () const; - inline void setViewer ( CellViewer* ); - inline EngineState getState () const; - inline const Matrix* getMatrix () const; - inline const vector& getGCells () const; - inline const vector& getOvEdges () const; - inline GCell* getSouthWestGCell () const; - inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; - inline GCell* getGCellUnder ( Point ) const; - int getCapacity ( Interval, Flags ) const; - size_t getNetsFromEdge ( const Edge*, NetSet& ); - inline void setState ( EngineState state ); - inline void setDensityMode ( unsigned int ); - inline void addOv ( Edge* ); - inline void removeOv ( Edge* ); - // Dijkstra related functions. - inline int getStamp () const; - inline int incStamp (); + static AnabaticEngine* create ( Cell* ); + static AnabaticEngine* get ( const Cell* ); + static const Name& staticGetName (); + virtual const Name& getName () const; + virtual Configuration* getConfiguration (); + inline unsigned int getDensityMode () const; + inline CellViewer* getViewer () const; + inline void setViewer ( CellViewer* ); + inline EngineState getState () const; + inline const Matrix* getMatrix () const; + inline const vector& getGCells () const; + inline const vector& getOvEdges () const; + inline GCell* getSouthWestGCell () const; + inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; + inline GCell* getGCellUnder ( Point ) const; + int getCapacity ( Interval, Flags ) const; + size_t getNetsFromEdge ( const Edge*, NetSet& ); + inline void setState ( EngineState state ); + inline void setDensityMode ( unsigned int ); + inline void addOv ( Edge* ); + inline void removeOv ( Edge* ); + // Dijkstra related functions. + inline int getStamp () const; + inline int incStamp (); // Global routing related functions. - void globalRoute (); - void cleanupGlobal (); + void globalRoute (); + void cleanupGlobal (); // Detailed routing related functions. - inline bool isInDemoMode () const; - inline bool doWarnOnGCellOverload () const; - inline bool doDestroyBaseContact () const; - inline bool doDestroyBaseSegment () const; - inline bool doDestroyTool () const; - inline DbU::Unit getGlobalThreshold () const; - inline float getSaturateRatio () const; - inline size_t getSaturateRp () const; - inline DbU::Unit getExtensionCap () const; - void updateDensity (); - inline void setGlobalThreshold ( DbU::Unit ); - inline void setSaturateRatio ( float ); - inline void setSaturateRp ( size_t ); - void loadGlobalRouting ( unsigned int method ); - void computeNetConstraints ( Net* ); - void toOptimals ( Net* ); - void updateNetTopology ( Net* ); - void finalizeLayout (); - inline const AutoContactLut& _getAutoContactLut () const; - inline const AutoSegmentLut& _getAutoSegmentLut () const; - void _link ( AutoContact* ); - void _link ( AutoSegment* ); - void _unlink ( AutoContact* ); - void _unlink ( AutoSegment* ); - AutoContact* _lookup ( Contact* ) const; - AutoSegment* _lookup ( Segment* ) const; - void _loadGrByNet (); - void _loadNetGlobalRouting ( Net* ); - void _computeNetOptimals ( Net* ); - void _computeNetTerminals ( Net* ); - void _alignate ( Net* ); - void _saveNet ( Net* ); - void _destroyAutoContacts (); - void _destroyAutoSegments (); - // Misc. functions. - inline const Flags& flags () const; - inline Flags& flags (); - void reset (); - void startMeasures (); - void stopMeasures (); - void printMeasures ( const string& ) const; - inline void _add ( GCell* ); - inline void _remove ( GCell* ); - inline void _updateLookup ( GCell* ); - inline bool _inDestroy () const; - // Inspector support. - virtual Record* _getRecord () const; - virtual string _getString () const; - virtual string _getTypeName () const; + inline bool isInDemoMode () const; + inline bool isChip () const; + inline bool doWarnOnGCellOverload () const; + inline bool doDestroyBaseContact () const; + inline bool doDestroyBaseSegment () const; + inline bool doDestroyTool () const; + inline DbU::Unit getGlobalThreshold () const; + inline float getSaturateRatio () const; + inline size_t getSaturateRp () const; + inline DbU::Unit getExtensionCap () const; + inline Net* getBlockageNet () const; + inline const NetRoutingStates& getNetRoutingStates () const; + NetRoutingState* getRoutingState ( Net*, unsigned int flags=Flags::NoFlags ); + void updateDensity (); + size_t checkGCellDensities (); + inline void setGlobalThreshold ( DbU::Unit ); + inline void setSaturateRatio ( float ); + inline void setSaturateRp ( size_t ); + void chipPrep (); + void setupSpecialNets (); + void setupPreRouteds (); + void loadGlobalRouting ( unsigned int method ); + void computeNetConstraints ( Net* ); + void toOptimals ( Net* ); + void updateNetTopology ( Net* ); + bool moveUpNetTrunk ( AutoSegment*, set& globalNets, GCell::Set& invalidateds ); + void layerAssign ( unsigned int method ); + void finalizeLayout (); + inline const AutoContactLut& _getAutoContactLut () const; + inline const AutoSegmentLut& _getAutoSegmentLut () const; + void _link ( AutoContact* ); + void _link ( AutoSegment* ); + void _unlink ( AutoContact* ); + void _unlink ( AutoSegment* ); + AutoContact* _lookup ( Contact* ) const; + AutoSegment* _lookup ( Segment* ) const; + void _loadGrByNet (); + void _loadNetGlobalRouting ( Net* ); + void _computeNetOptimals ( Net* ); + void _computeNetTerminals ( Net* ); + void _alignate ( Net* ); + void _desaturate ( unsigned int depth, set&, unsigned long& total, unsigned long& globals ); + void _layerAssignByLength ( unsigned long& total, unsigned long& global, set& ); + void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set& ); + void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& ); + void _layerAssignByTrunk ( Net*, set&, unsigned long& total, unsigned long& global ); + void _saveNet ( Net* ); + void _destroyAutoContacts (); + void _destroyAutoSegments (); + // Misc. functions. + inline const Flags& flags () const; + inline Flags& flags (); + void reset (); + void startMeasures (); + void stopMeasures (); + void printMeasures ( const string& ) const; + inline void _add ( GCell* ); + inline void _remove ( GCell* ); + inline void _updateLookup ( GCell* ); + inline bool _inDestroy () const; + // Inspector support. + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; protected: - AnabaticEngine ( Cell* ); - virtual ~AnabaticEngine (); - virtual void _postCreate (); - virtual void _preDestroy (); - void _gutAnabatic (); - private: - AnabaticEngine ( const AnabaticEngine& ); - AnabaticEngine& operator= ( const AnabaticEngine& ); + AnabaticEngine ( Cell* ); + virtual ~AnabaticEngine (); + virtual void _postCreate (); + virtual void _preDestroy (); + void _gutAnabatic (); + private: + AnabaticEngine ( const AnabaticEngine& ); + AnabaticEngine& operator= ( const AnabaticEngine& ); private: - static Name _toolName; - Timer _timer; - Configuration* _configuration; - EngineState _state; - Matrix _matrix; - vector _gcells; - vector _ovEdges; - CellViewer* _viewer; - Flags _flags; - int _stamp; - unsigned int _densityMode; - AutoSegmentLut _autoSegmentLut; - AutoContactLut _autoContactLut; + static Name _toolName; + Timer _timer; + Configuration* _configuration; + ChipTools _chipTools; + EngineState _state; + Matrix _matrix; + vector _gcells; + vector _ovEdges; + CellViewer* _viewer; + Flags _flags; + int _stamp; + unsigned int _densityMode; + AutoSegmentLut _autoSegmentLut; + AutoContactLut _autoContactLut; + NetRoutingStates _netRoutingStates; + Net* _blockageNet; }; - 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 unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; } - inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; } - 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::isInDemoMode () const { return _flags & Flags::DemoMode; } - 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 void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } - inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } - inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } + 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 unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; } + inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; } + 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::isInDemoMode () const { return _flags & Flags::DemoMode; } + inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); } + 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 Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; } + inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } + inline const NetRoutingStates& AnabaticEngine::getNetRoutingStates () const { return _netRoutingStates; } + inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } + inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } inline void AnabaticEngine::_add ( GCell* gcell ) { @@ -227,6 +249,9 @@ namespace Anabatic { if (*iedge == edge) { _ovEdges.erase(iedge); break; } } + + extern const char* badMethod; + } // Anabatic namespace. diff --git a/anabatic/src/anabatic/ChipTools.h b/anabatic/src/anabatic/ChipTools.h new file mode 100644 index 00000000..92635ca1 --- /dev/null +++ b/anabatic/src/anabatic/ChipTools.h @@ -0,0 +1,118 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./anabatic/ChipTools.h" | +// +-----------------------------------------------------------------+ + + +#ifndef ANABATIC_CHIP_TOOLS_H +#define ANABATIC_CHIP_TOOLS_H + +#include +#include "hurricane/DbU.h" +#include "hurricane/Torus.h" +namespace Hurricane { + class Cell; + class Instance; +} + + +namespace Anabatic { + + using Hurricane::Record; + using Hurricane::DbU; + using Hurricane::Box; + using Hurricane::Torus; + using Hurricane::Cell; + using Hurricane::Instance; + + + class ChipTools { + public: + ChipTools ( Cell* ); + inline bool isChip () const; + inline Cell* getCell () const; + inline Instance* getCore () const; + inline Cell* getReferencePad () const; + inline DbU::Unit getPadWidth () const; + inline DbU::Unit getPadHeight () const; + inline DbU::Unit getPadPowerWidth () const; + inline DbU::Unit getPadClockWidth () const; + inline const Box& getChipBb () const; + inline const Box& getLeftPadsBb () const; + inline const Box& getRightPadsBb () const; + inline const Box& getTopPadsBb () const; + inline const Box& getBottomPadsBb () const; + inline const Torus& getCorona () const; + inline const Box& getCoronaBb () const; + inline bool intersectVPads ( const Box& ) const; + inline bool intersectHPads ( const Box& ) const; + inline bool vPadsEnclosed ( const Box& ) const; + inline bool hPadsEnclosed ( const Box& ) const; + public: + Record* _getRecord () const; + std::string _getString () const; + inline std::string _getTypeName () const; + private: + Cell* _cell; + Instance* _core; + Cell* _referencePad; + bool _isChip; + Box _chipBb; + Box _leftPadsBb; + Box _rightPadsBb; + Box _topPadsBb; + Box _bottomPadsBb; + Torus _chipCorona; + DbU::Unit _padWidth; + DbU::Unit _padHeight; + DbU::Unit _padPowerWidth; + DbU::Unit _padClockWidth; + }; + + +// Inline Functions. + inline bool ChipTools::isChip () const { return _isChip; } + inline Cell* ChipTools::getCell () const { return _cell; } + inline Instance* ChipTools::getCore () const { return _core; } + inline Cell* ChipTools::getReferencePad () const { return _referencePad; } + inline DbU::Unit ChipTools::getPadWidth () const { return _padWidth; } + inline DbU::Unit ChipTools::getPadHeight () const { return _padHeight; } + inline DbU::Unit ChipTools::getPadPowerWidth () const { return _padPowerWidth; } + inline DbU::Unit ChipTools::getPadClockWidth () const { return _padClockWidth; } + inline const Box& ChipTools::getChipBb () const { return _chipBb; } + inline const Box& ChipTools::getLeftPadsBb () const { return _leftPadsBb; }; + inline const Box& ChipTools::getRightPadsBb () const { return _rightPadsBb; }; + inline const Box& ChipTools::getTopPadsBb () const { return _topPadsBb; }; + inline const Box& ChipTools::getBottomPadsBb () const { return _bottomPadsBb; }; + inline const Torus& ChipTools::getCorona () const { return _chipCorona; }; + inline const Box& ChipTools::getCoronaBb () const { return _chipCorona.getOuterBox(); } + inline std::string ChipTools::_getTypeName () const { return "ChipTools"; } + + inline bool ChipTools::intersectVPads ( const Box& box ) const + { return _leftPadsBb.intersect(box) or _rightPadsBb.intersect(box); } + + inline bool ChipTools::intersectHPads ( const Box& box ) const + { return _topPadsBb.intersect(box) or _bottomPadsBb.intersect(box); } + + inline bool ChipTools::vPadsEnclosed ( const Box& box ) const + { return _leftPadsBb.contains(box) or _rightPadsBb.contains(box); } + + inline bool ChipTools::hPadsEnclosed ( const Box& box ) const + { return _topPadsBb.contains(box) or _bottomPadsBb.contains(box); } + + +} // Anabatic namespace. + +INSPECTOR_PV_SUPPORT(Anabatic::ChipTools); + +#endif // ANABATIC_CHIP_TOOLS_H