// 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 : 19/07/2006 // Author : Christophe Alexandre // // Authors-Tag #include "CDataBase.h" using namespace CRL; #include "Bin.h" #include "Row.h" #include "Surface.h" #include "SimAnnealingPlacer.h" #include "SubRow.h" namespace MAUKA { SubRow::SubRow(const Cell* cell, Surface* surface, const Box& box) :Inherit(cell, box) , _surface(surface) , _row(NULL) , _binVector() , _size(0) , _capa(0) {} SubRow* SubRow::Create(const Cell* cell, Surface* surface, const Box& box, bool orientation) { SubRow* subRow = new SubRow(cell, surface, box); subRow->_PostCreate(orientation); return subRow; } void SubRow::_PostCreate(bool orientation) { _row = _surface->InsertSubRowInRow(this, orientation); unsigned nBins = 0; if (GetWidth() % _surface->_binWidthMax) nBins = GetWidth() / _surface->_binWidthMax + 1; else nBins = GetWidth() / _surface->_binWidthMax; if (nBins == 0) { assert (GetWidth() >= _surface->_binWidthMin); nBins = 1; } Unit pitch = GetCDataBase()->GetDefaultCGPitch(); Unit binsWidth = ((GetWidth() / pitch) / nBins) * pitch; if (GetWidth() % pitch) throw Error("Subrow Width: " + GetString(GetWidth()) + " is not a multiple of pitch"); if (binsWidth % pitch) throw Error("Bins Width not a multiple of pitch"); Unit totalBinsWidth = binsWidth * nBins; Unit binsWidthRemain = GetWidth() - totalBinsWidth; if (binsWidthRemain % pitch) throw Error("Bins Width not a multiple of pitch"); unsigned binsWidthRemainPitch = binsWidthRemain / pitch; Unit xMin = GetXMin(); Unit xMax = xMin; for (unsigned binId = 0; binId < nBins; binId++) { if (binsWidthRemainPitch > 0) { xMax += binsWidth + pitch; binsWidthRemainPitch--; } else xMax += binsWidth; Bin* bin = Bin::Create(GetCell(), this, Box(xMin, GetYMin(), xMax, GetYMax())); _binVector.push_back(bin); unsigned binIdx = _binVector.size() - 1; _binXMax[bin->GetXMax()] = binIdx; xMin = xMax; } Inherit::_PostCreate(); } bool SubRow::_MergeBins() { if (_binVector.size() > 1) { cerr << "merging " << this << endl; _size = 0; Bin* bin = Bin::Create(GetCell(), this, Box(GetXMin(), GetYMin(), GetXMax(), GetYMax())); for (BinVector::iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) { for (Mauka::UList::const_iterator ulit = (*bvit)->_instanceOccurrenceIds.begin(); ulit != (*bvit)->_instanceOccurrenceIds.end(); ulit++) { _surface->_mauka->_simAnnealingPlacer->_instanceBins[*ulit] = NULL; } (*bvit)->Delete(); } _binVector.clear(); _binVector.push_back(bin); return true; } return false; } void SubRow::_ComputeCapacity(double margin) { for (BinVector::const_iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) { (*bvit)->_ComputeCapacity(margin); _capa += (*bvit)->_capa; } } void SubRow::_PreDelete() { Inherit::_PreDelete(); for (BinVector::iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) { (*bvit)->Delete(); } } void SubRow::DisplayBinHits() const { for (BinVector::const_iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) { (*bvit)->DisplayHits(); } } Bin* SubRow::GetBinBetween(Unit lowerX, Unit upperX, const Bin* srcbin) { assert(lowerX <= upperX); assert(lowerX >= GetXMin()); assert(upperX <= GetXMax()); if (_binVector.size() == 1) return _binVector[0]; Unit searchPosition = lowerX + GetUnit((int)(GetValue(upperX-lowerX) * rand() / (RAND_MAX + 1.0))); unsigned binId = _binXMax.upper_bound(searchPosition)->second; if (_binVector[binId] == srcbin) { if (binId == 0) return _binVector[1]; if (binId == _binVector.size() - 1) return _binVector[_binVector.size() - 2]; static bool altern = true; if (altern) { altern = false; return _binVector[binId + 1]; } else { altern = true; return _binVector[binId - 1]; } } return _binVector[binId]; } void SubRow::_AddSize(Unit value) { _size += value; _row->_AddSize(value); } double SubRow::GetCost() const { return abs(GetValue(_size - _capa)); } double SubRow::GetBinCost() const { double binCost = 0.0; for (BinVector::const_iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) binCost += (*bvit)->GetCost(); return binCost; } Unit SubRow::GetBinsSize() const { Unit totalBinsSize = 0; for (BinVector::const_iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) { totalBinsSize += (*bvit)->GetSize(); } return totalBinsSize; } Unit SubRow::GetBinsCapa() const { Unit totalBinsCapa = 0; for (BinVector::const_iterator bvit = _binVector.begin(); bvit != _binVector.end(); bvit++) { totalBinsCapa += (*bvit)->GetCapa(); } return totalBinsCapa; } Cell* SubRow::GetCell() const { return _row->GetCell(); } }