499 lines
11 KiB
C++
499 lines
11 KiB
C++
// -*- C++ -*-
|
|
//
|
|
// This file is part of the Coriolis Software.
|
|
// Copyright (c) UPMC 2015-2018, All Rights Reserved
|
|
//
|
|
// +-----------------------------------------------------------------+
|
|
// | C O R I O L I S |
|
|
// | B o r a - A n a l o g S l i c i n g T r e e |
|
|
// | |
|
|
// | Authors : Eric LAO |
|
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
|
// | =============================================================== |
|
|
// | C++ Module : "./BoxSet.cpp" |
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
#include "hurricane/Error.h"
|
|
#include "hurricane/Warning.h"
|
|
#include "hurricane/Cell.h"
|
|
#include "crlcore/RoutingGauge.h"
|
|
#include "bora/BoxSet.h"
|
|
|
|
|
|
namespace Bora {
|
|
|
|
using namespace std;
|
|
using Hurricane::Error;
|
|
using Hurricane::Warning;
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::BoxSet".
|
|
|
|
|
|
BoxSet::BoxSet ( DbU::Unit height, DbU::Unit width )
|
|
: _height(height)
|
|
, _width (width)
|
|
, _cpt (1)
|
|
{ }
|
|
|
|
|
|
BoxSet::BoxSet ( BoxSet* boxSet )
|
|
: _height(0)
|
|
, _width (0)
|
|
, _cpt (1)
|
|
{
|
|
if (boxSet) {
|
|
_height = boxSet->getHeight();
|
|
_width = boxSet->getWidth();
|
|
_cpt = boxSet->getCpt();
|
|
}
|
|
}
|
|
|
|
|
|
BoxSet::~BoxSet ()
|
|
{ }
|
|
|
|
|
|
void BoxSet::print () const
|
|
{
|
|
cerr << "area: " << setprecision(4) << getOccupationArea() ;
|
|
cerr << "%, \t cpt: " << getCpt();
|
|
if ((getWidth() == 0) && (getHeight() == 0)) cerr << ", \t ratio (W/H):inf";
|
|
else cerr << ", \t ratio (W/H):" << setprecision(2) << getWidth()/getHeight();
|
|
cerr << ", \t ratio (W*H):" << setprecision(4) << DbU::getPhysical(getWidth(),DbU::Micro) * DbU::getPhysical(getHeight(),DbU::Micro) << "um²";
|
|
if (getType() == DeviceSNode){ cerr << ", \t Nfing: " << getNFing(); }
|
|
cerr << ", \t H: " << setprecision(4) << DbU::getPhysical(getHeight(),DbU::Micro) << "um" ;
|
|
cerr << ", W: " << DbU::getPhysical(getWidth(),DbU::Micro)<< "um";
|
|
cerr << endl;
|
|
}
|
|
|
|
|
|
const vector<BoxSet*>& BoxSet::getSet () const
|
|
{
|
|
cerr << Warning( "BoxSet::getSet(): DBoxSet and RHVBoxSet do not have vector of BoxSets." ) << endl;
|
|
|
|
static const vector<BoxSet*> emptyBoxSet = vector<BoxSet*>();
|
|
return emptyBoxSet;
|
|
}
|
|
|
|
|
|
int BoxSet::getNFing () const
|
|
{
|
|
cerr << Warning( "BoxSet::getNFing(): Only DBoxSet has fingers." ) << endl;
|
|
return 0;
|
|
}
|
|
|
|
|
|
size_t BoxSet::getIndex () const
|
|
{
|
|
cerr << Warning( "BoxSet::getIndex(): Only DBoxSet has parameter range indexes." ) << endl;
|
|
return 0;
|
|
}
|
|
|
|
|
|
void BoxSet::destroy()
|
|
{
|
|
if (_cpt < 2) delete this;
|
|
else --_cpt;
|
|
}
|
|
|
|
|
|
void BoxSet::setWidth ( DbU::Unit )
|
|
{ cerr << Warning( "BoxSet::setWidth(): Must never be called." ) << endl; }
|
|
|
|
|
|
void BoxSet::setHeight ( DbU::Unit )
|
|
{ cerr << Warning( "BoxSet::setWidth(): Must never be called." ) << endl; }
|
|
|
|
|
|
string BoxSet::_getTypeName () const
|
|
{ return "BoxSet"; }
|
|
|
|
|
|
string BoxSet::_getString () const
|
|
{
|
|
string s = "<" + _getTypeName()
|
|
+ " refs:" + getString(_cpt)
|
|
+ " w:" + DbU::getValueString(getWidth ())
|
|
+ " h:" + DbU::getValueString(getHeight())
|
|
+ ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::HVBoxSet".
|
|
|
|
|
|
HVBoxSet::HVBoxSet ( const vector<BoxSet*>& dimensionSet, DbU::Unit height, DbU::Unit width )
|
|
: BoxSet(height,width)
|
|
,_dimensionSet(dimensionSet)
|
|
{
|
|
for ( BoxSet* bs : _dimensionSet ) bs->incrementCpt();
|
|
}
|
|
|
|
|
|
HVBoxSet::HVBoxSet ( HVBoxSet* boxSet )
|
|
: BoxSet( boxSet )
|
|
, _dimensionSet( boxSet->getSet() )
|
|
{
|
|
for ( BoxSet* bs : _dimensionSet ) bs->incrementCpt();
|
|
}
|
|
|
|
|
|
HVBoxSet::~HVBoxSet ()
|
|
{ }
|
|
|
|
|
|
double HVBoxSet::getDevicesArea () const
|
|
{
|
|
double area = 0;
|
|
for ( BoxSet* bs : _dimensionSet ) area += bs->getDevicesArea();
|
|
return area;
|
|
}
|
|
|
|
|
|
string HVBoxSet::_getTypeName () const
|
|
{ return "HVBoxSet"; }
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::HBoxSet".
|
|
|
|
|
|
int HBoxSet::_count = 0;
|
|
int HBoxSet::_countAll = 0;
|
|
|
|
|
|
HBoxSet::HBoxSet ( const vector<BoxSet*>& dimensionSet, DbU::Unit height, DbU::Unit width )
|
|
: HVBoxSet( dimensionSet, height, width )
|
|
{
|
|
if ((_height == 0) and (_width == 0)) {
|
|
calculateHeight();
|
|
calculateWidth ();
|
|
}
|
|
}
|
|
|
|
|
|
HBoxSet::HBoxSet( HBoxSet* boxSet )
|
|
: HVBoxSet( boxSet )
|
|
{
|
|
++_count;
|
|
++_countAll;
|
|
}
|
|
|
|
|
|
HBoxSet::~HBoxSet ()
|
|
{
|
|
--_count;
|
|
}
|
|
|
|
|
|
HBoxSet* HBoxSet::create ( const vector<BoxSet*>& dimensionSet, DbU::Unit height, DbU::Unit width )
|
|
{
|
|
return new HBoxSet( dimensionSet, height, width );
|
|
}
|
|
|
|
|
|
HBoxSet* HBoxSet::clone ()
|
|
{ return HBoxSet::create( getSet(), getHeight(), getWidth() ); }
|
|
|
|
|
|
void HBoxSet::calculateHeight ()
|
|
{
|
|
DbU::Unit currentH = 0;
|
|
for ( BoxSet* bs : _dimensionSet ) currentH += bs->getHeight();
|
|
_height = currentH;
|
|
}
|
|
|
|
|
|
void HBoxSet::calculateWidth ()
|
|
{
|
|
DbU::Unit currentW = 0;
|
|
for ( BoxSet* bs : _dimensionSet ) {
|
|
if (currentW < bs->getWidth()) currentW = bs->getWidth();
|
|
}
|
|
_width = currentW;
|
|
}
|
|
|
|
|
|
void HBoxSet::destroy()
|
|
{
|
|
BoxSet::destroy();
|
|
}
|
|
|
|
|
|
string HBoxSet::_getTypeName () const
|
|
{ return "HBoxSet"; }
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::VBoxSet".
|
|
|
|
|
|
int VBoxSet::_count = 0;
|
|
int VBoxSet::_countAll = 0;
|
|
|
|
|
|
VBoxSet::VBoxSet ( const vector<BoxSet*>& dimensionSet, DbU::Unit height, DbU::Unit width )
|
|
: HVBoxSet( dimensionSet, height, width )
|
|
{
|
|
++_count;
|
|
++_countAll;
|
|
if ((_height == 0) and (_width == 0)){
|
|
calculateHeight();
|
|
calculateWidth ();
|
|
}
|
|
}
|
|
|
|
|
|
VBoxSet::VBoxSet ( VBoxSet* boxSet )
|
|
: HVBoxSet( boxSet )
|
|
{ }
|
|
|
|
|
|
VBoxSet::~VBoxSet ()
|
|
{
|
|
--_count;
|
|
}
|
|
|
|
|
|
VBoxSet* VBoxSet::create ( const vector<BoxSet*>& dimensionSet, DbU::Unit height, DbU::Unit width )
|
|
{
|
|
return new VBoxSet( dimensionSet, height, width );
|
|
}
|
|
|
|
|
|
VBoxSet* VBoxSet::clone ()
|
|
{
|
|
return VBoxSet::create( getSet(), getHeight(), getWidth() );
|
|
}
|
|
|
|
|
|
void VBoxSet::calculateHeight()
|
|
{
|
|
DbU::Unit currentH = 0;
|
|
for ( BoxSet* bs : _dimensionSet ) {
|
|
if (currentH < bs->getHeight()) currentH = bs->getHeight();
|
|
}
|
|
_height = currentH;
|
|
}
|
|
|
|
|
|
void VBoxSet::calculateWidth ()
|
|
{
|
|
DbU::Unit currentW = 0;
|
|
for ( BoxSet* bs : _dimensionSet ) currentW += bs->getWidth();
|
|
_width = currentW;
|
|
}
|
|
|
|
|
|
void VBoxSet::destroy()
|
|
{
|
|
BoxSet::destroy();
|
|
}
|
|
|
|
|
|
string VBoxSet::_getTypeName () const
|
|
{ return "VBoxSet"; }
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::DBoxSet".
|
|
|
|
|
|
int DBoxSet::_count = 0;
|
|
int DBoxSet::_countAll = 0;
|
|
|
|
|
|
DBoxSet::DBoxSet ( DbU::Unit height, DbU::Unit width, size_t index )
|
|
: BoxSet( height, width )
|
|
, _index(index)
|
|
{
|
|
++_count;
|
|
++_countAll;
|
|
}
|
|
|
|
|
|
DBoxSet::DBoxSet ( DBoxSet* boxSet )
|
|
: BoxSet( boxSet )
|
|
, _index( boxSet->getIndex() )
|
|
{ }
|
|
|
|
|
|
DBoxSet::~DBoxSet ()
|
|
{
|
|
--_count;
|
|
}
|
|
|
|
|
|
DBoxSet* DBoxSet::create ( Cell* cell, int index, CRL::RoutingGauge* rg )
|
|
{
|
|
DbU::Unit abHeight = cell->getAbutmentBox().getHeight();
|
|
DbU::Unit abWidth = cell->getAbutmentBox().getWidth();
|
|
|
|
if (rg) {
|
|
DbU::Unit h2pitch = rg->getHorizontalPitch()*2;
|
|
DbU::Unit v2pitch = rg->getVerticalPitch ()*2;
|
|
|
|
if (abHeight % h2pitch) {
|
|
cerr << Warning( "DBoxSet::create(): The height of device \"%s\" (%s) is not pitched on 2*%s (adjusted)."
|
|
, getString(cell->getName()).c_str()
|
|
, DbU::getValueString(abHeight ).c_str()
|
|
, DbU::getValueString(h2pitch/2).c_str()
|
|
) << endl;
|
|
abHeight += h2pitch - (abHeight % h2pitch);
|
|
}
|
|
if (abWidth % v2pitch) {
|
|
cerr << Warning( "DBoxSet::create(): The width of device \"%s\" (%s) is not pitched on 2*%s (adjusted)."
|
|
, getString(cell->getName()).c_str()
|
|
, DbU::getValueString(abWidth ).c_str()
|
|
, DbU::getValueString(v2pitch/2).c_str()
|
|
) << endl;
|
|
abWidth += v2pitch - (abWidth % v2pitch);
|
|
}
|
|
}
|
|
|
|
return new DBoxSet( abHeight, abWidth, index );
|
|
}
|
|
|
|
|
|
DBoxSet* DBoxSet::clone ()
|
|
{
|
|
return new DBoxSet( getHeight(), getWidth(), getNFing() );
|
|
}
|
|
|
|
|
|
void DBoxSet::destroy()
|
|
{
|
|
BoxSet::destroy();
|
|
}
|
|
|
|
|
|
string DBoxSet::_getTypeName () const
|
|
{ return "DBoxSet"; }
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::RHVBoxSet".
|
|
|
|
|
|
int RHVBoxSet::_count = 0;
|
|
int RHVBoxSet::_countAll = 0;
|
|
|
|
|
|
RHVBoxSet::RHVBoxSet ( DbU::Unit height, DbU::Unit width )
|
|
: BoxSet( height, width )
|
|
{
|
|
_width = width;
|
|
_height = height;
|
|
}
|
|
|
|
|
|
RHVBoxSet::RHVBoxSet ( RHVBoxSet* boxSet )
|
|
: BoxSet( boxSet )
|
|
{ }
|
|
|
|
|
|
RHVBoxSet::~RHVBoxSet ()
|
|
{ }
|
|
|
|
|
|
void RHVBoxSet::destroy ()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
|
|
void RHVBoxSet::print () const
|
|
{
|
|
cerr << "area: " << setprecision(4) << getOccupationArea() ;
|
|
cerr << "%, \t cpt: " << getCpt();
|
|
cerr << ", \t H: " << setprecision(4) << DbU::getPhysical(_height,DbU::Micro) << "um" ;
|
|
cerr << ", W: " << DbU::getPhysical(_width,DbU::Micro)<< "um";
|
|
cerr << endl;
|
|
}
|
|
|
|
|
|
string RHVBoxSet::_getTypeName () const
|
|
{ return "RHVBoxSet"; }
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::RHBoxSet".
|
|
|
|
|
|
RHBoxSet::RHBoxSet ( DbU::Unit height )
|
|
: RHVBoxSet( height, 0 )
|
|
{
|
|
_count++;
|
|
_countAll++;
|
|
}
|
|
|
|
|
|
RHBoxSet::RHBoxSet ( RHBoxSet* boxSet )
|
|
: RHVBoxSet( boxSet )
|
|
{ }
|
|
|
|
|
|
RHBoxSet::~RHBoxSet ()
|
|
{ }
|
|
|
|
|
|
RHBoxSet* RHBoxSet::create ( DbU::Unit height )
|
|
{
|
|
return new RHBoxSet ( height );
|
|
}
|
|
|
|
|
|
RHBoxSet* RHBoxSet::clone ()
|
|
{
|
|
return RHBoxSet::create( getHeight() );
|
|
}
|
|
|
|
|
|
string RHBoxSet::_getTypeName () const
|
|
{ return "RHBoxSet"; }
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "Bora::RVBoxSet".
|
|
|
|
|
|
RVBoxSet::RVBoxSet ( DbU::Unit width )
|
|
: RHVBoxSet( 0, width )
|
|
{
|
|
++_count;
|
|
++_countAll;
|
|
}
|
|
|
|
|
|
RVBoxSet::RVBoxSet( RVBoxSet* boxSet )
|
|
: RHVBoxSet( boxSet )
|
|
{ }
|
|
|
|
|
|
RVBoxSet::~RVBoxSet ()
|
|
{ }
|
|
|
|
|
|
RVBoxSet* RVBoxSet::create ( DbU::Unit width )
|
|
{
|
|
return new RVBoxSet( width );
|
|
}
|
|
|
|
|
|
RVBoxSet* RVBoxSet::clone()
|
|
{
|
|
return RVBoxSet::create( getWidth() );
|
|
}
|
|
|
|
|
|
string RVBoxSet::_getTypeName () const
|
|
{ return "RVBoxSet"; }
|
|
|
|
|
|
} // Bora namespace.
|