// -*- 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 | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./RoutingGauge.cpp" | // +-----------------------------------------------------------------+ #include #include #include #include "hurricane/Commons.h" #include "hurricane/ViaLayer.h" #include "hurricane/Technology.h" #include "hurricane/DataBase.h" #include "crlcore/RoutingLayerGauge.h" #include "crlcore/RoutingGauge.h" #include "crlcore/AllianceFramework.h" namespace { const char* dupLayerGauge = "RoutingGauge::AddLayerGauge() :\n\n" " Attempt to re-define layer gauge %s in routing gauge %s.\n"; } // End of anonymous namespace. namespace CRL { using namespace std; using Hurricane::JsonTypes; using Hurricane::JsonArray; using Hurricane::DataBase; using Hurricane::BasicLayer; using Hurricane::ViaLayer; using Hurricane::getCollection; // ------------------------------------------------------------------- // Class : "RoutingGauge". const size_t RoutingGauge::nlayerdepth = std::numeric_limits::max(); RoutingGauge::RoutingGauge ( const char* name ) : _name (name) , _layerGauges() , _viaLayers () , _technology (DataBase::getDB()->getTechnology()) , _isSymbolic (true) { } RoutingGauge::RoutingGauge ( const RoutingGauge& gauge ) : _name (gauge._name) , _layerGauges() , _viaLayers () , _technology (gauge._technology) , _isSymbolic (gauge._isSymbolic) { // Make a deep copy of the map. for ( size_t i=0 ; igetLayer() , gauge._layerGauges[i]->getDirection() , gauge._layerGauges[i]->getType() , gauge._layerGauges[i]->getDepth() , gauge._layerGauges[i]->getDensity() , gauge._layerGauges[i]->getOffset() , gauge._layerGauges[i]->getPitch() , gauge._layerGauges[i]->getWireWidth() , gauge._layerGauges[i]->getViaWidth() , gauge._layerGauges[i]->getObstacleDw() ) ); } RoutingGauge* RoutingGauge::create ( const char* name ) { RoutingGauge* gauge = new RoutingGauge ( name ); return gauge; } void RoutingGauge::_preDestroy () { for ( size_t i=0 ; i<_layerGauges.size() ; i++ ) _layerGauges[i]->destroy (); } void RoutingGauge::destroy() { _preDestroy (); delete this; } RoutingGauge::~RoutingGauge () { } RoutingGauge* RoutingGauge::getClone () const { return new RoutingGauge ( *this ); } RoutingLayerGauge* RoutingGauge::getHorizontalGauge () const { for ( RoutingLayerGauge* gauge : _layerGauges ) { if ( (gauge->getType() != Constant::LayerGaugeType::PinOnly) and gauge->isHorizontal() ) return gauge; } return NULL; } RoutingLayerGauge* RoutingGauge::getVerticalGauge () const { for ( RoutingLayerGauge* gauge : _layerGauges ) { if ( (gauge->getType() != Constant::LayerGaugeType::PinOnly) and gauge->isVertical() ) return gauge; } return NULL; } RoutingLayerGauge* RoutingGauge::getLayerGauge ( const Layer* layer ) const { for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { if ( _layerGauges[i]->getLayer() == layer ) return _layerGauges[i]; } return NULL; } unsigned int RoutingGauge::getLayerType ( const Layer* layer ) const { RoutingLayerGauge* layerGauge = getLayerGauge(layer); if ( !layerGauge ) return 0; return layerGauge->getType(); } unsigned int RoutingGauge::getLayerDirection ( const Layer* layer ) const { RoutingLayerGauge* layerGauge = getLayerGauge(layer); if ( !layerGauge ) return 0; return layerGauge->getDirection(); } size_t RoutingGauge::getViaDepth ( const Layer* layer ) const { const Layer* bottomLayer = layer; const Layer* viaLayer = dynamic_cast(layer); if (viaLayer) bottomLayer = viaLayer->getBottom(); for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { if ( _layerGauges[i]->getLayer()->getMask() == bottomLayer->getMask() ) return i; } return nlayerdepth; } size_t RoutingGauge::getLayerDepth ( const Layer* layer ) const { for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { if ( _layerGauges[i]->getLayer()->getMask() == layer->getMask() ) return i; } return nlayerdepth; } RoutingLayerGauge* RoutingGauge::getLayerGauge ( size_t depth ) const { if ( depth >= _layerGauges.size() ) return NULL; return _layerGauges[depth]; } const Layer* RoutingGauge::getRoutingLayer ( size_t depth ) const { if ( depth >= _layerGauges.size() ) return NULL; return _layerGauges[depth]->getLayer(); } Layer* RoutingGauge::getContactLayer ( size_t depth ) const { if ( depth >= _viaLayers.size() ) return NULL; return _viaLayers[depth]; } const vector& RoutingGauge::getLayerGauges () const { return _layerGauges; } void RoutingGauge::addLayerGauge ( RoutingLayerGauge* layerGauge ) { if (getLayerGauge(layerGauge->getLayer()) != NULL) throw Error( dupLayerGauge, getString(layerGauge->getLayer()->getName()).c_str() , getString(_name).c_str() ); _layerGauges.push_back( layerGauge ); size_t gaugeSize = _layerGauges.size(); if (gaugeSize > 1) { Layer* viaLayer = _technology->getViaBetween( _layerGauges[gaugeSize-2]->getLayer() , _layerGauges[gaugeSize-1]->getLayer() , _layerGauges[gaugeSize-1]->getLayer()->isSymbolic() ); if (not viaLayer) { cerr << Error( "Can't find a VIA between Gauge layers %s and %s." , getString(_layerGauges[gaugeSize-2]).c_str() , getString(_layerGauges[gaugeSize-1]).c_str() ) << endl; } _viaLayers.push_back( viaLayer ); } } void RoutingGauge::checkConnexity () const { if ( _layerGauges.empty() ) return; for ( size_t i=0 ; i<_viaLayers.size() ; i++ ) { if ( !_viaLayers[i] ) { cerr << Error("Gap in %s: %s and %s are not contiguous." ,getString(this).c_str() ,getString(_layerGauges[i ]->getLayer()).c_str() ,getString(_layerGauges[i+1]->getLayer()).c_str()) << endl; } if ( _layerGauges[i+1]->getType() == Constant::PinOnly ) { cerr << Error("In %s: only first layer can be PinOnly.\n" " (%s at depth %d)" ,getString(this).c_str() ,getString(_layerGauges[i+1]).c_str() ,i+1 ) << endl; } } } string RoutingGauge::_getTypeName () const { return "CRL::RoutingGauge"; } string RoutingGauge::_getString () const { ostringstream os; os << "<" << "RoutingGauge " << _name << ">"; return ( os.str() ); } Record* RoutingGauge::_getRecord ( Record* record ) const { if ( record == NULL ) record = new Record ( getString(this) ); record->add ( getSlot("_name" , _name ) ); record->add ( getSlot("_gauges" ,&_layerGauges) ); record->add ( getSlot("_isSymbolic", _isSymbolic ) ); return ( record ); } void RoutingGauge::toJson ( JsonWriter* w ) const { w->startObject(); jsonWrite( w, "@typename", "RoutingGauge" ); jsonWrite( w, "_name" , _name ); jsonWrite( w, "+routingLayerGauges", getCollection(getLayerGauges()) ); w->endObject(); } // ------------------------------------------------------------------- // Class : "JsonRoutingGauge" Initializer jsonRoutingGaugeInit ( 0 ); void JsonRoutingGauge::initialize () { JsonTypes::registerType( new JsonRoutingGauge (JsonWriter::RegisterMode) ); } JsonRoutingGauge::JsonRoutingGauge( unsigned long flags ) : JsonObject(flags) { add( "_name" , typeid(string) ); add( "+routingLayerGauges", typeid(JsonArray) ); } string JsonRoutingGauge::getTypeName () const { return "RoutingGauge"; } JsonRoutingGauge* JsonRoutingGauge::clone ( unsigned long flags ) const { return new JsonRoutingGauge ( flags ); } void JsonRoutingGauge::toData ( JsonStack& stack ) { check( stack, "JsonRoutingGauge::toData" ); AllianceFramework* af = get( stack, "_framework" ); string name = get ( stack, "_name" ); RoutingGauge* rg = NULL; if (stack.issetFlags(JsonWriter::TechnoMode)) { if (af) { if (not name.empty()) { rg = RoutingGauge::create( name.c_str() ); af->addRoutingGauge( rg ); } } else { cerr << Error( "JsonRoutingGauge::toData(): Missing \"_framework\" in stack context." ) << endl; } } else { rg = af->getRoutingGauge( name ); } update( stack, rg ); } } // End of CRL namespace.