coriolis/etesian/src/BloatCells.cpp

200 lines
4.7 KiB
C++

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | E t e s i a n - A n a l y t i c P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./BloatCells.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "etesian/BloatProperty.h"
#include "etesian/EtesianEngine.h"
namespace Etesian {
using std::cerr;
using std::endl;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::DbU;
BloatCell::BloatCell ( std::string name )
: _name(name)
{ }
BloatCell::~BloatCell ()
{ }
BloatKey::BloatKey ( string key )
: BloatCell(key)
{ }
BloatKey::~BloatKey ()
{ }
DbU::Unit BloatKey::getDx ( const Cell*, const EtesianEngine* ) const
{
cerr << Error( "BloatKey::getAb() must never be called (\"%s\").", getName().c_str() ) << endl;
return 0;
}
BloatDisabled::BloatDisabled ()
: BloatCell("disabled")
{ }
BloatDisabled::~BloatDisabled ()
{ }
DbU::Unit BloatDisabled::getDx ( const Cell* cell, const EtesianEngine* ) const
{ return 0; }
BloatNsxlib::BloatNsxlib ()
: BloatCell("nsxlib")
{ }
BloatNsxlib::~BloatNsxlib ()
{ }
DbU::Unit BloatNsxlib::getDx ( const Cell* cell, const EtesianEngine* etesian ) const
{
Box ab ( cell->getAbutmentBox() );
DbU::Unit vpitch = etesian->getSliceStep();;
int xsize = (ab.getWidth() + vpitch - 1) / vpitch;
if (xsize < 6) return vpitch*2;
return 0;
}
Bloat3Metals::Bloat3Metals ()
: BloatCell("3metals")
{ }
Bloat3Metals::~Bloat3Metals ()
{ }
DbU::Unit Bloat3Metals::getDx ( const Cell* cell, const EtesianEngine* etesian ) const
{
int terminals = 0;
for ( Net* net : cell->getNets() ) {
if (net->isExternal() and not net->isPower()) ++terminals;
}
Box ab ( cell->getAbutmentBox() );
DbU::Unit vpitch = etesian->getSliceStep();;
int xsize = (ab.getWidth() + vpitch - 1) / vpitch;
// float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch);
// if (termRatio > 0.5) {
// return vpitch*6;
// }
if (xsize < 4) return vpitch*4;
if (xsize < 6) return vpitch*2;
if (xsize < 8) return vpitch*1;
return 0;
}
Bloat90Percents::Bloat90Percents ()
: BloatCell("90%")
{ }
Bloat90Percents::~Bloat90Percents ()
{ }
DbU::Unit Bloat90Percents::getDx ( const Cell* cell, const EtesianEngine* etesian ) const
{
int terminals = 0;
for ( Net* net : cell->getNets() ) {
if (net->isExternal() and not net->isPower()) ++terminals;
}
Box ab ( cell->getAbutmentBox() );
DbU::Unit vpitch = etesian->getSliceStep();;
int xsize = (ab.getWidth() + vpitch - 1) / vpitch;
// float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch);
// if (termRatio > 0.5) {
// return vpitch*6;
// }
if (xsize < 4) return vpitch*11;
if (xsize < 6) return vpitch*8;
if (xsize < 8) return vpitch*6;
return vpitch*3;
}
bool BloatCells::select ( std::string profile )
{
BloatKey key ( profile );
auto ibloat = _bloatCells.find( &key );
if (ibloat != _bloatCells.end()) {
_selected = *ibloat;
return true;
}
cerr << Warning( "BloatCells::select(): No profile named \"%s\", using \"disabled\"."
, profile.c_str()
) << endl;
return select( "disabled" );
}
Box BloatCells::getAb ( Occurrence instanceOcc )
{
Instance* instance = dynamic_cast<Instance*>( instanceOcc.getEntity() );
if (not instance) {
cerr << Error( "BloatCells::getAb(): Occurrence argument do not refer an Instance (skipped).\n"
"(%s)"
, getString(instanceOcc).c_str() ) << endl;
return Box();
}
DbU::Unit dx = 0;
Cell* cell = instance->getMasterCell();
BloatState* state = BloatExtension::get( instanceOcc );
if (state) dx = state->getTracksCount() * _etesian->getSliceStep();
else dx = _selected->getDx( cell, _etesian );
_dxSpace += dx;
Box ab = cell->getAbutmentBox();
return ab.inflate( 0, 0, dx, 0 );
}
} // Etesian namespace.