coriolis/mauka/src/Surface.cpp.noRefactor

896 lines
32 KiB
Plaintext

// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// 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 <Christophe.Alexandre@lip6.fr>
//
// 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<Instance*>(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<Occurrence> 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<Occurrence> 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<PlacementProblem*> PlacementProblemList;
}
void Surface::_PostCreate() {
typedef set<Occurrence> 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<Instance*>(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<Instance*>(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<Instance*>(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;
}
}