// This file is part of the Coriolis Project. // Copyright (C) Laboratoire LIP6 - Departement ASIM // Universite Pierre et Marie Curie // // Main contributors : // Christophe Alexandre // Sophie Belloeil // Hugo Clément // Jean-Paul Chaput // Damien Dupuis // Christian Masson // Marek Sroka // // The Coriolis Project is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // The Coriolis Project is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with the Coriolis Project; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // // License-Tag // // Date : 29/01/2004 // Author : Christophe Alexandre // // Authors-Tag #include "CEditor.h" using namespace CRL; #include "Nimbus.h" using namespace NIMBUS; #include "Mauka.h" #include "SimAnnealingPlacer.h" #include "SubRow.h" #include "Row.h" #include "Surface.h" namespace MAUKA { namespace { void VerifyInstanceQuadtreeInsertion(Cell *cell) { cerr << "VerifyInstanceQuadtreeInsertion" << endl; for_each_instance(instance, cell->GetInstances()) { if (!instance->IsMaterialized()) { Cell* masterCell = instance->GetMasterCell(); cerr << tab << instance << " of " << masterCell << " is not materialized..." << endl; tab++; VerifyInstanceQuadtreeInsertion(masterCell); tab--; } end_for; } } void DisplayInstanceOccurrence(Occurrence& instanceOccurrence) { cerr << instanceOccurrence << " " << instanceOccurrence.GetBoundingBox() << endl; Instance* instance = static_cast(instanceOccurrence.GetEntity()); Path path = instanceOccurrence.GetPath(); cerr << path.GetTransformation() << endl; cerr << instance->GetTransformation() << endl; while (!path.IsEmpty()) { cerr << path.GetTailInstance() << " " << path.GetTailInstance()->GetTransformation() << endl; cerr << path.GetTailInstance()->GetMasterCell() << endl; cerr << path.GetTailInstance()->GetMasterCell()->GetAbutmentBox() << endl; cerr << path.GetTailInstance()->GetMasterCell()->GetBoundingBox() << endl; cerr << path.GetTailInstance()->GetAbutmentBox() << endl; cerr << path.GetTailInstance()->GetBoundingBox() << endl; path = path.GetHeadPath(); } } void DisplayNonLeafInstances(Cell* cell, Box area) { ltrace(100) << "display of " << cell << " in " << area << endl; for_each_instance(instance, cell->GetNonLeafInstancesUnder(area)) { ltrace(100) << instance << " " << instance->GetBoundingBox() << endl; Cell* masterCell = instance->GetMasterCell(); ltracein(20); DisplayNonLeafInstances(masterCell, area); ltraceout(20); end_for; } } } Surface::Surface(Mauka* mauka, const Box& placementbox, double searchratio) : Inherit(mauka->GetCell(), placementbox), _mauka(mauka), _rowVector(), _rowYMax(), _rowYMinInv(), _rowZeroOrientation(false), _margin(0.0), _binWidthMax(0), _binWidthMin(0), _searchRatio(searchratio), _searchWidth(0), _searchHeight(0) {} Surface* Surface::Create(Mauka* mauka, const Box& placementbox, double searchratio) { if (!mauka) { throw Error("Can't create " + _TName("Surface") + " : empty mauka"); } if (!mauka->GetCell()) { throw Error("Can't create " + _TName("Surface") + " : empty cell on mauka"); } Surface* surface = new Surface(mauka, placementbox, searchratio); surface->_PostCreate(); return surface; } namespace { void PlacementVerification(Cell* cell, Box& box) { set occurrenceSet; for_each_occurrence(occurrence, cell->GetLeafInstanceOccurrencesUnder(box)) { occurrenceSet.insert(occurrence); end_for; } for_each_occurrence(occurrence, cell->GetLeafInstanceOccurrences()) { if (occurrenceSet.find(occurrence) == occurrenceSet.end()) { cerr << occurrence << ":" << occurrence.GetBoundingBox() << endl; throw Error("occurrence is badly placed"); } end_for; } } typedef list InstanceOccurrencesList; class PlacementProblem { public: GCell* _gcell; public: InstanceOccurrencesList _fixedInstanceOccurrenceList; public: Mauka::UVector _toPlaceInstanceOccurrencesUVector; public: Surface::SubRowList _subRowList; PlacementProblem(GCell* gcell) : _gcell(gcell) , _fixedInstanceOccurrenceList() , _toPlaceInstanceOccurrencesUVector() , _subRowList() {} }; typedef list PlacementProblemList; } void Surface::_PostCreate() { typedef set OccurrenceSet; Inherit::_PostCreate(); Nimbus* nimbus = NULL; if (_box.IsEmpty()) { nimbus = GetNimbus(GetCell()); if (!nimbus) { throw Error("Can't create " + _TName("Surface") + " : no Box and no Nimbus"); } _box = nimbus->GetGrid()->GetRoot()->GetBox(); } PlacementVerification(GetCell(), _box); Unit sliceHeight = GetUnit(1); Unit pitch = GetUnit(1); CDataBase* cdb = GetCDataBase(); if (cdb != NULL) { sliceHeight = GetCDataBase()->GetDefaultCGSliceHeight(); pitch = GetCDataBase()->GetDefaultCGPitch(); } else { //for the moment very stupid method... take the first instantiated cell for_each_instance(instance, GetCell()->GetInstances()) { Cell* masterCell = instance->GetMasterCell(); sliceHeight = masterCell->GetAbutmentBox().GetHeight(); break; end_for; } } if (_box.IsEmpty() || _box.IsPonctual() ||_box.IsFlat()) { throw Error("Wrong Box for Area"); } if (GetHeight() % sliceHeight) { throw Error("Box Height must be a multiple of Slice Height"); } Unit instanceToPlaceWidthMax = 0; Unit instanceToPlaceWidthSum = 0; for (unsigned id = 0; id < _mauka->_instanceWidths.size(); id++) { Unit instanceWidth = _mauka->_instanceWidths[id]; instanceToPlaceWidthSum += instanceWidth; if (instanceWidth % pitch) { cerr << _mauka->_instanceOccurrencesVector[id] << endl; throw Error("Instance width (" + GetString(instanceWidth) + ") is not a multiple of pitch (" + GetString(pitch) + ")."); } if (instanceWidth > instanceToPlaceWidthMax) instanceToPlaceWidthMax = instanceWidth; } _binWidthMax = GetUnit((unsigned)( 2.0 * GetValue(instanceToPlaceWidthMax) / GetValue(pitch)) * GetValue(pitch)); _binWidthMin = GetUnit((unsigned)( GetValue(_binWidthMax) / (GetValue(pitch) * 2)) * GetValue(pitch)); Unit surfaceTotalWidth = 0; PlacementProblemList placementProblemList; OccurrenceSet verifyInstanceOccurrencesSet; if (nimbus) { // cerr << "verif" << endl; for_each_gcell(gcell, nimbus->GetPlacementLeaves()) { // cerr << gcell << endl; PlacementProblem* placementProblem = new PlacementProblem(gcell); placementProblemList.push_back(placementProblem); InstanceOccurrencesList toPlaceInstanceOccurrencesList; //search for preplaced leaf instances for_each_occurrence(occurrence, _mauka->GetCell()->GetLeafInstanceOccurrencesUnder(gcell->GetBox())) { Instance* instance = static_cast(occurrence.GetEntity()); if (instance->IsFixed()) { placementProblem->_fixedInstanceOccurrenceList.push_back(occurrence); //cerr << "Fixed : " << occurrence << endl; } else { Mauka::InstanceOccurrencesMap::const_iterator iomit = _mauka->_instanceOccurrencesMap.find(occurrence); if (iomit == _mauka->_instanceOccurrencesMap.end()) { throw Error("bug"); } // cerr << occurrence << endl; placementProblem->_toPlaceInstanceOccurrencesUVector.push_back(iomit->second); verifyInstanceOccurrencesSet.insert(occurrence); } end_for; } // cerr << endl << endl; // Unit searchWidth = GetUnit(floor(0.3 * GetValue(gcell->GetWidth()))); Unit searchWidth = GetUnit(_searchRatio * GetValue(gcell->GetWidth())); if (_searchWidth < searchWidth) _searchWidth = searchWidth; // Unit searchHeight = GetUnit(floor(0.3 * GetValue(gcell->GetHeight()))); Unit searchHeight = GetUnit(_searchRatio * GetValue(gcell->GetHeight())); if (_searchHeight < searchHeight) _searchHeight = searchHeight; end_for; } for (PlacementProblemList::iterator pplit = placementProblemList.begin(); pplit != placementProblemList.end(); pplit++) { PlacementProblem* placementProblem = *pplit; GCell* gcell = placementProblem->_gcell; if (placementProblem->_fixedInstanceOccurrenceList.size() != 0) { bool rowZeroOrientation = false; int width = (unsigned)(gcell->GetWidth() / pitch); //number of x pitch int height = (unsigned)(gcell->GetHeight() / sliceHeight); //number of y slices Mauka::PrePlaceTab prePlaceTab(height, Mauka::PrePlaceRow(width, false)); InstanceOccurrencesList::const_iterator iolit = placementProblem->_fixedInstanceOccurrenceList.begin(); // find the orientation of the first row. Instance* refInstance = static_cast(iolit->GetEntity()); Box refAbutmentBox = refInstance->GetAbutmentBox(); Transformation refTransformation = refInstance->GetTransformation(); iolit->GetPath().GetTransformation().ApplyOn(refAbutmentBox); iolit->GetPath().GetTransformation().ApplyOn(refTransformation); Box preplacedBox = gcell->GetIntersection(refAbutmentBox); // position en y ramene au slice int refInsYPos = (int)((preplacedBox.GetYMin() - gcell->GetYMin()) / sliceHeight); // hauteur ramene a la hauteur du slice int refInsSliceHeight = (int)(preplacedBox.GetHeight() / sliceHeight); Transformation::Orientation orientation = refTransformation.GetOrientation(); //cerr << "refInstance : " << *iolit << " : " << preplacedBox << ":" << refTransformation << endl; if (refInsYPos % 2 == 0) { if ((refInsSliceHeight % 2 == 0) || (orientation == Transformation::Orientation::ID) || (orientation == Transformation::Orientation::MX)) rowZeroOrientation = true; else rowZeroOrientation = false; } else { if ((refInsSliceHeight % 2 == 0) || (orientation == Transformation::Orientation::ID) || (orientation == Transformation::Orientation::MX)) rowZeroOrientation = false; else rowZeroOrientation = true; } // tests for each instance for (InstanceOccurrencesList::iterator iolit = placementProblem->_fixedInstanceOccurrenceList.begin(); iolit != placementProblem->_fixedInstanceOccurrenceList.end(); iolit++) { Instance* instance = static_cast(iolit->GetEntity()); Box instanceAbutmentBox = instance->GetAbutmentBox(); iolit->GetPath().GetTransformation().ApplyOn(instanceAbutmentBox); Box preplacedBox = gcell->GetIntersection(instanceAbutmentBox); Unit insWidth = preplacedBox.GetWidth(); Unit insHeight = preplacedBox.GetHeight(); int insPitchWidth = (int)(insWidth / pitch); // largeur ramene au pitch int insSliceHeight = (int)(insHeight / sliceHeight); // hauteur ramene a la hauteur du slice int ypos = (int)((preplacedBox.GetYMin() - gcell->GetYMin()) / sliceHeight); // position en y ramene au slice int xpos = (int)((preplacedBox.GetXMin() - gcell->GetXMin()) / pitch); // position en x ramene au pitch #if 0 if ((pins->YINS - _dy) % 50 != 0) { cerr << " o ERROR : in preplacement file : y position of " << pins->INSNAME << " is incorrect" << endl; exit (1); } if ((pins->XINS - _dx) % 5 != 0) { cerr << " o ERROR : in preplacement file : x position of " << pins->INSNAME << " is incorrect" << endl; exit (1); } if ( (pins->TRANSF == ROT_P) || (pins->TRANSF == ROT_M) || (pins->TRANSF == SY_RP) || (pins->TRANSF == SY_RM) ) { cerr << " o ERROR : " << pins->INSNAME << " : incorrect rotation" << endl; exit(1); } // check if orientation of instance matches bool insOrient; if ((pinsheightrow == 2) || (pins->TRANSF == NOSYM) || (pins->TRANSF == SYM_X)) insOrient = true; else insOrient = false; if ( ((ycoord % 2 == 0) && (insOrient != rowZeroOrientation)) || ((ycoord % 2 != 0) && (insOrient == rowZeroOrientation)) ) { cerr << " o ERROR : " << pins->INSNAME << " badly oriented" << endl << " Incoherence with " << refpins->INSNAME << endl; exit(1); } #endif for (int yit = ypos; yit < ypos + insSliceHeight; yit++) { for (int xit = xpos; xit < xpos + insPitchWidth; xit++) { if ( (xit > width - 1) || (yit > height - 1) || (xit < 0 ) || (yit < 0 ) ) { cerr << " o ERROR : " << *iolit << " out of the abutment box" << endl; exit(1); } if (prePlaceTab[yit][xit] == false) { prePlaceTab[yit][xit] = true; } else { cerr << " o ERROR : " << *iolit << " badly placed .... There is already an instance at its position ...." << endl; exit (1); } } } } bool rowOrientation = rowZeroOrientation; for (int y = 0; y < (int)prePlaceTab.size(); y++) { int x = 0; while (x < (int)prePlaceTab[y].size()) { while ((x < (int)prePlaceTab[y].size()) && (prePlaceTab[y][x] == true)) ++x; Unit subRowXMin = gcell->GetXMin() + x * pitch; if (x >= (int)prePlaceTab[y].size()) break; while ((x < (int)prePlaceTab[y].size()) && (prePlaceTab[y][x] == false)) ++x; Unit subRowXMax = gcell->GetXMin() + x * pitch; if (subRowXMax - subRowXMin > _binWidthMin) { //cerr << "orientation " << rowOrientation << endl; SubRow* subRow = SubRow::Create(GetCell(), this, Box(subRowXMin, gcell->GetYMin() + y * sliceHeight , subRowXMax, gcell->GetYMin() + (y+1) * sliceHeight) , rowOrientation); //cerr << "after create : " << subRow << endl; placementProblem->_subRowList.push_back(subRow); } } rowOrientation = !rowOrientation; } } else { bool rowOrientation = false; for (Unit ymin = gcell->GetYMin(); ymin <= gcell->GetYMax() - sliceHeight; ymin += sliceHeight) { SubRow* subRow = SubRow::Create(GetCell(), this , Box(gcell->GetXMin(), ymin, gcell->GetXMax(), ymin + sliceHeight), rowOrientation); placementProblem->_subRowList.push_back(subRow); rowOrientation = !rowOrientation; } } } } else { PlacementProblem* placementProblem = new PlacementProblem(NULL); _searchHeight = GetHeight(); _searchWidth = GetWidth(); bool rowOrientation = false; unsigned nRows = GetHeight() / sliceHeight; surfaceTotalWidth = GetWidth() * nRows; for (Unit ymin = GetYMin(); ymin <= GetYMax() - sliceHeight; ymin += sliceHeight) { SubRow* subRow = SubRow::Create(GetCell(), this , Box(GetXMin(), ymin, GetXMax(), ymin + sliceHeight), rowOrientation); placementProblem->_subRowList.push_back(subRow); rowOrientation = !rowOrientation; } for (unsigned id = 0; id < _mauka->_instanceOccurrencesVector.size(); id++) { placementProblem->_toPlaceInstanceOccurrencesUVector.push_back(id); } throw Error("Mauka needs Nimbus"); } for (PlacementProblemList::iterator pplit = placementProblemList.begin(); pplit != placementProblemList.end(); pplit++) { _DisplayInstances((*pplit)->_toPlaceInstanceOccurrencesUVector, (*pplit)->_subRowList); delete *pplit; } placementProblemList.clear(); if (verifyInstanceOccurrencesSet.size() != _mauka->_instanceOccurrencesVector.size()) { cerr << "error " << _mauka->_instanceOccurrencesVector.size() - verifyInstanceOccurrencesSet.size() << " not taken into account" << endl; VerifyInstanceQuadtreeInsertion(_mauka->GetCell()); for (Mauka::InstanceOccurrencesVector::iterator iovit = _mauka->_instanceOccurrencesVector.begin(); iovit != _mauka->_instanceOccurrencesVector.end(); iovit++) { OccurrenceSet::iterator osit = verifyInstanceOccurrencesSet.find(*iovit); if (osit == verifyInstanceOccurrencesSet.end()) { cerr << " o problem with " << *iovit << endl; DisplayInstanceOccurrence(*iovit); cerr << "display" << endl; DisplayNonLeafInstances(_mauka->GetCell(), iovit->GetBoundingBox()); #if 0 for_each_occurrence(occurrence, _mauka->GetCell()->GetLeafInstanceOccurrencesUnder(_mauka->GetCell()->GetAbutmentBox())) { if (occurrence == *iovit) { cerr << occurrence << "found " << occurrence.GetBoundingBox() << endl; cerr << "ounce again" << endl; DisplayNonLeafInstances(_mauka->GetCell(), occurrence.GetBoundingBox()); break; } end_for; } #endif return; } } throw Error(""); } for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) { surfaceTotalWidth += (*rvit)->GetSubRowsWidth(); } _ComputeRowsAndSubRows(); _margin = 1.0 - GetValue(instanceToPlaceWidthSum) / GetValue(surfaceTotalWidth); if (_margin < 0) { cerr << "Surface Free Space = " << surfaceTotalWidth << endl; cerr << "To Place Instances Width = " << instanceToPlaceWidthSum << endl; throw Error(" o Mauka Error : there is not enough free space to place the circuit"); } if (_margin < 0.15) cerr << _margin << " margin in area: possible problems" << endl; _ComputeCapacity(); } void Surface::_PreDelete() { Inherit::_PreDelete(); for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) (*rvit)->Delete(); _rowVector.clear(); } void Surface::_ComputeCapacity() { for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) (*rvit)->_ComputeCapacity(_margin); } namespace { struct RowSortByY { bool operator()(const Container* row1, const Container* row2) const { return row1->GetYMin() < row2->GetYMin(); } }; } Row* Surface::InsertSubRowInRow(SubRow* subrow, bool orientation) { //cerr << subrow << endl; Row* row = NULL; if (_rowVector.size() == 0) { row = Row::Create(GetCell(), this, subrow->GetBox(), orientation); _rowVector.push_back(row); } else { RowVector::iterator rvit = lower_bound(_rowVector.begin(), _rowVector.end(), subrow, RowSortByY()); if (rvit == _rowVector.end()) { row = Row::Create(GetCell(), this, subrow->GetBox(), orientation); _rowVector.push_back(row); } else if ((*rvit)->GetYMin() == subrow->GetYMin()) { row = *rvit; if (row->_orientation != orientation) { cerr << "PROBLEM in " << row << " orientation with " << subrow << endl; } //assert(row->_orientation == orientation); } else { row = Row::Create(GetCell(), this, subrow->GetBox(), orientation); _rowVector.insert(rvit, row); } } row->_InsertSubRow(subrow); //cerr << row << endl; return row; } void Surface::_ComputeRowsAndSubRows() { _rowYMax.clear(); _rowYMinInv.clear(); for (unsigned i = 0; i < _rowVector.size(); i++) { Row* row = _rowVector[i]; _rowYMax[row->GetYMax()] = i; _rowYMinInv[row->GetYMin()] = i; row->_ComputeSubRows(); } } Bin* Surface::GetBinInSurface(Bin* srcbin, double dist) { Point srcPos = srcbin->GetCenter(); Unit lowerY = srcPos.GetY() - GetUnit((dist * GetValue(_searchHeight))); if (lowerY < GetYMin()) lowerY = GetYMin(); Unit upperY = srcPos.GetY() + GetUnit((dist * GetValue(_searchHeight))); if (upperY > GetYMax()) upperY = GetYMax(); RowYMax::iterator rinf = _rowYMax.upper_bound(lowerY); RowYMax::iterator rsup = _rowYMinInv.upper_bound(upperY); unsigned randidx = rinf->second + (unsigned)((rsup->second - rinf->second + 1) * (rand() / (RAND_MAX+1.0))); Row* searchRow = _rowVector[randidx]; Unit lowerX = srcPos.GetX() - GetUnit((dist * GetValue(_searchWidth))); if ((lowerX < searchRow->GetXMin()) || (lowerX > searchRow->GetXMax())) lowerX = searchRow->GetXMin(); Unit upperX = srcPos.GetX() + GetUnit((dist * GetValue(_searchWidth))); if ((upperX > searchRow->GetXMax()) || (upperX < searchRow->GetXMin())) upperX = searchRow->GetXMax(); SubRow* subRow = searchRow->GetSubRowBetween(lowerX, upperX); if ((lowerX < subRow->GetXMin()) || (lowerX > subRow->GetXMax())) lowerX = subRow->GetXMin(); if ((upperX > subRow->GetXMax()) || (upperX < subRow->GetXMin())) upperX = subRow->GetXMax(); Bin* dstBin = subRow->GetBinBetween(lowerX, upperX, srcbin); return dstBin; } double Surface::GetBinCost() const { double binCost = 0.0; for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) binCost += (*rvit)->GetBinCost(); return binCost; } double Surface::GetRowCost() const { double rowCost = 0.0; for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) rowCost += (*rvit)->GetCost(); return rowCost; } Unit Surface::GetBinsSize() const { Unit totalBinsSize = 0; for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) totalBinsSize += (*rvit)->GetBinsSize(); return totalBinsSize; } Unit Surface::GetBinsCapa() const { Unit totalBinsCapa = 0; for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) totalBinsCapa += (*rvit)->GetBinsCapa(); return totalBinsCapa; } Unit Surface::GetSubRowsCapa() const { Unit totalSubRowsCapa = 0; for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) { totalSubRowsCapa += (*rvit)->GetSubRowsCapa(); } return totalSubRowsCapa; } namespace { class SortInstanceOccurrencesIdsByWidth { private: Mauka* _mauka; public: SortInstanceOccurrencesIdsByWidth(Mauka* mauka): _mauka(mauka) {} public: bool operator()(unsigned instanceoccurrenceid1, unsigned instanceoccurrenceid2) const { Unit width1 = _mauka->GetInstanceIdWidth(instanceoccurrenceid1); Unit width2 = _mauka->GetInstanceIdWidth(instanceoccurrenceid2); return width1 > width2; } }; } void Surface::_DisplayInstances(Mauka::UVector& instanceids, SubRowList& subrowlist) { // Insert instances in subrows sort(instanceids.begin(), instanceids.end(), SortInstanceOccurrencesIdsByWidth(_mauka)); SubRowList::iterator srlit = subrowlist.begin(); Mauka::UVector::const_iterator insIterator = instanceids.begin(); Mauka::UVector::const_iterator lastLoopInsertedInsIterator = insIterator; while(1) { if (insIterator == instanceids.end()) { if (_mauka->_verbosity.ActionIsOn()) { cout << " o Initial Placement Computing ... done. " << endl; } break; // end of insertion } if (srlit == subrowlist.end()) { srlit = subrowlist.begin(); if (lastLoopInsertedInsIterator != insIterator) lastLoopInsertedInsIterator = insIterator; else { // insertion of instances with respect of Bins margin // did not succed, inserting what's left. while (insIterator != instanceids.end()) { for (SubRow::BinVector::iterator bvit = (*srlit)->_binVector.begin(); bvit != (*srlit)->_binVector.end(); bvit++) { Bin* bin = *bvit; unsigned instanceId = *insIterator; Unit instanceWidth = _mauka->_instanceWidths[instanceId]; if (instanceWidth > (*srlit)->GetWidthVsSize()) break; bin->AddInstance(instanceId); ++insIterator; if (insIterator == instanceids.end()) break; } if (insIterator == instanceids.end()) break; ++srlit; if (srlit == subrowlist.end()) { if (lastLoopInsertedInsIterator == insIterator) { //impossible to succeed // try to merge all bins in subrows bool merged = false; for (srlit = subrowlist.begin(); srlit != subrowlist.end(); srlit++) { merged = (*srlit)->_MergeBins(); } if (merged) { insIterator = instanceids.begin(); } else { //count instances to place unsigned nbInstancesToPlace = 0; while (insIterator++ != instanceids.end()) ++nbInstancesToPlace; cerr << " o There is not enough free space, I need a bigger abutment box ......" << endl; cerr << " o There are still " << nbInstancesToPlace << " Instances to place ..." << endl; throw Error(""); } } srlit = subrowlist.begin(); lastLoopInsertedInsIterator = insIterator; } } } } if (insIterator != instanceids.end()) { SubRow* subRow = *srlit; for (SubRow::BinVector::iterator bvit = (*srlit)->_binVector.begin(); bvit != (*srlit)->_binVector.end(); bvit++) { Bin* bin = *bvit; if (insIterator == instanceids.end()) break; unsigned instanceId = *insIterator; Unit instanceWidth = _mauka->_instanceWidths[instanceId]; if (instanceWidth > subRow->GetCapaVsSize()) break; if (bin->TryAddInstance(instanceId)) ++insIterator; } ++srlit; } } } Record* Surface::_GetRecord() const { Record* record = Inherit::_GetRecord(); if (record) { record->Add(GetSlot("Mauka", _mauka)); } return record; } void Surface::DisplayBinHits() const { for (RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++) (*rvit)->DisplayBinHits(); } void Surface::PlotBinsStats(ofstream& out) const { out << "plot [:] '-' w l 2" << endl ; } void Surface::Plot(ofstream& out) const { out << GetXMin() << " " << GetYMin() << endl << GetXMin() << " " << GetYMax() << endl << GetXMax() << " " << GetYMax() << endl << GetXMax() << " " << GetYMin() << endl << GetXMin() << " " << GetYMin() << endl << endl; out << "EOF" << endl; } }