Added management of tie *inside* cells.
* New: In Etesian/Placement::Area, added support to take into account bulk inside cells. Currently only hard-wired configuration for FlexLib is available. Should add a front-end to analyse the cells of the library to lookup for bulk ties in the future.
This commit is contained in:
parent
70d32528cd
commit
49ffe1e1ba
|
@ -21,9 +21,10 @@
|
|||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Path.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Library.h"
|
||||
#include "hurricane/viewer/CellWidget.h"
|
||||
#include "hurricane/viewer/CellViewer.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
|
@ -40,18 +41,100 @@ namespace {
|
|||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::DBo;
|
||||
using Hurricane::Occurrence;
|
||||
using Hurricane::Instance;
|
||||
using Hurricane::Path;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Library;
|
||||
using CRL::AllianceFramework;
|
||||
using CRL::CatalogExtension;
|
||||
using CRL::getTransformation;
|
||||
using Etesian::EtesianEngine;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::TieDatas".
|
||||
|
||||
class TieDatas {
|
||||
public:
|
||||
inline TieDatas ( Cell* cell=NULL, DbU::Unit leftDistance=0, DbU::Unit rightDistance=0 );
|
||||
inline Cell* getCell () const;
|
||||
inline DbU::Unit getLeftDistance () const;
|
||||
inline DbU::Unit getRightDistance() const;
|
||||
private:
|
||||
Cell* _cell;
|
||||
DbU::Unit _leftDistance;
|
||||
DbU::Unit _rightDistance;
|
||||
};
|
||||
|
||||
|
||||
inline TieDatas::TieDatas ( Cell* cell, DbU::Unit leftDistance, DbU::Unit rightDistance )
|
||||
: _cell (cell)
|
||||
, _leftDistance (leftDistance)
|
||||
, _rightDistance(rightDistance)
|
||||
{ }
|
||||
|
||||
inline Cell* TieDatas::getCell () const { return _cell; }
|
||||
inline DbU::Unit TieDatas::getLeftDistance () const { return _leftDistance; }
|
||||
inline DbU::Unit TieDatas::getRightDistance() const { return _rightDistance; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::TieLUT".
|
||||
|
||||
class TieLUT {
|
||||
public:
|
||||
inline TieLUT ();
|
||||
inline const TieDatas* getTieDatas ( Cell* ) const;
|
||||
inline DbU::Unit getLeftDistance ( Cell* ) const;
|
||||
inline DbU::Unit getRightDistance ( Cell* ) const;
|
||||
inline void addTieDatas ( Cell*, DbU::Unit leftDistance, DbU::Unit rightDistance );
|
||||
private:
|
||||
map< Cell*, TieDatas, DBo::CompareById > _tieLut;
|
||||
};
|
||||
|
||||
|
||||
inline TieLUT::TieLUT ()
|
||||
: _tieLut()
|
||||
{ }
|
||||
|
||||
|
||||
inline void TieLUT::addTieDatas ( Cell* cell, DbU::Unit leftDistance, DbU::Unit rightDistance )
|
||||
{
|
||||
const TieDatas* datas = getTieDatas( cell );
|
||||
if (datas) {
|
||||
cerr << Error( "TieLUT::addTieDatas(): Duplicate datas for % (ignoreds)."
|
||||
, getString(cell).c_str()
|
||||
) << endl;
|
||||
}
|
||||
_tieLut[ cell ] = TieDatas( cell, leftDistance, rightDistance );
|
||||
}
|
||||
|
||||
|
||||
inline const TieDatas* TieLUT::getTieDatas ( Cell* cell ) const
|
||||
{
|
||||
auto iDatas = _tieLut.find( cell );
|
||||
return (iDatas != _tieLut.end()) ? &((*iDatas).second) : NULL;
|
||||
}
|
||||
|
||||
|
||||
inline DbU::Unit TieLUT::getLeftDistance ( Cell* cell ) const
|
||||
{
|
||||
const TieDatas* datas = getTieDatas( cell );
|
||||
return (datas) ? datas->getLeftDistance() : 0;
|
||||
}
|
||||
|
||||
|
||||
inline DbU::Unit TieLUT::getRightDistance ( Cell* cell ) const
|
||||
{
|
||||
const TieDatas* datas = getTieDatas( cell );
|
||||
return (datas) ? datas->getRightDistance() : 0;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::Tile".
|
||||
|
||||
|
@ -66,6 +149,8 @@ namespace {
|
|||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getXMax () const;
|
||||
inline DbU::Unit getWidth () const;
|
||||
inline Cell* getMasterCell () const;
|
||||
inline Instance* getInstance () const;
|
||||
inline const Occurrence& getOccurrence () const;
|
||||
inline void translate ( DbU::Unit );
|
||||
private:
|
||||
|
@ -82,17 +167,17 @@ namespace {
|
|||
inline DbU::Unit Tile::getXMax () const { return _xMin+_width; }
|
||||
inline DbU::Unit Tile::getWidth () const { return _width; }
|
||||
inline const Occurrence& Tile::getOccurrence () const { return _occurrence; }
|
||||
inline Instance* Tile::getInstance () const { return static_cast<Instance*>( _occurrence.getEntity() ); }
|
||||
inline Cell* Tile::getMasterCell () const { return getInstance()->getMasterCell(); }
|
||||
|
||||
inline bool Tile::isFixed () const
|
||||
{
|
||||
return static_cast<Instance*>( _occurrence.getEntity() )->getPlacementStatus()
|
||||
== Instance::PlacementStatus::FIXED;
|
||||
}
|
||||
{ return getInstance()->getPlacementStatus() == Instance::PlacementStatus::FIXED; }
|
||||
|
||||
|
||||
inline void Tile::translate ( DbU::Unit dx )
|
||||
{
|
||||
cerr << " Tile::translate(), dx:" << DbU::getValueString(dx) << ", " << _occurrence << endl;
|
||||
Instance* instance = static_cast<Instance*>( _occurrence.getEntity() );
|
||||
cdebug_log(121,0) << " Tile::translate(), dx:" << DbU::getValueString(dx) << ", " << _occurrence << endl;
|
||||
Instance* instance = getInstance();
|
||||
Transformation reference = instance->getTransformation();
|
||||
Transformation transf = Transformation( reference.getTx() + dx
|
||||
, reference.getTy()
|
||||
|
@ -137,6 +222,7 @@ namespace {
|
|||
SubSlice ( Slice*, const list<Tile>::iterator& beginTile );
|
||||
inline const list<Tile>::iterator getBeginTile () const;
|
||||
inline const list<Tile>::iterator getEndTile () const;
|
||||
inline DbU::Unit getYBottom () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getXMax () const;
|
||||
DbU::Unit getAverageChunk ( size_t& ) const;
|
||||
|
@ -156,23 +242,25 @@ namespace {
|
|||
|
||||
class Slice {
|
||||
public:
|
||||
Slice ( Area*, DbU::Unit ybottom );
|
||||
inline DbU::Unit getYBottom () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getXMax () const;
|
||||
inline Interval getXSpan () const;
|
||||
inline Area* getArea () const;
|
||||
inline EtesianEngine* getEtesian () const;
|
||||
inline size_t getSpinSlice0 () const;
|
||||
bool validate () const;
|
||||
inline list<Tile>& getTiles ();
|
||||
void merge ( const Occurrence&, const Box& );
|
||||
void addFeeds ( size_t islice );
|
||||
void fillHole ( DbU::Unit xmin, DbU::Unit xmax, DbU::Unit ybottom, size_t yspin );
|
||||
void buildSubSlices ();
|
||||
void showSubSlices ();
|
||||
void insertTies ( DbU::Unit latchUpMax );
|
||||
string _getString () const;
|
||||
Slice ( Area*, DbU::Unit ybottom );
|
||||
inline DbU::Unit getYBottom () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getXMax () const;
|
||||
inline Interval getXSpan () const;
|
||||
inline Area* getArea () const;
|
||||
inline EtesianEngine* getEtesian () const;
|
||||
inline size_t getSpinSlice0 () const;
|
||||
inline DbU::Unit getLeftDistance ( Cell* cell ) const;
|
||||
inline DbU::Unit getRightDistance ( Cell* cell ) const;
|
||||
bool validate ( DbU::Unit latchUpMax ) const;
|
||||
inline list<Tile>& getTiles ();
|
||||
void merge ( const Occurrence&, const Box& );
|
||||
void addFeeds ( size_t islice );
|
||||
void fillHole ( DbU::Unit xmin, DbU::Unit xmax, DbU::Unit ybottom, size_t yspin );
|
||||
void buildSubSlices ();
|
||||
void showSubSlices ();
|
||||
void insertTies ( DbU::Unit latchUpMax );
|
||||
string _getString () const;
|
||||
private:
|
||||
Area* _area;
|
||||
DbU::Unit _ybottom;
|
||||
|
@ -189,15 +277,39 @@ namespace {
|
|||
{ }
|
||||
|
||||
|
||||
bool Slice::validate () const
|
||||
bool Slice::validate ( DbU::Unit latchUpMax ) const
|
||||
{
|
||||
if (_tiles.empty()) return true;
|
||||
|
||||
bool validated = true;
|
||||
auto iTile = _tiles.begin();
|
||||
auto iTileNext = iTile;
|
||||
cdebug_log(121,1) << "Slice::validate() @Y=" << DbU::getValueString(_ybottom) << endl;
|
||||
|
||||
Cell* feed = getEtesian()->getFeedCells().getBiggestFeed();
|
||||
DbU::Unit feedWidth = feed->getAbutmentBox().getWidth();
|
||||
DbU::Unit cellLength = 0;
|
||||
bool validated = true;
|
||||
auto iTile = _tiles.begin();
|
||||
auto iTileNext = iTile;
|
||||
auto iTileFeed = _tiles.begin();
|
||||
++iTileNext;
|
||||
while ( iTileNext != _tiles.end() ) {
|
||||
cellLength += (*iTile).getWidth();
|
||||
if ( ((*iTileNext).getXMin() - (*iTile).getXMax() >= feedWidth)
|
||||
or ((*iTile).getMasterCell() == feed)) {
|
||||
if ((*iTile).getMasterCell() == feed)
|
||||
cellLength -= feedWidth;
|
||||
//if (feed and ((*iTile).getMasterCell() == feed)) {
|
||||
cdebug_log(121,0) << "cellLength=" << DbU::getValueString(cellLength) << endl;
|
||||
if (cellLength > latchUpMax) {
|
||||
while ( (iTileFeed != iTileNext) and (iTileFeed != _tiles.end()) ) {
|
||||
cdebug_log(121,0) << "| " << DbU::getValueString((*iTileFeed).getXMin())
|
||||
<< " " << (*iTileFeed).getOccurrence() << endl;
|
||||
++iTileFeed;
|
||||
}
|
||||
} else {
|
||||
iTileFeed = iTileNext;
|
||||
}
|
||||
cellLength = 0;
|
||||
}
|
||||
if ((*iTile).getXMax() > (*iTileNext).getXMin()) {
|
||||
cerr << Error( "Slice::validate(): Overlap in slice @%s between instances,\n"
|
||||
" %s @%s\n"
|
||||
|
@ -213,6 +325,7 @@ namespace {
|
|||
++iTile; ++iTileNext;
|
||||
}
|
||||
|
||||
cdebug_log(121,-1);
|
||||
return validated;
|
||||
}
|
||||
|
||||
|
@ -251,23 +364,24 @@ namespace {
|
|||
{
|
||||
if (_tiles.empty()) return;
|
||||
|
||||
cerr << "+ Slice @" << DbU::getValueString(_ybottom) << endl;
|
||||
cdebug_log(121,0) << "+ Slice @" << DbU::getValueString(_ybottom) << endl;
|
||||
for ( const SubSlice& subSlice : _subSlices ) {
|
||||
size_t count = 0;
|
||||
DbU::Unit avg = subSlice.getAverageChunk( count );
|
||||
cerr << "| [" << DbU::getValueString(subSlice.getXMin())
|
||||
<< " " << DbU::getValueString(subSlice.getXMax())
|
||||
<< "] tiles:" << count
|
||||
<< " avg:" << DbU::getValueString(avg)
|
||||
<< " " << endl;
|
||||
cdebug_log(121,0) << "| [" << DbU::getValueString(subSlice.getXMin())
|
||||
<< " " << DbU::getValueString(subSlice.getXMax())
|
||||
<< "] tiles:" << count
|
||||
<< " avg:" << DbU::getValueString(avg)
|
||||
<< " " << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Slice::insertTies ( DbU::Unit latchUpMax )
|
||||
{
|
||||
cerr << "Slice::insertTies() @" << DbU::getValueString(_ybottom) << endl;
|
||||
cdebug_log(121,1) << "Slice::insertTies() @" << DbU::getValueString(_ybottom) << endl;
|
||||
for ( SubSlice& subSlice : _subSlices ) subSlice.insertTies( latchUpMax );
|
||||
cdebug_tabw(121,-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,21 +460,24 @@ namespace {
|
|||
|
||||
class Area {
|
||||
public:
|
||||
Area ( EtesianEngine* );
|
||||
~Area ();
|
||||
inline EtesianEngine* getEtesian () const;
|
||||
inline size_t getSpinSlice0 () const;
|
||||
inline void setSpinSlice0 ( size_t );
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getXMax () const;
|
||||
bool validate () const;
|
||||
void merge ( const Occurrence&, const Box& );
|
||||
void addFeeds ();
|
||||
void buildSubSlices ();
|
||||
void showSubSlices ();
|
||||
void insertTies ( DbU::Unit latchUpMax );
|
||||
Area ( EtesianEngine* );
|
||||
~Area ();
|
||||
inline EtesianEngine* getEtesian () const;
|
||||
inline size_t getSpinSlice0 () const;
|
||||
inline void setSpinSlice0 ( size_t );
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getXMax () const;
|
||||
inline DbU::Unit getLeftDistance ( Cell* cell ) const;
|
||||
inline DbU::Unit getRightDistance ( Cell* cell ) const;
|
||||
bool validate ( DbU::Unit latchUpMax ) const;
|
||||
void merge ( const Occurrence&, const Box& );
|
||||
void addFeeds ();
|
||||
void buildSubSlices ();
|
||||
void showSubSlices ();
|
||||
void insertTies ( DbU::Unit latchUpMax );
|
||||
private:
|
||||
EtesianEngine* _etesian;
|
||||
TieLUT _tieLut;
|
||||
Box _cellAb;
|
||||
DbU::Unit _sliceHeight;
|
||||
vector<Slice*> _slices;
|
||||
|
@ -370,6 +487,7 @@ namespace {
|
|||
|
||||
Area::Area ( EtesianEngine* etesian )
|
||||
: _etesian (etesian)
|
||||
, _tieLut ()
|
||||
, _cellAb (etesian->getBlockCell()->getAbutmentBox())
|
||||
, _sliceHeight(_etesian->getSliceHeight())
|
||||
, _slices ()
|
||||
|
@ -377,6 +495,18 @@ namespace {
|
|||
size_t slicesNb = _cellAb.getHeight() / _sliceHeight;
|
||||
for ( size_t islice=0 ; islice<slicesNb ; ++islice )
|
||||
_slices.push_back( new Slice( this, _cellAb.getYMin()+islice*_sliceHeight ) );
|
||||
|
||||
Cell* feed = getEtesian()->getFeedCells().getBiggestFeed();
|
||||
if (feed) {
|
||||
Library* library = feed->getLibrary();
|
||||
if (feed->getLibrary()->getName() == "FlexLib") {
|
||||
cmess2 << " o Using hard-coded tie/cell datas suited for \"FlexLib\"." << endl;
|
||||
Cell* masterCell = library->getCell( "sff1_x4" );
|
||||
if (masterCell) {
|
||||
_tieLut.addTieDatas( masterCell, DbU::fromMicrons(1.28), DbU::fromMicrons(11.7) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -387,18 +517,20 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
inline EtesianEngine* Area::getEtesian () const { return _etesian; }
|
||||
inline size_t Area::getSpinSlice0 () const { return _spinSlice0; }
|
||||
inline void Area::setSpinSlice0 ( size_t spinSlice0 ) { _spinSlice0 = spinSlice0; }
|
||||
inline DbU::Unit Area::getXMin () const { return _cellAb.getXMin(); }
|
||||
inline DbU::Unit Area::getXMax () const { return _cellAb.getXMax(); }
|
||||
inline EtesianEngine* Area::getEtesian () const { return _etesian; }
|
||||
inline size_t Area::getSpinSlice0 () const { return _spinSlice0; }
|
||||
inline void Area::setSpinSlice0 ( size_t spinSlice0 ) { _spinSlice0 = spinSlice0; }
|
||||
inline DbU::Unit Area::getXMin () const { return _cellAb.getXMin(); }
|
||||
inline DbU::Unit Area::getXMax () const { return _cellAb.getXMax(); }
|
||||
inline DbU::Unit Area::getLeftDistance ( Cell* cell ) const { return _tieLut.getLeftDistance(cell); }
|
||||
inline DbU::Unit Area::getRightDistance ( Cell* cell ) const { return _tieLut.getRightDistance(cell); }
|
||||
|
||||
|
||||
bool Area::validate () const
|
||||
bool Area::validate ( DbU::Unit latchUpMax ) const
|
||||
{
|
||||
bool validated = true;
|
||||
for ( const Slice* slice : _slices )
|
||||
validated = validated and slice->validate();
|
||||
validated = slice->validate(latchUpMax) and validated;
|
||||
return validated;
|
||||
}
|
||||
|
||||
|
@ -438,7 +570,7 @@ namespace {
|
|||
void Area::insertTies ( DbU::Unit latchUpMax )
|
||||
{
|
||||
for ( Slice* slice : _slices ) slice->insertTies( latchUpMax );
|
||||
validate();
|
||||
validate( latchUpMax );
|
||||
}
|
||||
|
||||
|
||||
|
@ -454,6 +586,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
inline DbU::Unit SubSlice::getYBottom () const { return _slice->getYBottom(); }
|
||||
|
||||
inline DbU::Unit SubSlice::getXMin () const
|
||||
{ return (_beginTile == _slice->getTiles().begin()) ? _slice->getXMin() : (*_beginTile).getXMin(); }
|
||||
|
@ -485,6 +618,16 @@ namespace {
|
|||
|
||||
void SubSlice::insertTies ( DbU::Unit latchUpMax )
|
||||
{
|
||||
size_t count = 0;
|
||||
DbU::Unit averageChunk = getAverageChunk( count );
|
||||
if (averageChunk > latchUpMax) {
|
||||
cerr << Error( "SubSlice::insertTies(): Not enough free space to insert polarization ties.\n"
|
||||
" @Y=%s, begin=%s"
|
||||
, getString(DbU::getValueString(getYBottom())).c_str()
|
||||
, getString((*_beginTile).getOccurrence()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
|
||||
Cell* feed = _slice->getEtesian()->getFeedCells().getBiggestFeed();
|
||||
if (feed == NULL) {
|
||||
cerr << Error( "SubSlice::insertTies(): No feed has been registered, ignoring." ) << endl;
|
||||
|
@ -492,8 +635,8 @@ namespace {
|
|||
}
|
||||
DbU::Unit feedWidth = feed->getAbutmentBox().getWidth();
|
||||
|
||||
cerr << "SubSlice::insterTies(): LatchUpMax:" << DbU::getValueString( latchUpMax ) << endl;
|
||||
cerr << " Direct subSlice walkthrough." << endl;
|
||||
cdebug_log(121,1) << "SubSlice::insterTies(): LatchUpMax:" << DbU::getValueString( latchUpMax ) << endl;
|
||||
cdebug_log(121,1) << "Direct subSlice walkthrough." << endl;
|
||||
|
||||
DbU::Unit xMin = getXMin();
|
||||
DbU::Unit xMax = getXMax();
|
||||
|
@ -514,15 +657,23 @@ namespace {
|
|||
DbU::Unit tileLength = 0;
|
||||
auto iTile = _beginTile;
|
||||
while ( true ) {
|
||||
Instance* instance = (*iTile).getInstance();
|
||||
DbU::Unit cellTieLeft = _slice->getLeftDistance ( instance->getMasterCell() );
|
||||
DbU::Unit cellTieRight = _slice->getRightDistance( instance->getMasterCell() );
|
||||
|
||||
DbU::Unit dxLeft = (*iTile).getXMin() - leftPosition;
|
||||
if (dxLeft >= feedWidth) {
|
||||
cerr << " Enough space, reset rigth shift." << endl;
|
||||
cdebug_log(121,0) << "Enough space, reset rigth shift." << endl;
|
||||
leftPosition = (*iTile).getXMin();
|
||||
tileLength = 0;
|
||||
}
|
||||
if (cellTieLeft) {
|
||||
cdebug_log(121,0) << instance->getName() << " contains a tie, reset tile length." << endl;
|
||||
tileLength = cellTieRight;
|
||||
}
|
||||
|
||||
if (tileLength + (*iTile).getWidth() > latchUpMax) {
|
||||
cerr << " Length above threshold, insert tie space." << endl;
|
||||
cdebug_log(121,0) << "Length above threshold, insert tie space." << endl;
|
||||
leftPosition += feedWidth;
|
||||
tileLength = 0;
|
||||
}
|
||||
|
@ -535,62 +686,86 @@ namespace {
|
|||
++iTile;
|
||||
}
|
||||
|
||||
cerr << " Reverse subSlice walkthrough (feedWidth:" << DbU::getValueString(feedWidth) << ")" << endl;
|
||||
leftPosition = xMax;
|
||||
iTile = endTile;
|
||||
if (iTile == _slice->getTiles().end()) --iTile;
|
||||
|
||||
cdebug_tabw(121,-1);
|
||||
cdebug_log(121,1) << "Reverse subSlice walkthrough, in excess of "
|
||||
<< DbU::getValueString((*iTile).getXMax() - leftPosition)
|
||||
<< " (feedWidth:" << DbU::getValueString(feedWidth) << ")" << endl;
|
||||
|
||||
if ((*iTile).getXMax() > leftPosition) {
|
||||
tileLength = 0;
|
||||
DbU::Unit prevDxRight = (*iTile).getXMax() - leftPosition;
|
||||
DbU::Unit prevTileShift = leftPosition - (*iTile).getXMax();
|
||||
while ( true ) {
|
||||
DbU::Unit dxRight = (*iTile).getXMax() - leftPosition;
|
||||
if (dxRight <= 0) {
|
||||
cerr << " Negative dxRight, all shift has been compensated." << endl;
|
||||
Instance* instance = (*iTile).getInstance();
|
||||
DbU::Unit cellTieLeft = _slice->getLeftDistance ( instance->getMasterCell() );
|
||||
DbU::Unit cellTieRight = _slice->getRightDistance( instance->getMasterCell() );
|
||||
if (cellTieRight) {
|
||||
cdebug_log(121,0) << instance->getName() << " contains a tie, reset tile length." << endl;
|
||||
tileLength = cellTieLeft - (*iTile).getWidth();
|
||||
}
|
||||
|
||||
DbU::Unit tileShift = leftPosition - (*iTile).getXMax();
|
||||
cdebug_log(121,0) << "tileShift=" << DbU::getValueString(tileShift)
|
||||
<< " leftHole=" << DbU::getValueString(prevTileShift-tileShift)
|
||||
<< endl;
|
||||
DbU::Unit holeLength = tileShift - prevTileShift;
|
||||
if (holeLength == 0) {
|
||||
cdebug_log(121,0) << "No change in shift (no hole, abuted tiles)." << endl;
|
||||
} else {
|
||||
if (holeLength < feedWidth) {
|
||||
cdebug_log(121,0) << "Hole is less than a feed width ("
|
||||
<< DbU::getValueString(holeLength) << " < "
|
||||
<< DbU::getValueString(feedWidth) << "), should not occur." << endl;
|
||||
} else {
|
||||
if (tileLength+(*iTile).getWidth() < latchUpMax) {
|
||||
cdebug_log(121,0) << "Absorbing whole shift (below latch up distance, tile length="
|
||||
<< DbU::getValueString(tileLength) << ")" << endl;
|
||||
} else {
|
||||
cdebug_log(121,0) << "Absorbing shift, keeping one feed spacing." << endl;
|
||||
leftPosition -= feedWidth;
|
||||
tileLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_log(121,0) << "Left position (+width) " << DbU::getValueString(leftPosition)
|
||||
<< " width:" << DbU::getValueString((*iTile).getWidth()) << endl;
|
||||
if (leftPosition > (*iTile).getXMax()) {
|
||||
cdebug_log(121,0) << "Positive tileShift, all excess has been compensated." << endl;
|
||||
break;
|
||||
}
|
||||
DbU::Unit leftHole = prevDxRight - dxRight;
|
||||
if (leftHole > feedWidth) {
|
||||
cerr << " Absorbing shift (wide hole)" << endl;
|
||||
leftHole -= feedWidth;
|
||||
leftPosition += leftHole;
|
||||
prevDxRight = dxRight - leftHole;
|
||||
tileLength = 0;
|
||||
} else if (leftHole != 0) {
|
||||
if (tileLength+(*iTile).getWidth() < latchUpMax) {
|
||||
cerr << " Absorbing shift (full, below latchUp) delta leftPos:"
|
||||
<< DbU::getValueString(leftHole) << endl;
|
||||
leftHole = 0;
|
||||
} else {
|
||||
cerr << " Keeping spacing." << endl;
|
||||
leftPosition -= leftHole;
|
||||
tileLength = 0;
|
||||
}
|
||||
prevDxRight = dxRight - leftHole;
|
||||
} else {
|
||||
cerr << " No change in shift." << endl;
|
||||
}
|
||||
|
||||
cerr << " Left position (+width) " << DbU::getValueString(leftPosition)
|
||||
<< " width:" << DbU::getValueString((*iTile).getWidth()) << endl;
|
||||
(*iTile).translate( leftPosition - (*iTile).getXMax() );
|
||||
leftPosition -= (*iTile).getWidth();
|
||||
tileLength += (*iTile).getWidth();
|
||||
|
||||
if (iTile == _beginTile) break;
|
||||
if (iTile == _beginTile) {
|
||||
cerr << Error( "SubSlice::insertTies(): Not enough free space to insert polarization ties.\n"
|
||||
" @Y=%s, begin=%s"
|
||||
, getString(DbU::getValueString(getYBottom())).c_str()
|
||||
, getString((*iTile).getOccurrence()).c_str()
|
||||
) << endl;
|
||||
break;
|
||||
}
|
||||
--iTile;
|
||||
}
|
||||
}
|
||||
cdebug_tabw(121,-2);
|
||||
}
|
||||
|
||||
|
||||
inline DbU::Unit Slice::getYBottom () const { return _ybottom; }
|
||||
inline DbU::Unit Slice::getXMin () const { return _area->getXMin(); }
|
||||
inline DbU::Unit Slice::getXMax () const { return _area->getXMax(); }
|
||||
inline Interval Slice::getXSpan () const { return Interval( getXMin(), getXMax() ); }
|
||||
inline Area* Slice::getArea () const { return _area; }
|
||||
inline EtesianEngine* Slice::getEtesian () const { return getArea()->getEtesian(); }
|
||||
inline size_t Slice::getSpinSlice0 () const { return getArea()->getSpinSlice0(); }
|
||||
inline list<Tile>& Slice::getTiles () { return _tiles; }
|
||||
inline DbU::Unit Slice::getYBottom () const { return _ybottom; }
|
||||
inline DbU::Unit Slice::getXMin () const { return _area->getXMin(); }
|
||||
inline DbU::Unit Slice::getXMax () const { return _area->getXMax(); }
|
||||
inline DbU::Unit Slice::getLeftDistance ( Cell* cell ) const { return _area->getLeftDistance(cell); }
|
||||
inline DbU::Unit Slice::getRightDistance ( Cell* cell ) const { return _area->getRightDistance(cell); }
|
||||
inline Interval Slice::getXSpan () const { return Interval( getXMin(), getXMax() ); }
|
||||
inline Area* Slice::getArea () const { return _area; }
|
||||
inline EtesianEngine* Slice::getEtesian () const { return getArea()->getEtesian(); }
|
||||
inline size_t Slice::getSpinSlice0 () const { return getArea()->getSpinSlice0(); }
|
||||
inline list<Tile>& Slice::getTiles () { return _tiles; }
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
@ -662,8 +837,8 @@ namespace Etesian {
|
|||
area.buildSubSlices();
|
||||
area.showSubSlices();
|
||||
if (getConfiguration()->getLatchUpDistance()) {
|
||||
DbU::Unit tieSpacing = getConfiguration()->getLatchUpDistance()*2;
|
||||
Cell* feed = getFeedCells().getBiggestFeed();
|
||||
DbU::Unit tieSpacing = getConfiguration()->getLatchUpDistance()*2 - feed->getAbutmentBox().getWidth();
|
||||
if (feed != NULL)
|
||||
tieSpacing -= feed->getAbutmentBox().getWidth();
|
||||
area.insertTies( tieSpacing );
|
||||
|
|
Loading…
Reference in New Issue