// -*- mode: C++; explicit-buffer-name: "Configuration.cpp" -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC 2008-2016, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | K a t a b a t i c - Routing Toolbox | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./Configuration.cpp" | // +-----------------------------------------------------------------+ #include #include #include #include "vlsisapd/configuration/Configuration.h" #include "hurricane/Warning.h" #include "hurricane/Error.h" #include "hurricane/Technology.h" #include "hurricane/DataBase.h" #include "hurricane/RegularLayer.h" #include "hurricane/Cell.h" #include "crlcore/Utilities.h" #include "crlcore/CellGauge.h" #include "crlcore/RoutingGauge.h" #include "crlcore/RoutingLayerGauge.h" #include "crlcore/AllianceFramework.h" #include "katabatic/Configuration.h" namespace Katabatic { using std::cout; using std::cerr; using std::endl; using std::setprecision; using std::ostringstream; using std::vector; using Hurricane::tab; using Hurricane::Warning; using Hurricane::Error; using Hurricane::Technology; using Hurricane::DataBase; using Hurricane::RegularLayer; using CRL::AllianceFramework; using CRL::RoutingGauge; using CRL::RoutingLayerGauge; // ------------------------------------------------------------------- // Class : "Katabatic::Configuration". Configuration::Configuration () { } Configuration::~Configuration () { } // ------------------------------------------------------------------- // Class : "Katabatic::ConfigurationConcrete". ConfigurationConcrete::ConfigurationConcrete ( const CellGauge* cg, const RoutingGauge* rg ) : Configuration () , _cg (NULL) , _rg (NULL) , _extensionCaps () , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble()) , _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt()) , _globalThreshold(0) , _allowedDepth (0) , _hEdgeCapacity (0) , _vEdgeCapacity (0) { if (cg == NULL) cg = AllianceFramework::get()->getCellGauge(); if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge(); _cg = cg->getClone(); _rg = rg->getClone(); if (Cfg::hasParameter("katabatic.topRoutingLayer")) { _setTopRoutingLayer( Cfg::getParamString("katabatic.topRoutingLayer")->asString() ); } else _allowedDepth = rg->getDepth()-1; _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh"); _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv"); _gcontact = DataBase::getDB()->getTechnology()->getLayer("gcontact"); if (_gcontact == NULL) cerr << Warning("Cannot get \"gcontact\" layer from the Technology.") << endl; if (_gmetalv == NULL) cerr << Warning("Cannot get \"gmetalv\" layer from the Technology.") << endl; if (_gmetalh == NULL) cerr << Warning("Cannot get \"gmetalh\" layer from the Technology.") << endl; DbU::Unit sliceHeight = _cg->getSliceHeight(); _globalThreshold = DbU::fromLambda ( (double)Cfg::getParamInt("katabatic.globalLengthThreshold",29*DbU::toLambda(sliceHeight))->asInt() ); const vector& layerGauges = rg->getLayerGauges(); for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) { const RegularLayer* regularLayer = dynamic_cast( layerGauges[depth]->getLayer() ); if (regularLayer) _extensionCaps.push_back( regularLayer->getExtentionCap() ); else { _extensionCaps.push_back( 0 ); cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n" " (%s)" , depth , getString(layerGauges[depth]->getLayer()).c_str() ) << endl; } if (layerGauges[depth]->getType() != Constant::Default) continue; if (layerGauges[depth]->getDirection() == Constant::Horizontal) { _hEdgeCapacity += layerGauges[depth]->getTrackNumber( 0, sliceHeight ) - 1; } else if (layerGauges[depth]->getDirection() == Constant::Vertical) { _vEdgeCapacity += layerGauges[depth]->getTrackNumber( 0, sliceHeight ) - 1; } } } ConfigurationConcrete::ConfigurationConcrete ( const ConfigurationConcrete& other ) : Configuration() , _gmetalh (other._gmetalh) , _gmetalv (other._gmetalv) , _gcontact (other._gcontact) , _cg (NULL) , _rg (NULL) , _extensionCaps (other._extensionCaps) , _saturateRatio (other._saturateRatio) , _globalThreshold (other._globalThreshold) , _allowedDepth (other._allowedDepth) { if (other._cg) _cg = other._cg->getClone(); if (other._rg) _rg = other._rg->getClone(); } ConfigurationConcrete::~ConfigurationConcrete () { cdebug_log(145,0) << "About to delete attribute _rg (RoutingGauge)." << endl; _cg->destroy (); _rg->destroy (); } ConfigurationConcrete* ConfigurationConcrete::clone () const { return new ConfigurationConcrete(*this); } bool ConfigurationConcrete::isGMetal ( const Layer* layer ) const { return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); } bool ConfigurationConcrete::isGContact ( const Layer* layer ) const { return (layer and (layer == _gcontact)); } size_t ConfigurationConcrete::getDepth () const { return _rg->getDepth(); } size_t ConfigurationConcrete::getAllowedDepth () const { return _allowedDepth; } size_t ConfigurationConcrete::getLayerDepth ( const Layer* layer ) const { return _rg->getLayerDepth(layer); } CellGauge* ConfigurationConcrete::getCellGauge () const { return _cg; } RoutingGauge* ConfigurationConcrete::getRoutingGauge () const { return _rg; } RoutingLayerGauge* ConfigurationConcrete::getLayerGauge ( size_t depth ) const { return _rg->getLayerGauge(depth); } const Layer* ConfigurationConcrete::getRoutingLayer ( size_t depth ) const { return _rg->getRoutingLayer(depth); } Layer* ConfigurationConcrete::getContactLayer ( size_t depth ) const { return _rg->getContactLayer(depth); } DbU::Unit ConfigurationConcrete::getSliceHeight () const { return _cg->getSliceHeight(); } DbU::Unit ConfigurationConcrete::getSliceStep () const { return _cg->getSliceStep(); } DbU::Unit ConfigurationConcrete::getPitch ( const Layer* layer, unsigned int flags ) const { return getPitch( getLayerDepth(layer), flags ); } DbU::Unit ConfigurationConcrete::getOffset ( const Layer* layer ) const { return getOffset( getLayerDepth(layer) ); } DbU::Unit ConfigurationConcrete::getExtensionCap ( const Layer* layer ) const { return getExtensionCap( getLayerDepth(layer) ); } DbU::Unit ConfigurationConcrete::getWireWidth ( const Layer* layer ) const { return getWireWidth( getLayerDepth(layer) ); } unsigned int ConfigurationConcrete::getDirection ( const Layer* layer ) const { return getDirection( getLayerDepth(layer) ); } DbU::Unit ConfigurationConcrete::getPitch ( size_t depth, unsigned int flags ) const { if (flags == NoFlags) return _rg->getLayerPitch(depth); if (flags & Configuration::PitchAbove) { if (depth < getAllowedDepth()) return _rg->getLayerPitch( depth + 1 ); else { if ( (depth > 0) and (_rg->getLayerType(depth-1) != Constant::PinOnly) ) return _rg->getLayerPitch( depth - 1 ); } } if (flags & Configuration::PitchBelow) { if ( (depth > 0) and (_rg->getLayerType(depth-1) != Constant::PinOnly) ) return _rg->getLayerPitch( depth - 1 ); else { if (depth < getAllowedDepth()) return _rg->getLayerPitch( depth + 1 ); } } // Should issue at least a warning here. return _rg->getLayerPitch(depth); } DbU::Unit ConfigurationConcrete::getOffset ( size_t depth ) const { return _rg->getLayerOffset(depth); } DbU::Unit ConfigurationConcrete::getWireWidth ( size_t depth ) const { return _rg->getLayerWireWidth(depth); } DbU::Unit ConfigurationConcrete::getExtensionCap ( size_t depth ) const { return _extensionCaps[depth]; } unsigned int ConfigurationConcrete::getDirection ( size_t depth ) const { return _rg->getLayerDirection(depth); } float ConfigurationConcrete::getSaturateRatio () const { return _saturateRatio; } size_t ConfigurationConcrete::getSaturateRp () const { return _saturateRp; } DbU::Unit ConfigurationConcrete::getGlobalThreshold () const { return _globalThreshold; } size_t ConfigurationConcrete::getHEdgeCapacity () const { return _hEdgeCapacity; } size_t ConfigurationConcrete::getVEdgeCapacity () const { return _vEdgeCapacity; } void ConfigurationConcrete::setAllowedDepth ( size_t allowedDepth ) { _allowedDepth = (allowedDepth > getDepth()) ? getDepth() : allowedDepth; } void ConfigurationConcrete::_setTopRoutingLayer ( Name name ) { for ( size_t depth=0 ; depth<_rg->getDepth() ; ++depth ) { if (_rg->getRoutingLayer(depth)->getName() == name) { _allowedDepth = _rg->getLayerGauge(depth)->getDepth(); return; } } cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n" " The routing gauge <%s> has no layer named <%s>" , getString(_rg->getName()).c_str() , getString(name).c_str() ) << endl; } void ConfigurationConcrete::setSaturateRatio ( float ratio ) { _saturateRatio = ratio; } void ConfigurationConcrete::setSaturateRp ( size_t threshold ) { _saturateRp = threshold; } void ConfigurationConcrete::setGlobalThreshold ( DbU::Unit threshold ) { _globalThreshold = threshold; } void ConfigurationConcrete::print ( Cell* cell ) const { string topLayerName = "UNKOWN"; const Layer* topLayer = _rg->getRoutingLayer( _allowedDepth ); if (topLayer) topLayerName = getString( topLayer->getName() ); cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl; cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl; cout << Dots::asPercentage(" - GCell saturation threshold" ,_saturateRatio) << endl; cout << Dots::asDouble (" - Long global length threshold",DbU::toLambda(_globalThreshold)) << endl; } string ConfigurationConcrete::_getTypeName () const { return "ConfigurationConcrete"; } string ConfigurationConcrete::_getString () const { ostringstream os; os << "<" << _getTypeName() << " " << _rg->getName() << ">"; return os.str(); } Record* ConfigurationConcrete::_getRecord () const { Record* record = new Record ( _getString() ); record->add ( getSlot ( "_rg" , _rg ) ); record->add ( getSlot ( "_gmetalh" , _gmetalh ) ); record->add ( getSlot ( "_gmetalv" , _gmetalv ) ); record->add ( getSlot ( "_gcontact" , _gcontact ) ); record->add ( getSlot ( "_saturateRatio" , _saturateRatio ) ); record->add ( DbU::getValueSlot ( "_globalThreshold" , &_globalThreshold ) ); record->add ( getSlot ( "_allowedDepth" , _allowedDepth ) ); record->add ( getSlot ( "_hEdgeCapacity" , _hEdgeCapacity ) ); record->add ( getSlot ( "_vEdgeCapacity" , _vEdgeCapacity ) ); return ( record ); } } // End of katabatic namespace.