Use fill_x0 instead of tie_x0 in Etesian::Slice::fillHole()
* Change: In Etesian::Slice::fillHole(), instead of cramming the home with tix_x0 only, put one tie at both ends and fill the rest with fill_x0. This should help the vendor density filler to equalze. * New: In Etesian::Configuration, add the parameter: "etesian.tieName" (for tix_x0) as it now separate from the simple filler cells.
This commit is contained in:
parent
fdf66cbf64
commit
6fc7ece575
|
@ -69,7 +69,8 @@ def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False )
|
||||||
if cell.getName().endswith('_cts'): views |= CRL.Catalog.State.Logical
|
if cell.getName().endswith('_cts'): views |= CRL.Catalog.State.Logical
|
||||||
if cell.getName().endswith('_r' ): views |= CRL.Catalog.State.Logical
|
if cell.getName().endswith('_r' ): views |= CRL.Catalog.State.Logical
|
||||||
framework.saveCell( cell, views )
|
framework.saveCell( cell, views )
|
||||||
CRL.Spice.save( cell )
|
spiceFlags = CRL.Spice.TopCell if depth == 0 else 0
|
||||||
|
CRL.Spice.save( cell, spiceFlags )
|
||||||
for instance in cell.getInstances():
|
for instance in cell.getInstances():
|
||||||
#print( ' {}| {}.'.format(' '*(depth*2), instance) )
|
#print( ' {}| {}.'.format(' '*(depth*2), instance) )
|
||||||
masterCell = instance.getMasterCell()
|
masterCell = instance.getMasterCell()
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace Etesian {
|
||||||
, _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() )
|
, _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() )
|
||||||
, _antennaInsertThreshold
|
, _antennaInsertThreshold
|
||||||
( Cfg::getParamDouble ("etesian.antennaInsertThreshold", 50.0)->asDouble() )
|
( Cfg::getParamDouble ("etesian.antennaInsertThreshold", 50.0)->asDouble() )
|
||||||
|
, _tieName ( Cfg::getParamString ("etesian.tieName" ,"tie_x0" )->asString() )
|
||||||
, _feedNames ( Cfg::getParamString ("etesian.feedNames" ,"tie_x0,rowend_x0")->asString() )
|
, _feedNames ( Cfg::getParamString ("etesian.feedNames" ,"tie_x0,rowend_x0")->asString() )
|
||||||
, _diodeName ( Cfg::getParamString ("etesian.diodeName" ,"dio_x0" )->asString() )
|
, _diodeName ( Cfg::getParamString ("etesian.diodeName" ,"dio_x0" )->asString() )
|
||||||
, _spareBufferName ( Cfg::getParamString ("spares.buffer" ,"buf_x8" )->asString() )
|
, _spareBufferName ( Cfg::getParamString ("spares.buffer" ,"buf_x8" )->asString() )
|
||||||
|
@ -107,6 +108,7 @@ namespace Etesian {
|
||||||
, _spaceMargin ( other._spaceMargin )
|
, _spaceMargin ( other._spaceMargin )
|
||||||
, _aspectRatio ( other._aspectRatio )
|
, _aspectRatio ( other._aspectRatio )
|
||||||
, _antennaInsertThreshold( other._antennaInsertThreshold )
|
, _antennaInsertThreshold( other._antennaInsertThreshold )
|
||||||
|
, _tieName ( other._tieName )
|
||||||
, _feedNames ( other._feedNames )
|
, _feedNames ( other._feedNames )
|
||||||
, _diodeName ( other._diodeName )
|
, _diodeName ( other._diodeName )
|
||||||
, _spareBufferName ( other._spareBufferName )
|
, _spareBufferName ( other._spareBufferName )
|
||||||
|
@ -173,6 +175,7 @@ namespace Etesian {
|
||||||
record->add ( getSlot( "_spaceMargin" , _spaceMargin ) );
|
record->add ( getSlot( "_spaceMargin" , _spaceMargin ) );
|
||||||
record->add ( getSlot( "_aspectRatio" , _aspectRatio ) );
|
record->add ( getSlot( "_aspectRatio" , _aspectRatio ) );
|
||||||
record->add ( getSlot( "_antennaInsertThreshold", _antennaInsertThreshold ) );
|
record->add ( getSlot( "_antennaInsertThreshold", _antennaInsertThreshold ) );
|
||||||
|
record->add ( getSlot( "_tieName" , _tieName ) );
|
||||||
record->add ( getSlot( "_feedNames" , _feedNames ) );
|
record->add ( getSlot( "_feedNames" , _feedNames ) );
|
||||||
record->add ( getSlot( "_diodeName" , _diodeName ) );
|
record->add ( getSlot( "_diodeName" , _diodeName ) );
|
||||||
record->add ( getSlot( "_spareBufferName" , _spareBufferName ) );
|
record->add ( getSlot( "_spareBufferName" , _spareBufferName ) );
|
||||||
|
|
|
@ -381,6 +381,13 @@ namespace Etesian {
|
||||||
, feedName.c_str()
|
, feedName.c_str()
|
||||||
) << endl;
|
) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string tieName = getConfiguration()->getTieName();
|
||||||
|
Cell* tie = DataBase::getDB()->getCell( tieName );
|
||||||
|
if (not tie)
|
||||||
|
tie = AllianceFramework::get()->getCell( tieName, Catalog::State::Views|Catalog::State::Foreign );
|
||||||
|
if (tie)
|
||||||
|
_feedCells.useTie( tie );
|
||||||
}
|
}
|
||||||
_sliceHeight = getCellGauge()->getSliceHeight();
|
_sliceHeight = getCellGauge()->getSliceHeight();
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,25 @@ namespace Etesian {
|
||||||
using Hurricane::DbU;
|
using Hurricane::DbU;
|
||||||
|
|
||||||
|
|
||||||
|
void FeedCells::useTie ( Cell* cell )
|
||||||
|
{
|
||||||
|
if (cell == NULL) return;
|
||||||
|
|
||||||
|
DbU::Unit pitch = _etesian->getSliceStep();
|
||||||
|
|
||||||
|
if (cell->getAbutmentBox().getWidth() % pitch != 0)
|
||||||
|
cerr << Warning( "FeedCells::useTie(): \"%s\" has not a width (%s) multiple of pitch (%s)."
|
||||||
|
, getString(cell->getName()).c_str()
|
||||||
|
, DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str()
|
||||||
|
, DbU::getValueString(pitch).c_str()
|
||||||
|
) << endl;
|
||||||
|
|
||||||
|
int pitchNb = (int)( cell->getAbutmentBox().getWidth() / pitch );
|
||||||
|
|
||||||
|
_tieCell = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FeedCells::useFeed ( Cell* cell )
|
void FeedCells::useFeed ( Cell* cell )
|
||||||
{
|
{
|
||||||
if ( cell == NULL ) return;
|
if ( cell == NULL ) return;
|
||||||
|
@ -39,7 +58,7 @@ namespace Etesian {
|
||||||
DbU::Unit pitch = _etesian->getSliceStep();
|
DbU::Unit pitch = _etesian->getSliceStep();
|
||||||
|
|
||||||
if (cell->getAbutmentBox().getWidth() % pitch != 0)
|
if (cell->getAbutmentBox().getWidth() % pitch != 0)
|
||||||
cerr << Warning( "FeedCells::addFeed(): \"%s\" has not a width (%s) multiple of pitch (%s)."
|
cerr << Warning( "FeedCells::useFeed(): \"%s\" has not a width (%s) multiple of pitch (%s)."
|
||||||
, getString(cell->getName()).c_str()
|
, getString(cell->getName()).c_str()
|
||||||
, DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str()
|
, DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str()
|
||||||
, DbU::getValueString(pitch).c_str()
|
, DbU::getValueString(pitch).c_str()
|
||||||
|
|
|
@ -227,7 +227,6 @@ namespace Etesian {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbU::Unit feedWidth = feed->getAbutmentBox().getWidth();
|
|
||||||
DbU::Unit xtie = xmin;
|
DbU::Unit xtie = xmin;
|
||||||
DbU::Unit modulo = (xmin - getXMin()) % getEtesian()->getSliceStep();
|
DbU::Unit modulo = (xmin - getXMin()) % getEtesian()->getSliceStep();
|
||||||
if (modulo) {
|
if (modulo) {
|
||||||
|
@ -239,7 +238,60 @@ namespace Etesian {
|
||||||
// << " getXMin()=" << DbU::getValueString(getXMin())
|
// << " getXMin()=" << DbU::getValueString(getXMin())
|
||||||
// << endl;
|
// << endl;
|
||||||
}
|
}
|
||||||
|
modulo = (xmax - getXMin()) % getEtesian()->getSliceStep();
|
||||||
|
if (modulo) xmax -= modulo;
|
||||||
|
|
||||||
|
Cell* tie = getEtesian()->getFeedCells().getTie();
|
||||||
|
DbU::Unit feedWidth = 0;
|
||||||
|
if (tie) {
|
||||||
|
DbU::Unit feedWidth = tie->getAbutmentBox().getWidth();
|
||||||
|
if (xtie+feedWidth < xmax) {
|
||||||
|
Point blockPoint = getEtesian()->toBlock( Point(xtie,_ybottom) );
|
||||||
|
Instance* instance = Instance::create
|
||||||
|
( getEtesian()->getBlockCell()
|
||||||
|
, getEtesian()->getFeedCells().getUniqueInstanceName().c_str()
|
||||||
|
, tie
|
||||||
|
, getTransformation( tie->getAbutmentBox()
|
||||||
|
, blockPoint.getX()
|
||||||
|
, blockPoint.getY()
|
||||||
|
, (yspin) ? Transformation::Orientation::MY
|
||||||
|
: Transformation::Orientation::ID
|
||||||
|
)
|
||||||
|
, Instance::PlacementStatus::PLACED
|
||||||
|
);
|
||||||
|
_tiles.insert( before
|
||||||
|
, Tile( xtie
|
||||||
|
, tie->getAbutmentBox().getWidth()
|
||||||
|
, getEtesian()->toCell( Occurrence(instance) )));
|
||||||
|
xtie += feedWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xtie+feedWidth < xmax) {
|
||||||
|
Point blockPoint = getEtesian()->toBlock( Point(xmax-feedWidth,_ybottom) );
|
||||||
|
Instance* instance = Instance::create
|
||||||
|
( getEtesian()->getBlockCell()
|
||||||
|
, getEtesian()->getFeedCells().getUniqueInstanceName().c_str()
|
||||||
|
, tie
|
||||||
|
, getTransformation( tie->getAbutmentBox()
|
||||||
|
, blockPoint.getX()
|
||||||
|
, blockPoint.getY()
|
||||||
|
, (yspin) ? Transformation::Orientation::MY
|
||||||
|
: Transformation::Orientation::ID
|
||||||
|
)
|
||||||
|
, Instance::PlacementStatus::PLACED
|
||||||
|
);
|
||||||
|
_tiles.insert( before
|
||||||
|
, Tile( xmax-feedWidth
|
||||||
|
, tie->getAbutmentBox().getWidth()
|
||||||
|
, getEtesian()->toCell( Occurrence(instance) )));
|
||||||
|
xmax -= feedWidth;
|
||||||
|
before--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << Error("Slice::fillHole(): No tie has been registered, not inserting.") << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
feedWidth = feed->getAbutmentBox().getWidth();
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
if (xtie >= xmax) break;
|
if (xtie >= xmax) break;
|
||||||
if (xtie+feedWidth > xmax) {
|
if (xtie+feedWidth > xmax) {
|
||||||
|
@ -290,6 +342,11 @@ namespace Etesian {
|
||||||
cerr << Error("Slice::createDiodeUnder(): No feed has been registered, ignoring.") << endl;
|
cerr << Error("Slice::createDiodeUnder(): No feed has been registered, ignoring.") << endl;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Cell* tie = getEtesian()->getFeedCells().getTie();
|
||||||
|
if (tie == NULL) {
|
||||||
|
cerr << Error("Slice::createDiodeUnder(): No tie has been registered, ignoring.") << endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
cdebug_log(147,0) << "Slice::createDiodeUnder(): xHint=" << DbU::getValueString(xHint) << endl;
|
cdebug_log(147,0) << "Slice::createDiodeUnder(): xHint=" << DbU::getValueString(xHint) << endl;
|
||||||
cdebug_log(147,0) << " rp=" << rp << endl;
|
cdebug_log(147,0) << " rp=" << rp << endl;
|
||||||
|
@ -304,7 +361,8 @@ namespace Etesian {
|
||||||
if ((*iTile).getXMax() <= diodeArea.getXMin()) continue;
|
if ((*iTile).getXMax() <= diodeArea.getXMin()) continue;
|
||||||
if ((*iTile).getXMin() >= diodeArea.getXMax()) break;
|
if ((*iTile).getXMin() >= diodeArea.getXMax()) break;
|
||||||
cdebug_log(147,0) << "| " << (*iTile) << endl;
|
cdebug_log(147,0) << "| " << (*iTile) << endl;
|
||||||
if ((*iTile).getMasterCell() != feed) continue;
|
if ( ((*iTile).getMasterCell() != feed)
|
||||||
|
and ((*iTile).getMasterCell() != tie )) continue;
|
||||||
if (blockInst) {
|
if (blockInst) {
|
||||||
if ((*iTile).getOccurrence().getPath().getHeadInstance() != blockInst) {
|
if ((*iTile).getOccurrence().getPath().getHeadInstance() != blockInst) {
|
||||||
cdebug_log(147,0) << "> Reject, not in block instance" << endl;
|
cdebug_log(147,0) << "> Reject, not in block instance" << endl;
|
||||||
|
|
|
@ -68,6 +68,7 @@ namespace Etesian {
|
||||||
inline double getSpaceMargin () const;
|
inline double getSpaceMargin () const;
|
||||||
inline double getAspectRatio () const;
|
inline double getAspectRatio () const;
|
||||||
inline double getAntennaInsertThreshold () const;
|
inline double getAntennaInsertThreshold () const;
|
||||||
|
inline string getTieName () const;
|
||||||
inline string getFeedNames () const;
|
inline string getFeedNames () const;
|
||||||
inline string getDiodeName () const;
|
inline string getDiodeName () const;
|
||||||
inline string getSpareBufferName () const;
|
inline string getSpareBufferName () const;
|
||||||
|
@ -92,6 +93,7 @@ namespace Etesian {
|
||||||
double _spaceMargin;
|
double _spaceMargin;
|
||||||
double _aspectRatio;
|
double _aspectRatio;
|
||||||
double _antennaInsertThreshold;
|
double _antennaInsertThreshold;
|
||||||
|
string _tieName;
|
||||||
string _feedNames;
|
string _feedNames;
|
||||||
string _diodeName;
|
string _diodeName;
|
||||||
string _spareBufferName;
|
string _spareBufferName;
|
||||||
|
@ -114,6 +116,7 @@ namespace Etesian {
|
||||||
inline double Configuration::getSpaceMargin () const { return _spaceMargin; }
|
inline double Configuration::getSpaceMargin () const { return _spaceMargin; }
|
||||||
inline double Configuration::getAspectRatio () const { return _aspectRatio; }
|
inline double Configuration::getAspectRatio () const { return _aspectRatio; }
|
||||||
inline double Configuration::getAntennaInsertThreshold () const { return _antennaInsertThreshold; }
|
inline double Configuration::getAntennaInsertThreshold () const { return _antennaInsertThreshold; }
|
||||||
|
inline string Configuration::getTieName () const { return _tieName; }
|
||||||
inline string Configuration::getFeedNames () const { return _feedNames; }
|
inline string Configuration::getFeedNames () const { return _feedNames; }
|
||||||
inline string Configuration::getDiodeName () const { return _diodeName; }
|
inline string Configuration::getDiodeName () const { return _diodeName; }
|
||||||
inline string Configuration::getSpareBufferName () const { return _spareBufferName; }
|
inline string Configuration::getSpareBufferName () const { return _spareBufferName; }
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
#ifndef ETESIAN_FEEDCELLS_H
|
#pragma once
|
||||||
#define ETESIAN_FEEDCELLS_H
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
|
|
||||||
|
@ -31,13 +29,16 @@ namespace Etesian {
|
||||||
public:
|
public:
|
||||||
inline FeedCells ( EtesianEngine* );
|
inline FeedCells ( EtesianEngine* );
|
||||||
inline size_t feedNumbers () const;
|
inline size_t feedNumbers () const;
|
||||||
|
void useTie ( Cell* );
|
||||||
void useFeed ( Cell* );
|
void useFeed ( Cell* );
|
||||||
Cell* getBiggestFeed () const;
|
Cell* getBiggestFeed () const;
|
||||||
Cell* getSmallestFeed () const;
|
Cell* getSmallestFeed () const;
|
||||||
|
inline Cell* getTie () const;
|
||||||
Cell* getFeed ( int pitches ) const;
|
Cell* getFeed ( int pitches ) const;
|
||||||
std::string getUniqueInstanceName () const;
|
std::string getUniqueInstanceName () const;
|
||||||
private:
|
private:
|
||||||
EtesianEngine* _etesian;
|
EtesianEngine* _etesian;
|
||||||
|
Cell* _tieCell;
|
||||||
std::map<int,Cell*> _feedCells;
|
std::map<int,Cell*> _feedCells;
|
||||||
mutable unsigned int _feedCount;
|
mutable unsigned int _feedCount;
|
||||||
};
|
};
|
||||||
|
@ -46,14 +47,14 @@ namespace Etesian {
|
||||||
// Inline Methods.
|
// Inline Methods.
|
||||||
inline FeedCells::FeedCells ( EtesianEngine* etesian )
|
inline FeedCells::FeedCells ( EtesianEngine* etesian )
|
||||||
: _etesian (etesian)
|
: _etesian (etesian)
|
||||||
|
, _tieCell (NULL)
|
||||||
, _feedCells()
|
, _feedCells()
|
||||||
, _feedCount(0)
|
, _feedCount(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
inline size_t FeedCells::feedNumbers () const { return _feedCells.size(); }
|
inline size_t FeedCells::feedNumbers () const { return _feedCells.size(); }
|
||||||
|
inline Cell* FeedCells::getTie () const { return _tieCell; }
|
||||||
|
|
||||||
|
|
||||||
} // Etesian namespace.
|
} // Etesian namespace.
|
||||||
|
|
||||||
#endif // ETESIAN_FEEDCELLS_H
|
|
||||||
|
|
Loading…
Reference in New Issue