* ./mauka:

- Cleanup: removing extraneous unused files.
This commit is contained in:
Jean-Paul Chaput 2010-07-15 12:29:15 +00:00
parent 9f6e840036
commit 11581e0ae1
11 changed files with 0 additions and 5100 deletions

View File

@ -1,732 +0,0 @@
// 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>
// inspired by Andrew Caldwell's BranchSmallPlacer
// Authors-Tag
/**************************************************************************
***
*** Copyright (c) 1995-2000 Regents of the University of California,
*** Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
*** Copyright (c) 2000-2002 Regents of the University of Michigan,
*** Saurabh N. Adya and Igor L. Markov
***
*** Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
*** Original Affiliation: UCLA, Computer Science Department,
*** Los Angeles, CA 90095-1596 USA
***
*** Permission is hereby granted, free of charge, to any person obtaining
*** a copy of this software and associated documentation files (the
*** "Software"), to deal in the Software without restriction, including
*** without limitation
*** the rights to use, copy, modify, merge, publish, distribute, sublicense,
*** and/or sell copies of the Software, and to permit persons to whom the
*** Software is furnished to do so, subject to the following conditions:
***
*** The above copyright notice and this permission notice shall be included
*** in all copies or substantial portions of the Software.
***
*** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
*** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
*** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
*** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
***
***
***************************************************************************/
#include "UpdateSession.h"
#include "Net.h"
USING_NAMESPACE_HURRICANE
#include "CDataBase.h"
#include "CEditor.h"
#include "CToolBox.h"
using namespace CRL;
#include "Nimbus.h"
using namespace NIMBUS;
#include "Mauka.h"
#include "Surface.h"
#include "Row.h"
#include "SubRow.h"
#include "Bin.h"
#include "BBPlacer.h"
namespace MAUKA {
namespace {
class CompareInstancePosition
{
private: BBPlacer* _bbPlacer;
public: CompareInstancePosition(BBPlacer* bbplacer)
: _bbPlacer(bbplacer)
{}
public: bool operator()(unsigned id1, unsigned id2) const
{
return _bbPlacer->GetInstanceIdX(id1) < _bbPlacer->GetInstanceIdX(id2);
}
};
}
//#define PLACE_DEBUG 1
BBPlacer::BBPlacer(Mauka* mauka)
: _mauka(mauka)
, _subRowVector()
, _subRowInstances()
, _instanceX()
, _instanceY()
, _instancePlaced()
, _netVector()
, _netBBoxes()
, _netCosts()
, _netCurrCostMark()
, _netFlags()
, _instanceToOptimize()
, _leftEdge(0)
, _rightEdge(0)
, _oldCost(0.0)
, _cost(0.0)
, _bestCost(0.0)
, _costFlag(0)
, _queue()
, _stack()
, _loopVect()
, _bestSolution()
, _idx(0)
{
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
_instanceMarginWidth.push_back(_mauka->_instanceWidths[i]);
_instanceX.push_back(0);
_instanceY.push_back(0);
_instancePlaced.push_back(true);
}
for (unsigned netid = 0; netid < _mauka->_nets.size(); netid++)
{
vector<Box> bboxes(2);
_netBBoxes.push_back(bboxes);
vector<double> costs(2);
_netCosts.push_back(costs);
_netFlags.push_back(0);
_netCurrCostMark.push_back(0);
}
Surface::RowVector& rowVector = _mauka->_surface->_rowVector;
for (Surface::RowVector::iterator rvit = rowVector.begin();
rvit != rowVector.end();
rvit++)
{
Row::SubRowVector& subRowVector = (*rvit)->_subRowVector;
for (Row::SubRowVector::iterator srvit = subRowVector.begin();
srvit != subRowVector.end();
srvit++)
{
SubRow* subRow = *srvit;
if (subRow->GetSize() > 0)
{
_subRowVector.push_back(subRow);
_subRowInstances.push_back(Mauka::UVector());
Unit totalInstanceSizeInRow = 0;
for (SubRow::BinVector::iterator bvit = subRow->_binVector.begin();
bvit != subRow->_binVector.end();
bvit++)
{
Bin* bin = *bvit;
totalInstanceSizeInRow += bin->GetSize();
for (Mauka::UList::const_iterator ulit = bin->InstanceOccurrenceIdsBegin();
ulit != bin->InstanceOccurrenceIdsEnd();
ulit++)
{
unsigned instanceId = *ulit;
_subRowInstances.back().push_back(instanceId);
}
}
Unit pitch = GetCDataBase()->GetDefaultCGPitch();
Unit whiteSpace = subRow->GetWidth() - totalInstanceSizeInRow;
Unit instanceWhiteSpacePitch = (whiteSpace / _subRowInstances.back().size()) / pitch;
Unit whiteSpaceRemain = whiteSpace
- (instanceWhiteSpacePitch * _subRowInstances.back().size() * pitch);
assert(!(whiteSpaceRemain%pitch));
if (instanceWhiteSpacePitch > 0)
{
for (Mauka::UVector::const_iterator uvit = _subRowInstances.back().begin();
uvit != _subRowInstances.back().end();
uvit++)
{
_instanceMarginWidth[*uvit] += instanceWhiteSpacePitch * pitch;
}
}
Mauka::UVector::const_iterator uvit = _subRowInstances.back().begin();
while (whiteSpaceRemain > 0)
{
_instanceMarginWidth[*uvit++] += pitch;
whiteSpaceRemain -= pitch;
assert(uvit != _subRowInstances.back().end());
}
Unit xPos = subRow->GetXMin();
Unit yPos = subRow->GetYMin();
for (Mauka::UVector::const_iterator uvit = _subRowInstances.back().begin();
uvit != _subRowInstances.back().end();
uvit++)
{
unsigned instanceId = *uvit;
_instanceX[instanceId] = xPos;
_instanceY[instanceId] = yPos;
xPos += _instanceMarginWidth[instanceId];
}
}
}
}
}
void BBPlacer::Save()
{
OpenUpdateSession();
for (unsigned i = 0; i < _subRowInstances.size(); i++)
{
SubRow* subRow = _subRowVector[i];
bool rowOrientation = subRow->GetRow()->GetOrientation();
for (unsigned j = 0; j < _subRowInstances[i].size(); j++)
{
unsigned instanceId = _subRowInstances[i][j];
Unit x = _instanceX[instanceId];
Unit y = _instanceY[instanceId];
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[instanceId];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Transformation::Orientation orientation;
if (rowOrientation)
orientation = Transformation::Orientation::ID;
else
orientation = Transformation::Orientation::MY;
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
Transformation instanceTransformation = GetTransformation(masterABox
, x
, y
, orientation);
#if 0
cerr << masterABox.GetXMin() << "," << masterABox.GetYMin()
<< masterABox.GetXMax() << "," << masterABox.GetYMax() << endl;
cerr << x << "," << y << endl;
cerr << instanceTransformation << endl;
cerr << "occ transfo : " << instanceOccurrence.GetPath().GetTransformation() << endl;
#endif
instanceOccurrence.GetPath().GetTransformation().Invert().ApplyOn(instanceTransformation);
instance->SetTransformation(instanceTransformation);
instance->SetPlacementStatus(Instance::PlacementStatus::PLACED);
//SetPlacementStatusRecursivelyToPlaced(instance);
}
}
CloseUpdateSession();
}
void BBPlacer::Plot(ofstream& out) const
{
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
Unit x = _instanceX[i];
Unit y = _instanceY[i];
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[i];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
Box instanceBox = Box(
x,
y,
x + masterABox.GetWidth(),
y + masterABox.GetHeight());
out << instanceBox.GetXMin()+0.4 << " " << instanceBox.GetYMin()+0.4 << endl
<< instanceBox.GetXMin()+0.4 << " " << instanceBox.GetYMax()-0.4 << endl
<< instanceBox.GetXMax()-0.4 << " " << instanceBox.GetYMax()-0.4 << endl
<< instanceBox.GetXMax()-0.4 << " " << instanceBox.GetYMin()+0.4 << endl
<< instanceBox.GetXMin()+0.4 << " " << instanceBox.GetYMin()+0.4 << endl << endl;
}
out << "EOF" << endl << endl;
out << "#nets" << endl;
for (unsigned i = 0; i < _mauka->_netInstances.size(); i++)
{
if (_mauka->_hasInitX[i])
continue;
unsigned nbInstances = 0;
Unit baryX = 0;
Unit baryY = 0;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[instanceId];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
++nbInstances;
baryX += _instanceX[instanceId] + masterABox.GetWidth() / 2;
baryY += _instanceY[instanceId] + masterABox.GetHeight() / 2;
}
baryX = baryX / nbInstances;
baryY = baryY / nbInstances;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[instanceId];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
out << baryX << " " << baryY << endl
<< _instanceX[instanceId] + masterABox.GetWidth() / 2 << " "
<< _instanceY[instanceId] + masterABox.GetHeight() / 2 << endl << endl;
}
}
out << "EOF" << endl << endl;
out << "#nets with fixed point" << endl;
for (unsigned i = 0; i < _mauka->_netInstances.size(); i++)
{
if (!_mauka->_hasInitX[i])
continue;
unsigned nbInstances = 1;
Unit baryX = 0;
Unit baryY = 0;
baryX += _mauka->_netInitX[i];
baryY += _mauka->_netInitY[i];
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[instanceId];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
++nbInstances;
baryX += _instanceX[instanceId] + masterABox.GetWidth() / 2;
baryY += _instanceY[instanceId] + masterABox.GetHeight() / 2;
}
baryX = baryX / nbInstances;
baryY = baryY / nbInstances;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[instanceId];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
out << baryX << " " << baryY << endl
<< _instanceX[instanceId] + masterABox.GetWidth() / 2 << " "
<< _instanceY[instanceId] + masterABox.GetHeight() / 2 << endl << endl;
}
out << baryX << " " << baryY << endl
<< _mauka->_netInitX[i] << " "
<< _mauka->_netInitY[i] << endl << endl;
}
out << "EOF" << endl << endl;
}
void BBPlacer::Run()
{
for (unsigned i = 0; i < _subRowInstances.size(); i++)
{
unsigned decal = 2;
unsigned nInstancesToOptimize = 0;
Mauka::UVector::iterator ifirst = _subRowInstances[i].begin();
Mauka::UVector::iterator ilast = _subRowInstances[i].end();
while (1)
{
_instanceToOptimize.clear();
while (1)
{
if (ifirst == ilast)
break;
_instanceToOptimize.push_back(*ifirst++);
++nInstancesToOptimize;
if (nInstancesToOptimize >= 6)
{
nInstancesToOptimize = 0;
break;
}
}
Optimize();
if (ifirst == ilast)
break;
sort(_subRowInstances[i].begin(), _subRowInstances[i].end(), CompareInstancePosition(this));
if ((6 + decal) <= nInstancesToOptimize)
{
ifirst = _subRowInstances[i].begin() + decal;
}
else
{
ifirst = _subRowInstances[i].begin() + decal - 1;
}
decal += 2;
}
}
}
bool BBPlacer::Optimize()
{
bool optimizationResult = false;
const int numberInstances = _instanceToOptimize.size();
// Save Initial Solution
_bestSolution.reserve(numberInstances);
for (unsigned i=0; i<_instanceToOptimize.size(); i++)
{
_queue.push_back(_instanceToOptimize[i]);
}
Mauka::UVector::iterator ifirst = _instanceToOptimize.begin();
Mauka::UVector::iterator ilast = _instanceToOptimize.end();
vector<Unit>::iterator it = _bestSolution.begin();
while (ifirst != ilast)
*it++ = _instanceX[*ifirst++];
// Init Best Cost
_bestCost = InitCost();
#ifdef PLACE_DEBUG
cout<<" Orig Cost: "<< _bestCost << endl;
cout<<" Actual Cost: " << CurrentCost() << endl;
#endif
// Init Initial Cost
// Init Edges
_leftEdge = _instanceX[*_instanceToOptimize.begin()];
_rightEdge = _instanceX[*_instanceToOptimize.rbegin()]
+ _instanceMarginWidth[*_instanceToOptimize.rbegin()];
UnplaceAll();
_cost = InitCost();
#ifdef PLACE_DEBUG
cout << " Init Cost: " << _cost << endl;
#endif
_loopVect.reserve(numberInstances + 2);
for (int id = 0; id < numberInstances + 2; id++)
_loopVect.push_back(0);
_loopVect[numberInstances] = numberInstances;
_loopVect[numberInstances + 1] = numberInstances + 1;
_stack.reserve(numberInstances);
_idx = numberInstances - 1;
unsigned numAdds = 0;
while(_idx < numberInstances)
{
AddIns();
numAdds++;
if(_loopVect[_idx] == 0 || _cost >= _bestCost)
{
_loopVect[_idx] = 0; //force a bound
if(_cost < _bestCost) //got here if:
// new best complete soln (curWL < best)
// bounded partial soln (curWL > best)
// so there is no need to additionally
// check to ensure this is a complete soln
{
optimizationResult = true;
_bestCost = _cost;
#ifdef PLACE_DEBUG
cout<<" New Best: "<< _cost <<" found after "<< numAdds << endl;
cout << "Cost recalculated: " << InitCost() << endl;
cout << "Actual Cost: " << CurrentCost() << endl;
#endif
ifirst = _instanceToOptimize.begin();
it = _bestSolution.begin();
while (ifirst != ilast)
{
*it++ = _instanceX[*ifirst++];
}
#if 0
Save();
for_each_view(view, _mauka->GetCell()->GetViews())
{
if (CEditor* editor = dynamic_cast<CEditor*>(view))
{
editor->Stop("coucou");
break;
}
end_for;
}
#endif
}
while(_loopVect[_idx] == 0)
{
if(_idx < numberInstances)
RemoveIns();
_loopVect[++_idx]--;
}
}
--_idx;
}
ifirst = _instanceToOptimize.begin();
it = _bestSolution.begin();
while (ifirst != ilast)
_instanceX[*ifirst++] = *it++;
PlaceAll();
_bestSolution.clear();
#ifdef PLACE_DEBUG
cout<<" Total Add Operations: "<< numAdds<< endl;
cout<<" Final solution has cost: "<< _bestCost << endl << endl;
#endif
_loopVect.clear();
_queue.clear();
_stack.clear();
return optimizationResult;
}
void BBPlacer::AddIns()
{
_stack.push_back(_queue.front());
_queue.pop_front();
_loopVect[_idx] = _idx;
unsigned instanceId = _stack.back();
//cerr << "Adding: " << _instanceOccurrenceVector[instanceId] << " " ;
if(_idx%2)
{
_instanceX[instanceId] = _rightEdge - _instanceMarginWidth[instanceId];
_rightEdge -= _instanceMarginWidth[instanceId];
}
else
{
_instanceX[instanceId] = _leftEdge;
_leftEdge += _instanceMarginWidth[instanceId];
}
//cerr << _instanceX[instanceId] << " ";
_instancePlaced[instanceId] = true;
_cost += UpdateInstanceCost(instanceId);
//cerr << _cost << endl;
//cerr << "verify " << CurrentCost() << endl;
}
void BBPlacer::RemoveIns()
{
unsigned instanceId = _stack.back();
//cerr << "Removing: " << _instanceOccurrenceVector[instanceId] << " " ;
_queue.push_back(instanceId);
_stack.pop_back();
if(_idx%2)
_rightEdge += _instanceMarginWidth[instanceId];
else
_leftEdge -= _instanceMarginWidth[instanceId];
_instancePlaced[instanceId] = false;
_cost += UpdateInstanceCost(instanceId);
//cerr << _cost << endl;
}
void BBPlacer::PlaceAll()
{
for (Mauka::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
{
_instancePlaced[*uvit] = true;
}
}
void BBPlacer::UnplaceAll()
{
for (Mauka::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
{
_instancePlaced[*uvit] = false;
}
}
double BBPlacer::InitCost()
{
++_costFlag;
double cost = 0.0;
for (Mauka::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
{
cost += InitInstanceCost(*uvit);
}
return cost;
}
double BBPlacer::CurrentCost()
{
++_costFlag;
double cost = 0.0;
for (Mauka::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
cost += CurrentInstanceCost(*uvit);
return cost;
}
double BBPlacer::UpdateInstanceCost(unsigned instanceid)
{
double deltaCost = 0.0;
for (Mauka::UVector::const_iterator uvit = _mauka->_instanceNets[instanceid].begin();
uvit != _mauka->_instanceNets[instanceid].end();
uvit++)
{
deltaCost += UpdateNetCost(*uvit);
}
return deltaCost;
}
double BBPlacer::UpdateNetCost(unsigned netid)
{
Box& netBBox = _netBBoxes[netid][_netFlags[netid]];
double& netCost = _netCosts[netid][_netFlags[netid]];
double initCost = netCost;
netBBox.MakeEmpty();
if (_mauka->_hasInitX[netid])
netBBox.Merge(_mauka->_netInitX[netid], netBBox.GetYMin());
if (_mauka->_hasInitY[netid])
netBBox.Merge(netBBox.GetXMin(), _mauka->_netInitY[netid]);
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netid].begin();
uvit != _mauka->_netInstances[netid].end();
uvit++)
{
if (_instancePlaced[*uvit])
{
//FIXME
netBBox.Merge(Point(_instanceX[*uvit], _instanceY[*uvit]));
}
}
netCost = ComputeCost(netBBox);
return (netCost - initCost);
}
double BBPlacer::InitInstanceCost(unsigned instanceid)
{
double cost = 0.0;
for (Mauka::UVector::const_iterator uvit = _mauka->_instanceNets[instanceid].begin();
uvit != _mauka->_instanceNets[instanceid].end();
uvit++)
{
ComputeNetBBox(*uvit);
//SaveNetTempValue(*uvit);
cost += CurrentNetCost(*uvit);
}
return cost;
}
double BBPlacer::CurrentInstanceCost(unsigned instanceid)
{
double cost = 0.0;
for (Mauka::UVector::const_iterator uvit = _mauka->_instanceNets[instanceid].begin();
uvit != _mauka->_instanceNets[instanceid].end();
uvit++)
{
cost += CurrentNetCost(*uvit);
}
return cost;
}
void BBPlacer::SaveNetTempValue(unsigned netid)
{
_netFlags[netid] = !_netFlags[netid];
}
void BBPlacer::ComputeNetBBox(unsigned netid)
{
//cerr << _netVector[netid] << endl;
//Box& netTmpBBox = _netBBoxes[netid][!_netFlags[netid]];
Box& netTmpBBox = _netBBoxes[netid][_netFlags[netid]];
//FIXME
netTmpBBox.MakeEmpty();
if (_mauka->_hasInitX[netid])
netTmpBBox.Merge(_mauka->_netInitX[netid], netTmpBBox.GetYMin());
if (_mauka->_hasInitY[netid])
netTmpBBox.Merge(netTmpBBox.GetXMin(), _mauka->_netInitY[netid]);
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netid].begin();
uvit != _mauka->_netInstances[netid].end();
uvit++)
{
if (_instancePlaced[*uvit])
{
//FIXME
netTmpBBox.Merge(Point(_instanceX[*uvit], _instanceY[*uvit]));
//cerr << netTmpBBox << endl;
}
}
_netCosts[netid][_netFlags[netid]] = ComputeCost(netTmpBBox);
//_netCosts[netid][!_netFlags[netid]] = ComputeCost(netTmpBBox);
//cerr << _netCosts[netid][!_netFlags[netid]] << endl;
}
double BBPlacer::ComputeCost(const Box& box) const
{
if (!box.IsEmpty())
return GetValue(box.GetYMax() - box.GetYMin() + box.GetXMax() - box.GetXMin());
else
return 0.0;
}
double BBPlacer::CurrentNetCost(unsigned netid)
{
if (_netCurrCostMark[netid] != _costFlag)
{
_netCurrCostMark[netid] = _costFlag;
return _netCosts[netid][_netFlags[netid]];
}
return 0;
}
}

View File

@ -1,191 +0,0 @@
// 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 "SubRow.h"
#include "Bin.h"
#include "Surface.h"
#include "SimAnnealingPlacer.h"
namespace MAUKA {
Bin::Bin(const Cell* cell, SubRow* subrow, const Box& box)
: Inherit(cell, box)
, _subRow(subrow)
, _mauka(NULL)
, _instanceOccurrenceIds()
, _size(0)
, _capa(0)
, _sourceHits(0)
, _targetHits(0)
{}
Bin* Bin::Create(const Cell* cell, SubRow* subrow, const Box& box)
{
Bin* bin = new Bin(cell, subrow, box);
bin->_PostCreate();
return bin;
}
void Bin::_PostCreate()
{
if (!_subRow)
throw Error("Empty SubRow for Bin");
_mauka = _subRow->GetSurface()->GetMauka();
if (!_mauka)
throw Error("Empty SimAnnealingPlacer for Bin");
_capa = GetUnit(GetValue(GetWidth()) * (1.0 - _subRow->GetSurface()->GetMargin()));
Inherit::_PostCreate();
}
void Bin::_ComputeCapacity(double margin)
{
_capa = GetUnit(GetValue(GetWidth()) * (1.0 - margin));
}
Cell* Bin::GetCell() const
{
return _subRow->GetCell();
}
void Bin::AddInstance(unsigned instanceid)
{
_instanceOccurrenceIds.push_back(instanceid);
Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = this;
}
void Bin::_AddSize(Unit value)
{
_size += value;
_subRow->_AddSize(value);
}
void Bin::RemoveInstance(unsigned instanceid)
{
_instanceOccurrenceIds.remove(instanceid);
Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(-insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = NULL;
}
void Bin::RemoveBackInstance(unsigned instanceid)
{
assert(_instanceOccurrenceIds.back() == instanceid);
_instanceOccurrenceIds.pop_back();
Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(-insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = NULL;
}
void Bin::RemoveFrontInstance(unsigned instanceid)
{
assert(_instanceOccurrenceIds.front() == instanceid);
_instanceOccurrenceIds.pop_front();
Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(-insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = NULL;
}
bool Bin::TryAddInstance(unsigned instanceid)
{
Unit insWidth = _mauka->_instanceWidths[instanceid];
if (GetCapaVsSize() < insWidth)
return false;
AddInstance(instanceid);
return true;
}
bool Bin::UnderOccupied() const
{
// On Considère pour l'instant qu'un Bin est sous-occupé
// et donc qu'il est intéressant d'y déplacer une instance
// si il a 20% de vide par rapport à son remplissage idéal
return ((_instanceOccurrenceIds.size() == 0)
|| (_size <= (1.0 - _subRow->GetSurface()->GetMargin() - 0.2) * _capa));
}
double Bin::GetCost() const
{
return abs(GetValue(_size - _capa));
}
void Bin::DisplayHits() const
{
cout << this << " nb source hits: " << _sourceHits << endl;
cout << this << " nb target hits: " << _targetHits << endl;
}
void Bin::IncrementSourceHits()
{
++_sourceHits;
}
void Bin::IncrementTargetHits()
{
++_targetHits;
}
void Bin::PlotStats(ofstream& out) const
{
unsigned x = (unsigned)(GetValue(GetXMin())) + (unsigned)(GetValue(GetXMax() - GetXMin())) / 2;
//unsigned decal = (unsigned)(GetValue(GetYMax() - GetYMin())) / 4;
//unsigned y = (unsigned)(GetValue(GetYMin()));
unsigned y = (unsigned)(GetValue(GetYMin())) + (unsigned)(GetValue(GetYMax() - GetYMin())) / 2;
unsigned totalMoves = _mauka->_simAnnealingPlacer->GetMoves();
if (totalMoves)
{
//double sourcePercent = (_sourceHits * 100.0) / totalMoves;
double targetPercent = (_targetHits * 100.0) / totalMoves;
out << "set label \""
<< targetPercent << "%\" at " << x << "," << y << " center"
<< endl;
//out << "set label \""
// << targetPercent << "%\" at " << x << "," << y + decal << " center"
// << endl;
}
}
void Bin::Plot(ofstream& out) const
{
out << GetValue(GetXMin()) + 0.3 << " " << GetValue(GetYMin()) + 0.3 << endl
<< GetValue(GetXMin()) + 0.3 << " " << GetValue(GetYMax()) - 0.3 << endl
<< GetValue(GetXMax()) - 0.3 << " " << GetValue(GetYMax()) - 0.3 << endl
<< GetValue(GetXMax()) - 0.3 << " " << GetValue(GetYMin()) + 0.3 << endl
<< GetValue(GetXMin()) + 0.3 << " " << GetValue(GetYMin()) + 0.3 << endl << endl;
}
}

View File

@ -1,84 +0,0 @@
// 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 "Container.h"
namespace MAUKA {
Container::Container(const Cell* cell, const Box& box)
: Inherit(GetDisplaySlot(cell, "Mauka"))
, _box(box)
{}
bool Container::_IsInterceptedBy(View* view, const Point& point, const Unit& aperture) const
// ******************************************************************************************
{
return false;
}
void Container::_Draw(View* view, BasicLayer* basiclayer, const Box& updatearea, const Transformation& transformation)
// *******************************************************************************************************************
{
if (basiclayer)
throw Error("Container::_Draw : basiclayer sould be null !");
view->DrawRectangle(transformation.GetBox(_box));
}
void Container::_Highlight(View* view, const Box& updatearea, const Transformation& transformation)
{
_Draw(view, NULL, updatearea, transformation);
}
string Container::_GetString() const
// *********************************
{
string s = Inherit::_GetString();
s.insert(s.length() - 1, " " + GetString(_box));
return s;
}
Record* Container::_GetRecord() const
// ****************************
{
Record* record = Inherit::_GetRecord();
if (record)
{
record->Add(GetSlot("Box", _box));
}
return record;
}
}

View File

@ -1,678 +0,0 @@
// 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 "Cell.h"
#include "HyperNet.h"
USING_NAMESPACE_HURRICANE
#include "CTimer.h"
#include "CDataBase.h"
#include "CCellGauge.h"
using namespace CRL;
#include "Nimbus.h"
using namespace NIMBUS;
#include "Surface.h"
#include "Row.h"
#include "SimAnnealingPlacer.h"
#include "BBPlacer.h"
#include "Mauka.h"
namespace MAUKA {
namespace {
Name MaukaName("Mauka");
}
Mauka::Mauka(Cell* cell)
// *************************
: Inherit(cell)
, _params()
, _displaySlot(NULL)
, _instanceOccurrencesVector()
, _instanceOccurrencesMap()
, _instanceWidths()
, _instanceNets()
, _nets()
, _netInstances()
, _netInitX()
, _netInitY()
, _hasInitX()
, _hasInitY()
, _surface(NULL)
, _simAnnealingPlacer(NULL)
, _bbPlacer(NULL)
{}
Mauka* Mauka::Create(Cell* cell, double searchratio, Box placementbox)
// *******************************************************************
{
Mauka* mauka = new Mauka(cell);
mauka->_PostCreate(placementbox, searchratio);
return mauka;
}
void Mauka::_PostCreate(Box& placementbox, double searchratio)
// ***********************************************************
{
Inherit::_PostCreate();
Construct();
//_simAnnealingPlacer = new SimAnnealingPlacer(this, 1, 0.0, 0.0);
_simAnnealingPlacer = new SimAnnealingPlacer(this, 0.9, 0.05, 0.05);
_displaySlot = DisplaySlot::Create(GetCell(),MaukaName,139,0,139);
_surface = Surface::Create(this, placementbox, searchratio);
_simAnnealingPlacer->Init();
//Plot();
}
#if 0
void Mauka::ReInit()
// *******************
{
Box placementBox = _surface->GetBox();
_surface->Delete();
_simAnnealingPlacer->Delete();
_surface = Surface::Create(this, placementBox);
_simAnnealingPlacer = SimAnnealingPlacer::Create(this);
}
#endif
void Mauka::Run()
{
CTimer timer;
timer.Start();
while (_simAnnealingPlacer->Iterate())
;
timer.Stop();
if (_verbosity.MajorStatsIsOn())
{
_simAnnealingPlacer->DisplayResults();
}
if (_params.plotBins)
{
//PlotBinsStats();
}
if (_verbosity.SystemResourcesIsOn())
{
cout << endl << " o Simulated Annealing run took " << timer.GetUserTime() << " s ..." << endl;
}
//Plot();
_bbPlacer = new BBPlacer(this);
_bbPlacer->Run();
_bbPlacer->Save();
//Plot();
}
namespace {
void VerifyPathCellBox(const Occurrence& occurrence)
//On occurrence Path set all cells Abox to (0,0,0,0) if Box is empty
//This avoids bad Transfos on Path
{
Path path = occurrence.GetPath();
while (!path.IsEmpty())
{
Instance* instance = path.GetHeadInstance();
Cell* model = instance->GetMasterCell();
if (model->GetAbutmentBox().IsEmpty())
{
model->SetAbutmentBox(Box(Point(0,0), Point(0,0)));
}
path = path.GetTailPath();
}
}
}
void Mauka::Construct()
// **********************
{
typedef map<Occurrence, unsigned> InstanceOccurrenceMap;
typedef set<Instance*> InstanceSet;
typedef map<Net*, unsigned> NetMap;
InstanceSet instanceSet;
NetMap netMap;
unsigned instanceId = 0;
unsigned netId = 0;
Unit standardCellHeight = 0;
for_each_occurrence(occurrence, GetCell()->GetLeafInstanceOccurrences())
{
Instance* instance = static_cast<Instance*>(occurrence.GetEntity());
if (!instance->IsFixed())
{
//cerr << "unplaced " << occurrence << occurrence.GetBoundingBox() << endl;
Cell* model = instance->GetMasterCell();
Unit insWidth = model->GetAbutmentBox().GetWidth();
Unit insHeight = model->GetAbutmentBox().GetHeight();
if (standardCellHeight == 0)
standardCellHeight = insHeight;
else if (insHeight != standardCellHeight)
{
throw Error("All non-standard instances : "
+ GetString(instance->GetName())
+ " must be placed");
}
_instanceOccurrencesVector.push_back(occurrence);
//VerifyPathCellBox(occurrence);
_instanceWidths.push_back(insWidth);
InstanceSet::iterator isit = instanceSet.find(instance);
if (isit != instanceSet.end())
{
cerr << "Unplaced Instance : " << *isit << endl;
cerr << "Unplaced Occurrence : " << occurrence << endl;
cerr << (*isit)->GetPlacementStatus() << endl;
throw Error("Each unplaced instance must have one occurrence only");
}
_instanceOccurrencesMap[occurrence] = instanceId++;
instanceSet.insert(instance);
_instanceNets.push_back(UVector());
}
end_for;
}
if (_instanceOccurrencesVector.size() == 0)
throw Error("No Instance to place...");
typedef set<Net*> NetSet;
NetSet treatedNets;
for (InstanceOccurrencesVector::const_iterator iovit = _instanceOccurrencesVector.begin();
iovit != _instanceOccurrencesVector.end();
iovit++)
{
Instance* instance = static_cast<Instance*>(iovit->GetEntity());
for_each_plug(plug, instance->GetConnectedPlugs())
{
Net* net = plug->GetNet();
if (net->IsGlobal())
continue;
typedef list<Occurrence> InstanceOccurrenceList;
InstanceOccurrenceList instanceOccurrenceList;
Occurrence rootNetOccurrence = GetHyperNetRootNetOccurrence(Occurrence(net, iovit->GetPath()));
Net* rootNet = static_cast<Net*>(rootNetOccurrence.GetEntity());
NetSet::iterator snit = treatedNets.find(rootNet);
if (snit != treatedNets.end())
continue;
treatedNets.insert(rootNet);
HyperNet hyperNet(rootNetOccurrence);
typedef list<Point> PointList;
PointList pointList;
for_each_occurrence(occurrence, hyperNet.GetNetOccurrences())
{
Instance* instance = occurrence.GetPath().GetTailInstance();
if (instance && instance->IsLeaf())
{
Occurrence instanceOccurrence = Occurrence(instance, occurrence.GetPath().GetHeadPath());
if (instance->IsFixed())
pointList.push_back(instanceOccurrence.GetBoundingBox().GetCenter());
else
instanceOccurrenceList.push_back(instanceOccurrence);
}
end_for;
}
unsigned pointListSize = pointList.size();
Point fixedPoint(0,0);
if (pointListSize > 0)
{
for (PointList::iterator plit = pointList.begin();
plit != pointList.end();
plit++)
{
fixedPoint.SetX(fixedPoint.GetX() + plit->GetX() / pointListSize);
fixedPoint.SetY(fixedPoint.GetY() + plit->GetY() / pointListSize);
}
}
if ((instanceOccurrenceList.size() < 2) && pointListSize == 0)
continue;
_netInstances.push_back(UVector());
_nets.push_back(net);
if (pointListSize > 0)
{
_netInitX.push_back(fixedPoint.GetX());
_netInitY.push_back(fixedPoint.GetY());
_hasInitX.push_back(true);
_hasInitY.push_back(true);
}
else
{
_netInitX.push_back(0);
_netInitY.push_back(0);
_hasInitX.push_back(false);
_hasInitY.push_back(false);
}
netMap[net] = netId;
for (InstanceOccurrenceList::iterator iolit = instanceOccurrenceList.begin();
iolit != instanceOccurrenceList.end();
iolit++)
{
InstanceOccurrenceMap::const_iterator iomit = _instanceOccurrencesMap.find(*iolit);
if (iomit == _instanceOccurrencesMap.end())
{
cerr << "cannot find " << iomit->first << endl;
throw Error("Error in netsInstances construction in SimAnnealingPlacer");
}
_netInstances.back().push_back(iomit->second);
_instanceNets[iomit->second].push_back(netId);
}
++netId;
end_for;
}
}
#if DEBUG
//debug ... display netlist
for (unsigned instanceId = 0; instanceId < _instanceOccurrencesVector.size(); instanceId++)
{
cerr << "instance " << _instanceOccurrencesVector[instanceId] << endl;
cerr << "is connected to " << endl;
for (UVector::const_iterator uvit = _instanceNets[instanceId].begin();
uvit != _instanceNets[instanceId].end();
uvit++)
{
unsigned netid = *uvit;
cerr << _nets[netid] << endl;
for (UVector::const_iterator nuvit = _netInstances[netid].begin();
nuvit != _netInstances[netid].end();
nuvit++)
{
cerr << _instanceOccurrencesVector[*nuvit] << endl;
}
cerr << endl;
}
cerr << endl;
}
#endif
}
bool Mauka::Iterate()
// ******************
{
bool canContinue = _simAnnealingPlacer->Iterate();
Save();
return canContinue;
}
void Mauka::_PreDelete()
// *********************
{
_surface->Delete();
if (_simAnnealingPlacer)
delete _simAnnealingPlacer;
if (_bbPlacer)
delete _bbPlacer;
_displaySlot->Delete();
Inherit::_PreDelete();
}
Record* Mauka::_GetRecord() const
// ************************
{
Record* record = Inherit::_GetRecord();
if (record) {
record->Add(GetSlot("Surface", _surface));
}
return record;
}
const Name& Mauka::GetName() const
// *******************************
{
return MaukaName;
}
void Mauka::Save() const
// *********************
{
if (_bbPlacer)
_bbPlacer->Save();
else if (_simAnnealingPlacer)
_simAnnealingPlacer->Save();
}
Mauka* GetMauka(const Cell* cell)
// ******************************
{
return static_cast<Mauka*>(GetCEngine(cell, MaukaName));
}
namespace {
class TestSubRow : public Box {
public: Unit _size; // sum of the contained instances width
public: TestSubRow(const Box& box): Box(box), _size(0) {}
};
typedef list<TestSubRow*> TestSubRowsList;
typedef vector<Occurrence> InstanceOccurrencesVector;
typedef list<Occurrence> InstanceOccurrencesList;
void DestroyTestSubRows(TestSubRowsList& testsubrowslist)
{
for (TestSubRowsList::iterator tsrlit = testsubrowslist.begin();
tsrlit != testsubrowslist.end();
tsrlit++)
{
delete *tsrlit;
}
testsubrowslist.clear();
}
struct SortInstanceOccurrencesByWidth
{
bool operator()(Occurrence occurrence1, Occurrence occurrence2)
{
Instance* instance1 = static_cast<Instance*>(occurrence1.GetEntity());
Instance* instance2 = static_cast<Instance*>(occurrence2.GetEntity());
return instance1->GetAbutmentBox().GetWidth() > instance2->GetAbutmentBox().GetWidth();
}
};
bool TryDisplayInstancesInSubRows(
InstanceOccurrencesVector& instanceoccurrencesvector, TestSubRowsList& testsubrowslist)
{
// Try Insert instances in subrows
sort(instanceoccurrencesvector.begin(), instanceoccurrencesvector.end(), SortInstanceOccurrencesByWidth());
TestSubRowsList::iterator tsrlit = testsubrowslist.begin();
InstanceOccurrencesVector::const_iterator insIterator = instanceoccurrencesvector.begin();
InstanceOccurrencesVector::const_iterator lastLoopInsertedInsIterator = insIterator;
while(insIterator != instanceoccurrencesvector.end())
{
if (tsrlit == testsubrowslist.end())
{
tsrlit = testsubrowslist.begin();
if (lastLoopInsertedInsIterator != insIterator)
lastLoopInsertedInsIterator = insIterator;
else
{
return false;
}
}
TestSubRow* testSubRow = *tsrlit;
Instance* instance = static_cast<Instance*>(insIterator->GetEntity());
Cell* model = instance->GetMasterCell();
Unit insWidth = model->GetAbutmentBox().GetWidth();
if (insWidth <= testSubRow->GetWidth() - testSubRow->_size)
{
testSubRow->_size += insWidth;
++insIterator;
}
++tsrlit;
}
return true;
}
}
bool TestMaukaConstruction(Cell* cell, GCell* gcell)
// *************************************************
{
Unit pitch = GetCDataBase()->GetDefaultCGPitch();
Unit sliceHeight = GetCDataBase()->GetDefaultCGSliceHeight();
const Box& box = gcell->GetBox();
if (box.IsEmpty() || box.IsPonctual() ||box.IsFlat())
throw Error("Wrong Box for GCell");
if (box.GetHeight() % sliceHeight)
throw Error("Box Height must be a multiple of Slice Height");
InstanceOccurrencesList fixedInstanceOccurrenceList;
InstanceOccurrencesVector toPlaceInstanceOccurrencesVector;
//search for preplaced leaf instances
Unit instanceToPlaceWidthMax = 0;
for_each_occurrence(occurrence, cell->GetLeafInstanceOccurrencesUnder(gcell->GetBox()))
{
Instance* instance = static_cast<Instance*>(occurrence.GetEntity());
if (instance->IsFixed())
fixedInstanceOccurrenceList.push_back(occurrence);
else
{
Cell* model = instance->GetMasterCell();
Unit insWidth = model->GetAbutmentBox().GetWidth();
toPlaceInstanceOccurrencesVector.push_back(occurrence);
if (instanceToPlaceWidthMax > insWidth)
instanceToPlaceWidthMax = insWidth;
}
end_for;
}
Unit binWidthMax = GetUnit((unsigned)(
2.0 * GetValue(instanceToPlaceWidthMax) / GetValue(pitch)) * GetValue(pitch));
Unit binWidthMin = GetUnit((unsigned)(
GetValue(binWidthMax) / (GetValue(pitch) * 2)) * GetValue(pitch));
TestSubRowsList testSubRowsList;
if (fixedInstanceOccurrenceList.size() != 0)
{
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));
for (InstanceOccurrencesList::iterator iolit = fixedInstanceOccurrenceList.begin();
iolit != 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
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);
}
}
}
}
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)
{
testSubRowsList.push_back(new TestSubRow(
Box(subRowXMin, gcell->GetYMin() + y * sliceHeight
, subRowXMax, gcell->GetYMin() + (y+1) * sliceHeight)
));
}
}
}
}
else
{
for (Unit ymin = gcell->GetYMin(); ymin <= gcell->GetYMax() - sliceHeight; ymin += sliceHeight)
{
testSubRowsList.push_back(new TestSubRow(
Box(gcell->GetXMin(), ymin, gcell->GetXMax(), ymin + sliceHeight)
));
}
}
bool tryInstanceInsertion = TryDisplayInstancesInSubRows(toPlaceInstanceOccurrencesVector, testSubRowsList);
DestroyTestSubRows(testSubRowsList);
return tryInstanceInsertion;
}
void Mauka::PlotBinsStats() const
// ******************************
{
ofstream out("binsstats.gpl");
out << "set noxtics" << endl << "set noytics" << endl
<< "set noborder" << endl << "set nokey" << endl
<< "set title '" << GetCell()->GetName() << "'" << endl
<< "#set terminal postscript eps color solid" << endl
<< "#set output 'binsstats.ps'" << endl;
_surface->PlotBinsStats(out);
}
void Mauka::Plot() const
// *********************
{
static unsigned count = 0;
string cellNameString = GetString(GetCell()->GetName())
+ "_" + GetString(count) + ".gpl";
++count;
ofstream out(cellNameString.c_str());
out << "set noxtics" << endl << "set noytics" << endl
<< "set noborder" << endl << "set nokey" << endl
<< "set title '" << cellNameString << "'" << endl
<< "#set terminal postscript eps color solid" << endl << "#set output '"
<< cellNameString << ".ps'" << endl;
Box boundingBox = _surface->GetBox();
boundingBox.Merge(PlotFixedPointsLabels(out));
out << "set xrange[" << boundingBox.GetXMin()
<< ":" << boundingBox.GetXMax() << "]" << endl
<< "set yrange[" << boundingBox.GetYMin()
<< ":" << boundingBox.GetYMax() << "]" << endl;
out << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4" << endl;
// << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4" << endl;
_surface->Plot(out);
if (_bbPlacer)
_bbPlacer->Plot(out);
else
_simAnnealingPlacer->Plot(out);
out << "pause -1 'press any key'" << endl;
}
Box Mauka::PlotFixedPointsLabels(ofstream& out) const
// ****************************************************
{
Box boundingBox;
out << "#FixedPoints" << endl;
for (unsigned i = 0; i < _netInstances.size(); i++)
{
if (_hasInitX[i])
{
out << "set label \""
<< GetString(_nets[i]->GetName()) << "\" at "
<< _netInitX[i] << "," << _netInitY[i] << " center"
<< endl;
}
boundingBox.Merge(_netInitX[i], _netInitY[i]);
}
return boundingBox;
}
void Mauka::Hide() {
if (_displaySlot != NULL) {
_displaySlot->Hide();
}
}
void Mauka::Show() {
if (_displaySlot != NULL) {
_displaySlot->Show();
}
}
unsigned Mauka::GetRandomInstanceId() const {
unsigned instanceId = (unsigned)((double)_instanceOccurrencesVector.size() * rand() / (RAND_MAX + 1.0));
return instanceId;
}
}

View File

@ -1,105 +0,0 @@
// 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 : 19/07/2006
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
//
// Authors-Tag
#include "MaukaBox.h"
namespace MAUKA {
Box& Update(Box& box, const Point& src, const Point& dst)
{
Unit minX = box.GetXMin();
Unit maxX = box.GetXMax();
Unit minY = box.GetYMin();
Unit maxY = box.GetYMax();
if (dst.GetX() > src.GetX())
{
if (src.GetX() == minX)
{
box = Box();
return box;
}
else
if (dst.GetX() > maxX)
{
maxX = dst.GetX();
}
}
else
if (dst.GetX() < src.GetX())
{
if (src.GetX() == maxX)
{
box = Box();
return box;
}
else
if (dst.GetX() < minX)
{
minX = dst.GetX();
}
}
if (dst.GetY() > src.GetY())
{
if (src.GetY() == minY)
{
box = Box();
return box;
}
else
if (dst.GetY() > maxY)
{
maxY = dst.GetY();
}
}
else
if (dst.GetY() < src.GetY())
{
if (src.GetY() == maxY)
{
box = Box();
return box;
}
else
if (dst.GetY() < minY)
{
minY = dst.GetY();
}
}
box = Box(Point(minX, minY), Point(maxX, maxY));
return box;
}
}

View File

@ -1,678 +0,0 @@
// 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 "Cell.h"
#include "HyperNet.h"
USING_NAMESPACE_HURRICANE
#include "CTimer.h"
#include "CDataBase.h"
#include "CCellGauge.h"
using namespace CRL;
#include "Nimbus.h"
using namespace NIMBUS;
#include "Surface.h"
#include "Row.h"
#include "SimAnnealingPlacer.h"
#include "BBPlacer.h"
#include "Mauka.h"
namespace MAUKA {
namespace {
Name MaukaName("Mauka");
}
Mauka::Mauka(Cell* cell)
// *************************
: Inherit(cell)
, _params()
, _displaySlot(NULL)
, _instanceOccurrencesVector()
, _instanceOccurrencesMap()
, _instanceWidths()
, _instanceNets()
, _nets()
, _netInstances()
, _netInitX()
, _netInitY()
, _hasInitX()
, _hasInitY()
, _surface(NULL)
, _simAnnealingPlacer(NULL)
, _bbPlacer(NULL)
{}
Mauka* Mauka::create(Cell* cell, double searchratio, Box placementbox)
// *******************************************************************
{
Mauka* mauka = new Mauka(cell);
mauka->_postCreate(placementbox, searchratio);
return mauka;
}
void Mauka::_postCreate(Box& placementbox, double searchratio)
// ***********************************************************
{
Inherit::_postCreate();
Construct();
//_simAnnealingPlacer = new SimAnnealingPlacer(this, 1, 0.0, 0.0);
_simAnnealingPlacer = new SimAnnealingPlacer(this, 0.9, 0.05, 0.05);
_displaySlot = DisplaySlot::create(getCell(),MaukaName,139,0,139);
_surface = Surface::create(this, placementbox, searchratio);
_simAnnealingPlacer->init();
//Plot();
}
#if 0
void Mauka::ReInit()
// *******************
{
Box placementBox = _surface->getBox();
_surface->destroy();
_simAnnealingPlacer->destroy();
_surface = Surface::create(this, placementBox);
_simAnnealingPlacer = SimAnnealingPlacer::create(this);
}
#endif
void Mauka::Run()
{
CTimer timer;
timer.Start();
while (_simAnnealingPlacer->Iterate())
;
timer.Stop();
if (_verbosity.MajorStatsIsOn())
{
_simAnnealingPlacer->DisplayResults();
}
if (_params.plotBins)
{
//PlotBinsStats();
}
if (_verbosity.SystemResourcesIsOn())
{
cout << endl << " o Simulated Annealing run took " << timer.getUserTime() << " s ..." << endl;
}
//Plot();
_bbPlacer = new BBPlacer(this);
_bbPlacer->Run();
_bbPlacer->Save();
//Plot();
}
namespace {
void VerifyPathCellBox(const Occurrence& occurrence)
//On occurrence Path set all cells Abox to (0,0,0,0) if Box is empty
//This avoids bad Transfos on Path
{
Path path = occurrence.getPath();
while (!path.isEmpty())
{
Instance* instance = path.getHeadInstance();
Cell* model = instance->getMasterCell();
if (model->getAbutmentBox().isEmpty())
{
model->setAbutmentBox(Box(Point(0,0), Point(0,0)));
}
path = path.getTailPath();
}
}
}
void Mauka::Construct()
// **********************
{
typedef map<Occurrence, unsigned> InstanceOccurrenceMap;
typedef set<Instance*> InstanceSet;
typedef map<Net*, unsigned> NetMap;
InstanceSet instanceSet;
NetMap netMap;
unsigned instanceId = 0;
unsigned netId = 0;
DbU::Unit standardCellHeight = 0;
for_each_occurrence(occurrence, getCell()->getLeafInstanceOccurrences())
{
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
if (!instance->isFixed())
{
//cerr << "unplaced " << occurrence << occurrence.getBoundingBox() << endl;
Cell* model = instance->getMasterCell();
DbU::Unit insWidth = model->getAbutmentBox().getWidth();
DbU::Unit insHeight = model->getAbutmentBox().getHeight();
if (standardCellHeight == 0)
standardCellHeight = insHeight;
else if (insHeight != standardCellHeight)
{
throw Error("All non-standard instances : "
+ getString(instance->getName())
+ " must be placed");
}
_instanceOccurrencesVector.push_back(occurrence);
//VerifyPathCellBox(occurrence);
_instanceWidths.push_back(insWidth);
InstanceSet::iterator isit = instanceSet.find(instance);
if (isit != instanceSet.end())
{
cerr << "Unplaced Instance : " << *isit << endl;
cerr << "Unplaced Occurrence : " << occurrence << endl;
cerr << (*isit)->getPlacementStatus() << endl;
throw Error("Each unplaced instance must have one occurrence only");
}
_instanceOccurrencesMap[occurrence] = instanceId++;
instanceSet.insert(instance);
_instanceNets.push_back(UVector());
}
end_for;
}
if (_instanceOccurrencesVector.size() == 0)
throw Error("No Instance to place...");
typedef set<Net*> NetSet;
NetSet treatedNets;
for (InstanceOccurrencesVector::const_iterator iovit = _instanceOccurrencesVector.begin();
iovit != _instanceOccurrencesVector.end();
iovit++)
{
Instance* instance = static_cast<Instance*>(iovit->getEntity());
for_each_plug(plug, instance->getConnectedPlugs())
{
Net* net = plug->getNet();
if (net->isGlobal())
continue;
typedef list<Occurrence> InstanceOccurrenceList;
InstanceOccurrenceList instanceOccurrenceList;
Occurrence rootNetOccurrence = getHyperNetRootNetOccurrence(Occurrence(net, iovit->getPath()));
Net* rootNet = static_cast<Net*>(rootNetOccurrence.getEntity());
NetSet::iterator snit = treatedNets.find(rootNet);
if (snit != treatedNets.end())
continue;
treatedNets.insert(rootNet);
HyperNet hyperNet(rootNetOccurrence);
typedef list<Point> PointList;
PointList pointList;
for_each_occurrence(occurrence, hyperNet.getNetOccurrences())
{
Instance* instance = occurrence.getPath().getTailInstance();
if (instance && instance->isLeaf())
{
Occurrence instanceOccurrence = Occurrence(instance, occurrence.getPath().getHeadPath());
if (instance->isFixed())
pointList.push_back(instanceOccurrence.getBoundingBox().getCenter());
else
instanceOccurrenceList.push_back(instanceOccurrence);
}
end_for;
}
unsigned pointListSize = pointList.size();
Point fixedPoint(0,0);
if (pointListSize > 0)
{
for (PointList::iterator plit = pointList.begin();
plit != pointList.end();
plit++)
{
fixedPoint.setX(fixedPoint.getX() + plit->getX() / pointListSize);
fixedPoint.setY(fixedPoint.getY() + plit->getY() / pointListSize);
}
}
if ((instanceOccurrenceList.size() < 2) && pointListSize == 0)
continue;
_netInstances.push_back(UVector());
_nets.push_back(net);
if (pointListSize > 0)
{
_netInitX.push_back(fixedPoint.getX());
_netInitY.push_back(fixedPoint.getY());
_hasInitX.push_back(true);
_hasInitY.push_back(true);
}
else
{
_netInitX.push_back(0);
_netInitY.push_back(0);
_hasInitX.push_back(false);
_hasInitY.push_back(false);
}
netMap[net] = netId;
for (InstanceOccurrenceList::iterator iolit = instanceOccurrenceList.begin();
iolit != instanceOccurrenceList.end();
iolit++)
{
InstanceOccurrenceMap::const_iterator iomit = _instanceOccurrencesMap.find(*iolit);
if (iomit == _instanceOccurrencesMap.end())
{
cerr << "cannot find " << iomit->first << endl;
throw Error("Error in netsInstances construction in SimAnnealingPlacer");
}
_netInstances.back().push_back(iomit->second);
_instanceNets[iomit->second].push_back(netId);
}
++netId;
end_for;
}
}
#if DEBUG
//debug ... display netlist
for (unsigned instanceId = 0; instanceId < _instanceOccurrencesVector.size(); instanceId++)
{
cerr << "instance " << _instanceOccurrencesVector[instanceId] << endl;
cerr << "is connected to " << endl;
for (UVector::const_iterator uvit = _instanceNets[instanceId].begin();
uvit != _instanceNets[instanceId].end();
uvit++)
{
unsigned netid = *uvit;
cerr << _nets[netid] << endl;
for (UVector::const_iterator nuvit = _netInstances[netid].begin();
nuvit != _netInstances[netid].end();
nuvit++)
{
cerr << _instanceOccurrencesVector[*nuvit] << endl;
}
cerr << endl;
}
cerr << endl;
}
#endif
}
bool Mauka::Iterate()
// ******************
{
bool canContinue = _simAnnealingPlacer->Iterate();
Save();
return canContinue;
}
void Mauka::_preDestroy()
// *********************
{
_surface->destroy();
if (_simAnnealingPlacer)
delete _simAnnealingPlacer;
if (_bbPlacer)
delete _bbPlacer;
_displaySlot->destroy();
Inherit::_preDestroy();
}
Record* Mauka::_getRecord() const
// ************************
{
Record* record = Inherit::_getRecord();
if (record) {
record->add(getSlot("Surface", _surface));
}
return record;
}
const Name& Mauka::getName() const
// *******************************
{
return MaukaName;
}
void Mauka::Save() const
// *********************
{
if (_bbPlacer)
_bbPlacer->Save();
else if (_simAnnealingPlacer)
_simAnnealingPlacer->Save();
}
Mauka* getMauka(const Cell* cell)
// ******************************
{
return static_cast<Mauka*>(getCEngine(cell, MaukaName));
}
namespace {
class TestSubRow : public Box {
public: DbU::Unit _size; // sum of the contained instances width
public: TestSubRow(const Box& box): Box(box), _size(0) {}
};
typedef list<TestSubRow*> TestSubRowsList;
typedef vector<Occurrence> InstanceOccurrencesVector;
typedef list<Occurrence> InstanceOccurrencesList;
void DestroyTestSubRows(TestSubRowsList& testsubrowslist)
{
for (TestSubRowsList::iterator tsrlit = testsubrowslist.begin();
tsrlit != testsubrowslist.end();
tsrlit++)
{
delete *tsrlit;
}
testsubrowslist.clear();
}
struct sortInstanceOccurrencesByWidth
{
bool operator()(Occurrence occurrence1, Occurrence occurrence2)
{
Instance* instance1 = static_cast<Instance*>(occurrence1.getEntity());
Instance* instance2 = static_cast<Instance*>(occurrence2.getEntity());
return instance1->getAbutmentBox().getWidth() > instance2->getAbutmentBox().getWidth();
}
};
bool TryDisplayInstancesInSubRows(
InstanceOccurrencesVector& instanceoccurrencesvector, TestSubRowsList& testsubrowslist)
{
// Try Insert instances in subrows
sort(instanceoccurrencesvector.begin(), instanceoccurrencesvector.end(), sortInstanceOccurrencesByWidth());
TestSubRowsList::iterator tsrlit = testsubrowslist.begin();
InstanceOccurrencesVector::const_iterator insIterator = instanceoccurrencesvector.begin();
InstanceOccurrencesVector::const_iterator lastLoopInsertedInsIterator = insIterator;
while(insIterator != instanceoccurrencesvector.end())
{
if (tsrlit == testsubrowslist.end())
{
tsrlit = testsubrowslist.begin();
if (lastLoopInsertedInsIterator != insIterator)
lastLoopInsertedInsIterator = insIterator;
else
{
return false;
}
}
TestSubRow* testSubRow = *tsrlit;
Instance* instance = static_cast<Instance*>(insIterator->getEntity());
Cell* model = instance->getMasterCell();
DbU::Unit insWidth = model->getAbutmentBox().getWidth();
if (insWidth <= testSubRow->getWidth() - testSubRow->_size)
{
testSubRow->_size += insWidth;
++insIterator;
}
++tsrlit;
}
return true;
}
}
bool TestMaukaConstruction(Cell* cell, GCell* gcell)
// *************************************************
{
DbU::Unit pitch = getCDataBase()->getDefaultCGPitch();
DbU::Unit sliceHeight = getCDataBase()->getDefaultCGSliceHeight();
const Box& box = gcell->getBox();
if (box.isEmpty() || box.isPonctual() ||box.isFlat())
throw Error("Wrong Box for GCell");
if (box.getHeight() % sliceHeight)
throw Error("Box Height must be a multiple of Slice Height");
InstanceOccurrencesList fixedInstanceOccurrenceList;
InstanceOccurrencesVector toPlaceInstanceOccurrencesVector;
//search for preplaced leaf instances
DbU::Unit instanceToPlaceWidthMax = 0;
for_each_occurrence(occurrence, cell->getLeafInstanceOccurrencesUnder(gcell->getBox()))
{
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
if (instance->isFixed())
fixedInstanceOccurrenceList.push_back(occurrence);
else
{
Cell* model = instance->getMasterCell();
DbU::Unit insWidth = model->getAbutmentBox().getWidth();
toPlaceInstanceOccurrencesVector.push_back(occurrence);
if (instanceToPlaceWidthMax > insWidth)
instanceToPlaceWidthMax = insWidth;
}
end_for;
}
DbU::Unit binWidthMax = DbU::lambda((unsigned)(
2.0 * getValue(instanceToPlaceWidthMax) / getValue(pitch)) * getValue(pitch));
DbU::Unit binWidthMin = DbU::lambda((unsigned)(
getValue(binWidthMax) / (getValue(pitch) * 2)) * getValue(pitch));
TestSubRowsList testSubRowsList;
if (fixedInstanceOccurrenceList.size() != 0)
{
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));
for (InstanceOccurrencesList::iterator iolit = fixedInstanceOccurrenceList.begin();
iolit != fixedInstanceOccurrenceList.end();
iolit++)
{
Instance* instance = static_cast<Instance*>(iolit->getEntity());
Box instanceAbutmentBox = instance->getAbutmentBox();
iolit->getPath().getTransformation().ApplyOn(instanceAbutmentBox);
Box preplacedBox = gcell->getIntersection(instanceAbutmentBox);
DbU::Unit insWidth = preplacedBox.getWidth();
DbU::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
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);
}
}
}
}
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;
DbU::Unit subRowXMin = gcell->getXMin() + x * pitch;
if (x >= (int)prePlaceTab[y].size())
break;
while ((x < (int)prePlaceTab[y].size()) && (prePlaceTab[y][x] == false))
++x;
DbU::Unit subRowXMax = gcell->getXMin() + x * pitch;
if (subRowXMax - subRowXMin > binWidthMin)
{
testSubRowsList.push_back(new TestSubRow(
Box(subRowXMin, gcell->getYMin() + y * sliceHeight
, subRowXMax, gcell->getYMin() + (y+1) * sliceHeight)
));
}
}
}
}
else
{
for (DbU::Unit ymin = gcell->getYMin(); ymin <= gcell->getYMax() - sliceHeight; ymin += sliceHeight)
{
testSubRowsList.push_back(new TestSubRow(
Box(gcell->getXMin(), ymin, gcell->getXMax(), ymin + sliceHeight)
));
}
}
bool tryInstanceInsertion = TryDisplayInstancesInSubRows(toPlaceInstanceOccurrencesVector, testSubRowsList);
DestroyTestSubRows(testSubRowsList);
return tryInstanceInsertion;
}
void Mauka::PlotBinsStats() const
// ******************************
{
ofstream out("binsstats.gpl");
out << "set noxtics" << endl << "set noytics" << endl
<< "set noborder" << endl << "set nokey" << endl
<< "set title '" << getCell()->getName() << "'" << endl
<< "#set terminal postscript eps color solid" << endl
<< "#set output 'binsstats.ps'" << endl;
_surface->PlotBinsStats(out);
}
void Mauka::Plot() const
// *********************
{
static unsigned count = 0;
string cellNameString = getString(getCell()->getName())
+ "_" + getString(count) + ".gpl";
++count;
ofstream out(cellNameString.c_str());
out << "set noxtics" << endl << "set noytics" << endl
<< "set noborder" << endl << "set nokey" << endl
<< "set title '" << cellNameString << "'" << endl
<< "#set terminal postscript eps color solid" << endl << "#set output '"
<< cellNameString << ".ps'" << endl;
Box boundingBox = _surface->getBox();
boundingBox.merge(PlotFixedPointsLabels(out));
out << "set xrange[" << boundingBox.getXMin()
<< ":" << boundingBox.getXMax() << "]" << endl
<< "set yrange[" << boundingBox.getYMin()
<< ":" << boundingBox.getYMax() << "]" << endl;
out << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4" << endl;
// << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4" << endl;
_surface->Plot(out);
if (_bbPlacer)
_bbPlacer->Plot(out);
else
_simAnnealingPlacer->Plot(out);
out << "pause -1 'press any key'" << endl;
}
Box Mauka::PlotFixedPointsLabels(ofstream& out) const
// ****************************************************
{
Box boundingBox;
out << "#FixedPoints" << endl;
for (unsigned i = 0; i < _netInstances.size(); i++)
{
if (_hasInitX[i])
{
out << "set label \""
<< getString(_nets[i]->getName()) << "\" at "
<< _netInitX[i] << "," << _netInitY[i] << " center"
<< endl;
}
boundingBox.merge(_netInitX[i], _netInitY[i]);
}
return boundingBox;
}
void Mauka::hide() {
if (_displaySlot != NULL) {
_displaySlot->hide();
}
}
void Mauka::show() {
if (_displaySlot != NULL) {
_displaySlot->show();
}
}
unsigned Mauka::getRandomInstanceId() const {
unsigned instanceId = (unsigned)((double)_instanceOccurrencesVector.size() * rand() / (RAND_MAX + 1.0));
return instanceId;
}
}

View File

@ -1,541 +0,0 @@
// 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 <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#include "Error.h"
#include "Plug.h"
USING_NAMESPACE_HURRICANE
#include "CEditor.h"
using namespace CRL;
#include "Mauka.h"
#include "Bin.h"
#include "SubRow.h"
#include "Row.h"
#include "MaukaBox.h"
#include "SimAnnealingPlacer.h"
#include "Surface.h"
#include "Move.h"
namespace MAUKA {
namespace {
Unit PositionRand(const Unit position, const double distance, const Unit min, const Unit max)
{
Unit borneInf, borneSup;
if ((borneSup = position + GetUnit((int)(distance * GetValue(max) + 0.5)) ) > max )
borneSup = max;
if ((borneInf = position - GetUnit((int)(distance * GetValue(max) + 0.5)) ) < min )
borneInf = min;
return borneInf + GetUnit((int)(GetValue(borneSup - borneInf) * rand() / (RAND_MAX+1.0)));
}
}
Move::Move(SimAnnealingPlacer* simannealingplacer)
: _simAnnealingPlacer(simannealingplacer)
, _mauka(_simAnnealingPlacer->_mauka)
, _surface(_mauka->_surface)
, _exchange(false)
, _srcIns(0)
, _srcBin(NULL)
, _srcBinInitCost(0.0)
, _srcSubRow(NULL)
, _srcRow(NULL)
, _srcRowInitCost(0.0)
, _srcWidth(0)
, _dstBin(NULL)
, _dstBinInitCost(0.0)
, _dstSubRow(NULL)
, _dstRow(NULL)
, _dstRowInitCost(0.0)
, _dstIns(0)
, _dstWidth(0)
, _affectedNets()
{}
double Move::GetDeltaRowCost() const
{
double deltaRowCost = -_srcRowInitCost;
deltaRowCost -= _dstRowInitCost;
deltaRowCost += _srcRow->GetCost();
deltaRowCost += _dstRow->GetCost();
return deltaRowCost;
}
double Move::GetDeltaBinCost() const
{
double deltaBinCost = -_srcBinInitCost;
deltaBinCost -= _dstBinInitCost;
deltaBinCost += _srcBin->GetCost();
deltaBinCost += _dstBin->GetCost();
#if 0
cerr << "src init cost " << _srcBinInitCost << endl;
cerr << "dst init cost " << _dstBinInitCost << endl;
cerr << "src after cost " << _srcBin->GetCost() << endl;
cerr << "dst after cost " << _dstBin->GetCost() << endl;
cerr << deltaBinCost << endl;
if (_exchange)
{
cerr << "exchange" << endl;
cerr << "srcWidth " << _srcWidth << endl;
cerr << "dstWidth " << _dstWidth << endl;
cerr << "after .... src " << endl;
cerr << "srcsize " << _srcBin->GetSize() << endl;
cerr << "srccapa " << _srcBin->GetCapa() << endl;
}
else
{
cerr << "move" << endl;
cerr << _srcWidth << endl;
cerr << "after .... src " << endl;
cerr << _srcBin->GetSize() << endl;
cerr << _srcBin->GetCapa() << endl;
}
#endif
return deltaBinCost;
}
static const unsigned NetSrc = 1;
static const unsigned NetDst = 2;
static const unsigned NetSrcDst = 3;
double Move::GetDeltaNetCost()
{
// Find affected nets
// ==================
_affectedNets.clear();
for (Mauka::UVector::const_iterator uvit = _mauka->_instanceNets[_srcIns].begin();
uvit != _mauka->_instanceNets[_srcIns].end();
uvit++)
{
_affectedNets[*uvit] = NetSrc;
}
if (_exchange)
{
for (Mauka::UVector::const_iterator uvit = _mauka->_instanceNets[_dstIns].begin();
uvit != _mauka->_instanceNets[_dstIns].end();
uvit++)
{
unsigned netId = *uvit;
if (_affectedNets.find(netId) == _affectedNets.end())
_affectedNets[netId] = NetDst;
else
if (_affectedNets[netId] != NetDst)
_affectedNets[netId] = NetSrcDst;
}
}
// Compute delta
// =============
double delta = 0.0;
for (AffectedNets::iterator anit = _affectedNets.begin();
anit != _affectedNets.end();
anit++)
{
unsigned netId = anit->first;
unsigned flag = anit->second;
double& netCost = _simAnnealingPlacer->_GetNetIdCost(netId);
//cerr << "netCost " << netCost << endl;
double& netTmpCost = _simAnnealingPlacer->_GetNetIdTmpCost(netId);
//cerr << "netTmpCost " << netTmpCost << endl;
Box& currBox = _simAnnealingPlacer->_GetNetIdBBox(netId);
Box& tmpBox = _simAnnealingPlacer->_GetNetTmpBBox(netId);
//cerr << "before" << endl;
//cerr << "currBox " << currBox << endl;
//cerr << "tmpBox " << tmpBox << endl;
if (flag == NetSrc)
{
tmpBox = currBox;
if ((tmpBox = Update(tmpBox , _srcBin->GetCenter(), _dstBin->GetCenter())).IsEmpty())
{
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netId].begin();
uvit != _mauka->_netInstances[netId].end();
uvit++)
{
unsigned instanceId = *uvit;
Bin* bin = _simAnnealingPlacer->_instanceBins[instanceId];
tmpBox.Merge(bin->GetCenter().GetX(), bin->GetCenter().GetY());
}
}
if (_mauka->_hasInitX[netId])
tmpBox.Merge(_mauka->_netInitX[netId], tmpBox.GetYMin());
if (_mauka->_hasInitY[netId])
tmpBox.Merge(tmpBox.GetXMin(), _mauka->_netInitY[netId]);
Unit width = tmpBox.GetWidth();
if (width == 0)
{
width = _srcBin->GetWidth() / 2;
}
netTmpCost = GetValue(tmpBox.GetHeight() + width);
#if 0
cerr << "tmpBox " << tmpBox <<endl;
cerr << " SrcPos = " << _srcBin->GetCenter() << endl;
cerr << " DstPos = " << _dstBin->GetCenter() << endl;
cerr << "netTmpCost(netSrc) " << netTmpCost << endl << endl;
#endif
delta += netTmpCost - netCost;
#if 0 // code pour debug ....
Box checkBox;
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netId].begin();
uvit != _mauka->_netInstances[netId].end();
uvit++)
{
unsigned instanceId = *uvit;
Bin* bin = _mauka->_instanceBins[instanceId];
checkBox.Merge(bin->GetCenter().GetX(), bin->GetCenter().GetY());
}
if (checkBox != tmpBox) {
cout << "error: mauvaise bbox : NetSrc" << endl;
cout << " checkBox = " << checkBox << endl;
cout << " tmpBox = " << tmpBox << endl;
cout << " CurrBBox = " << currBox << endl;
cout << " SrcPos = " << _srcBin->GetCenter() << endl;
cout << " DstPos = " << _dstBin->GetCenter() << endl;
exit(1);
}
#endif
}
else
if (flag == NetDst)
{
tmpBox = currBox;
if ((tmpBox = Update(tmpBox , _dstBin->GetCenter(), _srcBin->GetCenter())).IsEmpty())
{
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netId].begin();
uvit != _mauka->_netInstances[netId].end();
uvit++)
{
Bin* bin = _simAnnealingPlacer->_instanceBins[*uvit];
tmpBox.Merge(bin->GetCenter().GetX(), bin->GetCenter().GetY());
}
}
if (_mauka->_hasInitX[netId])
tmpBox.Merge(_mauka->_netInitX[netId], tmpBox.GetYMin());
if (_mauka->_hasInitY[netId])
tmpBox.Merge(tmpBox.GetXMin(), _mauka->_netInitY[netId]);
Unit width = tmpBox.GetWidth();
if (width == 0)
{
width = _dstBin->GetWidth() / 2;
}
netTmpCost = GetValue(tmpBox.GetHeight() + width);
#if 0
cerr << "netDst" << endl;
cerr << "width " << tmpBox.GetWidth() << endl;
cerr << "height " << tmpBox.GetHeight() << endl;
cerr << "netTmpCost(netDst) " << netTmpCost << endl << endl;
#endif
delta += netTmpCost - netCost;
#ifdef MOVE_DEBUG
cout << "end" << endl;
cout << "check" << endl;
Box checkBox;
for_each_plug(plug, net);
{
Instance* ins = plug->GetInstance();
SurfContainer* container = PGetContainer(*ins);
cout << container->GetXCenter() << " " << container->GetYCenter() << endl;
checkBox.Merge(container->GetXCenter(), container->GetYCenter());
end_for;
}
if (checkBox != *PTmpBBox(*net)) {
cout << "error: mauvaise bbox : NetDst" << endl;
cout << " check_bbox = " << checkBox << endl;
cout << " TmpBBox = " << PTmpBBox(*net) << endl;
cout << " CurrentBBox = " << PCurrentBBox(*net) << endl;
cout << " SrcPos = " << _dstBin->GetPos() << endl;
cout << " DstPos = " << _srcBin->GetPos() << endl;
exit(1);
}
#endif
}
}
return delta;
}
void Move::TryMove()
{
if (!_exchange)
{
_srcBin->RemoveInstance(_srcIns);
_dstBin->AddInstance(_srcIns);
}
else
{
_srcBin->RemoveInstance(_srcIns);
_dstBin->RemoveFrontInstance(_dstIns);
_dstBin->AddInstance(_srcIns);
_srcBin->AddInstance(_dstIns);
}
}
bool Move::Next(double dist)
{
bool moveCondition;
unsigned nbrefused = 0;
// Choisi un mouvement
// ===================
do {
#if 0
if (1)
{
if (dist < 0.4)
for_each_view(view, _mauka->GetCell()->GetViews())
{
if (CEditor* editor = dynamic_cast<CEditor*>(view))
{
if (_srcBin)
editor->Unselect(_srcBin);
if (_dstBin && (_dstBin != _srcBin))
editor->Unselect(_dstBin);
break;
}
end_for;
}
}
#endif
moveCondition = true;
_srcIns = _mauka->GetRandomInstanceId();
assert ( _srcIns < _simAnnealingPlacer->_instanceBins.size() ); // d2 11/02/05
_srcBin = _simAnnealingPlacer->_instanceBins[_srcIns];
_srcSubRow = _srcBin->GetSubRow();
_srcRow = _srcSubRow->GetRow();
assert ( _srcIns < _mauka->_instanceWidths.size() ); // d2 11/02/05
_srcWidth = _mauka->_instanceWidths[_srcIns];
_srcBinInitCost = _srcBin->GetCost();
#if 0
cerr << "_srcBin " << endl;
cerr << "srcbinsize " << _srcBin->GetSize() << endl;
cerr << "srcbincapa " << _srcBin->GetCapa() << endl;
#endif
_srcRowInitCost = _srcRow->GetCost();
_dstBin = _surface->GetBinInSurface(_srcBin, dist);
_dstSubRow = _dstBin->GetSubRow();
_dstRow = _dstSubRow->GetRow();
#if 0
if (1)
{
if (dist < 0.4)
{
for_each_view(view, _mauka->GetCell()->GetViews())
{
if (CEditor* editor = dynamic_cast<CEditor*>(view))
{
cerr << _srcBin << endl;
cerr << _srcRow << endl;
cerr << _srcSubRow << endl;
cerr << _dstBin << endl;
cerr << _dstRow << endl;
cerr << _dstSubRow << endl;
cerr << endl;
editor->Select(_srcBin);
if (_dstBin != _srcBin)
editor->Select(_dstBin);
editor->Stop("gli");
break;
}
end_for;
}
}
}
#endif
_dstBinInitCost = _dstBin->GetCost();
#if 0
cerr << "initially .... dst" << endl;
cerr << "dstbinsize " << _dstBin->GetSize() << endl;
cerr << "dstbincapa " << _dstBin->GetCapa() << endl;
#endif
_dstRowInitCost = _dstRow->GetCost();
if (_dstBin == _srcBin)
{
_simAnnealingPlacer->IncrSourceEqualTargetMovementNumber();
moveCondition = false;
}
if (moveCondition && _dstBin->UnderOccupied())
{
_exchange = false;
// Le bin destination est sous-occupé
// On tente de déplacer l'instance
if (_dstSubRow->GetWidth() - _dstSubRow->GetSize() < _srcWidth)
{
moveCondition = false;
_simAnnealingPlacer->IncrSurOccupationTargetMovementNumber();
}
}
else if (moveCondition)
{
_exchange = true;
_dstIns = _dstBin->GetFirstInstanceOccurrenceId();
assert ( _dstIns < _mauka->_instanceWidths.size() ); // d2 11/02/05
_dstWidth = _mauka->_instanceWidths[_dstIns];
if (_srcSubRow->GetWidth() - _srcSubRow->GetSize() < _dstWidth - _srcWidth)
{
//Try to move the src ins to dst bin
if (_dstSubRow->GetWidth() - _dstSubRow->GetSize() < _srcWidth)
{
moveCondition = false;
_simAnnealingPlacer->IncrSurOccupationTargetMovementNumber();
}
_exchange = false;
}
if (_exchange
&& (_dstSubRow->GetWidth() - _dstSubRow->GetSize() < _srcWidth - _dstWidth))
{
//Try to move the dst ins to src bin
if (_srcSubRow->GetWidth() - _srcSubRow->GetSize() < _dstWidth)
{
moveCondition = false;
_simAnnealingPlacer->IncrSurOccupationTargetMovementNumber();
}
else
{
_exchange = false;
_srcIns = _dstIns;
_srcWidth = _dstWidth;
Bin* tmpBin = _dstBin;
_dstBin = _srcBin;
_srcBin = tmpBin;
SubRow* tmpSubRow = _dstSubRow;
_dstSubRow = _srcSubRow;
_srcSubRow = tmpSubRow;
Row* tmpRow = _dstRow;
_dstRow = _srcRow;
_srcRow = tmpRow;
double tmp2 = _dstRowInitCost;
_dstRowInitCost = _srcRowInitCost;
_srcRowInitCost = tmp2;
tmp2 = _dstBinInitCost;
_dstBinInitCost = _srcBinInitCost;
_srcBinInitCost = tmp2;
}
}
}
if (!moveCondition)
{
++nbrefused;
}
if (nbrefused > (unsigned)(1.5 * _mauka->_instanceOccurrencesVector.size()))
return false;
} while (!moveCondition);
// Deplace les instances
// =====================
_srcBin->IncrementSourceHits();
_dstBin->IncrementTargetHits();
TryMove();
if (_mauka->_verbosity.ActionIsOn())
{
if (dist < 0.4)
for_each_view(view, _mauka->GetCell()->GetViews())
{
if (CEditor* editor = dynamic_cast<CEditor*>(view))
{
editor->Refresh();
editor->Stop("coucou");
break;
}
end_for;
}
}
return true;
}
void
Move::Accept()
{
// Sauvegarde des cout des nets
for (AffectedNets::iterator anit = _affectedNets.begin();
anit != _affectedNets.end();
anit++)
{
unsigned netId = anit->first;
unsigned flag = anit->second;
if (flag == NetSrc || flag == NetDst)
{
_simAnnealingPlacer->_InvertNetIdFlag(netId);
}
}
}
void
Move::Reject()
{
if (!_exchange)
{
_dstBin->RemoveBackInstance(_srcIns);
_srcBin->AddInstance(_srcIns);
}
else
{
_srcBin->RemoveBackInstance(_dstIns);
_dstBin->RemoveBackInstance(_srcIns);
_dstBin->AddInstance(_dstIns);
_srcBin->AddInstance(_srcIns);
}
}
}

View File

@ -1,249 +0,0 @@
// 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 : 19/07/2006
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
//
// Authors-Tag
#include "SubRow.h"
#include "Surface.h"
#include "Row.h"
namespace MAUKA {
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 " + _TName("Row") + " : empty surface");
Row* row = new Row(cell, surface, box, orientation);
row->_PostCreate();
return row;
}
void Row::_PreDelete()
{
Inherit::_PreDelete();
for (SubRowVector::iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
(*srit)->Delete();
}
_subRowVector.clear();
}
namespace {
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(Unit x1, 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);
SubRowXMax::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(Unit value)
{
_size += value;
}
double Row::GetCost() const
{
return abs(GetValue(_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;
}
Unit Row::GetBinsSize() const
{
Unit totalBinsSize = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
totalBinsSize += (*srit)->GetBinsSize();
}
return totalBinsSize;
}
Unit Row::GetBinsCapa() const
{
Unit totalBinsCapa = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
totalBinsCapa += (*srit)->GetBinsCapa();
}
return totalBinsCapa;
}
Unit Row::GetSubRowsWidth() const
{
Unit subRowsWidth = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
subRowsWidth += (*srit)->GetWidth();
}
return subRowsWidth;
}
Unit Row::GetSubRowsCapa() const
{
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();
}
}

View File

@ -1,682 +0,0 @@
// 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 <math.h>
using namespace std;
#include "UpdateSession.h"
USING_NAMESPACE_HURRICANE
#include "CToolBox.h"
using namespace CRL;
#include "Surface.h"
#include "Bin.h"
#include "Row.h"
#include "Mauka.h"
#include "Move.h"
#include "SimAnnealingPlacer.h"
namespace {
double ComputeStdDev(double sumcost, double sumsquare, unsigned accepted)
{
if (accepted <= 1)
return 0.0;
double stdDev = (sumsquare - sumcost * sumcost / (double)accepted) / ((double)accepted - 1.0);
if (stdDev > 0.0)
stdDev = sqrt(stdDev);
else
stdDev = 0.0;
return stdDev;
}
}
namespace MAUKA {
SimAnnealingPlacer::SimAnnealingPlacer(Mauka* mauka, double netmult, double binmult, double rowmult)
// *****************************************************************************************************
: _mauka(mauka)
, _instanceBins()
, _netBBoxes()
, _netCosts()
, _netFlags()
, _netCost(0.0)
, _binCost(0.0)
, _rowCost(0.0)
, _initNetCost(0.0)
, _initBinCost(0.0)
, _initRowCost(0.0)
, _netMult(netmult)
, _binMult(binmult)
, _rowMult(rowmult)
, _temperature(0.0)
, _distance(0.0)
, _loop(0)
, _iterationsFactor(0.0)
, _iterations(0)
, _moves(0)
, _sourceEqualTargetMovementNumber(0)
, _surOccupationTargetMovementNumber(0)
, _impossibleExchangeMovementNumber(0)
{
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
_instanceBins.push_back(NULL);
}
for (unsigned netid = 0; netid < _mauka->_nets.size(); netid++)
{
vector<Box> bboxes(2);
_netBBoxes.push_back(bboxes);
vector<double> costs(2);
_netCosts.push_back(costs);
_netFlags.push_back(0);
}
}
void SimAnnealingPlacer::Init()
{
Surface* surface = _mauka->_surface;
if (!surface)
throw Error("Cannot init with no surface ...");
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
if (_instanceBins[i] == NULL)
cerr << "no bin for " << _mauka->_instanceOccurrencesVector[i] << endl;
}
_initNetCost = _netCost = GetNetCost();
_initBinCost = _binCost = surface->GetBinCost();
_initRowCost = _rowCost = surface->GetRowCost();
double stdDev = 0.0;
double sumCost = 0.0;
double sumSquare = 0.0;
unsigned accepted = 0;
_temperature = 1e30;
_distance = 1.0;
if (_mauka->_verbosity.MajorStatsIsOn())
{
cout << " o Beginning global placement ...." << endl;
cout << " o Number of nodes to place is: " << _mauka->_instanceOccurrencesVector.size() << endl;
cout << " o Margin is: " << 100.0 * surface->GetMargin() << "%" << endl;
cout << " o Initial RowCost = " << _rowCost << endl;
cout << " o Initial BinCost = " << _binCost << endl;
cout << " o Initial NetCost = " << _netCost << endl;
cout << " o Initial Cost = " << GetCost() << endl;
cout << " o total bins capa = " << surface->GetBinsCapa() << endl;
cout << " o total bins size = " << surface->GetBinsSize() << endl;
cout << " o total subrows capa = " << surface->GetSubRowsCapa() << endl;
cout << " o Computing Initial Temperature ...";
}
Move move(this);
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
if (!move.Next(_distance))
{
if (_mauka->_verbosity.IsOn())
{
cout << " o No More Mouvement Possible ....." << endl;
}
return;
}
double deltaRowCost = move.GetDeltaRowCost();
double deltaBinCost = move.GetDeltaBinCost();
double deltaNetCost = move.GetDeltaNetCost();
double deltaCost = ComputeCost(deltaRowCost, deltaBinCost, deltaNetCost);
if (Accept(deltaCost))
{
move.Accept();
accepted += 1;
_rowCost += deltaRowCost;
_netCost += deltaNetCost;
_binCost += deltaBinCost;
double cost = GetCost();
sumCost += cost; sumSquare += cost * cost;
//sumCost += deltaCost; sumSquare += deltaCost * deltaCost;
}
else
{
move.Reject();
}
++_moves;
}
stdDev = ComputeStdDev(sumCost, sumSquare, accepted);
_temperature = 20.0 * stdDev;
_iterationsFactor = 15.0;
_iterations = (unsigned)(_iterationsFactor * pow(_mauka->_instanceOccurrencesVector.size(), 1.33));
if (false)
{
double debug = DebugNetCost();
cout << "debug = " << debug << endl;
cout << "NetCost = " << _netCost << endl << endl;
// assert ((netCost - 1.0 <= debug) && (debug <= netCost + 1.0));
}
if (_mauka->_verbosity.IsOn())
{
cout << "...... done" << endl;
}
}
bool SimAnnealingPlacer::Iterate()
{
unsigned accepted = 0;
double sumCost = 0.0;
double sumSquare = 0.0;
double stdDev = 0.0, sucRatio = 0.0;
double oldTemperature = 0.0;
Move move(this);
for (unsigned i = 0; i < _iterations; ++i)
{
if (!move.Next(_distance))
{
if (_mauka->_verbosity.IsOn())
{
cout << " o No More Mouvement Possible ....." << endl;
}
return false;
}
double deltaRowCost = move.GetDeltaRowCost();
double deltaBinCost = move.GetDeltaBinCost();
double deltaNetCost = move.GetDeltaNetCost();
double deltaCost = ComputeCost(deltaRowCost, deltaBinCost, deltaNetCost);
#if 0
cerr << deltaRowCost << endl;
cerr << deltaBinCost << endl;
cerr << deltaNetCost << endl;
cerr << deltaCost << endl << endl;
#endif
if (Accept(deltaCost)) {
move.Accept();
accepted += 1;
_rowCost += deltaRowCost;
_binCost += deltaBinCost;
_netCost += deltaNetCost;
double cost = GetCost();
sumCost += cost; sumSquare += cost * cost;
//sumCost += deltaCost; sumSquare += deltaCost * deltaCost;
}
else
{
move.Reject();
}
++_moves;
}
++_loop;
oldTemperature = _temperature;
stdDev = ComputeStdDev(sumCost, sumSquare, accepted);
if (stdDev == 0.0)
_temperature = 0.0;
else
_temperature = _temperature * max(0.5, exp(-0.7 * _temperature / stdDev));
sucRatio = accepted / (double)_iterations;
_distance = max(0.1, min(_distance * (1.0 - 0.44 + sucRatio), 1.0));
if (_mauka->_verbosity.MajorStatsIsOn())
{
cout << "Loop = " << _loop << ", NIns = " << _mauka->_instanceOccurrencesVector.size()
<< ", Temperature = " << _temperature << ", Cost = " << GetCost() << endl;
cout << " RowCost = " << _rowCost << ", BinCost = " << _binCost
<< ", NetCost = " << _netCost << endl;
cout << " Success Ratio = " << sucRatio * 100.0 << "%, Dist = " << _distance << ", Delta = "
<< _temperature / oldTemperature << endl;
}
else if (_mauka->_verbosity.IsOn())
cerr << ".";
if (false)
{
double debug = DebugNetCost();
cout << "debug = " << debug << endl;
cout << "NetCost = " << _netCost << endl << endl;
// assert ((netCost - 1.0 <= debug) && (debug <= netCost + 1.0));
}
return ((_temperature != 0.0)
&& ((sucRatio > 0.15) || (stdDev > (0.0001 / GetCost()))));
}
double SimAnnealingPlacer::GetNetCost()
// ************************************
{
double totalNetCost = 0.0;
for (unsigned netid = 0; netid < _mauka->_netInstances.size(); netid++)
{
unsigned lastInstanceId = 0;
unsigned insCount = 0;
Box& netBBox = _netBBoxes[netid][_netFlags[netid]];
double& netCost = _netCosts[netid][_netFlags[netid]];
netCost = 0.0;
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netid].begin();
uvit != _mauka->_netInstances[netid].end();
uvit++)
{
unsigned instanceId = *uvit;
lastInstanceId = instanceId;
Bin* bin = _instanceBins[instanceId];
netBBox.Merge(bin->GetCenter().GetX(), bin->GetCenter().GetY());
++insCount;
}
if (_mauka->_hasInitX[netid])
netBBox.Merge(_mauka->_netInitX[netid], netBBox.GetYMin());
if (_mauka->_hasInitY[netid])
netBBox.Merge(netBBox.GetXMin(), _mauka->_netInitY[netid]);
if (!insCount)
{
if (_mauka->_verbosity.IsOn())
{
cout << " o Placer Warning : Net "
<< _mauka->_nets[netid] << " is not connected..." << endl;
}
}
else
{
Unit width = 0;
#if 0
if (_mauka->_params.takeSplittersIntoAccountOptimization)
{
Instance* instance = _instanceOccurrences[lastInstanceId];
Net* net = _nets[netid];
Plug* netPlug = NULL;
for_each_plug(plug, instance->GetConnectedPlugs())
{
Net* plugNet = plug->GetNet();
if (plugNet == net)
{
netPlug = plug;
break;
}
end_for;
}
if (!netPlug)
throw Error("Mauka internal error: no plug");
Hook* bodyHook = netPlug->GetBodyHook();
for_each_hook(hook, bodyHook->GetHooks())
{
Component* component = hook->GetComponent();
if (SplitterContact* splitterContact = dynamic_cast<SplitterContact*>(component))
{
if (VFence* vfence = dynamic_cast<VFence*>(splitterContact->GetSplitter()->GetFence()))
{
if (_hasInitX[netid])
_hasInitX[netid] = false;
else
{
_hasInitX[netid] = true;
_netInitX[netid] = vfence->GetX();
}
}
else if (HFence* hfence = dynamic_cast<HFence*>(splitterContact->GetSplitter()->GetFence()))
{
if (_hasInitY[netid])
_hasInitY[netid] = false;
else
{
_hasInitY[netid] = true;
_netInitY[netid] = hfence->GetY();
}
}
else throw Error("Mauka internal error");
}
else if (Pin* pin = dynamic_cast<Pin*>(component))
{
if (!_mauka->_params.ignorePins)
{
netBBox.Merge(pin->GetX(), pin->GetY());
}
}
end_for;
}
if (_hasInitX[netid])
netBBox.Merge(_netInitX[netid], netBBox.GetYMin());
if (_hasInitY[netid])
netBBox.Merge(netBBox.GetXMin(), _netInitY[netid]);
}
#endif
width = netBBox.GetWidth();
if (width == 0)
{
//all instances in the same bin...
//take for width half of the bin
Bin* bin = _instanceBins[lastInstanceId];
width = bin->GetWidth() / 2;
}
double cost = GetValue(netBBox.GetHeight() + width);
netCost = cost;
totalNetCost += cost;
}
}
return totalNetCost;
}
double SimAnnealingPlacer::DebugNetCost()
// **************************************
{
double totalNetCost = 0.0;
for (unsigned netid = 0; netid < _mauka->_netInstances.size(); netid++)
{
unsigned lastInstanceId = 0;
unsigned insCount = 0;
Box box;
for (Mauka::UVector::const_iterator uvit = _mauka->_netInstances[netid].begin();
uvit != _mauka->_netInstances[netid].end();
uvit++)
{
unsigned instanceId = *uvit;
lastInstanceId = instanceId;
Bin* bin = _instanceBins[instanceId];
box.Merge(bin->GetCenter().GetX(), bin->GetCenter().GetY());
++insCount;
}
if (insCount)
{
#if 0
if (_mauka->_params.takeSplittersIntoAccountOptimization)
{
Occurrence instanceOccurrence = _instanceOccurrences[lastInstanceId];
Instance* instance = dynamic_cast<Instance*>(instanceOccurrence.GetEntity());
assert(instance);
Net* net = _nets[netid];
Plug* netPlug = NULL;
for_each_plug(plug, instance->GetConnectedPlugs())
{
Net* plugNet = plug->GetNet();
if (plugNet == net)
{
netPlug = plug;
break;
}
end_for;
}
if (!netPlug)
throw Error("Mauka internal error: no plug");
Hook* bodyHook = netPlug->GetBodyHook();
bool hasInitX = false;
bool hasInitY = false;
Unit netInitX = 0;
Unit netInitY = 0;
for_each_hook(hook, bodyHook->GetHooks())
{
if (SplitterContact* splitterContact = dynamic_cast<SplitterContact*>(hook->GetComponent()))
{
if (VFence* vfence = dynamic_cast<VFence*>(splitterContact->GetSplitter()->GetFence()))
{
if (hasInitX)
hasInitX = false;
else
{
hasInitX = true;
netInitX = vfence->GetX();
}
}
else if (HFence* hfence = dynamic_cast<HFence*>(splitterContact->GetSplitter()->GetFence()))
{
if (hasInitY)
hasInitY = false;
else
{
hasInitY = true;
netInitY = hfence->GetY();
}
}
else throw Error("Mauka internal error");
}
end_for;
}
if (hasInitX)
box.Merge(netInitX, box.GetYMin());
if (hasInitY)
box.Merge(box.GetXMin(), netInitY);
}
#endif
Unit width = box.GetWidth();
if (width == 0)
{
//all instances in the same bin...
//take for width half of the bin
Bin* bin = _instanceBins[lastInstanceId];
width = bin->GetWidth() / 2;
}
totalNetCost += GetValue(box.GetHeight() + width);
}
}
return totalNetCost;
}
void SimAnnealingPlacer::DisplayResults() const
{
unsigned totalImpossibleMovements =
_impossibleExchangeMovementNumber
+ _sourceEqualTargetMovementNumber
+ _surOccupationTargetMovementNumber;
cout << " o Total impossible movements = " << totalImpossibleMovements << endl;
cout << " o " << 100.0 * _surOccupationTargetMovementNumber / totalImpossibleMovements
<< " % suroccupied target" << endl;
cout << " o " << 100.0 * _sourceEqualTargetMovementNumber / totalImpossibleMovements
<< " % source equal target" << endl;
cout << " o " << 100.0 * _impossibleExchangeMovementNumber / totalImpossibleMovements
<< " % impossible exchange" << endl;
cout << " o Global Placement finished ....." << endl;
cout << " o Gain for RowCost = "
<< 100.0 * (_initRowCost - _rowCost) / _initRowCost << "%" << endl;
cout << " o Gain for BinCost = "
<< 100.0 * (_initBinCost - _binCost) / _initBinCost << "%" << endl;
cout << " o Gain for NetCost = "
<< 100.0 * (_initNetCost - _netCost) / _initNetCost << "%" << endl;
cout << " o NetCost Estimated = " << _netCost << endl;
}
double SimAnnealingPlacer::GetCost() const
{
return ComputeCost(_rowCost, _binCost, _netCost);
}
double SimAnnealingPlacer::ComputeCost(double rowcost, double bincost, double netcost) const
{
return rowcost / _initRowCost * _rowMult
+ bincost / _initBinCost * _binMult
+ netcost / _initNetCost * _netMult;
}
bool SimAnnealingPlacer::Accept(double deltacost) const
{
if (_mauka->_params.standardSimulatedAnnealing)
{
double doubleRand = (double) (rand() / (RAND_MAX + 1.0));
return ((deltacost <= 0.0)
|| ((_temperature != 0.0)
&& (exp(-deltacost / _temperature) > doubleRand)));
}
else
return deltacost <= 0.0;
}
void SimAnnealingPlacer::Save() const
{
OpenUpdateSession();
for(unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
Occurrence instanceOccurrence = _mauka->_instanceOccurrencesVector[i];
Instance* instance = static_cast<Instance*>(instanceOccurrence.GetEntity());
Bin* bin = _instanceBins[i];
bool rowOrientation = bin->GetSubRow()->GetRow()->GetOrientation();
if (!bin)
throw Error("No bin for instance");
Unit xPos = bin->GetCenter().GetX();
Unit yPos = bin->GetCenter().GetY();
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
Transformation::Orientation orientation;
if (rowOrientation)
orientation = Transformation::Orientation::ID;
else
orientation = Transformation::Orientation::MY;
Transformation instanceTransformation = GetTransformation(masterABox
, xPos - masterABox.GetHalfWidth()
, yPos - masterABox.GetHalfHeight()
, orientation);
instanceOccurrence.GetPath().GetTransformation().Invert().ApplyOn(instanceTransformation);
instance->SetTransformation(instanceTransformation);
instance->SetPlacementStatus(Instance::PlacementStatus::PLACED);
//SetPlacementStatusRecursivelyToPlaced(instance);
}
CloseUpdateSession();
}
void SimAnnealingPlacer::Plot(ofstream& out) const
{
out << "#instances" << endl;
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
Instance* instance = static_cast<Instance*>(_mauka->_instanceOccurrencesVector[i].GetEntity());
const Bin* bin = _instanceBins[i];
if (!bin)
throw Error("No bin for instance");
Unit xPos = bin->GetCenter().GetX();
Unit yPos = bin->GetCenter().GetY();
Box masterABox = instance->GetMasterCell()->GetAbutmentBox();
Box instanceBox = Box(
xPos - masterABox.GetWidth() / 2,
yPos - masterABox.GetHeight() / 2,
xPos + masterABox.GetWidth() / 2,
yPos + masterABox.GetHeight() / 2);
out << instanceBox.GetXMin()+0.4 << " " << instanceBox.GetYMin()+0.4 << endl
<< instanceBox.GetXMin()+0.4 << " " << instanceBox.GetYMax()-0.4 << endl
<< instanceBox.GetXMax()-0.4 << " " << instanceBox.GetYMax()-0.4 << endl
<< instanceBox.GetXMax()-0.4 << " " << instanceBox.GetYMin()+0.4 << endl
<< instanceBox.GetXMin()+0.4 << " " << instanceBox.GetYMin()+0.4 << endl << endl;
}
out << "EOF" << endl << endl;
out << "#nets" << endl;
for (unsigned i = 0; i < _mauka->_netInstances.size(); i++)
{
if (_mauka->_hasInitX[i])
continue;
unsigned nbInstances = 0;
Unit baryX = 0;
Unit baryY = 0;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
++nbInstances;
const Bin* bin = _instanceBins[instanceId];
baryX += bin->GetCenter().GetX();
baryY += bin->GetCenter().GetY();
}
baryX = baryX / nbInstances;
baryY = baryY / nbInstances;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
const Bin* bin = _instanceBins[instanceId];
out << baryX << " " << baryY << endl
<< bin->GetCenter().GetX() << " "
<< bin->GetCenter().GetY() << endl << endl;
}
}
out << "EOF" << endl << endl;
out << "#nets with fixed point" << endl;
for (unsigned i = 0; i < _mauka->_netInstances.size(); i++)
{
if (!_mauka->_hasInitX[i])
continue;
unsigned nbInstances = 1;
Unit baryX = 0;
Unit baryY = 0;
baryX += _mauka->_netInitX[i];
baryY += _mauka->_netInitY[i];
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
++nbInstances;
const Bin* bin = _instanceBins[instanceId];
baryX += bin->GetCenter().GetX();
baryY += bin->GetCenter().GetY();
}
baryX = baryX / nbInstances;
baryY = baryY / nbInstances;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
const Bin* bin = _instanceBins[instanceId];
out << baryX << " " << baryY << endl
<< bin->GetCenter().GetX() << " "
<< bin->GetCenter().GetY() << endl << endl;
}
out << baryX << " " << baryY << endl
<< _mauka->_netInitX[i] << " "
<< _mauka->_netInitY[i] << endl << endl;
}
out << "EOF" << endl << endl;
}
}

View File

@ -1,265 +0,0 @@
// 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 : 19/07/2006
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
//
// 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();
}
}

View File

@ -1,895 +0,0 @@
// 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;
}
}