// -*- C++ -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved // // =================================================================== // // $Id$ // // x-----------------------------------------------------------------x // | | // | C O R I O L I S | // | C o r e L i b r a r y | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./RoutingLayerGauge.cpp" | // | *************************************************************** | // | U p d a t e s | // | | // x-----------------------------------------------------------------x #include #include "hurricane/BasicLayer.h" #include "crlcore/RoutingLayerGauge.h" namespace { // --------------------------------------------------------------- // Local Variables. const char* notBasicLayer = "%s :\n\n" " %s is not a .\n"; const char* notConductingLayer = "%s :\n\n" " %s is not a CONDUCTING .\n"; const char* negativeIndex = "RoutingLayerGauge::getTrackIndex() :\n\n" " In gauge %s :\n" " Track position %s leads to a negative index [%s,%s].\n"; const char* overflowIndex = "RoutingLayerGauge::getTrackIndex() :\n\n" " In gauge %s :\n" " Track position %s leads to an index out of bounds [%s,%s].\n"; const char* badExactPosition = "RoutingLayerGauge::getTrackIndex() :\n\n" " In gauge %s :\n" " Track position %s do not exactly match a track.\n"; const char* badInterval = "RoutingLayerGauge::getTrackNumber() :\n\n" " In gauge %s :\n" " Invalid interval [%s,%s] given for track number calculation.\n"; } // End of anonymous namespace. namespace Constant { Direction perpandicular ( unsigned int direction ) { switch ( direction ) { case Horizontal: return Vertical; case Vertical: default: break; } return Horizontal; } } // End of Constants namespace. namespace CRL { using namespace std; using Hurricane::Tabulation; using Hurricane::BasicLayer; using Hurricane::trace_in; using Hurricane::trace_out; using Hurricane::in_trace; using Hurricane::tab; // ------------------------------------------------------------------- // Class : "RoutingLayerGauge" RoutingLayerGauge::RoutingLayerGauge ( const Layer* layer , unsigned int direction , unsigned int type , unsigned int depth , double density , DbU::Unit offset , DbU::Unit pitch , DbU::Unit wireWidth , DbU::Unit viaWidth ) : _layer (layer) , _blockageLayer(layer->getBlockageLayer()) , _direction (direction) , _type (type) , _depth (depth) , _density (density) , _offset (offset) , _pitch (pitch) , _wireWidth (wireWidth) , _viaWidth (viaWidth) { } RoutingLayerGauge* RoutingLayerGauge::create ( const Layer* layer , unsigned int direction , unsigned int type , unsigned int depth , double density , DbU::Unit offset , DbU::Unit pitch , DbU::Unit wireWidth , DbU::Unit viaWidth ) { // Temporary: must write a more smart check. // BasicLayer* basicLayer = dynamic_cast(layer); // if ( basicLayer == NULL ) // throw Error ( notBasicLayer, "CRL::RoutingLayerGauge::create()", getString(layer).c_str() ); // if ( basicLayer->getMaterial() != BasicLayer::Material::metal ) // throw Error ( notConductingLayer, "CRL::RoutingLayerGauge::create()", getString(layer).c_str() ); RoutingLayerGauge* gauge = new RoutingLayerGauge ( layer , direction , type , depth , density , offset , pitch , wireWidth , viaWidth ); return gauge; } void RoutingLayerGauge::_preDestroy () { } void RoutingLayerGauge::destroy () { _preDestroy (); delete this; } RoutingLayerGauge::~RoutingLayerGauge () { } void RoutingLayerGauge::divide ( DbU::Unit dividend, long& quotient, long& modulo ) const { quotient = ( dividend - _offset ) / _pitch; modulo = ( dividend - _offset ) % _pitch; } unsigned RoutingLayerGauge::getTrackNumber ( DbU::Unit start, DbU::Unit stop ) const { if ( start > stop ) throw Error ( badInterval , getString(this).c_str() , DbU::getValueString(start).c_str() , DbU::getValueString(stop).c_str() ); long startModulo; long startQuotient; long stopModulo; long stopQuotient; long trackNumber; divide ( start, startQuotient, startModulo ); divide ( stop , stopQuotient , stopModulo ); if ( startModulo != 0 ) startQuotient += 1; trackNumber = stopQuotient - startQuotient + 1; return ( (trackNumber>0) ? trackNumber : 0 ); } unsigned RoutingLayerGauge::getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const { trace << "RoutingLayerGauge::getTrackIndex ( " << position << " )" << endl; trace_in (); long modulo; long depth; divide ( position-start, depth, modulo ); trace << "depth := " << depth << endl; if ( depth < 0 ) throw Error ( negativeIndex , getString(this).c_str() , DbU::getValueString(position).c_str() , DbU::getValueString(start).c_str() , DbU::getValueString(stop).c_str() ); if ( ( mode & Constant::Exact ) && ( modulo != 0 ) ) throw Error ( badExactPosition, getString(this).c_str(), DbU::getValueString(position).c_str() ); if ( mode & Constant::Superior ) { if ( modulo != 0 ) depth++; } else if ( mode & Constant::Nearest ) { if ( modulo > _pitch / 2 ) depth++; } if ( (unsigned)depth >= getTrackNumber(start,stop) ) throw Error ( overflowIndex , getString(this).c_str() , DbU::getValueString(position).c_str() , DbU::getValueString(start).c_str() , DbU::getValueString(stop).c_str() ); trace_out (); return depth; } DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, unsigned depth ) const { return depth * _pitch + _offset + start; } string RoutingLayerGauge::_getTypeName () const { return "CRL::RoutingLayerGauge"; } string RoutingLayerGauge::_getString () const { ostringstream os; os << "<" << "RoutingLayerGauge " << _layer->getName() << " "; if ( _direction == Constant::Horizontal ) os << "Horizontal "; else os << "Vertical "; os << DbU::getValueString(_offset) << ",+" << DbU::getValueString(_pitch) << " " << _density << "% (" << DbU::getValueString(_wireWidth) << "," << DbU::getValueString(_viaWidth) << ")>"; return os.str(); } Record* RoutingLayerGauge::_getRecord () const { Record* record = new Record ( getString(this) ); record->add ( getSlot ( "_layer" , _layer ) ); record->add ( getSlot ( "_direction", _direction ) ); record->add ( getSlot ( "_type" , _type ) ); record->add ( getSlot ( "_depth" , _depth ) ); record->add ( getSlot ( "_density" , _density ) ); record->add ( getSlot ( "_offset" , _offset ) ); record->add ( getSlot ( "_pitch" , _pitch ) ); record->add ( getSlot ( "_wireWidth", _wireWidth ) ); record->add ( getSlot ( "_viaWidth" , _viaWidth ) ); return ( record ); } } // End of Coriolis namespace.