// -*- 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( 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.