357 lines
9.7 KiB
C++
357 lines
9.7 KiB
C++
// -*- 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 <limits>
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
#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<size_t>::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 ; i<gauge._layerGauges.size() ; i++ )
|
|
addLayerGauge ( RoutingLayerGauge::create
|
|
( gauge._layerGauges[i]->getLayer()
|
|
, 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<const ViaLayer*>(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<RoutingLayerGauge*>& 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<JsonRoutingGauge> 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<AllianceFramework*>( stack, "_framework" );
|
|
string name = get<string> ( 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.
|