// 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 "mauka/SubRow.h" #include "mauka/Surface.h" #include "mauka/Row.h" namespace Mauka { using std::cerr; using std::endl; using Hurricane::Error; Row::Row(Cell* cell, Surface* surface, const Box& box, bool orientation) :Inherit(cell, box) , _surface(surface) , _subRowVector() , _subRowXMax() , _subRowXMinInv() , _orientation(orientation) , _size(0) , _capa(0) {} Row* Row::create(Cell* cell, Surface* surface, const Box& box, bool orientation) { if (!surface) throw Error("Can't create Mauka::Row : empty surface"); Row* row = new Row(cell, surface, box, orientation); row->_postCreate(); return row; } void Row::_preDestroy() { Inherit::_preDestroy(); for (SubRowVector::iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { (*srit)->destroy(); } _subRowVector.clear(); } namespace { using namespace Hurricane; struct SubRowSortByX { bool operator()(const SubRow* subrow1, const SubRow* subrow2) const { return subrow1->getXMin() < subrow2->getXMin(); } }; } void Row::_InsertSubRow(SubRow* subrow) { if (_subRowVector.size() == 0) _subRowVector.push_back(subrow); else { SubRowVector::iterator srvit = lower_bound(_subRowVector.begin(), _subRowVector.end(), subrow, SubRowSortByX()); if (srvit == _subRowVector.end()) { _subRowVector.push_back(subrow); } else if ((*srvit)->getXMin() == subrow->getXMin()) { throw Error("Bug in SubRow insertion"); } else { _subRowVector.insert(srvit, subrow); } } _box.merge(subrow->getBox()); } void Row::_computeSubRows() { _subRowXMax.clear(); _subRowXMinInv.clear(); for (unsigned i = 0; i < _subRowVector.size(); i++) { SubRow* subRow = _subRowVector[i]; _subRowXMax[subRow->getXMax()] = i; _subRowXMinInv[subRow->getXMin()] = i; } } SubRow* Row::getSubRowBetween(DbU::Unit x1, DbU::Unit x2) { assert(x1 <= x2); assert(x1 >= getXMin()); assert(x2 <= getXMax()); if (_subRowVector.size() == 1) return _subRowVector[0]; SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1); SubRowXMinInv::iterator rsup = _subRowXMinInv.upper_bound(x2); unsigned randidx = rinf->second + (unsigned)((rsup->second - rinf->second + 1) * (rand() / (RAND_MAX+1.0))); #if 0 //cerr << x1 << endl; //cerr << x2 << endl; for (SubRowXMax::iterator srit = _subRowXMax.begin(); srit != _subRowXMax.end(); srit++) { cerr << srit->first << "," << srit->second << endl; } cerr << randidx << endl << endl;; #endif return _subRowVector[randidx]; } void Row::_AddSize(DbU::Unit value) { _size += value; } double Row::getCost() const { return abs(DbU::getLambda(_size - _capa)); } double Row::getBinCost() const { double binCost = 0.0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { binCost += (*srit)->getBinCost(); } return binCost; } DbU::Unit Row::getBinsSize() const { DbU::Unit totalBinsSize = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { totalBinsSize += (*srit)->getBinsSize(); } return totalBinsSize; } DbU::Unit Row::getBinsCapa() const { DbU::Unit totalBinsCapa = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { totalBinsCapa += (*srit)->getBinsCapa(); } return totalBinsCapa; } DbU::Unit Row::getSubRowsWidth() const { DbU::Unit subRowsWidth = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { subRowsWidth += (*srit)->getWidth(); } return subRowsWidth; } DbU::Unit Row::getSubRowsCapa() const { DbU::Unit totalSubRowsCapa = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { totalSubRowsCapa += (*srit)->getCapa(); } return totalSubRowsCapa; } void Row::_computeCapacity(double margin) { _capa = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { (*srit)->_computeCapacity(margin); _capa += (*srit)->_capa; } } void Row::DisplayBinHits() const { for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { (*srit)->DisplayBinHits(); } } Cell* Row::getCell() const { return _surface->getCell(); } }