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:
Jean-Paul Chaput 2021-06-24 11:18:22 +02:00
parent fdf66cbf64
commit 6fc7ece575
7 changed files with 104 additions and 12 deletions

View File

@ -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()

View File

@ -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 ) );

View File

@ -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();

View File

@ -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()

View File

@ -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;

View File

@ -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; }

View File

@ -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