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('_r' ): views |= CRL.Catalog.State.Logical
|
||||
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():
|
||||
#print( ' {}| {}.'.format(' '*(depth*2), instance) )
|
||||
masterCell = instance.getMasterCell()
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace Etesian {
|
|||
, _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() )
|
||||
, _antennaInsertThreshold
|
||||
( 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() )
|
||||
, _diodeName ( Cfg::getParamString ("etesian.diodeName" ,"dio_x0" )->asString() )
|
||||
, _spareBufferName ( Cfg::getParamString ("spares.buffer" ,"buf_x8" )->asString() )
|
||||
|
@ -107,6 +108,7 @@ namespace Etesian {
|
|||
, _spaceMargin ( other._spaceMargin )
|
||||
, _aspectRatio ( other._aspectRatio )
|
||||
, _antennaInsertThreshold( other._antennaInsertThreshold )
|
||||
, _tieName ( other._tieName )
|
||||
, _feedNames ( other._feedNames )
|
||||
, _diodeName ( other._diodeName )
|
||||
, _spareBufferName ( other._spareBufferName )
|
||||
|
@ -173,6 +175,7 @@ namespace Etesian {
|
|||
record->add ( getSlot( "_spaceMargin" , _spaceMargin ) );
|
||||
record->add ( getSlot( "_aspectRatio" , _aspectRatio ) );
|
||||
record->add ( getSlot( "_antennaInsertThreshold", _antennaInsertThreshold ) );
|
||||
record->add ( getSlot( "_tieName" , _tieName ) );
|
||||
record->add ( getSlot( "_feedNames" , _feedNames ) );
|
||||
record->add ( getSlot( "_diodeName" , _diodeName ) );
|
||||
record->add ( getSlot( "_spareBufferName" , _spareBufferName ) );
|
||||
|
|
|
@ -370,7 +370,7 @@ namespace Etesian {
|
|||
feedNames.clear();
|
||||
}
|
||||
|
||||
Cell* feed = DataBase::getDB()->getCell( feedName );
|
||||
Cell* feed = DataBase::getDB()->getCell( feedName );
|
||||
if (not feed)
|
||||
feed = AllianceFramework::get()->getCell( feedName, Catalog::State::Views|Catalog::State::Foreign );
|
||||
|
||||
|
@ -381,6 +381,13 @@ namespace Etesian {
|
|||
, feedName.c_str()
|
||||
) << 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();
|
||||
|
||||
|
|
|
@ -32,6 +32,25 @@ namespace Etesian {
|
|||
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 )
|
||||
{
|
||||
if ( cell == NULL ) return;
|
||||
|
@ -39,7 +58,7 @@ namespace Etesian {
|
|||
DbU::Unit pitch = _etesian->getSliceStep();
|
||||
|
||||
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()
|
||||
, DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str()
|
||||
, DbU::getValueString(pitch).c_str()
|
||||
|
|
|
@ -227,9 +227,8 @@ namespace Etesian {
|
|||
return;
|
||||
}
|
||||
|
||||
DbU::Unit feedWidth = feed->getAbutmentBox().getWidth();
|
||||
DbU::Unit xtie = xmin;
|
||||
DbU::Unit modulo = (xmin - getXMin()) % getEtesian()->getSliceStep();
|
||||
DbU::Unit xtie = xmin;
|
||||
DbU::Unit modulo = (xmin - getXMin()) % getEtesian()->getSliceStep();
|
||||
if (modulo) {
|
||||
xtie += getEtesian()->getSliceStep() - modulo;
|
||||
// cerr << "Misaligned hole @" << yspin
|
||||
|
@ -239,7 +238,60 @@ namespace Etesian {
|
|||
// << " getXMin()=" << DbU::getValueString(getXMin())
|
||||
// << 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 ) {
|
||||
if (xtie >= xmax) break;
|
||||
if (xtie+feedWidth > xmax) {
|
||||
|
@ -290,6 +342,11 @@ namespace Etesian {
|
|||
cerr << Error("Slice::createDiodeUnder(): No feed has been registered, ignoring.") << endl;
|
||||
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) << " rp=" << rp << endl;
|
||||
|
@ -304,7 +361,8 @@ namespace Etesian {
|
|||
if ((*iTile).getXMax() <= diodeArea.getXMin()) continue;
|
||||
if ((*iTile).getXMin() >= diodeArea.getXMax()) break;
|
||||
cdebug_log(147,0) << "| " << (*iTile) << endl;
|
||||
if ((*iTile).getMasterCell() != feed) continue;
|
||||
if ( ((*iTile).getMasterCell() != feed)
|
||||
and ((*iTile).getMasterCell() != tie )) continue;
|
||||
if (blockInst) {
|
||||
if ((*iTile).getOccurrence().getPath().getHeadInstance() != blockInst) {
|
||||
cdebug_log(147,0) << "> Reject, not in block instance" << endl;
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace Etesian {
|
|||
inline double getSpaceMargin () const;
|
||||
inline double getAspectRatio () const;
|
||||
inline double getAntennaInsertThreshold () const;
|
||||
inline string getTieName () const;
|
||||
inline string getFeedNames () const;
|
||||
inline string getDiodeName () const;
|
||||
inline string getSpareBufferName () const;
|
||||
|
@ -92,6 +93,7 @@ namespace Etesian {
|
|||
double _spaceMargin;
|
||||
double _aspectRatio;
|
||||
double _antennaInsertThreshold;
|
||||
string _tieName;
|
||||
string _feedNames;
|
||||
string _diodeName;
|
||||
string _spareBufferName;
|
||||
|
@ -114,6 +116,7 @@ namespace Etesian {
|
|||
inline double Configuration::getSpaceMargin () const { return _spaceMargin; }
|
||||
inline double Configuration::getAspectRatio () const { return _aspectRatio; }
|
||||
inline double Configuration::getAntennaInsertThreshold () const { return _antennaInsertThreshold; }
|
||||
inline string Configuration::getTieName () const { return _tieName; }
|
||||
inline string Configuration::getFeedNames () const { return _feedNames; }
|
||||
inline string Configuration::getDiodeName () const { return _diodeName; }
|
||||
inline string Configuration::getSpareBufferName () const { return _spareBufferName; }
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ETESIAN_FEEDCELLS_H
|
||||
#define ETESIAN_FEEDCELLS_H
|
||||
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include "hurricane/Cell.h"
|
||||
|
||||
|
@ -31,13 +29,16 @@ namespace Etesian {
|
|||
public:
|
||||
inline FeedCells ( EtesianEngine* );
|
||||
inline size_t feedNumbers () const;
|
||||
void useTie ( Cell* );
|
||||
void useFeed ( Cell* );
|
||||
Cell* getBiggestFeed () const;
|
||||
Cell* getSmallestFeed () const;
|
||||
inline Cell* getTie () const;
|
||||
Cell* getFeed ( int pitches ) const;
|
||||
std::string getUniqueInstanceName () const;
|
||||
private:
|
||||
EtesianEngine* _etesian;
|
||||
Cell* _tieCell;
|
||||
std::map<int,Cell*> _feedCells;
|
||||
mutable unsigned int _feedCount;
|
||||
};
|
||||
|
@ -46,14 +47,14 @@ namespace Etesian {
|
|||
// Inline Methods.
|
||||
inline FeedCells::FeedCells ( EtesianEngine* etesian )
|
||||
: _etesian (etesian)
|
||||
, _tieCell (NULL)
|
||||
, _feedCells()
|
||||
, _feedCount(0)
|
||||
{ }
|
||||
|
||||
|
||||
inline size_t FeedCells::feedNumbers () const { return _feedCells.size(); }
|
||||
inline Cell* FeedCells::getTie () const { return _tieCell; }
|
||||
|
||||
|
||||
} // Etesian namespace.
|
||||
|
||||
#endif // ETESIAN_FEEDCELLS_H
|
||||
|
|
Loading…
Reference in New Issue