412 lines
14 KiB
C++
412 lines
14 KiB
C++
// -*- 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 |
|
|
// | C o r e L i b r a r y |
|
|
// | |
|
|
// | Author : Jean-Paul CHAPUT |
|
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
|
// | =============================================================== |
|
|
// | C++ Module : "./RoutingLayerGauge.cpp" |
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
#include <sstream>
|
|
#include "hurricane/BasicLayer.h"
|
|
#include "hurricane/DataBase.h"
|
|
#include "hurricane/Technology.h"
|
|
#include "crlcore/RoutingLayerGauge.h"
|
|
#include "crlcore/RoutingGauge.h"
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// Local Variables.
|
|
|
|
// const char* notBasicLayer =
|
|
// "%s :\n\n"
|
|
// " %s is not a <BasicLayer>.\n";
|
|
|
|
// const char* notConductingLayer =
|
|
// "%s :\n\n"
|
|
// " %s is not a CONDUCTING <BasicLayer>.\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::JsonTypes;
|
|
using Hurricane::Tabulation;
|
|
using Hurricane::BasicLayer;
|
|
using Hurricane::tab;
|
|
using Hurricane::DataBase;
|
|
using Hurricane::Technology;
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "RoutingLayerGauge"
|
|
|
|
RoutingLayerGauge::RoutingLayerGauge ( const Layer* layer
|
|
, Constant::Direction direction
|
|
, Constant::LayerGaugeType type
|
|
, unsigned int depth
|
|
, double density
|
|
, DbU::Unit offset
|
|
, DbU::Unit pitch
|
|
, DbU::Unit wireWidth
|
|
, DbU::Unit viaWidth
|
|
, DbU::Unit obsDw )
|
|
: _layer (layer)
|
|
, _blockageLayer(layer->getBlockageLayer())
|
|
, _direction (direction)
|
|
, _type (type)
|
|
, _depth (depth)
|
|
, _density (density)
|
|
, _offset (offset)
|
|
, _pitch (pitch)
|
|
, _wireWidth (wireWidth)
|
|
, _viaWidth (viaWidth)
|
|
, _obstacleDw (obsDw)
|
|
{ }
|
|
|
|
|
|
RoutingLayerGauge* RoutingLayerGauge::create ( const Layer* layer
|
|
, Constant::Direction direction
|
|
, Constant::LayerGaugeType type
|
|
, unsigned int depth
|
|
, double density
|
|
, DbU::Unit offset
|
|
, DbU::Unit pitch
|
|
, DbU::Unit wireWidth
|
|
, DbU::Unit viaWidth
|
|
, DbU::Unit obsDw )
|
|
{
|
|
// Temporary: must write a more smart check.
|
|
// BasicLayer* basicLayer = dynamic_cast<BasicLayer*>(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
|
|
, obsDw );
|
|
|
|
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
|
|
{
|
|
cdebug_log(100,1) << "RoutingLayerGauge::getTrackIndex ( " << position << " )" << endl;
|
|
|
|
long modulo;
|
|
long index;
|
|
|
|
divide ( position-start, index, modulo );
|
|
|
|
cdebug_log(100,0) << "index := " << index << endl;
|
|
|
|
if ( index < 0 ) {
|
|
cdebug_tabw(100,-1);
|
|
return 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 ) and ( modulo != 0 ) )
|
|
throw Error ( badExactPosition, getString(this).c_str(), DbU::getValueString(position).c_str() );
|
|
|
|
if ( mode & Constant::Superior ) {
|
|
if ( modulo != 0 ) index++;
|
|
} else if ( mode & Constant::Nearest ) {
|
|
if ( modulo > _pitch / 2 ) index++;
|
|
}
|
|
|
|
unsigned int tracksNumber = getTrackNumber(start,stop);
|
|
if ( (unsigned)index >= tracksNumber ) {
|
|
cdebug_tabw(100,-1);
|
|
return (tracksNumber > 0) ? tracksNumber-1 : 0;
|
|
// throw Error ( overflowIndex
|
|
// , getString(this).c_str()
|
|
// , DbU::getValueString(position).c_str()
|
|
// , DbU::getValueString(start).c_str()
|
|
// , DbU::getValueString(stop).c_str()
|
|
// );
|
|
}
|
|
|
|
cdebug_tabw(100,-1);
|
|
|
|
return index;
|
|
}
|
|
|
|
|
|
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 ( DbU::getValueSlot ( "_offset" , &_offset ) );
|
|
record->add ( DbU::getValueSlot ( "_pitch" , &_pitch ) );
|
|
record->add ( DbU::getValueSlot ( "_wireWidth", &_wireWidth ) );
|
|
record->add ( DbU::getValueSlot ( "_viaWidth" , &_viaWidth ) );
|
|
|
|
return ( record );
|
|
}
|
|
|
|
|
|
void RoutingLayerGauge::toJson ( JsonWriter* w ) const
|
|
{
|
|
w->startObject();
|
|
jsonWrite( w, "@typename", "RoutingLayerGauge" );
|
|
jsonWrite( w, "_layer" , _layer->getName() );
|
|
jsonWrite( w, "_direction" , getString(&_direction) );
|
|
jsonWrite( w, "_type" , getString(&_type ) );
|
|
jsonWrite( w, "_depth" , _depth );
|
|
jsonWrite( w, "_density" , _density );
|
|
jsonWrite( w, "_offset" , _offset );
|
|
jsonWrite( w, "_pitch" , _pitch );
|
|
jsonWrite( w, "_wireWidth" , _wireWidth );
|
|
jsonWrite( w, "_viaWidth" , _viaWidth );
|
|
jsonWrite( w, "_obstacleDw" , _obstacleDw );
|
|
w->endObject();
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "JsonRoutingLayerGauge"
|
|
|
|
Initializer<JsonRoutingLayerGauge> jsonRoutingLayerGaugeInit ( 0 );
|
|
|
|
|
|
void JsonRoutingLayerGauge::initialize ()
|
|
{ JsonTypes::registerType( new JsonRoutingLayerGauge (JsonWriter::RegisterMode) ); }
|
|
|
|
|
|
JsonRoutingLayerGauge::JsonRoutingLayerGauge( unsigned long flags )
|
|
: JsonObject(flags)
|
|
{
|
|
add( ".RoutingGauge" , typeid(RoutingGauge*) );
|
|
add( "_layer" , typeid(string) );
|
|
add( "_direction" , typeid(string) );
|
|
add( "_type" , typeid(string) );
|
|
add( "_depth" , typeid(unsigned int) );
|
|
add( "_density" , typeid(double) );
|
|
add( "_offset" , typeid(int64_t) );
|
|
add( "_pitch" , typeid(int64_t) );
|
|
add( "_wireWidth" , typeid(int64_t) );
|
|
add( "_viaWidth" , typeid(int64_t) );
|
|
add( "_obstacleDw" , typeid(int64_t) );
|
|
}
|
|
|
|
|
|
string JsonRoutingLayerGauge::getTypeName () const
|
|
{ return "RoutingLayerGauge"; }
|
|
|
|
|
|
JsonRoutingLayerGauge* JsonRoutingLayerGauge::clone ( unsigned long flags ) const
|
|
{ return new JsonRoutingLayerGauge ( flags ); }
|
|
|
|
|
|
void JsonRoutingLayerGauge::toData ( JsonStack& stack )
|
|
{
|
|
check( stack, "JsonRoutingLayerGauge::toData" );
|
|
|
|
Technology* techno = DataBase::getDB()->getTechnology();
|
|
RoutingGauge* rg = get<RoutingGauge*>( stack, ".RoutingGauge" );
|
|
RoutingLayerGauge* rlg = NULL;
|
|
string layer = get<string> ( stack, "_layer" );
|
|
unsigned int depth = get<int64_t> ( stack, "_depth" );
|
|
double density = get<double> ( stack, "_density" );
|
|
DbU::Unit offset = get<int64_t> ( stack, "_offset" );
|
|
DbU::Unit pitch = get<int64_t> ( stack, "_pitch" );
|
|
DbU::Unit wireWidth = get<int64_t> ( stack, "_wireWidth" );
|
|
DbU::Unit viaWidth = get<int64_t> ( stack, "_viaWidth" );
|
|
DbU::Unit obstacleDw = get<int64_t> ( stack, "_obstacleDw" );
|
|
|
|
Constant::Direction direction;
|
|
Constant::LayerGaugeType type;
|
|
from( direction, get<string>(stack,"_direction") );
|
|
from( type , get<string>(stack,"_type" ) );
|
|
|
|
if (stack.issetFlags(JsonWriter::TechnoMode)) {
|
|
if (rg) {
|
|
if (not layer.empty()) {
|
|
rlg = RoutingLayerGauge::create( techno->getLayer(layer)
|
|
, direction
|
|
, type
|
|
, depth
|
|
, density
|
|
, offset
|
|
, pitch
|
|
, wireWidth
|
|
, viaWidth
|
|
, obstacleDw
|
|
);
|
|
rg->addLayerGauge( rlg );
|
|
}
|
|
} else {
|
|
cerr << Error( "JsonRoutingLayerGauge::toData(): Missing \".RoutingGauge\" in stack context." ) << endl;
|
|
}
|
|
} else {
|
|
if (rg) {
|
|
rlg = rg->getLayerGauge( techno->getLayer(layer) );
|
|
}
|
|
}
|
|
|
|
update( stack, rlg );
|
|
}
|
|
|
|
|
|
} // Coriolis namespace.
|