diff --git a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp index 82f039b9..86eade10 100644 --- a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp +++ b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp @@ -188,8 +188,11 @@ namespace CRL { Instance* instance = Instance::create( cell, node->getName(), master ); instance->setTransformation( toTransformation(node) ); - if (node->isFixed()) + if (node->isFixed() || node->isTerminal()) instance->setPlacementStatus( Instance::PlacementStatus::FIXED ); + // TODO: the alliance framework is not persisted, hence we cannot modify the pitch and slice height here; this is worked around in Etesian + else + af->getCellGauge()->setPitch(master->getAbutmentBox().getHeight()); for ( auto ipin : node->getPins() ) { Name netName = ipin.second->getNet()->getName(); diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index bb8b63a1..17b112b3 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -311,6 +311,7 @@ namespace Etesian { ) << endl; } } + _sliceHeight = getCellGauge()->getSliceHeight(); } @@ -478,18 +479,6 @@ namespace Etesian { size_t instancesNb = 0; for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { - Instance* instance = static_cast(occurrence.getEntity()); - Cell* masterCell = instance->getMasterCell(); - - if ( (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED) - and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED ) - and (masterCell->getAbutmentBox().getHeight() != getSliceHeight()) ) { - throw Error( "EtesianEngine::toColoquinte(): Cannot manage unplaced block, instance \"%s\" of \"%s\"." - , getString(instance ->getName()).c_str() - , getString(masterCell->getName()).c_str() - ); - } - ++instancesNb; } @@ -674,6 +663,42 @@ namespace Etesian { _placementUB = _placementLB; } + void EtesianEngine::adjustSliceHeight () + { + /* + * Modify the slice height if it doesn't match the one given by the Alliance Framework. + * Useful for Bookshelf benchmarks + */ + + bool isSliceHeightSet = false; + for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) + { + Instance* instance = static_cast(occurrence.getEntity()); + Cell* masterCell = instance->getMasterCell(); + + if ( (instance->getPlacementStatus() != Instance::PlacementStatus::PLACED) + and (instance->getPlacementStatus() != Instance::PlacementStatus::FIXED )) + { + DbU::Unit cellHeight = masterCell->getAbutmentBox().getHeight(); + bool sliceHeightChange = cellHeight != getSliceHeight(); + if (isSliceHeightSet) + { + if (sliceHeightChange) throw Error( "EtesianEngine::toColoquinte(): Cannot manage unplaced block, instance \"%s\" of \"%s\": slice height was set to %d but cell height is %d." + , getString(instance ->getName()).c_str() + , getString(masterCell->getName()).c_str() + , getSliceHeight() + , cellHeight + ); + } + else + { + if (sliceHeightChange) cerr << Warning("Adjusting slice height from %d to %d fit a placeable cell.", getSliceHeight(), cellHeight) << endl; + _sliceHeight = cellHeight; + } + isSliceHeightSet = true; + } + } + } void EtesianEngine::preplace () { @@ -919,6 +944,7 @@ namespace Etesian { getBlockCell()->uniquify(); getConfiguration()->print( getCell() ); + adjustSliceHeight(); if (getBlockCell()->getAbutmentBox().isEmpty()) setDefaultAb(); findYSpin(); diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index f6d2b4f3..78fc9ebe 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -81,6 +81,7 @@ namespace Etesian { inline Instance* getBlockInstance () const; inline void setBlock ( Instance* ); void setDefaultAb (); + void adjustSliceHeight (); void resetPlacement (); void toColoquinte (); void preplace (); @@ -116,6 +117,7 @@ namespace Etesian { FeedCells _feedCells; BloatCells _bloatCells; size_t _yspinSlice0; + DbU::Unit _sliceHeight; protected: // Constructors & Destructors. @@ -140,7 +142,7 @@ namespace Etesian { inline CellGauge* EtesianEngine::getCellGauge () const { return getConfiguration()->getCellGauge(); } inline DbU::Unit EtesianEngine::getHorizontalPitch () const { return getGauge()->getHorizontalPitch(); } inline DbU::Unit EtesianEngine::getVerticalPitch () const { return getGauge()->getVerticalPitch(); } - inline DbU::Unit EtesianEngine::getSliceHeight () const { return getCellGauge()->getSliceHeight(); } + inline DbU::Unit EtesianEngine::getSliceHeight () const { return _sliceHeight; } inline Effort EtesianEngine::getPlaceEffort () const { return getConfiguration()->getPlaceEffort(); } inline GraphicUpdate EtesianEngine::getUpdateConf () const { return getConfiguration()->getUpdateConf(); } inline Density EtesianEngine::getSpreadingConf () const { return getConfiguration()->getSpreadingConf(); } diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index a7f19462..9b44ecd1 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -100,7 +100,9 @@ namespace Unicorn { _importCell.addImporter ( "JSON (experimental)" , std::bind( &Cell::fromJson , placeholders::_1 ) ); _importCell.addImporter ( "BLIF (Yosys/ABC)" , std::bind( &Blif::load , placeholders::_1, true ) ); _importCell.addImporter ( "ACM/SIGDA (aka MCNC, .bench)", std::bind( &AcmSigda::load , placeholders::_1 ) ); + /* Disabled because this is never the one you want _importCell.addImporter ( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) ); + */ _importCell.addImporter ( "ISPD'05 (Bookshelf)" , std::bind( &Ispd05::load , placeholders::_1 ) ); _importCell.addImporter ( "ICCAD'04 (LEF/DEF)" , std::bind( &Iccad04Lefdef::load, placeholders::_1, 0 ) ); _importCell.addImporter ( "Alliance compliant DEF" , std::bind( &DefImport::load , placeholders::_1, DefImport::FitAbOnCells) );