parent
9f6e840036
commit
11581e0ae1
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue