diff --git a/cumulus/src/plugins/rsave.py b/cumulus/src/plugins/rsave.py index 0df225fa..d0295aa5 100644 --- a/cumulus/src/plugins/rsave.py +++ b/cumulus/src/plugins/rsave.py @@ -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() diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index 87f32774..4dfaa973 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -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 ) ); diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 53154c27..bed8891e 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -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(); diff --git a/etesian/src/FeedCells.cpp b/etesian/src/FeedCells.cpp index d4554d74..bcd07d87 100644 --- a/etesian/src/FeedCells.cpp +++ b/etesian/src/FeedCells.cpp @@ -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() diff --git a/etesian/src/Placement.cpp b/etesian/src/Placement.cpp index e123ef6d..8a8ec225 100644 --- a/etesian/src/Placement.cpp +++ b/etesian/src/Placement.cpp @@ -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; diff --git a/etesian/src/etesian/Configuration.h b/etesian/src/etesian/Configuration.h index e22d08ef..e3c2609d 100644 --- a/etesian/src/etesian/Configuration.h +++ b/etesian/src/etesian/Configuration.h @@ -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; } diff --git a/etesian/src/etesian/FeedCells.h b/etesian/src/etesian/FeedCells.h index 4a5f8a25..ea9406c3 100644 --- a/etesian/src/etesian/FeedCells.h +++ b/etesian/src/etesian/FeedCells.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef ETESIAN_FEEDCELLS_H -#define ETESIAN_FEEDCELLS_H - +#pragma once #include #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 _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