* ./mauka:

- New: Initial port from Coriolis 1. Needs to re-introduce Nimbus :-(.
        Modificated to provide Configuration & standard ConfigurationWidget.
This commit is contained in:
Jean-Paul Chaput 2010-06-08 12:09:50 +00:00
parent ab78dd054b
commit a9808704a0
52 changed files with 13051 additions and 0 deletions

52
mauka/CMakeLists.txt Normal file
View File

@ -0,0 +1,52 @@
PROJECT(MAUKA)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0)
SET(CMAKE_C_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE)
SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE)
#SET(CMAKE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
#SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
#SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
#SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
IF(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND CMAKE_POLICY)
# This macro has to be included in all the tools CMakeLists.txt as it's
# the sole means of localizing other tools/projects.
MACRO(SETUP_PROJECT_PATHS project)
IF( NOT("$ENV{${project}_TOP}" STREQUAL "") )
MESSAGE("-- ${project}_TOP is set to $ENV{${project}_TOP}")
SET(PROJECT_MODULE_PATH "${DESTDIR}$ENV{${project}_TOP}/share/cmake/Modules/")
LIST(INSERT CMAKE_MODULE_PATH 0 "${PROJECT_MODULE_PATH}")
ENDIF( NOT("$ENV{${project}_TOP}" STREQUAL "") )
IF( NOT("$ENV{${project}_USER_TOP}" STREQUAL "") )
MESSAGE("-- ${project}_USER_TOP is set to $ENV{${project}_USER_TOP}")
SET(PROJECT_MODULE_PATH "${DESTDIR}$ENV{${project}_USER_TOP}/share/cmake/Modules/")
LIST(INSERT CMAKE_MODULE_PATH 0 "${PROJECT_MODULE_PATH}")
ENDIF( NOT("$ENV{${project}_USER_TOP}" STREQUAL "") )
LIST(REMOVE_DUPLICATES CMAKE_MODULE_PATH)
ENDMACRO(SETUP_PROJECT_PATHS project)
SETUP_PROJECT_PATHS(VLSISAPD)
SETUP_PROJECT_PATHS(CORIOLIS)
MESSAGE("-- Components of CMAKE_MODULE_PATH:")
FOREACH(PATH IN LISTS CMAKE_MODULE_PATH)
MESSAGE("-- ${PATH}")
ENDFOREACH(PATH)
SET(QT_USE_QTXML "true")
FIND_PACKAGE(Qt4 REQUIRED) # find and setup Qt4 for this project
FIND_PACKAGE(HURRICANE REQUIRED)
FIND_PACKAGE(CORIOLIS REQUIRED)
FIND_PACKAGE(NIMBUS REQUIRED)
SET_LIB_LINK_MODE()
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(cmake_modules)

View File

@ -0,0 +1 @@
install ( FILES FindMAUKA.cmake DESTINATION share/cmake/Modules )

View File

@ -0,0 +1,37 @@
# - Find the Mauka includes and libraries.
# The following variables are set if Coriolis is found. If MAUKA is not
# found, MAUKA_FOUND is set to false.
# MAUKA_FOUND - True when the Coriolis include directory is found.
# MAUKA_INCLUDE_DIR - the path to where the Coriolis include files are.
# MAUKA_LIBRARIES - The path to where the Coriolis library files are.
SET(MAUKA_INCLUDE_PATH_DESCRIPTION "directory containing the Mauka/flute include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
SET(MAUKA_DIR_MESSAGE "Set the MAUKA_INCLUDE_DIR cmake cache entry to the ${MAUKA_INCLUDE_PATH_DESCRIPTION}")
# don't even bother under WIN32
IF(UNIX)
#
# Look for an installation.
#
FIND_PATH(MAUKA_INCLUDE_PATH NAMES mauka/MaukaEngine.h PATHS
# Look in other places.
${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis2
# Help the user find it if we cannot.
DOC "The ${MAUKA_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(MAUKA_LIBRARY_PATH
NAMES mauka
PATHS ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES lib${LIB_SUFFIX}
# Help the user find it if we cannot.
DOC "The ${MAUKA_INCLUDE_PATH_DESCRIPTION}"
)
SET_LIBRARIES_PATH(MAUKA MAUKA)
HURRICANE_CHECK_LIBRARIES(MAUKA)
ENDIF(UNIX)

735
mauka/src/BBPlacer.cpp Normal file
View File

@ -0,0 +1,735 @@
// 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 "hurricane/UpdateSession.h"
#include "hurricane/Net.h"
#include "hurricane/Cell.h"
#include "crlcore/ToolBox.h"
#include "crlcore/CellGauge.h"
#include "crlcore/AllianceFramework.h"
#include "mauka/MaukaEngine.h"
#include "mauka/Surface.h"
#include "mauka/Row.h"
#include "mauka/SubRow.h"
#include "mauka/Bin.h"
#include "mauka/BBPlacer.h"
namespace {
using namespace Mauka;
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);
}
};
} // End of anonymous namespace.
namespace Mauka {
using namespace std;
using namespace Hurricane;
using namespace CRL;
//#define PLACE_DEBUG 1
BBPlacer::BBPlacer(MaukaEngine* 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(MaukaEngine::UVector());
DbU::Unit totalInstanceSizeInRow = 0;
for (SubRow::BinVector::iterator bvit = subRow->_binVector.begin();
bvit != subRow->_binVector.end();
bvit++)
{
Bin* bin = *bvit;
totalInstanceSizeInRow += bin->getSize();
for (MaukaEngine::UList::const_iterator ulit = bin->InstanceOccurrenceIdsBegin();
ulit != bin->InstanceOccurrenceIdsEnd();
ulit++)
{
unsigned instanceId = *ulit;
_subRowInstances.back().push_back(instanceId);
}
}
DbU::Unit pitch = AllianceFramework::get()->getCellGauge()->getPitch();
DbU::Unit whiteSpace = subRow->getWidth() - totalInstanceSizeInRow;
DbU::Unit instanceWhiteSpacePitch = (whiteSpace / _subRowInstances.back().size()) / pitch;
DbU::Unit whiteSpaceRemain = whiteSpace
- (instanceWhiteSpacePitch * _subRowInstances.back().size() * pitch);
assert(!(whiteSpaceRemain%pitch));
if (instanceWhiteSpacePitch > 0)
{
for (MaukaEngine::UVector::const_iterator uvit = _subRowInstances.back().begin();
uvit != _subRowInstances.back().end();
uvit++)
{
_instanceMarginWidth[*uvit] += instanceWhiteSpacePitch * pitch;
}
}
MaukaEngine::UVector::const_iterator uvit = _subRowInstances.back().begin();
while (whiteSpaceRemain > 0)
{
_instanceMarginWidth[*uvit++] += pitch;
whiteSpaceRemain -= pitch;
assert(uvit != _subRowInstances.back().end());
}
DbU::Unit xPos = subRow->getXMin();
DbU::Unit yPos = subRow->getYMin();
for (MaukaEngine::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()
{
UpdateSession::open();
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];
DbU::Unit x = _instanceX[instanceId];
DbU::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);
}
}
UpdateSession::close();
}
void BBPlacer::Plot(ofstream& out) const
{
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
DbU::Unit x = _instanceX[i];
DbU::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;
DbU::Unit baryX = 0;
DbU::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;
DbU::Unit baryX = 0;
DbU::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;
MaukaEngine::UVector::iterator ifirst = _subRowInstances[i].begin();
MaukaEngine::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]);
}
MaukaEngine::UVector::iterator ifirst = _instanceToOptimize.begin();
MaukaEngine::UVector::iterator ilast = _instanceToOptimize.end();
vector<DbU::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 (MaukaEngine::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
{
_instancePlaced[*uvit] = true;
}
}
void BBPlacer::UnplaceAll()
{
for (MaukaEngine::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
{
_instancePlaced[*uvit] = false;
}
}
double BBPlacer::initCost()
{
++_costFlag;
double cost = 0.0;
for (MaukaEngine::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
{
cost += initInstanceCost(*uvit);
}
return cost;
}
double BBPlacer::CurrentCost()
{
++_costFlag;
double cost = 0.0;
for (MaukaEngine::UVector::iterator uvit = _instanceToOptimize.begin();
uvit != _instanceToOptimize.end();
uvit++)
cost += CurrentInstanceCost(*uvit);
return cost;
}
double BBPlacer::UpdateInstanceCost(unsigned instanceid)
{
double deltaCost = 0.0;
for (MaukaEngine::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 (MaukaEngine::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 (MaukaEngine::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 (MaukaEngine::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 (MaukaEngine::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 DbU::getLambda(box.getYMax() - box.getYMin() + box.getXMax() - box.getXMin());
else
return 0.0;
}
double BBPlacer::CurrentNetCost(unsigned netid)
{
if (_netCurrCostMark[netid] != _costFlag)
{
_netCurrCostMark[netid] = _costFlag;
return _netCosts[netid][_netFlags[netid]];
}
return 0;
}
}

View File

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

207
mauka/src/Bin.cpp Normal file
View File

@ -0,0 +1,207 @@
// 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 "hurricane/Error.h"
#include "mauka/SubRow.h"
#include "mauka/Bin.h"
#include "mauka/Surface.h"
#include "mauka/SimAnnealingPlacer.h"
namespace Mauka {
using namespace std;
using Hurricane::Error;
const Name Bin::_goName = "Mauka::Bin";
Bin::Bin(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(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 = DbU::lambda(DbU::getLambda(getWidth()) * (1.0 - _subRow->getSurface()->getMargin()));
Inherit::_postCreate();
}
void Bin::_computeCapacity(double margin)
{
_capa = DbU::lambda(DbU::getLambda(getWidth()) * (1.0 - margin));
}
const Name& Bin::getStaticName ()
{
return _goName;
}
const Name& Bin::getName () const
{
return _goName;
}
Cell* Bin::getCell() const
{
return _subRow->getCell();
}
void Bin::addInstance(unsigned instanceid)
{
_instanceOccurrenceIds.push_back(instanceid);
DbU::Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = this;
}
void Bin::_AddSize(DbU::Unit value)
{
_size += value;
_subRow->_AddSize(value);
}
void Bin::removeInstance(unsigned instanceid)
{
_instanceOccurrenceIds.remove(instanceid);
DbU::Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(-insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = NULL;
}
void Bin::removeBackInstance(unsigned instanceid)
{
assert(_instanceOccurrenceIds.back() == instanceid);
_instanceOccurrenceIds.pop_back();
DbU::Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(-insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = NULL;
}
void Bin::removeFrontInstance(unsigned instanceid)
{
assert(_instanceOccurrenceIds.front() == instanceid);
_instanceOccurrenceIds.pop_front();
DbU::Unit insWidth = _mauka->_instanceWidths[instanceid];
_AddSize(-insWidth);
_mauka->_simAnnealingPlacer->_instanceBins[instanceid] = NULL;
}
bool Bin::TryAddInstance(unsigned instanceid)
{
DbU::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(DbU::getLambda(_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)(DbU::getLambda(getXMin())) + (unsigned)(DbU::getLambda(getXMax() - getXMin())) / 2;
//unsigned decal = (unsigned)(DbU::getLambda(getYMax() - getYMin())) / 4;
//unsigned y = (unsigned)(DbU::getLambda(getYMin()));
unsigned y = (unsigned)(DbU::getLambda(getYMin())) + (unsigned)(DbU::getLambda(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 << DbU::getLambda(getXMin()) + 0.3 << " " << DbU::getLambda(getYMin()) + 0.3 << endl
<< DbU::getLambda(getXMin()) + 0.3 << " " << DbU::getLambda(getYMax()) - 0.3 << endl
<< DbU::getLambda(getXMax()) - 0.3 << " " << DbU::getLambda(getYMax()) - 0.3 << endl
<< DbU::getLambda(getXMax()) - 0.3 << " " << DbU::getLambda(getYMin()) + 0.3 << endl
<< DbU::getLambda(getXMin()) + 0.3 << " " << DbU::getLambda(getYMin()) + 0.3 << endl << endl;
}
} // End of Mauka namespace.

View File

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

48
mauka/src/CMakeLists.txt Normal file
View File

@ -0,0 +1,48 @@
include ( ${QT_USE_FILE} )
include_directories ( ${MAUKA_SOURCE_DIR}/src
${HURRICANE_INCLUDE_DIR}
${CORIOLIS_INCLUDE_DIR}
)
set ( includes mauka/Configuration.h
mauka/BBPlacer.h
mauka/Bin.h
mauka/Container.h
mauka/MaukaBox.h
mauka/Move.h
mauka/Row.h
mauka/SimAnnealingPlacer.h
mauka/SubRow.h
mauka/Surface.h
mauka/MaukaEngine.h
)
set ( mocIncludes mauka/ConfigurationWidget.h
mauka/GraphicMaukaEngine.h )
set ( cpps Configuration.cpp
ConfigurationWidget.cpp
BBPlacer.cpp
Bin.cpp
Container.cpp
MaukaBox.cpp
Move.cpp
Row.cpp
SimAnnealingPlacer.cpp
SubRow.cpp
Surface.cpp
MaukaEngine.cpp
GraphicMaukaEngine.cpp
)
qt4_wrap_cpp ( mocCpps ${mocIncludes} )
add_library ( mauka ${cpps} ${mocCpps} )
target_link_libraries ( mauka ${CORIOLIS_LIBRARIES}
${HURRICANE_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${QT_LIBRARIES}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
)
install ( TARGETS mauka DESTINATION lib${LIB_SUFFIX} )
install ( FILES ${includes} ${mocIncludes} DESTINATION include/coriolis2/mauka )

133
mauka/src/Configuration.cpp Normal file
View File

@ -0,0 +1,133 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | M a u k a - P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./Configuration.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <iostream>
#include <iomanip>
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
#include "mauka/Configuration.h"
namespace Mauka {
using std::cout;
using std::cerr;
using std::endl;
using std::setprecision;
using std::ostringstream;
using std::string;
using Hurricane::tab;
using Hurricane::inltrace;
// -------------------------------------------------------------------
// Class : "Mauka::Configuration".
Configuration* Configuration::_default = NULL;
Configuration* Configuration::getDefault ()
{
if ( _default == NULL ) {
_default = new Configuration ();
}
return _default;
}
Configuration::Configuration ()
: _standardSimulatedAnnealing(false)
, _ignorePins (false)
, _plotBins (true)
, _searchRatio (0.50)
, _annealingNetMult (0.90)
, _annealingBinMult (0.05)
, _annealingRowMult (0.05)
{ }
Configuration::Configuration ( const Configuration& other )
: _standardSimulatedAnnealing(other._standardSimulatedAnnealing)
, _ignorePins (other._ignorePins)
, _plotBins (other._plotBins)
, _searchRatio (other._searchRatio)
, _annealingNetMult (other._annealingNetMult)
, _annealingBinMult (other._annealingBinMult)
, _annealingRowMult (other._annealingRowMult)
{ }
Configuration::~Configuration ()
{ }
Configuration* Configuration::clone () const
{ return new Configuration(*this); }
void Configuration::print ( Cell* cell ) const
{
cout << " o Configuration of ToolEngine<Mauka> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asBool (" - Use standard simulated annealing" ,_standardSimulatedAnnealing) << endl;
cout << Dots::asBool (" - Ignore Pins" ,_ignorePins) << endl;
cout << Dots::asBool (" - Plot Bins" ,_plotBins) << endl;
cout << Dots::asPercentage(" - Search Ratio" ,_searchRatio) << endl;
}
string Configuration::_getTypeName () const
{
return "Mauka::Configuration";
}
string Configuration::_getString () const
{
ostringstream os;
os << "<" << _getTypeName() << ">";
return os.str();
}
Record* Configuration::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add ( getSlot( "_standardSimulatedAnnealing", _standardSimulatedAnnealing) );
record->add ( getSlot( "_ignorePins" , _ignorePins ) );
record->add ( getSlot( "_plotBins" , _plotBins ) );
record->add ( getSlot( "_searchRatio" , _searchRatio ) );
return ( record );
}
} // End of Mauka namespace.

View File

@ -0,0 +1,371 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | M a u k a - P l a c e r |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./ConfigurationWidget.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <QLabel>
#include <QPushButton>
#include <QFrame>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QCheckBox>
#include <QLineEdit>
#include <QIntValidator>
#include <QDoubleValidator>
#include "hurricane/viewer/Graphics.h"
#include "nimbus/Configuration.h"
#include "mauka/Configuration.h"
#include "mauka/ConfigurationWidget.h"
namespace Mauka {
using Hurricane::Graphics;
// -------------------------------------------------------------------
// Class : "Mauka::ConfigurationWidget".
ConfigurationWidget::ConfigurationWidget ( QWidget* parent )
: QWidget(parent)
, _nimbusConfiguration (NULL)
, _maukaConfiguration (NULL)
, _standardAnnealingState(new QCheckBox())
, _ignorePinsState (new QCheckBox())
, _plotBinsState (new QCheckBox())
, _pinsPlacementState (new QCheckBox())
, _searchRatioEdit (new QLineEdit())
, _annealingNetMultEdit (new QLineEdit())
, _annealingBinMultEdit (new QLineEdit())
, _annealingRowMultEdit (new QLineEdit())
, _aspectRatioEdit (new QLineEdit())
, _marginEdit (new QLineEdit())
{
setAttribute ( Qt::WA_QuitOnClose, false );
QVBoxLayout* vLayout = new QVBoxLayout ();
QGridLayout* gLayout = new QGridLayout ();
QLabel* label = new QLabel();
label->setFont ( Graphics::getNormalFont(true) );
label->setText ( "Mauka - Placer" );
gLayout->addWidget ( label, 0, 0, 1, 4, Qt::AlignLeft );
// Nimbus configuration.
label = new QLabel();
label->setText ( "Pins Placement" );
_pinsPlacementState->setEnabled ( false );
gLayout->addWidget ( label , 1, 0, Qt::AlignRight );
gLayout->addWidget ( _pinsPlacementState, 1, 1, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Aspect Ratio: X/Y (%)" );
_aspectRatioEdit->setValidator ( new QDoubleValidator(this) );
_aspectRatioEdit->setEnabled ( false );
gLayout->addWidget ( label , 1, 2, Qt::AlignRight );
gLayout->addWidget ( _aspectRatioEdit, 1, 3, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Space Margin (%)" );
_marginEdit->setValidator ( new QDoubleValidator(this) );
_marginEdit->setEnabled ( false );
gLayout->addWidget ( label , 2, 2, Qt::AlignRight );
gLayout->addWidget ( _marginEdit, 2, 3, Qt::AlignLeft );
QFrame* separator = new QFrame ();
separator->setFrameShape ( QFrame::HLine );
separator->setFrameShadow ( QFrame::Sunken );
gLayout->addWidget ( separator, 3, 0, 1, 4 );
// Mauka configuration.
label = new QLabel();
label->setText ( "Standard Annealing" );
_standardAnnealingState->setEnabled ( false );
gLayout->addWidget ( label , 4, 0, Qt::AlignRight );
gLayout->addWidget ( _standardAnnealingState, 4, 1, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Ignore Pins" );
_ignorePinsState->setEnabled ( false );
gLayout->addWidget ( label , 5, 0, Qt::AlignRight );
gLayout->addWidget ( _ignorePinsState, 5, 1, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Plot Bins" );
_plotBinsState->setEnabled ( false );
gLayout->addWidget ( label , 6, 0, Qt::AlignRight );
gLayout->addWidget ( _plotBinsState, 6, 1, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Search Ratio (%)" );
_searchRatioEdit->setValidator ( new QDoubleValidator(this) );
_searchRatioEdit->setEnabled ( false );
gLayout->addWidget ( label , 4, 2, Qt::AlignRight );
gLayout->addWidget ( _searchRatioEdit, 4, 3, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Annealing Net Mult (%)" );
_annealingNetMultEdit->setValidator ( new QDoubleValidator(this) );
_annealingNetMultEdit->setEnabled ( false );
gLayout->addWidget ( label , 5, 2, Qt::AlignRight );
gLayout->addWidget ( _annealingNetMultEdit, 5, 3, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Annealing Bin Mult (%)" );
_annealingBinMultEdit->setValidator ( new QDoubleValidator(this) );
_annealingBinMultEdit->setEnabled ( false );
gLayout->addWidget ( label , 6, 2, Qt::AlignRight );
gLayout->addWidget ( _annealingBinMultEdit, 6, 3, Qt::AlignLeft );
label = new QLabel();
label->setText ( "Annealing Row Mult (%)" );
_annealingRowMultEdit->setValidator ( new QDoubleValidator(this) );
_annealingRowMultEdit->setEnabled ( false );
gLayout->addWidget ( label , 7, 2, Qt::AlignRight );
gLayout->addWidget ( _annealingRowMultEdit, 7, 3, Qt::AlignLeft );
separator = new QFrame ();
separator->setFrameShape ( QFrame::HLine );
separator->setFrameShadow ( QFrame::Sunken );
gLayout->addWidget ( separator, 8, 0, 1, 4 );
vLayout->addLayout ( gLayout );
QHBoxLayout* hLayout = new QHBoxLayout ();
hLayout->addStretch ();
QPushButton* apply = new QPushButton ();
apply->setText ( tr("Apply") );
hLayout->addWidget ( apply );
hLayout->addStretch ();
vLayout->addLayout ( hLayout );
vLayout->addStretch ();
setLayout ( vLayout );
connect ( apply, SIGNAL(clicked()), this, SLOT(_applySettings()) );
}
void ConfigurationWidget::setConfiguration ( Nimbus::Configuration* nimbusConfig
, Configuration* maukaConfig )
{
if ( maukaConfig != NULL ) {
_searchRatioEdit ->setText ( QString("%1").arg(maukaConfig ->getSearchRatio()) );
_annealingNetMultEdit->setText ( QString("%1").arg(maukaConfig ->getAnnealingNetMult()) );
_annealingBinMultEdit->setText ( QString("%1").arg(maukaConfig ->getAnnealingBinMult()) );
_annealingRowMultEdit->setText ( QString("%1").arg(maukaConfig ->getAnnealingRowMult()) );
_aspectRatioEdit ->setText ( QString("%1").arg(nimbusConfig->getAspectRatio()) );
_marginEdit ->setText ( QString("%1").arg(nimbusConfig->getMargin()) );
_standardAnnealingState->setChecked ( maukaConfig ->useStandardSimulatedAnnealing() );
_ignorePinsState ->setChecked ( maukaConfig ->doIgnorePins() );
_plotBinsState ->setChecked ( maukaConfig ->doPlotBins() );
_pinsPlacementState ->setChecked ( nimbusConfig->doPinsPlacement() );
_searchRatioEdit ->setEnabled ( true );
_annealingNetMultEdit ->setEnabled ( true );
_annealingBinMultEdit ->setEnabled ( true );
_annealingRowMultEdit ->setEnabled ( true );
_aspectRatioEdit ->setEnabled ( true );
_marginEdit ->setEnabled ( true );
_standardAnnealingState->setEnabled ( true );
_ignorePinsState ->setEnabled ( true );
_plotBinsState ->setEnabled ( true );
_pinsPlacementState ->setEnabled ( true );
} else {
_searchRatioEdit ->setEnabled ( false );
_annealingNetMultEdit ->setEnabled ( false );
_annealingBinMultEdit ->setEnabled ( false );
_annealingRowMultEdit ->setEnabled ( false );
_marginEdit ->setEnabled ( false );
_standardAnnealingState->setEnabled ( false );
_standardAnnealingState->setEnabled ( false );
_ignorePinsState ->setEnabled ( false );
_plotBinsState ->setEnabled ( false );
_pinsPlacementState ->setEnabled ( false );
_nimbusConfiguration = NULL;
_maukaConfiguration = NULL;
}
_nimbusConfiguration = nimbusConfig;
_maukaConfiguration = maukaConfig;
}
void ConfigurationWidget::_applySettings ()
{
if ( _maukaConfiguration == NULL ) return;
_updateStandardAnnealingState ();
_updateIgnorePinsState ();
_updatePlotBinsState ();
_updatePinsPlacementState ();
_updateSearchRatio ();
_updateAnnealingNetMult ();
_updateAnnealingBinMult ();
_updateAnnealingRowMult ();
_updateAspectRatio ();
_updateMargin ();
}
void ConfigurationWidget::_updateSearchRatio ()
{
if ( _maukaConfiguration == NULL ) return;
bool success = false;
float ratio = _searchRatioEdit->displayText().toFloat ( &success );
if ( success ) {
_maukaConfiguration->setSearchRatio ( ratio );
success = (_maukaConfiguration->getSearchRatio() == ratio);
}
if ( not success )
_searchRatioEdit->setText ( QString("%1").arg(_maukaConfiguration->getSearchRatio()) );
}
void ConfigurationWidget::_updateAnnealingNetMult ()
{
if ( _maukaConfiguration == NULL ) return;
bool success = false;
float ratio = _annealingNetMultEdit->displayText().toFloat ( &success );
if ( success ) {
_maukaConfiguration->setAnnealingNetMult ( ratio );
success = (_maukaConfiguration->getAnnealingNetMult() == ratio);
}
if ( not success )
_annealingNetMultEdit->setText ( QString("%1").arg(_maukaConfiguration->getAnnealingNetMult()) );
}
void ConfigurationWidget::_updateAnnealingBinMult ()
{
if ( _maukaConfiguration == NULL ) return;
bool success = false;
float ratio = _annealingBinMultEdit->displayText().toFloat ( &success );
if ( success ) {
_maukaConfiguration->setAnnealingBinMult ( ratio );
success = (_maukaConfiguration->getAnnealingBinMult() == ratio);
}
if ( not success )
_annealingBinMultEdit->setText ( QString("%1").arg(_maukaConfiguration->getAnnealingBinMult()) );
}
void ConfigurationWidget::_updateAnnealingRowMult ()
{
if ( _maukaConfiguration == NULL ) return;
bool success = false;
float ratio = _annealingRowMultEdit->displayText().toFloat ( &success );
if ( success ) {
_maukaConfiguration->setAnnealingRowMult ( ratio );
success = (_maukaConfiguration->getAnnealingRowMult() == ratio);
}
if ( not success )
_annealingRowMultEdit->setText ( QString("%1").arg(_maukaConfiguration->getAnnealingRowMult()) );
}
void ConfigurationWidget::_updateAspectRatio ()
{
if ( _nimbusConfiguration == NULL ) return;
bool success = false;
float ratio = _aspectRatioEdit->displayText().toFloat ( &success );
if ( success ) {
_nimbusConfiguration->setAspectRatio ( ratio );
success = (_nimbusConfiguration->getAspectRatio() == ratio);
}
if ( not success )
_aspectRatioEdit->setText ( QString("%1").arg(_nimbusConfiguration->getAspectRatio()) );
}
void ConfigurationWidget::_updateMargin ()
{
if ( _nimbusConfiguration == NULL ) return;
bool success = false;
float ratio = _marginEdit->displayText().toFloat ( &success );
if ( success ) {
_nimbusConfiguration->setMargin ( ratio );
success = (_nimbusConfiguration->getMargin() == ratio);
}
if ( not success )
_marginEdit->setText ( QString("%1").arg(_nimbusConfiguration->getMargin()) );
}
void ConfigurationWidget::_updateStandardAnnealingState ()
{
if ( _maukaConfiguration == NULL ) return;
_maukaConfiguration->setStandardSimulatedAnnealing ( _standardAnnealingState->isChecked() );
}
void ConfigurationWidget::_updateIgnorePinsState ()
{
if ( _maukaConfiguration == NULL ) return;
_maukaConfiguration->setIgnorePins ( _ignorePinsState->isChecked() );
}
void ConfigurationWidget::_updatePlotBinsState ()
{
if ( _maukaConfiguration == NULL ) return;
_maukaConfiguration->setPlotBins ( _plotBinsState->isChecked() );
}
void ConfigurationWidget::_updatePinsPlacementState ()
{
if ( _nimbusConfiguration == NULL ) return;
_nimbusConfiguration->setPinsPlacement ( _pinsPlacementState->isChecked() );
}
} // End of Mauka namespace.

80
mauka/src/Container.cpp Normal file
View File

@ -0,0 +1,80 @@
// 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 "mauka/Container.h"
namespace Mauka {
using namespace std;
const Name Container::_goName = "Mauka::Container";
Container::Container(Cell* cell, const Box& box)
: ExtensionGo(cell)
, _box(box)
{}
const Name& Container::getStaticName()
// ***********************************
{
return _goName;
}
const Name& Container::getName() const
// ***********************************
{
return _goName;
}
string Container::_getString() const
// *********************************
{
string s = Inherit::_getString();
s.insert(s.length() - 1, " " + getString(_box));
return s;
}
Record* Container::_getRecord() const
// ****************************
{
Record* record = Inherit::_getRecord();
if (record)
{
record->add(getSlot("Box", _box));
}
return record;
}
}

View File

@ -0,0 +1,84 @@
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
// License-Tag
//
// Date : 29/01/2004
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
//
// Authors-Tag
#include "Container.h"
namespace MAUKA {
Container::Container(const Cell* cell, const Box& box)
: Inherit(GetDisplaySlot(cell, "Mauka"))
, _box(box)
{}
bool Container::_IsInterceptedBy(View* view, const Point& point, const Unit& aperture) const
// ******************************************************************************************
{
return false;
}
void Container::_Draw(View* view, BasicLayer* basiclayer, const Box& updatearea, const Transformation& transformation)
// *******************************************************************************************************************
{
if (basiclayer)
throw Error("Container::_Draw : basiclayer sould be null !");
view->DrawRectangle(transformation.GetBox(_box));
}
void Container::_Highlight(View* view, const Box& updatearea, const Transformation& transformation)
{
_Draw(view, NULL, updatearea, transformation);
}
string Container::_GetString() const
// *********************************
{
string s = Inherit::_GetString();
s.insert(s.length() - 1, " " + GetString(_box));
return s;
}
Record* Container::_GetRecord() const
// ****************************
{
Record* record = Inherit::_GetRecord();
if (record)
{
record->Add(GetSlot("Box", _box));
}
return record;
}
}

View File

@ -0,0 +1,287 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | M a u k a - P l a c e r |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./GraphicMaukaEngine.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <functional>
#include <boost/bind.hpp>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QApplication>
#include <hurricane/Warning.h>
#include <hurricane/Error.h>
#include <hurricane/Breakpoint.h>
#include <hurricane/DebugSession.h>
#include <hurricane/Go.h>
#include <hurricane/Net.h>
#include <hurricane/Cell.h>
#include <hurricane/UpdateSession.h>
#include <hurricane/viewer/Graphics.h>
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/CellViewer.h>
#include <hurricane/viewer/ControllerWidget.h>
#include <crlcore/Utilities.h>
#include <crlcore/AllianceFramework.h>
#include <nimbus/NimbusEngine.h>
#include <mauka/Container.h>
#include <mauka/GraphicMaukaEngine.h>
#include <mauka/ConfigurationWidget.h>
namespace Mauka {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Breakpoint;
using Hurricane::DebugSession;
using Hurricane::UpdateSession;
using Hurricane::Net;
using Hurricane::Graphics;
using Hurricane::ColorScale;
using Hurricane::ControllerWidget;
using CRL::Catalog;
using CRL::AllianceFramework;
using Nimbus::NimbusEngine;
size_t GraphicMaukaEngine::_references = 0;
GraphicMaukaEngine* GraphicMaukaEngine::_singleton = NULL;
void GraphicMaukaEngine::initMaukaContainer ( CellWidget* widget )
{
widget->getDrawingPlanes().setPen ( Graphics::getPen ("mauka.container",widget->getDarkening()) );
widget->getDrawingPlanes().setBrush ( Graphics::getBrush("mauka.container",widget->getDarkening()) );
}
void GraphicMaukaEngine::drawMaukaContainer ( CellWidget* widget
, const Go* go
, const BasicLayer* basicLayer
, const Box& box
, const Transformation& transformation
)
{
const Container* container = static_cast<const Container*>(go);
QPainter& painter = widget->getPainter();
painter.drawRect ( widget->dbuToDisplayRect(container->getBoundingBox()) );
}
MaukaEngine* GraphicMaukaEngine::createEngine ()
{
Cell* cell = getCell ();
MaukaEngine* mauka = MaukaEngine::get ( cell );
if ( mauka == NULL ) {
NimbusEngine* nimbus = NimbusEngine::create ( cell, AllianceFramework::get()->getLibrary(1) );
mauka = MaukaEngine::create ( cell );
} else
cerr << Warning("%s already has a Mauka engine.",getString(cell).c_str()) << endl;
return mauka;
}
MaukaEngine* GraphicMaukaEngine::getForFramework ()
{
MaukaEngine* mauka = MaukaEngine::get ( getCell() );
if ( mauka != NULL ) return mauka;
mauka = createEngine ();
if ( mauka == NULL )
throw Error("Failed to create Mauka engine on %s.",getString(getCell()).c_str());
return mauka;
}
void GraphicMaukaEngine::run ()
{
MaukaEngine* mauka = createEngine ();
if ( mauka == NULL ) {
throw Error("MaukaEngine not created yet, run the global router first.");
}
emit cellPreModificated ();
_viewer->clearToolInterrupt ();
_viewer->getCellWidget()->fitToContents ();
mauka->Run ();
emit cellPostModificated ();
}
void GraphicMaukaEngine::save ()
{
MaukaEngine* mauka = createEngine ();
if ( mauka == NULL ) {
throw Error("MaukaEngine not created yet, run the placer first.");
}
emit cellPreModificated ();
_viewer->clearToolInterrupt ();
mauka->Save ();
emit cellPostModificated ();
}
void GraphicMaukaEngine::postEvent ()
{
static unsigned int count = 0;
if ( not (count++ % 500) ) {
//UpdateSession::close ();
//_viewer->getCellWidget()->refresh ();
QApplication::processEvents ();
//UpdateSession::open ();
if ( _viewer->isToolInterrupted() ) {
//MaukaEngine* mauka = MaukaEngine::get ( getCell() );
//if ( mauka ) mauka->setInterrupt ( true );
_viewer->clearToolInterrupt ();
}
}
}
void GraphicMaukaEngine::addToMenu ( CellViewer* viewer )
{
assert ( _viewer == NULL );
_viewer = viewer;
QMenu* prMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute");
QMenu* stepMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute.stepByStep");
if ( prMenu == NULL ) {
QMenuBar* menuBar = _viewer->findChild<QMenuBar*>("viewer.menuBar");
if ( menuBar == NULL ) {
cerr << Warning("GraphicMaukaEngine::addToMenu() - No MenuBar in parent widget.") << endl;
return;
}
prMenu = menuBar->addMenu ( tr("P&&R") );
prMenu->setObjectName ( "viewer.menuBar.placeAndRoute" );
stepMenu = prMenu->addMenu ( tr("&Step by Step") );
stepMenu->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep" );
prMenu->addSeparator ();
}
QAction* placeAction = _viewer->findChild<QAction*>("viewer.menuBar.placeAndRoute.maukaPlace");
if ( placeAction != NULL )
cerr << Warning("GraphicMaukaEngine::addToMenu() - Mauka placer already hooked in.") << endl;
else {
QAction* placeAction = new QAction ( tr("Mauka - &Place"), _viewer );
placeAction->setObjectName ( "viewer.menuBar.placeAndRoute.maukaPlace" );
placeAction->setStatusTip ( tr("Run the <b>Mauka</b> placer") );
placeAction->setVisible ( true );
prMenu->addAction ( placeAction );
connect ( placeAction, SIGNAL(triggered()), this, SLOT(run()) );
}
connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) );
connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) );
ControllerWidget* controller = _viewer->getControllerWidget();
ConfigurationWidget* setting = controller->getSettings()
->findChild<ConfigurationWidget*>("controller.tabSettings.setting.mauka");
if ( setting == NULL ) {
setting = new ConfigurationWidget ();
setting->setObjectName ( "controller.tabSettings.setting.mauka" );
setting->setConfiguration ( Nimbus::Configuration::getDefault(), Configuration::getDefault() );
controller->addSetting ( setting, "Mauka" );
}
}
const Name& GraphicMaukaEngine::getName () const
{
return MaukaEngine::staticGetName ();
}
Cell* GraphicMaukaEngine::getCell ()
{
if ( _viewer == NULL ) {
throw Error ( "<b>Mauka:</b> GraphicMaukaEngine not bound to any Viewer." );
return NULL;
}
if ( _viewer->getCell() == NULL ) {
throw Error ( "<b>Mauka:</b> No Cell is loaded into the Viewer." );
return NULL;
}
return _viewer->getCell();
}
GraphicMaukaEngine* GraphicMaukaEngine::grab ()
{
if ( not _references ) {
_singleton = new GraphicMaukaEngine ();
}
_references++;
return _singleton;
}
size_t GraphicMaukaEngine::release ()
{
_references--;
if ( not _references ) {
delete _singleton;
_singleton = NULL;
}
return _references;
}
GraphicMaukaEngine::GraphicMaukaEngine ()
: GraphicTool()
, _viewer (NULL)
{
addDrawGo ( "Mauka::Container", initMaukaContainer, drawMaukaContainer );
addDrawGo ( "Mauka::Bin" , initMaukaContainer, drawMaukaContainer );
}
GraphicMaukaEngine::~GraphicMaukaEngine ()
{ }
} // End of Mauka namespace.

View File

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

107
mauka/src/MaukaBox.cpp Normal file
View File

@ -0,0 +1,107 @@
// 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 "mauka/MaukaBox.h"
namespace Mauka {
using Hurricane::DbU;
Box& Update(Box& box, const Point& src, const Point& dst)
{
DbU::Unit minX = box.getXMin();
DbU::Unit maxX = box.getXMax();
DbU::Unit minY = box.getYMin();
DbU::Unit maxY = box.getYMax();
if (dst.getX() > src.getX())
{
if (src.getX() == minX)
{
box = Box();
return box;
}
else
if (dst.getX() > maxX)
{
maxX = dst.getX();
}
}
else
if (dst.getX() < src.getX())
{
if (src.getX() == maxX)
{
box = Box();
return box;
}
else
if (dst.getX() < minX)
{
minX = dst.getX();
}
}
if (dst.getY() > src.getY())
{
if (src.getY() == minY)
{
box = Box();
return box;
}
else
if (dst.getY() > maxY)
{
maxY = dst.getY();
}
}
else
if (dst.getY() < src.getY())
{
if (src.getY() == maxY)
{
box = Box();
return box;
}
else
if (dst.getY() < minY)
{
minY = dst.getY();
}
}
box = Box(Point(minX, minY), Point(maxX, maxY));
return box;
}
}

View File

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

669
mauka/src/MaukaEngine.cpp Normal file
View File

@ -0,0 +1,669 @@
// 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 "hurricane/Cell.h"
#include "hurricane/HyperNet.h"
#include "hurricane/Timer.h"
#include "hurricane/DataBase.h"
#include "crlcore/CellGauge.h"
#include "crlcore/AllianceFramework.h"
#include "mauka/Surface.h"
#include "mauka/Row.h"
#include "mauka/SimAnnealingPlacer.h"
#include "mauka/BBPlacer.h"
#include "mauka/MaukaEngine.h"
namespace Mauka {
using Hurricane::Plug;
using Hurricane::Path;
using Hurricane::OccurrenceLocator;
using Hurricane::PlugLocator;
using Hurricane::HyperNet;
using Hurricane::Timer;
using namespace CRL;
Name MaukaEngine::_toolName = "Mauka";
MaukaEngine::MaukaEngine(Cell* cell)
// *********************************
: Inherit(cell)
, _configuration(Configuration::getDefault()->clone())
, _instanceOccurrencesVector()
, _instanceOccurrencesMap()
, _instanceWidths()
, _instanceNets()
, _nets()
, _netInstances()
, _netInitX()
, _netInitY()
, _hasInitX()
, _hasInitY()
, _surface(NULL)
, _simAnnealingPlacer(NULL)
, _bbPlacer(NULL)
{}
MaukaEngine* MaukaEngine::create(Cell* cell, Box placementbox)
// ***********************************************************
{
MaukaEngine* mauka = new MaukaEngine(cell);
mauka->_postCreate(placementbox);
return mauka;
}
void MaukaEngine::_postCreate(Box& placementbox)
// *********************************************
{
Inherit::_postCreate();
Construct();
//_simAnnealingPlacer = new SimAnnealingPlacer(this, 1, 0.0, 0.0);
_simAnnealingPlacer = new SimAnnealingPlacer(this);
//_displaySlot = DisplaySlot::create(getCell(),,139,0,139);
_surface = Surface::create(this, placementbox);
_simAnnealingPlacer->init();
//Plot();
}
#if 0
void MaukaEngine::ReInit()
// *******************
{
Box placementBox = _surface->getBox();
_surface->destroy();
_simAnnealingPlacer->destroy();
_surface = Surface::create(this, placementBox);
_simAnnealingPlacer = SimAnnealingPlacer::create(this);
}
#endif
void MaukaEngine::Run()
{
Timer timer;
timer.start();
while ( _simAnnealingPlacer->Iterate() );
timer.stop();
_simAnnealingPlacer->DisplayResults();
//if ( doPlotBins() ) PlotBinsStats();
//cmess2 << endl << " o Simulated Annealing run took " << timer.getUserTime() << " s ..." << endl;
cmess1 << " o Simulated annealing took " << Timer::getStringTime(timer.getCombTime())
<< " [+" << Timer::getStringMemory(timer.getIncrease()) << "]." << endl;
cmess1 << " (raw measurements : " << timer.getCombTime()
<< "s [+" << (timer.getIncrease()>>10) << "Ko/"
<< (timer.getMemorySize()>>10) << "Ko])" << 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 MaukaEngine::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::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::DbU::Unit insWidth = model->getAbutmentBox().getWidth();
DbU::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 MaukaEngine::Iterate()
// ******************
{
bool canContinue = _simAnnealingPlacer->Iterate();
Save();
return canContinue;
}
void MaukaEngine::_preDestroy()
// *********************
{
_surface->destroy();
if (_simAnnealingPlacer)
delete _simAnnealingPlacer;
if (_bbPlacer)
delete _bbPlacer;
delete _configuration;
Inherit::_preDestroy();
}
Record* MaukaEngine::_getRecord() const
// ************************
{
Record* record = Inherit::_getRecord();
if (record) {
record->add(getSlot("Surface", _surface));
}
return record;
}
const Name& MaukaEngine::staticGetName()
// *************************************
{
return _toolName;
}
const Name& MaukaEngine::getName() const
// *******************************
{
return _toolName;
}
void MaukaEngine::Save() const
// *********************
{
if (_bbPlacer)
_bbPlacer->Save();
else if (_simAnnealingPlacer)
_simAnnealingPlacer->Save();
}
MaukaEngine* MaukaEngine::get(Cell* cell)
// ********************************************
{
return static_cast<MaukaEngine*>(ToolEngine::get(cell,staticGetName()));
}
namespace {
class TestSubRow : public Box {
public: DbU::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::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)
// *************************************************
{
CellGauge* gauge = AllianceFramework::get()->getCellGauge();
DbU::Unit pitch = gauge->getPitch();
DbU::Unit sliceHeight = gauge->getSliceHeight();
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::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::DbU::Unit insWidth = model->getAbutmentBox().getWidth();
toPlaceInstanceOccurrencesVector.push_back(occurrence);
if (instanceToPlaceWidthMax > insWidth)
instanceToPlaceWidthMax = insWidth;
}
end_for;
}
DbU::DbU::Unit binWidthMax = DbU::lambda((unsigned)(
2.0 * DbU::getLambda(instanceToPlaceWidthMax) / DbU::getLambda(pitch)) * DbU::getLambda(pitch));
DbU::DbU::Unit binWidthMin = DbU::lambda((unsigned)(
DbU::getLambda(binWidthMax) / (DbU::getLambda(pitch) * 2)) * DbU::getLambda(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
MaukaEngine::PrePlaceTab prePlaceTab(height, MaukaEngine::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::DbU::Unit insWidth = preplacedBox.getWidth();
DbU::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::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::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::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 MaukaEngine::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 MaukaEngine::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 MaukaEngine::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;
}
unsigned MaukaEngine::getRandomInstanceId() const {
unsigned instanceId = (unsigned)((double)_instanceOccurrencesVector.size() * rand() / (RAND_MAX + 1.0));
return instanceId;
}
}

View File

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

542
mauka/src/Move.cpp Normal file
View File

@ -0,0 +1,542 @@
// 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 <cmath>
#include <cstdlib>
#include <climits>
#include "hurricane/Error.h"
#include "hurricane/Plug.h"
#include "mauka/MaukaEngine.h"
#include "mauka/Bin.h"
#include "mauka/SubRow.h"
#include "mauka/Row.h"
#include "mauka/MaukaBox.h"
#include "mauka/SimAnnealingPlacer.h"
#include "mauka/Surface.h"
#include "mauka/Move.h"
namespace {
using Hurricane::DbU;
DbU::Unit PositionRand(const DbU::Unit position, const double distance, const DbU::Unit min, const DbU::Unit max)
{
DbU::Unit borneInf, borneSup;
if ((borneSup = position + DbU::lambda((int)(distance * DbU::getLambda(max) + 0.5)) ) > max )
borneSup = max;
if ((borneInf = position - DbU::lambda((int)(distance * DbU::getLambda(max) + 0.5)) ) < min )
borneInf = min;
return borneInf + DbU::lambda((int)(DbU::getLambda(borneSup - borneInf) * rand() / (RAND_MAX+1.0)));
}
} // End of anonymous namespace.
namespace Mauka {
using namespace std;
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 (MaukaEngine::UVector::const_iterator uvit = _mauka->_instanceNets[_srcIns].begin();
uvit != _mauka->_instanceNets[_srcIns].end();
uvit++)
{
_affectedNets[*uvit] = NetSrc;
}
if (_exchange)
{
for (MaukaEngine::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 (MaukaEngine::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]);
DbU::Unit width = tmpBox.getWidth();
if (width == 0)
{
width = _srcBin->getWidth() / 2;
}
netTmpCost = DbU::getLambda(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 (MaukaEngine::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 (MaukaEngine::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]);
DbU::Unit width = tmpBox.getWidth();
if (width == 0)
{
width = _dstBin->getWidth() / 2;
}
netTmpCost = DbU::getLambda(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 TO_BE_PORTED_UNDER_CORIOLIS_2
if (_mauka->getRunMode().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;
}
}
#endif
return true;
}
void
Move::accept()
{
// Sauvegarde des cout des nets
for (AffectedNets::iterator anit = _affectedNets.begin();
anit != _affectedNets.end();
anit++)
{
unsigned netId = anit->first;
unsigned flag = anit->second;
if (flag == NetSrc || flag == NetDst)
{
_simAnnealingPlacer->_InvertNetIdFlag(netId);
}
}
}
void
Move::Reject()
{
if (!_exchange)
{
_dstBin->removeBackInstance(_srcIns);
_srcBin->addInstance(_srcIns);
}
else
{
_srcBin->removeBackInstance(_dstIns);
_dstBin->removeBackInstance(_srcIns);
_dstBin->addInstance(_dstIns);
_srcBin->addInstance(_srcIns);
}
}
}

View File

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

252
mauka/src/Row.cpp Normal file
View File

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

View File

@ -0,0 +1,249 @@
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
// License-Tag
//
// Date : 19/07/2006
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
//
// Authors-Tag
#include "SubRow.h"
#include "Surface.h"
#include "Row.h"
namespace MAUKA {
Row::Row(Cell* cell, Surface* surface, const Box& box, bool orientation)
:Inherit(cell, box)
, _surface(surface)
, _subRowVector()
, _subRowXMax()
, _subRowXMinInv()
, _orientation(orientation)
, _size(0)
, _capa(0)
{}
Row* Row::Create(Cell* cell, Surface* surface, const Box& box, bool orientation)
{
if (!surface)
throw Error("Can't create " + _TName("Row") + " : empty surface");
Row* row = new Row(cell, surface, box, orientation);
row->_PostCreate();
return row;
}
void Row::_PreDelete()
{
Inherit::_PreDelete();
for (SubRowVector::iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
(*srit)->Delete();
}
_subRowVector.clear();
}
namespace {
struct SubRowSortByX
{
bool operator()(const SubRow* subrow1, const SubRow* subrow2) const
{
return subrow1->GetXMin() < subrow2->GetXMin();
}
};
}
void Row::_InsertSubRow(SubRow* subrow)
{
if (_subRowVector.size() == 0)
_subRowVector.push_back(subrow);
else
{
SubRowVector::iterator srvit = lower_bound(_subRowVector.begin(), _subRowVector.end(), subrow, SubRowSortByX());
if (srvit == _subRowVector.end())
{
_subRowVector.push_back(subrow);
}
else if ((*srvit)->GetXMin() == subrow->GetXMin())
{
throw Error("Bug in SubRow insertion");
}
else
{
_subRowVector.insert(srvit, subrow);
}
}
_box.Merge(subrow->GetBox());
}
void Row::_ComputeSubRows()
{
_subRowXMax.clear();
_subRowXMinInv.clear();
for (unsigned i = 0; i < _subRowVector.size(); i++)
{
SubRow* subRow = _subRowVector[i];
_subRowXMax[subRow->GetXMax()] = i;
_subRowXMinInv[subRow->GetXMin()] = i;
}
}
SubRow* Row::GetSubRowBetween(Unit x1, Unit x2)
{
assert(x1 <= x2);
assert(x1 >= GetXMin());
assert(x2 <= GetXMax());
if (_subRowVector.size() == 1)
return _subRowVector[0];
SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1);
SubRowXMax::iterator rsup = _subRowXMinInv.upper_bound(x2);
unsigned randidx = rinf->second +
(unsigned)((rsup->second - rinf->second + 1) * (rand() / (RAND_MAX+1.0)));
#if 0
//cerr << x1 << endl;
//cerr << x2 << endl;
for (SubRowXMax::iterator srit = _subRowXMax.begin();
srit != _subRowXMax.end();
srit++)
{
cerr << srit->first << "," << srit->second << endl;
}
cerr << randidx << endl << endl;;
#endif
return _subRowVector[randidx];
}
void Row::_AddSize(Unit value)
{
_size += value;
}
double Row::GetCost() const
{
return abs(GetValue(_size - _capa));
}
double Row::GetBinCost() const
{
double binCost = 0.0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
binCost += (*srit)->GetBinCost();
}
return binCost;
}
Unit Row::GetBinsSize() const
{
Unit totalBinsSize = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
totalBinsSize += (*srit)->GetBinsSize();
}
return totalBinsSize;
}
Unit Row::GetBinsCapa() const
{
Unit totalBinsCapa = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
totalBinsCapa += (*srit)->GetBinsCapa();
}
return totalBinsCapa;
}
Unit Row::GetSubRowsWidth() const
{
Unit subRowsWidth = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
subRowsWidth += (*srit)->GetWidth();
}
return subRowsWidth;
}
Unit Row::GetSubRowsCapa() const
{
Unit totalSubRowsCapa = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
totalSubRowsCapa += (*srit)->GetCapa();
}
return totalSubRowsCapa;
}
void Row::_ComputeCapacity(double margin)
{
_capa = 0;
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
(*srit)->_ComputeCapacity(margin);
_capa += (*srit)->_capa;
}
}
void Row::DisplayBinHits() const
{
for (SubRowVector::const_iterator srit = _subRowVector.begin();
srit != _subRowVector.end();
srit++)
{
(*srit)->DisplayBinHits();
}
}
Cell* Row::GetCell() const
{
return _surface->GetCell();
}
}

View File

@ -0,0 +1,666 @@
// 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 <cmath>
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolBox.h"
#include "mauka/Surface.h"
#include "mauka/Bin.h"
#include "mauka/Row.h"
#include "mauka/MaukaEngine.h"
#include "mauka/Move.h"
#include "mauka/SimAnnealingPlacer.h"
namespace {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Transformation;
using Hurricane::UpdateSession;
using CRL::getTransformation;
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 {
using namespace std;
SimAnnealingPlacer::SimAnnealingPlacer(MaukaEngine* mauka)
// *******************************************************
: _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(_mauka->getAnnealingNetMult())
, _binMult(_mauka->getAnnealingBinMult())
, _rowMult(_mauka->getAnnealingRowMult())
, _temperature(0.0)
, _distance(0.0)
, _loop(0)
, _iterationsFactor(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;
cmess1 << " o Beginning global placement" << endl;
cmess2 << Dots::asSizet (" - Number of nodes to place",_mauka->_instanceOccurrencesVector.size()) << endl;
cmess2 << Dots::asPercentage(" - Margin" ,100.0 * surface->getMargin()) << endl;
cmess2 << Dots::asDouble(" - Initial RowCost" ,_rowCost) << endl;
cmess2 << Dots::asDouble(" - Initial BinCost" ,_binCost) << endl;
cmess2 << Dots::asDouble(" - Initial NetCost" ,_netCost) << endl;
cmess2 << Dots::asDouble(" - Initial Cost" ,getCost()) << endl;
cmess2 << Dots::asLambda(" - Total bins capa" ,surface->getBinsCapa()) << endl;
cmess2 << Dots::asLambda(" - Total bins size" ,surface->getBinsSize()) << endl;
cmess2 << Dots::asLambda(" - Total subrows capa",surface->getSubRowsCapa()) << endl;
cmess1 << " o Computing initial Temperature ...";
Move move(this);
for (unsigned i = 0; i < _mauka->_instanceOccurrencesVector.size(); i++)
{
if (!move.Next(_distance))
{
cmess2 << " 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;
_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));
}
cmess1 << " 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))
{
cmess1 << " 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));
cmess2 << " - Loop:" << setw(4) << setfill('0')<< _loop
<< " NIns:" << _mauka->_instanceOccurrencesVector.size()
<< " Temperature:" << _temperature
<< " Cost:" << getCost() << endl;
cmess2 << " RowCost:" << _rowCost
<< " BinCost:" << _binCost
<< " NetCost:" << _netCost << endl;
cmess2 << " Success Ratio:" << sucRatio * 100.0
<< "% Dist:" << _distance
<< " Delta:" << _temperature / oldTemperature << endl;
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 (MaukaEngine::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 == 0 )
{
cerr << Warning("Net <%s> is not connected.",getString(_mauka->_nets[netid]).c_str()) << endl;
}
else
{
DbU::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("MaukaEngine 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("MaukaEngine internal error");
}
else if (Pin* pin = dynamic_cast<Pin*>(component))
{
if (not _mauka->odIgnorePins())
{
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 = DbU::getLambda(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 (MaukaEngine::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("MaukaEngine internal error: no plug");
Hook* bodyHook = netPlug->getBodyHook();
bool hasInitX = false;
bool hasInitY = false;
DbU::Unit netInitX = 0;
DbU::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("MaukaEngine internal error");
}
end_for;
}
if (hasInitX)
box.merge(netInitX, box.getYMin());
if (hasInitY)
box.merge(box.getXMin(), netInitY);
}
#endif
DbU::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 += DbU::getLambda(box.getHeight() + width);
}
}
return totalNetCost;
}
void SimAnnealingPlacer::DisplayResults() const
{
unsigned totalImpossibleMovements
= _impossibleExchangeMovementNumber
+ _sourceEqualTargetMovementNumber
+ _surOccupationTargetMovementNumber;
cmess2 << Dots::asUInt (" - Total impossible movements",totalImpossibleMovements) << endl;
cmess2 << Dots::asPercentage(" - Suroccupied target" ,100.0 * _surOccupationTargetMovementNumber / totalImpossibleMovements) << endl;
cmess2 << Dots::asPercentage(" - Source equal target" ,100.0 * _sourceEqualTargetMovementNumber / totalImpossibleMovements) << endl;
cmess2 << Dots::asPercentage(" - Impossible exchange" ,100.0 * _impossibleExchangeMovementNumber / totalImpossibleMovements) << endl;
cmess1 << " o Global Placement finished" << endl;
cmess2 << Dots::asPercentage(" - Gain for RowCost" ,100.0 * (_initRowCost - _rowCost) / _initRowCost) << endl;
cmess2 << Dots::asPercentage(" - Gain for BinCost" ,100.0 * (_initBinCost - _binCost) / _initBinCost) << endl;
cmess2 << Dots::asPercentage(" - Gain for NetCost" ,100.0 * (_initNetCost - _netCost) / _initNetCost) << endl;
cmess2 << Dots::asDouble (" - 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->useStandardSimulatedAnnealing())
{
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
{
UpdateSession::open();
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");
DbU::Unit xPos = bin->getCenter().getX();
DbU::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);
}
UpdateSession::close();
}
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");
DbU::Unit xPos = bin->getCenter().getX();
DbU::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;
DbU::Unit baryX = 0;
DbU::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;
DbU::Unit baryX = 0;
DbU::Unit baryY = 0;
baryX += _mauka->_netInitX[i];
baryY += _mauka->_netInitY[i];
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
++nbInstances;
const Bin* bin = _instanceBins[instanceId];
baryX += bin->getCenter().getX();
baryY += bin->getCenter().getY();
}
baryX = baryX / nbInstances;
baryY = baryY / nbInstances;
for (unsigned j = 0; j < _mauka->_netInstances[i].size(); j++)
{
unsigned instanceId = _mauka->_netInstances[i][j];
const Bin* bin = _instanceBins[instanceId];
out << baryX << " " << baryY << endl
<< bin->getCenter().getX() << " "
<< bin->getCenter().getY() << endl << endl;
}
out << baryX << " " << baryY << endl
<< _mauka->_netInitX[i] << " "
<< _mauka->_netInitY[i] << endl << endl;
}
out << "EOF" << endl << endl;
}
}

View File

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

268
mauka/src/SubRow.cpp Normal file
View File

@ -0,0 +1,268 @@
// 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 "crlcore/CellGauge.h"
#include "crlcore/AllianceFramework.h"
#include "mauka/Bin.h"
#include "mauka/Row.h"
#include "mauka/Surface.h"
#include "mauka/SimAnnealingPlacer.h"
#include "mauka/SubRow.h"
namespace Mauka {
using namespace std;
using Hurricane::Error;
using CRL::AllianceFramework;
SubRow::SubRow(Cell* cell, Surface* surface, const Box& box)
:Inherit(cell, box)
, _surface(surface)
, _row(NULL)
, _binVector()
, _size(0)
, _capa(0)
{}
SubRow* SubRow::create(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;
}
DbU::Unit pitch = AllianceFramework::get()->getCellGauge()->getPitch();
DbU::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");
DbU::Unit totalBinsWidth = binsWidth * nBins;
DbU::Unit binsWidthRemain = getWidth() - totalBinsWidth;
if (binsWidthRemain % pitch)
throw Error("Bins Width not a multiple of pitch");
unsigned binsWidthRemainPitch = binsWidthRemain / pitch;
DbU::Unit xMin = getXMin();
DbU::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 (MaukaEngine::UList::const_iterator ulit = (*bvit)->_instanceOccurrenceIds.begin();
ulit != (*bvit)->_instanceOccurrenceIds.end();
ulit++)
{
_surface->_mauka->_simAnnealingPlacer->_instanceBins[*ulit] = NULL;
}
(*bvit)->destroy();
}
_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::_preDestroy()
{
Inherit::_preDestroy();
for (BinVector::iterator bvit = _binVector.begin();
bvit != _binVector.end();
bvit++)
{
(*bvit)->destroy();
}
}
void SubRow::DisplayBinHits() const
{
for (BinVector::const_iterator bvit = _binVector.begin();
bvit != _binVector.end();
bvit++)
{
(*bvit)->DisplayHits();
}
}
Bin* SubRow::getBinBetween(DbU::Unit lowerX, DbU::Unit upperX, const Bin* srcbin)
{
assert(lowerX <= upperX);
assert(lowerX >= getXMin());
assert(upperX <= getXMax());
if (_binVector.size() == 1)
return _binVector[0];
DbU::Unit searchPosition = lowerX +
DbU::lambda((int)(DbU::getLambda(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(DbU::Unit value)
{
_size += value;
_row->_AddSize(value);
}
double SubRow::getCost() const
{
return abs(DbU::getLambda(_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;
}
DbU::Unit SubRow::getBinsSize() const
{
DbU::Unit totalBinsSize = 0;
for (BinVector::const_iterator bvit = _binVector.begin();
bvit != _binVector.end();
bvit++)
{
totalBinsSize += (*bvit)->getSize();
}
return totalBinsSize;
}
DbU::Unit SubRow::getBinsCapa() const
{
DbU::Unit totalBinsCapa = 0;
for (BinVector::const_iterator bvit = _binVector.begin();
bvit != _binVector.end();
bvit++)
{
totalBinsCapa += (*bvit)->getCapa();
}
return totalBinsCapa;
}
Cell* SubRow::getCell() const
{
return _row->getCell();
}
}

View File

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

816
mauka/src/Surface.cpp Normal file
View File

@ -0,0 +1,816 @@
// 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 "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "crlcore/CellGauge.h"
#include "crlcore/AllianceFramework.h"
#include "nimbus/NimbusEngine.h"
#include "mauka/MaukaEngine.h"
#include "mauka/SimAnnealingPlacer.h"
#include "mauka/SubRow.h"
#include "mauka/Row.h"
#include "mauka/Surface.h"
namespace {
using namespace std;
using namespace Hurricane;
using namespace Mauka;
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;
}
}
} // End of anonymous namespace.
namespace Mauka {
using CRL::AllianceFramework;
using Nimbus::NimbusEngine;
using Nimbus::GCellLocator;
Surface::Surface(MaukaEngine* mauka, const Box& placementbox) :
Inherit(mauka->getCell(), placementbox),
_mauka(mauka),
_rowVector(),
_rowYMax(),
_rowYMinInv(),
_rowZeroOrientation(false),
_margin(0.0),
_binWidthMax(0),
_binWidthMin(0),
_searchWidth(0),
_searchHeight(0)
{}
Surface* Surface::create(MaukaEngine* mauka, const Box& placementbox) {
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);
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: MaukaEngine::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();
NimbusEngine* nimbus = NULL;
if (_box.isEmpty()) {
nimbus = NimbusEngine::get ( getCell() );
if (nimbus == NULL) {
throw Error("Can't create Mauka::Surface, no Box and no Nimbus");
}
_box = nimbus->getGrid()->getRoot()->getBox();
}
PlacementVerification ( getCell(), _box );
DbU::Unit sliceHeight = DbU::lambda(1);
DbU::Unit pitch = DbU::lambda(1);
AllianceFramework* af = AllianceFramework::get();
if (af != NULL) {
sliceHeight = af->getCellGauge()->getSliceHeight();
pitch = af->getCellGauge()->getPitch();
} else {
// For the moment very stupid method: take the first instantiated Cell.
forEach ( Instance*, iinstance, getCell()->getInstances() ) {
Cell* masterCell = iinstance->getMasterCell();
sliceHeight = masterCell->getAbutmentBox().getHeight();
break;
}
}
if ( _box.isEmpty() or _box.isPonctual() or _box.isFlat())
throw Error("Wrong Box for Area: %s",getString(_box).c_str());
if ( getHeight() % sliceHeight )
throw Error("Box Height %s must be a multiple of Slice Height %s"
,DbU::getValueString(getHeight()).c_str()
,DbU::getValueString(sliceHeight).c_str());
DbU::Unit instanceToPlaceWidthMax = 0;
DbU::Unit instanceToPlaceWidthSum = 0;
for ( unsigned int id = 0; id < _mauka->_instanceWidths.size(); ++id ) {
DbU::Unit instanceWidth = _mauka->_instanceWidths[id];
instanceToPlaceWidthSum += instanceWidth;
if ( instanceWidth % pitch )
throw Error("Width of %s (%s) is not a multiple of pitch (%s)."
,getString(_mauka->_instanceOccurrencesVector[id]).c_str()
,DbU::getValueString(instanceWidth).c_str()
,DbU::getValueString(pitch).c_str());
if (instanceWidth > instanceToPlaceWidthMax)
instanceToPlaceWidthMax = instanceWidth;
}
_binWidthMax = DbU::lambda
((unsigned)( 2.0 * DbU::getLambda(instanceToPlaceWidthMax) / DbU::getLambda(pitch))
* DbU::getLambda(pitch));
_binWidthMin = DbU::lambda
((unsigned)(DbU::getLambda(_binWidthMax) / (DbU::getLambda(pitch) * 2)) * DbU::getLambda(pitch));
DbU::Unit surfaceTotalWidth = 0;
PlacementProblemList placementProblemList;
OccurrenceSet verifyInstanceOccurrencesSet;
if ( nimbus ) {
forEach ( GCell*, igcell, nimbus->getPlacementLeaves() ) {
PlacementProblem* placementProblem = new PlacementProblem(*igcell);
placementProblemList.push_back(placementProblem);
InstanceOccurrencesList toPlaceInstanceOccurrencesList;
// Search for preplaced leaf instances
forEach ( Occurrence
, ioccurrence, _mauka->getCell()->getLeafInstanceOccurrencesUnder(igcell->getBox()) ) {
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
if ( instance->isFixed() ) {
placementProblem->_fixedInstanceOccurrenceList.push_back(*ioccurrence);
} else {
MaukaEngine::InstanceOccurrencesMap::const_iterator
iomit = _mauka->_instanceOccurrencesMap.find(*ioccurrence);
if ( iomit == _mauka->_instanceOccurrencesMap.end() )
throw Error("Instance occurrence unexpectedly appeared:\n"
" %s",getString(*ioccurrence).c_str());
placementProblem->_toPlaceInstanceOccurrencesUVector.push_back(iomit->second);
verifyInstanceOccurrencesSet.insert(*ioccurrence);
}
}
forEach(Occurrence, ioccurrence, _mauka->getCell()->getLeafInstanceOccurrences()) {
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
if ( instance->isFixed() ) continue;
MaukaEngine::InstanceOccurrencesMap::const_iterator iomit
= _mauka->_instanceOccurrencesMap.find(*ioccurrence);
if (iomit == _mauka->_instanceOccurrencesMap.end())
throw Error("Instance occurrence unexpectedly appeared:\n"
" %s",getString(*ioccurrence).c_str());
placementProblem->_toPlaceInstanceOccurrencesUVector.push_back(iomit->second);
verifyInstanceOccurrencesSet.insert(*ioccurrence);
}
DbU::Unit searchWidth = DbU::lambda(_mauka->getSearchRatio() * DbU::getLambda(igcell->getWidth()));
if (_searchWidth < searchWidth) _searchWidth = searchWidth;
DbU::Unit searchHeight = DbU::lambda(_mauka->getSearchRatio() * DbU::getLambda(igcell->getHeight()));
if (_searchHeight < searchHeight) _searchHeight = searchHeight;
}
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
MaukaEngine::PrePlaceTab prePlaceTab(height, MaukaEngine::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();
if ( refInsYPos % 2 == 0 ) {
if ( (refInsSliceHeight % 2 == 0)
or (orientation == Transformation::Orientation::ID)
or (orientation == Transformation::Orientation::MX))
rowZeroOrientation = true;
else
rowZeroOrientation = false;
} else {
if ( (refInsSliceHeight % 2 == 0)
or (orientation == Transformation::Orientation::ID)
or (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);
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) or (yit > height - 1) or (xit < 0) or (yit < 0) )
throw Error("%s is out of the abutment box"
,getString(*iolit).c_str());
if ( prePlaceTab[yit][xit] == false )
prePlaceTab[yit][xit] = true;
else
throw Error("%s is badly placed. There is another instance at it's position"
,getString(*iolit).c_str());
}
}
}
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()) and (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()) and (prePlaceTab[y][x] == false) ) ++x;
DbU::Unit subRowXMax = gcell->getXMin() + x * pitch;
if ( subRowXMax - subRowXMin > _binWidthMin ) {
SubRow* subRow = SubRow::create ( getCell()
, this
, Box(subRowXMin, gcell->getYMin() + y * sliceHeight
,subRowXMax, gcell->getYMin() + (y+1) * sliceHeight)
, rowOrientation );
placementProblem->_subRowList.push_back(subRow);
}
}
rowOrientation = not rowOrientation;
}
} else {
bool rowOrientation = false;
for ( DbU::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 = not rowOrientation;
}
}
}
} else {
PlacementProblem* placementProblem = new PlacementProblem(NULL);
_searchHeight = getHeight();
_searchWidth = getWidth();
bool rowOrientation = false;
unsigned nRows = getHeight() / sliceHeight;
surfaceTotalWidth = getWidth() * nRows;
for ( DbU::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 = not rowOrientation;
}
for ( unsigned int id=0; id < _mauka->_instanceOccurrencesVector.size(); ++id ) {
placementProblem->_toPlaceInstanceOccurrencesUVector.push_back(id);
}
throw Error("MaukaEngine needs NimbusEngine");
}
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("There are %d Instances not taken into account"
,(_mauka->_instanceOccurrencesVector.size() - verifyInstanceOccurrencesSet.size())) << endl;
VerifyInstanceQuadtreeInsertion(_mauka->getCell());
for ( MaukaEngine::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 );
DisplayNonLeafInstances ( _mauka->getCell(), iovit->getBoundingBox() );
return;
}
}
throw Error("There are %d Instances not taken into account"
,(_mauka->_instanceOccurrencesVector.size() - verifyInstanceOccurrencesSet.size()));
}
for ( RowVector::const_iterator rvit = _rowVector.begin(); rvit != _rowVector.end(); rvit++ ) {
surfaceTotalWidth += (*rvit)->getSubRowsWidth();
}
_computeRowsAndSubRows();
_margin = 1.0 - DbU::getLambda(instanceToPlaceWidthSum) / DbU::getLambda(surfaceTotalWidth);
if ( _margin < 0 ) {
throw Error("There is not enough free space to place the circuit %s < %s"
,DbU::getValueString(surfaceTotalWidth).c_str()
,DbU::getValueString(instanceToPlaceWidthSum).c_str()
);
}
if (_margin < 0.15)
cerr << Warning("Low margin %d, may not be able to complete successfully",_margin) << endl;
_computeCapacity();
}
void Surface::_preDestroy()
{
Inherit::_preDestroy();
for (RowVector::const_iterator rvit = _rowVector.begin();
rvit != _rowVector.end();
rvit++)
(*rvit)->destroy();
_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();
DbU::Unit lowerY = srcPos.getY() - DbU::lambda((dist * DbU::getLambda(_searchHeight)));
if (lowerY < getYMin())
lowerY = getYMin();
DbU::Unit upperY = srcPos.getY() + DbU::lambda((dist * DbU::getLambda(_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];
DbU::Unit lowerX = srcPos.getX() - DbU::lambda((dist * DbU::getLambda(_searchWidth)));
if ((lowerX < searchRow->getXMin()) || (lowerX > searchRow->getXMax()))
lowerX = searchRow->getXMin();
DbU::Unit upperX = srcPos.getX() + DbU::lambda((dist * DbU::getLambda(_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;
}
DbU::Unit Surface::getBinsSize() const
{
DbU::Unit totalBinsSize = 0;
for (RowVector::const_iterator rvit = _rowVector.begin();
rvit != _rowVector.end();
rvit++)
totalBinsSize += (*rvit)->getBinsSize();
return totalBinsSize;
}
DbU::Unit Surface::getBinsCapa() const
{
DbU::Unit totalBinsCapa = 0;
for (RowVector::const_iterator rvit = _rowVector.begin();
rvit != _rowVector.end();
rvit++)
totalBinsCapa += (*rvit)->getBinsCapa();
return totalBinsCapa;
}
DbU::Unit Surface::getSubRowsCapa() const
{
DbU::Unit totalSubRowsCapa = 0;
for (RowVector::const_iterator rvit = _rowVector.begin();
rvit != _rowVector.end();
rvit++)
{
totalSubRowsCapa += (*rvit)->getSubRowsCapa();
}
return totalSubRowsCapa;
}
namespace {
class sortInstanceOccurrencesIdsByWidth
{
private: MaukaEngine* _mauka;
public: sortInstanceOccurrencesIdsByWidth(MaukaEngine* mauka): _mauka(mauka) {}
public:
bool operator()(unsigned instanceoccurrenceid1, unsigned instanceoccurrenceid2) const
{
DbU::Unit width1 = _mauka->getInstanceIdWidth(instanceoccurrenceid1);
DbU::Unit width2 = _mauka->getInstanceIdWidth(instanceoccurrenceid2);
return width1 > width2;
}
};
}
void Surface::_DisplayInstances(MaukaEngine::UVector& instanceids, SubRowList& subrowlist)
{
// Insert instances in subrows
sort(instanceids.begin(), instanceids.end(), sortInstanceOccurrencesIdsByWidth(_mauka));
SubRowList::iterator srlit = subrowlist.begin();
MaukaEngine::UVector::const_iterator insIterator = instanceids.begin();
MaukaEngine::UVector::const_iterator lastLoopInsertedInsIterator = insIterator;
while(true)
{
if (insIterator == instanceids.end())
{
cmess1 << " 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;
DbU::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;
throw Error("Not enough free space to place all the instances.\n"
"Please increase the abutment box: %s (%d instances remains to place)"
,getString(getBoundingBox()).c_str()
,nbInstancesToPlace
);
}
}
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;
DbU::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("MaukaEngine", _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;
}
}

View File

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

126
mauka/src/mauka/BBPlacer.h Normal file
View File

@ -0,0 +1,126 @@
// 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
#ifndef __BBPLACER_H
#define __BBPLACER_H
#include "hurricane/Instance.h"
#include "mauka/SubRow.h"
#include "mauka/MaukaEngine.h"
namespace Mauka {
using Hurricane::DbU;
// ****************************************************************************************************
// BBPlacer declaration
// ****************************************************************************************************
class BBPlacer {
// *************
friend class MaukaEngine;
// Types
// *****
public: typedef std::vector<SubRow*> SubRowVector;
// Attributes
// **********
private: MaukaEngine* _mauka;
private: SubRowVector _subRowVector;
private: MaukaEngine::UTable _subRowInstances;
private: MaukaEngine::UnitVector _instanceMarginWidth;
private: MaukaEngine::UnitVector _instanceX; // Left Corner X position
private: MaukaEngine::UnitVector _instanceY;
private: MaukaEngine::BVector _instancePlaced;
private: MaukaEngine::NetVector _netVector;
private: MaukaEngine::BBoxes _netBBoxes;
private: MaukaEngine::Costs _netCosts;
private: MaukaEngine::UVector _netCurrCostMark;
private: MaukaEngine::UVector _netFlags;
// For the optimization engine itself
private: MaukaEngine::UVector _instanceToOptimize;
private: DbU::Unit _leftEdge;
private: DbU::Unit _rightEdge;
private: double _oldCost;
private: double _cost;
private: double _bestCost;
// _costFlag is for computing nets costs
// Each net must be visited only one time
private: unsigned _costFlag;
private: unsigned _saveFlag;
private: std::deque<unsigned> _queue; // ordering
private: MaukaEngine::UVector _stack;
private: MaukaEngine::UVector _loopVect; // use for loop
private: MaukaEngine::UnitVector _bestSolution;
private: int _idx;
// Constructors
// ************
public: BBPlacer(MaukaEngine* mauka);
// Accessors
// *********
public: DbU::Unit getInstanceIdX(unsigned id) const { return _instanceX[id]; }
// Updators
// ********
// Others
// ******
public: void Run();
public: void Save();
private: bool Optimize();
private: double initCost();
private: double CurrentCost();
private: void PlaceAll();
private: void UnplaceAll();
private: void addIns();
private: void removeIns();
private: double UpdateInstanceCost(unsigned instanceid);
private: double UpdateNetCost(unsigned netid);
private: double computeCost(const Box& box) const;
private: double initInstanceCost(unsigned instanceid);
private: double CurrentInstanceCost(unsigned instanceid);
private: void computeNetBBox(unsigned netid);
private: void SaveNetTempValue(unsigned netid);
private: double CurrentNetCost(unsigned netid);
private: void Plot(std::ofstream& out) const;
};
}
#endif // __BBPLACER_H

View File

@ -0,0 +1,126 @@
// 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
#ifndef __BBPLACER_H
#define __BBPLACER_H
#include "Instance.h"
USING_NAMESPACE_HURRICANE
#include "SubRow.h"
#include "Mauka.h"
namespace MAUKA {
// ****************************************************************************************************
// BBPlacer declaration
// ****************************************************************************************************
class BBPlacer {
// *************
friend class Mauka;
// Types
// *****
public: typedef vector<SubRow*> SubRowVector;
// Attributes
// **********
private: Mauka* _mauka;
private: SubRowVector _subRowVector;
private: Mauka::UTable _subRowInstances;
private: Mauka::UnitVector _instanceMarginWidth;
private: Mauka::UnitVector _instanceX; //Left Corner X position
private: Mauka::UnitVector _instanceY;
private: Mauka::BVector _instancePlaced;
private: Mauka::NetVector _netVector;
private: Mauka::BBoxes _netBBoxes;
private: Mauka::Costs _netCosts;
private: Mauka::UVector _netCurrCostMark;
private: Mauka::UVector _netFlags;
// For the optimization engine itself
private: Mauka::UVector _instanceToOptimize;
private: Unit _leftEdge;
private: Unit _rightEdge;
private: double _oldCost;
private: double _cost;
private: double _bestCost;
// _costFlag is for computing nets costs
// Each net must be visited only one time
private: unsigned _costFlag;
private: unsigned _saveFlag;
private: deque<unsigned> _queue; // ordering
private: Mauka::UVector _stack;
private: Mauka::UVector _loopVect; // use for loop
private: Mauka::UnitVector _bestSolution;
private: int _idx;
// Constructors
// ************
public: BBPlacer(Mauka* mauka);
// Accessors
// *********
public: Unit GetInstanceIdX(unsigned id) const { return _instanceX[id]; }
// Updators
// ********
// Others
// ******
public: void Run();
public: void Save();
private: bool Optimize();
private: double InitCost();
private: double CurrentCost();
private: void PlaceAll();
private: void UnplaceAll();
private: void AddIns();
private: void RemoveIns();
private: double UpdateInstanceCost(unsigned instanceid);
private: double UpdateNetCost(unsigned netid);
private: double ComputeCost(const Box& box) const;
private: double InitInstanceCost(unsigned instanceid);
private: double CurrentInstanceCost(unsigned instanceid);
private: void ComputeNetBBox(unsigned netid);
private: void SaveNetTempValue(unsigned netid);
private: double CurrentNetCost(unsigned netid);
private: void Plot(ofstream& out) const;
};
}
#endif // __BBPLACER_H

126
mauka/src/mauka/Bin.h Normal file
View File

@ -0,0 +1,126 @@
// 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
#ifndef __BIN_H
#define __BIN_H
#include "hurricane/Occurrences.h"
#include "mauka/Container.h"
#include "mauka/MaukaEngine.h"
namespace Mauka {
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Cell;
using Hurricane::Occurrence;
using Hurricane::Occurrences;
class SubRow;
class SimAnnealingPlacer;
// ****************************************************************************************************
// Bin declaration
// ****************************************************************************************************
class Bin : public Container {
// *************************
// Friends
// *******
friend class BBPlacer;
friend class SubRow;
// Types
// *****
public: typedef Container Inherit;
// Attributes
// **********
private: static const Name _goName;
private: SubRow* _subRow;
private: MaukaEngine* _mauka;
private: MaukaEngine::UList _instanceOccurrenceIds;
private: DbU::Unit _size; // sum of the contained instances width
private: DbU::Unit _capa; // ideal occupation of the bin
private: unsigned _sourceHits;
private: unsigned _targetHits;
// Constructors
// ************
protected: Bin(Cell* cell, SubRow* subrow, const Box& box);
public: static Bin* create(Cell* cell, SubRow* subrow, const Box& box);
// Accessors
// *********
public: static const Name& getStaticName();
public: virtual const Name& getName() const;
public: virtual Cell* getCell() const;
public: DbU::Unit getCapaVsSize() const { return (_capa - _size);}
public: DbU::Unit getSize() const { return _size; }
public: DbU::Unit getCapa() const { return _capa; }
public: SubRow* getSubRow() { return _subRow; }
public: unsigned getFirstInstanceOccurrenceId() const { return _instanceOccurrenceIds.front(); }
public: double getCost() const;
public: unsigned getInstanceOccurrenceIdSize() const { return _instanceOccurrenceIds.size(); }
public: const MaukaEngine::UList::const_iterator InstanceOccurrenceIdsBegin() const { return _instanceOccurrenceIds.begin(); }
public: const MaukaEngine::UList::const_iterator InstanceOccurrenceIdsEnd() const { return _instanceOccurrenceIds.end(); }
public: Occurrences getInstanceOccurrences() const;
// Updators
// ********
public: void removeInstance(unsigned instanceid);
public: void removeFrontInstance(unsigned instanceid);
public: void removeBackInstance(unsigned instanceid);
public: void addInstance(unsigned instanceid);
private:void _AddSize(DbU::Unit value);
// Others
// ******
private: void _computeCapacity(double margin);
public: void DisplayHits() const;
public: void incrementSourceHits();
public: void incrementTargetHits();
public: bool TryAddInstance(unsigned instanceid);
public: bool UnderOccupied() const;
protected: virtual void _postCreate();
public: virtual std::string _getTypeName() const {return "Bin";};
public: void PlotStats(std::ofstream& out) const;
public: void Plot(std::ofstream& out) const;
};
}
#endif // __BIN_H

View File

@ -0,0 +1,119 @@
// 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
#ifndef __BIN_H
#define __BIN_H
#include "Occurrences.h"
USING_NAMESPACE_HURRICANE
#include "Container.h"
#include "Mauka.h"
namespace MAUKA {
class SubRow;
class SimAnnealingPlacer;
// ****************************************************************************************************
// Bin declaration
// ****************************************************************************************************
class Bin : public Container {
// *************************
// Friends
// *******
friend class BBPlacer;
friend class SubRow;
// Types
// *****
public: typedef Container Inherit;
// Attributes
// **********
private: SubRow* _subRow;
private: Mauka* _mauka;
private: Mauka::UList _instanceOccurrenceIds;
private: Unit _size; // sum of the contained instances width
private: Unit _capa; // ideal occupation of the bin
private: unsigned _sourceHits;
private: unsigned _targetHits;
// Constructors
// ************
protected: Bin(const Cell* cell, SubRow* subrow, const Box& box);
public: static Bin* Create(const Cell* cell, SubRow* subrow, const Box& box);
// Accessors
// *********
public: virtual Cell* GetCell() const;
public: Unit GetCapaVsSize() const { return (_capa - _size);}
public: Unit GetSize() const { return _size; }
public: Unit GetCapa() const { return _capa; }
public: SubRow* GetSubRow() { return _subRow; }
public: unsigned GetFirstInstanceOccurrenceId() const { return _instanceOccurrenceIds.front(); }
public: double GetCost() const;
public: unsigned GetInstanceOccurrenceIdSize() const { return _instanceOccurrenceIds.size(); }
public: const Mauka::UList::const_iterator InstanceOccurrenceIdsBegin() const { return _instanceOccurrenceIds.begin(); }
public: const Mauka::UList::const_iterator InstanceOccurrenceIdsEnd() const { return _instanceOccurrenceIds.end(); }
public: Occurrences GetInstanceOccurrences() const;
// Updators
// ********
public: void RemoveInstance(unsigned instanceid);
public: void RemoveFrontInstance(unsigned instanceid);
public: void RemoveBackInstance(unsigned instanceid);
public: void AddInstance(unsigned instanceid);
private:void _AddSize(Unit value);
// Others
// ******
private: void _ComputeCapacity(double margin);
public: void DisplayHits() const;
public: void IncrementSourceHits();
public: void IncrementTargetHits();
public: bool TryAddInstance(unsigned instanceid);
public: bool UnderOccupied() const;
protected: virtual void _PostCreate();
public: virtual string _GetTypeName() const {return _TName("Bin");};
public: void PlotStats(ofstream& out) const;
public: void Plot(ofstream& out) const;
};
}
#endif // __BIN_H

View File

@ -0,0 +1,120 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | M a u k a - P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./Configuration.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __MAUKA_CONFIGURATION__
#define __MAUKA_CONFIGURATION__
#include <string>
namespace Hurricane {
class Record;
class Cell;
}
namespace Mauka {
using Hurricane::Cell;
using Hurricane::Record;
// -------------------------------------------------------------------
// Class : "Katabatic::Configuration".
class Configuration {
public:
static Configuration* getDefault ();
public:
// Constructor & Destructor.
Configuration ();
~Configuration ();
Configuration* clone () const;
// Methods.
inline bool useStandardSimulatedAnnealing () const;
inline bool doIgnorePins () const;
inline bool doPlotBins () const;
inline double getSearchRatio () const;
inline double getAnnealingNetMult () const;
inline double getAnnealingBinMult () const;
inline double getAnnealingRowMult () const;
void print ( Cell* ) const;
inline void setStandardSimulatedAnnealing ( bool );
inline void setIgnorePins ( bool );
inline void setPlotBins ( bool );
inline void setSearchRatio ( double );
inline void setAnnealingNetMult ( double );
inline void setAnnealingBinMult ( double );
inline void setAnnealingRowMult ( double );
inline static double _normPercentage ( double ratio, double min=0.0, double max=1.0 );
Record* _getRecord () const;
std::string _getString () const;
std::string _getTypeName () const;
private:
// Attributes.
static Configuration* _default;
bool _standardSimulatedAnnealing;
bool _ignorePins;
bool _plotBins; // Plot bins utilisation.
double _searchRatio;
double _annealingNetMult;
double _annealingBinMult;
double _annealingRowMult;
private:
Configuration ( const Configuration& );
Configuration& operator= ( const Configuration& );
};
// Inline Methods.
inline bool Configuration::useStandardSimulatedAnnealing () const { return _standardSimulatedAnnealing; }
inline bool Configuration::doIgnorePins () const { return _ignorePins; }
inline bool Configuration::doPlotBins () const { return _plotBins; }
inline double Configuration::getSearchRatio () const { return _searchRatio; }
inline double Configuration::getAnnealingNetMult () const { return _annealingNetMult; }
inline double Configuration::getAnnealingBinMult () const { return _annealingBinMult; }
inline double Configuration::getAnnealingRowMult () const { return _annealingRowMult; }
inline void Configuration::setStandardSimulatedAnnealing ( bool state ) { _standardSimulatedAnnealing=state; }
inline void Configuration::setIgnorePins ( bool state ) { _ignorePins=state; }
inline void Configuration::setPlotBins ( bool state ) { _plotBins=state; }
inline void Configuration::setSearchRatio ( double ratio ) { _searchRatio=_normPercentage(ratio,0.1); }
inline void Configuration::setAnnealingNetMult ( double mult ) { _annealingNetMult=_normPercentage(mult); }
inline void Configuration::setAnnealingBinMult ( double mult ) { _annealingBinMult=_normPercentage(mult); }
inline void Configuration::setAnnealingRowMult ( double mult ) { _annealingRowMult=_normPercentage(mult); }
inline double Configuration::_normPercentage ( double ratio, double min, double max ) {
if ( ratio < min ) return min;
if ( ratio > max ) return max;
return ratio;
}
} // End of Mauka namespace.
INSPECTOR_P_SUPPORT(Mauka::Configuration);
#endif // __MAUKA_CONFIGURATION__

View File

@ -0,0 +1,84 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | M a u k a - P l a c e r |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./ConfigurationWidget.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __MAUKA_CONFIGURATION_WIDGET__
#define __MAUKA_CONFIGURATION_WIDGET__
#include <QWidget>
class QLineEdit;
class QCheckBox;
namespace Nimbus {
class Configuration;
}
namespace Mauka {
class Configuration;
// -------------------------------------------------------------------
// Class : "Kite::ConfigurationWidget".
class ConfigurationWidget : public QWidget {
Q_OBJECT;
public:
ConfigurationWidget ( QWidget* parent=NULL );
public slots:
void setConfiguration ( Nimbus::Configuration*, Configuration* );
void _applySettings ();
void _updateStandardAnnealingState ();
void _updateIgnorePinsState ();
void _updatePlotBinsState ();
void _updatePinsPlacementState ();
void _updateSearchRatio ();
void _updateAnnealingNetMult ();
void _updateAnnealingBinMult ();
void _updateAnnealingRowMult ();
void _updateAspectRatio ();
void _updateMargin ();
private:
Nimbus::Configuration* _nimbusConfiguration;
Configuration* _maukaConfiguration;
QCheckBox* _standardAnnealingState;
QCheckBox* _ignorePinsState;
QCheckBox* _plotBinsState;
QCheckBox* _pinsPlacementState;
QLineEdit* _searchRatioEdit;
QLineEdit* _annealingNetMultEdit;
QLineEdit* _annealingBinMultEdit;
QLineEdit* _annealingRowMultEdit;
QLineEdit* _aspectRatioEdit;
QLineEdit* _marginEdit;
};
} // End of Mauka namespace.
#endif // __MAUKA_CONFIGURATION_WIDGET__

View File

@ -0,0 +1,98 @@
// 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
#ifndef __CONTAINER_H
#define __CONTAINER_H
#include "hurricane/Box.h"
#include "hurricane/ExtensionGo.h"
namespace Mauka {
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::DbU;
using Hurricane::Point;
using Hurricane::Box;
using Hurricane::Cell;
using Hurricane::ExtensionGo;
class Container: public ExtensionGo {
// ********************************
// Types
// *****
public: typedef ExtensionGo Inherit;
// Attributes
// **********
private: static const Name _goName;
protected: Box _box;
// Constructors
// ************
protected: Container(Cell* cell, const Box& box);
//
// Accessors
// *********
public: static const Name& getStaticName();
public: virtual const Name& getName() const;
public: Box getBoundingBox() const { return _box; };
public: const Box& getBox() const { return _box; };
public: const DbU::Unit& getXMin() const { return _box.getXMin(); };
public: const DbU::Unit& getYMin() const { return _box.getYMin(); };
public: const DbU::Unit& getXMax() const { return _box.getXMax(); };
public: const DbU::Unit& getYMax() const { return _box.getYMax(); };
public: DbU::Unit getHeight() const { return _box.getHeight(); };
public: DbU::Unit getWidth() const { return _box.getWidth(); };
public: Point getCenter() const { return _box.getCenter(); }
// Updators
// ********
public: virtual void translate(const DbU::Unit& dx, const DbU::Unit& dy) {}
// Others
// ******
public: virtual std::string _getTypeName() const {return "Container";};
public: virtual std::string _getString() const;
public: virtual Record* _getRecord() const;
};
}
#endif // __CONTAINER_H

View File

@ -0,0 +1,92 @@
// 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
#ifndef __CONTAINER_H
#define __CONTAINER_H
#include "Box.h"
#include "UserGo.h"
USING_NAMESPACE_HURRICANE
namespace MAUKA {
class Container: public UserGo {
// ******************************
// Types
// *****
public: typedef UserGo Inherit;
// Attributes
// **********
protected: Box _box;
// Constructors
// ************
protected: Container(const Cell* cell, const Box& box);
//
// Accessors
// *********
public: Box GetBoundingBox() const { return _box; };
public: const Box& GetBox() const { return _box; };
public: const Unit& GetXMin() const { return _box.GetXMin(); };
public: const Unit& GetYMin() const { return _box.GetYMin(); };
public: const Unit& GetXMax() const { return _box.GetXMax(); };
public: const Unit& GetYMax() const { return _box.GetYMax(); };
public: Unit GetHeight() const { return _box.GetHeight(); };
public: Unit GetWidth() const { return _box.GetWidth(); };
public: Point GetCenter() const { return _box.GetCenter(); }
// Updators
// ********
public: virtual void Translate(const Unit& dx, const Unit& dy) {}
// Others
// ******
public: virtual bool _IsInterceptedBy(View* view, const Point& point, const Unit& aperture) const;
public: virtual void _Draw(View* view, BasicLayer* basiclayer, const Box& updatearea, const Transformation& transformation);
public: virtual void _Highlight(View* view, const Box& updatearea, const Transformation& transformation);
public: virtual string _GetTypeName() const {return _TName("Container");};
public: virtual string _GetString() const;
public: virtual Record* _GetRecord() const;
};
}
#endif // __CONTAINER_H

View File

@ -0,0 +1,96 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | M a u k a - P l a c e r |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./GraphicMaukaEngine.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __MAUKA_GRAPHIC_MAUKA_ENGINE__
#define __MAUKA_GRAPHIC_MAUKA_ENGINE__
#include <QObject>
namespace Hurricane {
class Go;
class BasicLayer;
class Transformation;
class CellWidget;
class CellViewer;
}
#include "crlcore/GraphicToolEngine.h"
#include "mauka/MaukaEngine.h"
namespace Mauka {
using Hurricane::Go;
using Hurricane::Box;
using Hurricane::BasicLayer;
using Hurricane::Transformation;
using Hurricane::CellWidget;
using Hurricane::CellViewer;
using CRL::GraphicTool;
// -------------------------------------------------------------------
// Class : "Mauka::GraphicMaukaEngine".
class GraphicMaukaEngine : public GraphicTool {
Q_OBJECT;
public:
MaukaEngine* createEngine ();
MaukaEngine* getForFramework ();
static void initMaukaContainer ( CellWidget* );
static void drawMaukaContainer ( CellWidget*
, const Go*
, const BasicLayer*
, const Box&
, const Transformation&
);
static GraphicMaukaEngine* grab ();
virtual const Name& getName () const;
Cell* getCell ();
virtual size_t release ();
virtual void addToMenu ( CellViewer* );
void postEvent ();
public slots:
void run ();
void save ();
protected:
static size_t _references;
static GraphicMaukaEngine* _singleton;
CellViewer* _viewer;
protected:
GraphicMaukaEngine ();
virtual ~GraphicMaukaEngine ();
};
} // End of Mauka namespace.
#endif // __MAUKA_GRAPHIC_MAUKA_ENGINE__

View File

@ -0,0 +1,152 @@
// 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
#ifndef __MAUKA_H
#define __MAUKA_H
#include "Instance.h"
USING_NAMESPACE_HURRICANE
#include "CEngine.h"
using namespace CRL;
#include "GCell.h"
using namespace NIMBUS;
namespace MAUKA {
class Surface;
class SimAnnealingPlacer;
class BBPlacer;
class Mauka: public CEngine
// ************************
{
//Mauka: a cool, light, Hawaiian wind descending from the montains.
friend class Surface;
friend class SimAnnealingPlacer;
friend class Move;
friend class Bin;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef CEngine Inherit;
public: typedef vector<Occurrence> InstanceOccurrencesVector;
public: typedef map<Occurrence, unsigned> InstanceOccurrencesMap;
public: typedef vector<unsigned> UVector;
public: typedef list<unsigned> UList;
public: typedef vector<UVector> UTable;
public: typedef vector<bool> BVector;
public: typedef vector<Unit> UnitVector;
public: typedef vector<Net*> NetVector;
public: typedef vector<Box> BoxVector;
public: typedef vector<BoxVector> BBoxes;
public: typedef vector<vector<double> > Costs;
public: typedef vector<bool> PrePlaceRow;
public: typedef vector<PrePlaceRow> PrePlaceTab;
public:
class Parameters
{
public: bool standardSimulatedAnnealing;
public: bool ignorePins;
public: bool plotBins; //plot bins utilisation
public: Parameters()
: standardSimulatedAnnealing(false)
, ignorePins(false)
, plotBins(true)
{}
};
// Attributes
// **********
public: Parameters _params;
private: DisplaySlot* _displaySlot;
private: InstanceOccurrencesVector _instanceOccurrencesVector;
private: InstanceOccurrencesMap _instanceOccurrencesMap;
private: UnitVector _instanceWidths;
private: UTable _instanceNets;
private: NetVector _nets;
private: UTable _netInstances;
private: UVector _netInitX;
private: UVector _netInitY;
private: BVector _hasInitX;
private: BVector _hasInitY;
private: Surface* _surface;
private: SimAnnealingPlacer* _simAnnealingPlacer;
private: BBPlacer* _bbPlacer;
// Constructor
// ***********
private: Mauka(Cell* cell);
public: static Mauka* Create(Cell* cell, double searchratio = 0.5, Box placementbox = Box());
// Accessors
// *********
public: virtual const Name& GetName() const;
private: Surface* _GetSurface() const { return _surface; }
public: Unit GetInstanceIdWidth(unsigned id) const { return _instanceWidths[id]; }
public: unsigned GetRandomInstanceId() const;
// Others
// ******
private: void _PostCreate(Box& placementbox, double searchratio);
private: void _PreDelete();
//public: void ReInit();
public: bool Iterate();
public: void Run();
public: void Test();
public: virtual string _GetTypeName() const {return _TName("Mauka");};
public: virtual Record* _GetRecord() const;
public: void Save() const;
public: void PlotBinsStats() const;
public: void Plot() const;
private: Box PlotFixedPointsLabels(ofstream& out) const;
private: void Construct();
public: void Hide();
public: void Show();
};
void SetPlacementStatusRecursivelyToPlaced(Instance* instance);
Mauka* GetMauka (const Cell* cell);
bool TestMaukaConstruction(Cell* cell, GCell* gcell);
}
#endif /* __MAUKA_H */

View File

@ -0,0 +1,50 @@
// 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
#ifndef __MAUKABOX_H
#define __MAUKABOX_H
#include "hurricane/Box.h"
namespace Mauka {
using Hurricane::Box;
using Hurricane::Point;
Box& Update(Box& box, const Point& src, const Point& dst);
}
#endif /* __MAUKABOX_H */

View File

@ -0,0 +1,48 @@
// 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
#ifndef __MAUKABOX_H
#define __MAUKABOX_H
#include "Box.h"
USING_NAMESPACE_HURRICANE
namespace MAUKA {
Box& Update(Box& box, const Point& src, const Point& dst);
}
#endif /* __MAUKABOX_H */

View File

@ -0,0 +1,158 @@
// 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
#ifndef __MAUKA_H
#define __MAUKA_H
#include "hurricane/Instance.h"
#include "crlcore/ToolEngine.h"
#include "nimbus/GCell.h"
#include "mauka/Configuration.h"
namespace Mauka {
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Net;
using Hurricane::Cell;
using Hurricane::Instance;
using Hurricane::Occurrence;
using CRL::ToolEngine;
using Nimbus::GCell;
class Surface;
class SimAnnealingPlacer;
class BBPlacer;
class MaukaEngine: public ToolEngine
// *********************************
{
//Mauka: a cool, light, Hawaiian wind descending from the montains.
friend class Surface;
friend class SimAnnealingPlacer;
friend class Move;
friend class Bin;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef ToolEngine Inherit;
public: typedef std::vector<Occurrence> InstanceOccurrencesVector;
public: typedef std::map<Occurrence, unsigned> InstanceOccurrencesMap;
public: typedef std::vector<unsigned> UVector;
public: typedef std::list<unsigned> UList;
public: typedef std::vector<UVector> UTable;
public: typedef std::vector<bool> BVector;
public: typedef std::vector<DbU::Unit> UnitVector;
public: typedef std::vector<Net*> NetVector;
public: typedef std::vector<Box> BoxVector;
public: typedef std::vector<BoxVector> BBoxes;
public: typedef std::vector< std::vector<double> > Costs;
public: typedef std::vector<bool> PrePlaceRow;
public: typedef std::vector<PrePlaceRow> PrePlaceTab;
// Attributes
// **********
private: static Name _toolName;
private: Configuration* _configuration;
private: InstanceOccurrencesVector _instanceOccurrencesVector;
private: InstanceOccurrencesMap _instanceOccurrencesMap;
private: UnitVector _instanceWidths;
private: UTable _instanceNets;
private: NetVector _nets;
private: UTable _netInstances;
private: UVector _netInitX;
private: UVector _netInitY;
private: BVector _hasInitX;
private: BVector _hasInitY;
private: Surface* _surface;
private: SimAnnealingPlacer* _simAnnealingPlacer;
private: BBPlacer* _bbPlacer;
// Constructor
// ***********
private: MaukaEngine(Cell* cell);
public: static MaukaEngine* create(Cell* cell, Box placementbox = Box());
// Accessors
// *********
public:
static MaukaEngine* get (Cell*);
static const Name& staticGetName ();
virtual const Name& getName () const;
inline Configuration* getConfiguration () const { return _configuration; }
inline bool useStandardSimulatedAnnealing () const { return _configuration->useStandardSimulatedAnnealing(); }
inline bool doIgnorePins () const { return _configuration->doIgnorePins(); }
inline bool doPlotBins () const { return _configuration->doPlotBins(); }
inline double getSearchRatio () const { return _configuration->getSearchRatio(); }
inline double getAnnealingNetMult () const { return _configuration->getAnnealingNetMult(); }
inline double getAnnealingBinMult () const { return _configuration->getAnnealingBinMult(); }
inline double getAnnealingRowMult () const { return _configuration->getAnnealingRowMult(); }
DbU::Unit getInstanceIdWidth (unsigned id) const { return _instanceWidths[id]; }
unsigned getRandomInstanceId () const;
private:
inline Surface* _getSurface () const { return _surface; }
// Others
// ******
private: void _postCreate(Box& placementbox);
private: void _preDestroy();
public: static MaukaEngine* get ( const Cell* );
//public: void ReInit();
public: bool Iterate();
public: void Run();
public: void Test();
public: virtual std::string _getTypeName() const {return "MaukaEngine";};
public: virtual Record* _getRecord() const;
public: void Save() const;
public: void PlotBinsStats() const;
public: void Plot() const;
private: Box PlotFixedPointsLabels(std::ofstream& out) const;
private: void Construct();
};
void setPlacementStatusRecursivelyToPlaced(Instance* instance);
bool TestMaukaConstruction(Cell* cell, GCell* gcell);
} // Enf of Mauka namespace.
#endif /* __MAUKA_H */

View File

@ -0,0 +1,152 @@
// 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
#ifndef __MAUKA_H
#define __MAUKA_H
#include "Instance.h"
USING_NAMESPACE_HURRICANE
#include "ToolEngine.h"
using namespace CRL;
#include "GCell.h"
using namespace NIMBUS;
namespace MAUKA {
class Surface;
class SimAnnealingPlacer;
class BBPlacer;
class Mauka: public ToolEngine
// ************************
{
//Mauka: a cool, light, Hawaiian wind descending from the montains.
friend class Surface;
friend class SimAnnealingPlacer;
friend class Move;
friend class Bin;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef ToolEngine Inherit;
public: typedef vector<Occurrence> InstanceOccurrencesVector;
public: typedef map<Occurrence, unsigned> InstanceOccurrencesMap;
public: typedef vector<unsigned> UVector;
public: typedef list<unsigned> UList;
public: typedef vector<UVector> UTable;
public: typedef vector<bool> BVector;
public: typedef vector<DbU::Unit> DbU::UnitVector;
public: typedef vector<Net*> NetVector;
public: typedef vector<Box> BoxVector;
public: typedef vector<BoxVector> BBoxes;
public: typedef vector<vector<double> > Costs;
public: typedef vector<bool> PrePlaceRow;
public: typedef vector<PrePlaceRow> PrePlaceTab;
public:
class Parameters
{
public: bool standardSimulatedAnnealing;
public: bool ignorePins;
public: bool plotBins; //plot bins utilisation
public: Parameters()
: standardSimulatedAnnealing(false)
, ignorePins(false)
, plotBins(true)
{}
};
// Attributes
// **********
public: Parameters _params;
private: DisplaySlot* _displaySlot;
private: InstanceOccurrencesVector _instanceOccurrencesVector;
private: InstanceOccurrencesMap _instanceOccurrencesMap;
private: DbU::UnitVector _instanceWidths;
private: UTable _instanceNets;
private: NetVector _nets;
private: UTable _netInstances;
private: UVector _netInitX;
private: UVector _netInitY;
private: BVector _hasInitX;
private: BVector _hasInitY;
private: Surface* _surface;
private: SimAnnealingPlacer* _simAnnealingPlacer;
private: BBPlacer* _bbPlacer;
// Constructor
// ***********
private: Mauka(Cell* cell);
public: static Mauka* create(Cell* cell, double searchratio = 0.5, Box placementbox = Box());
// Accessors
// *********
public: virtual const Name& getName() const;
private: Surface* _getSurface() const { return _surface; }
public: DbU::Unit getInstanceIdWidth(unsigned id) const { return _instanceWidths[id]; }
public: unsigned getRandomInstanceId() const;
// Others
// ******
private: void _postCreate(Box& placementbox, double searchratio);
private: void _preDestroy();
//public: void ReInit();
public: bool Iterate();
public: void Run();
public: void Test();
public: virtual string _getTypeName() const {return _TName("Mauka");};
public: virtual Record* _getRecord() const;
public: void Save() const;
public: void PlotBinsStats() const;
public: void Plot() const;
private: Box PlotFixedPointsLabels(ofstream& out) const;
private: void Construct();
public: void hide();
public: void show();
};
void setPlacementStatusRecursivelyToPlaced(Instance* instance);
Mauka* getMauka (const Cell* cell);
bool TestMaukaConstruction(Cell* cell, GCell* gcell);
}
#endif /* __MAUKA_H */

104
mauka/src/mauka/Move.h Normal file
View File

@ -0,0 +1,104 @@
// 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
#ifndef __MOVE_H
#define __MOVE_H
#include <map>
#include "hurricane/Instance.h"
#include "hurricane/Net.h"
// ****************************************************************************************************
// Move declaration
// ****************************************************************************************************
namespace Mauka {
using Hurricane::DbU;
class Bin;
class Row;
class SubRow;
class Move {
// *********
// Types
// *****
public: typedef std::map<unsigned, unsigned> AffectedNets;
// Attributes
// **********
private: SimAnnealingPlacer* _simAnnealingPlacer;
private: MaukaEngine* _mauka;
private: Surface* _surface;
private: bool _exchange;
private: unsigned _srcIns;
private: Bin* _srcBin;
private: double _srcBinInitCost;
private: SubRow* _srcSubRow;
private: Row* _srcRow;
private: double _srcRowInitCost;
private: DbU::Unit _srcWidth;
private: Bin* _dstBin;
private: double _dstBinInitCost;
private: SubRow* _dstSubRow;
private: Row* _dstRow;
private: double _dstRowInitCost;
private: unsigned _dstIns;
private: DbU::Unit _dstWidth;
private: AffectedNets _affectedNets;
// Constructors
// ************
public: Move(SimAnnealingPlacer* simannealingplacer);
// Accessors
// *********
public: double getDeltaRowCost() const;
public: double getDeltaBinCost() const;
public: double getDeltaNetCost();
// Others
// ******
public: bool Next(const double dist);
public: void accept();
public: void Reject();
public: void TryMove();
};
}
#endif /* __MOVE_H */

View File

@ -0,0 +1,104 @@
// 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
#ifndef __MOVE_H
#define __MOVE_H
#include <map>
using namespace std;
#include "Instance.h"
#include "Net.h"
USING_NAMESPACE_HURRICANE
// ****************************************************************************************************
// Move declaration
// ****************************************************************************************************
namespace MAUKA {
class Bin;
class Row;
class SubRow;
class Move {
// *********
// Types
// *****
public: typedef map<unsigned, unsigned> AffectedNets;
// Attributes
// **********
private: SimAnnealingPlacer* _simAnnealingPlacer;
private: Mauka* _mauka;
private: Surface* _surface;
private: bool _exchange;
private: unsigned _srcIns;
private: Bin* _srcBin;
private: double _srcBinInitCost;
private: SubRow* _srcSubRow;
private: Row* _srcRow;
private: double _srcRowInitCost;
private: Unit _srcWidth;
private: Bin* _dstBin;
private: double _dstBinInitCost;
private: SubRow* _dstSubRow;
private: Row* _dstRow;
private: double _dstRowInitCost;
private: unsigned _dstIns;
private: Unit _dstWidth;
private: AffectedNets _affectedNets;
// Constructors
// ************
public: Move(SimAnnealingPlacer* simannealingplacer);
// Accessors
// *********
public: double GetDeltaRowCost() const;
public: double GetDeltaBinCost() const;
public: double GetDeltaNetCost();
// Others
// ******
public: bool Next(const double dist);
public: void Accept();
public: void Reject();
public: void TryMove();
};
}
#endif /* __MOVE_H */

109
mauka/src/mauka/Row.h Normal file
View File

@ -0,0 +1,109 @@
// 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
#ifndef __ROW_H
#define __ROW_H
#include "mauka/Container.h"
#include "mauka/SubRow.h"
namespace Mauka {
using Hurricane::DbU;
using Hurricane::Box;
class Surface;
// ****************************************************************************************************
// Row declaration
// ****************************************************************************************************
class Row : public Container {
// *************************
friend class Surface;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef Container Inherit;
public: typedef std::vector<SubRow*> SubRowVector;
public: typedef std::map< DbU::Unit, unsigned, std::less<DbU::Unit> > SubRowXMax;
public: typedef std::map< DbU::Unit, unsigned, std::greater<DbU::Unit> > SubRowXMinInv;
// Attributes
// **********
private: Surface* _surface;
private: SubRowVector _subRowVector;
private: SubRowXMax _subRowXMax;
private: SubRowXMinInv _subRowXMinInv;
private: bool _orientation;
private: DbU::Unit _size; // sum of the subrows size
private: DbU::Unit _capa;
// Constructors
// ************
protected: Row(Cell* cell, Surface* surface, const Box& box, bool orientation);
public: static Row* create(Cell* cell, Surface* surface, const Box& box, bool orientation);
// Accessors
// *********
public: SubRow* getSubRowBetween(DbU::Unit x1, DbU::Unit x2);
public: double getCost() const;
public: bool getOrientation() const { return _orientation; }
public: DbU::Unit getSubRowsWidth() const;
public: DbU::Unit getSubRowsCapa() const;
public: double getBinCost() const;
public: DbU::Unit getBinsSize() const;
public: DbU::Unit getBinsCapa() const;
// Updators
// ********
private: void _computeCapacity(double margin);
private: void _AddSize(DbU::Unit value);
// Others
// ******
public: virtual Cell* getCell() const;
protected: virtual void _preDestroy();
private: void _InsertSubRow(SubRow* subrow);
private: void _computeSubRows();
public: virtual std::string _getTypeName() const {return "Row";};
public: void DisplayBinHits() const;
};
}
#endif // __ROW_H

View File

@ -0,0 +1,106 @@
// 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
#ifndef __ROW_H
#define __ROW_H
#include "Container.h"
#include "SubRow.h"
namespace MAUKA {
class Surface;
// ****************************************************************************************************
// Row declaration
// ****************************************************************************************************
class Row : public Container {
// *************************
friend class Surface;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef Container Inherit;
public: typedef vector<SubRow*> SubRowVector;
public: typedef map<Unit, unsigned, less<Unit> > SubRowXMax;
public: typedef map<Unit, unsigned, greater<Unit> > SubRowXMinInv;
// Attributes
// **********
private: Surface* _surface;
private: SubRowVector _subRowVector;
private: SubRowXMax _subRowXMax;
private: SubRowXMinInv _subRowXMinInv;
private: bool _orientation;
private: Unit _size; // sum of the subrows size
private: Unit _capa;
// Constructors
// ************
protected: Row(Cell* cell, Surface* surface, const Box& box, bool orientation);
public: static Row* Create(Cell* cell, Surface* surface, const Box& box, bool orientation);
// Accessors
// *********
public: SubRow* GetSubRowBetween(Unit x1, Unit x2);
public: double GetCost() const;
public: bool GetOrientation() const { return _orientation; }
public: Unit GetSubRowsWidth() const;
public: Unit GetSubRowsCapa() const;
public: double GetBinCost() const;
public: Unit GetBinsSize() const;
public: Unit GetBinsCapa() const;
// Updators
// ********
private: void _ComputeCapacity(double margin);
private: void _AddSize(Unit value);
// Others
// ******
public: virtual Cell* GetCell() const;
protected: virtual void _PreDelete();
private: void _InsertSubRow(SubRow* subrow);
private: void _ComputeSubRows();
public: virtual string _GetTypeName() const {return _TName("Row");};
public: void DisplayBinHits() const;
};
}
#endif // __ROW_H

View File

@ -0,0 +1,122 @@
// 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
#ifndef __SIMANNEALINGPLACER_H
#define __SIMANNEALINGPLACER_H
#include "hurricane/Instance.h"
#include "crlcore/Utilities.h"
#include "mauka/MaukaEngine.h"
namespace Mauka {
class MaukaEngine;
class Bin;
class SimAnnealingPlacer {
// ***********************
friend class MaukaEngine;
friend class Move;
friend class Bin;
friend class SubRow;
// Types
// *****
public: typedef std::vector<Bin*> InstanceBins;
// Attributes
// **********
private: MaukaEngine* _mauka;
private: InstanceBins _instanceBins;
private: MaukaEngine::BBoxes _netBBoxes;
private: MaukaEngine::Costs _netCosts;
private: MaukaEngine::UVector _netFlags;
private: double _netCost;
private: double _binCost;
private: double _rowCost;
private: double _initNetCost;
private: double _initBinCost;
private: double _initRowCost;
private: double _netMult;
private: double _binMult;
private: double _rowMult;
private: double _temperature;
private: double _distance;
private: unsigned _loop;
private: unsigned _iterationsFactor;
private: unsigned _iterations;
private: unsigned _moves;
private: unsigned _sourceEqualTargetMovementNumber;
private: unsigned _surOccupationTargetMovementNumber;
private: unsigned _impossibleExchangeMovementNumber;
// Constructor
// ***********
public: SimAnnealingPlacer(MaukaEngine* mauka);
// Accessors
// *********
public: double getNetCost();
public: double getCost() const;
public: double& _getNetIdCost(unsigned netid) { return _netCosts[netid][_netFlags[netid]]; }
public: double& _getNetIdTmpCost(unsigned netid) { return _netCosts[netid][!_netFlags[netid]]; }
public: Box& _getNetIdBBox(unsigned netid) { return _netBBoxes[netid][_netFlags[netid]]; }
public: Box& _getNetTmpBBox(unsigned netid) { return _netBBoxes[netid][!_netFlags[netid]]; }
public: MaukaEngine* getMauka() { return _mauka; }
public: unsigned getMoves() const { return _moves; }
public: unsigned getRandInstance();
// Others
// ******
public: bool Iterate();
private: bool accept(double deltacost) const;
public: double DebugNetCost();
public: void DisplayResults() const;
public: void _setInstanceIdBin(unsigned instanceid, Bin* bin) { _instanceBins[instanceid] = bin; }
public: void _InvertNetIdFlag(unsigned netid) { _netFlags[netid] = !_netFlags[netid]; }
public: double computeCost(double rowcost, double bincost, double netcost) const;
public: void incrImpossibleExchangeMovementNumber() { ++_impossibleExchangeMovementNumber; }
public: void incrSourceEqualTargetMovementNumber() { ++_sourceEqualTargetMovementNumber; }
public: void incrSurOccupationTargetMovementNumber() { ++_surOccupationTargetMovementNumber; }
public: void init();
public: void Save() const;
private: void Plot(std::ofstream& out) const;
};
}
#endif /* __SIMANNEALINGPLACER_H */

View File

@ -0,0 +1,126 @@
// 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
#ifndef __SIMANNEALINGPLACER_H
#define __SIMANNEALINGPLACER_H
#include "Instance.h"
USING_NAMESPACE_HURRICANE
#include "CVerbosity.h"
using namespace CRL;
#include "Mauka.h"
namespace MAUKA {
class Mauka;
class Bin;
class SimAnnealingPlacer {
// ***********************
friend class Mauka;
friend class Move;
friend class Bin;
friend class SubRow;
// Types
// *****
public: typedef vector<Bin*> InstanceBins;
// Attributes
// **********
private: Mauka* _mauka;
private: InstanceBins _instanceBins;
private: Mauka::BBoxes _netBBoxes;
private: Mauka::Costs _netCosts;
private: Mauka::UVector _netFlags;
private: double _netCost;
private: double _binCost;
private: double _rowCost;
private: double _initNetCost;
private: double _initBinCost;
private: double _initRowCost;
private: double _netMult;
private: double _binMult;
private: double _rowMult;
private: double _temperature;
private: double _distance;
private: unsigned _loop;
private: unsigned _iterationsFactor;
private: unsigned _iterations;
private: unsigned _moves;
private: unsigned _sourceEqualTargetMovementNumber;
private: unsigned _surOccupationTargetMovementNumber;
private: unsigned _impossibleExchangeMovementNumber;
// Constructor
// ***********
public: SimAnnealingPlacer(Mauka* mauka, double netmult = 0.8, double binmult = 0.1, double rowmult = 0.1);
// Accessors
// *********
public: double GetNetCost();
public: double GetCost() const;
public: double& _GetNetIdCost(unsigned netid) { return _netCosts[netid][_netFlags[netid]]; }
public: double& _GetNetIdTmpCost(unsigned netid) { return _netCosts[netid][!_netFlags[netid]]; }
public: Box& _GetNetIdBBox(unsigned netid) { return _netBBoxes[netid][_netFlags[netid]]; }
public: Box& _GetNetTmpBBox(unsigned netid) { return _netBBoxes[netid][!_netFlags[netid]]; }
public: Mauka* GetMauka() { return _mauka; }
public: unsigned GetMoves() const { return _moves; }
public: unsigned GetRandInstance();
// Others
// ******
public: bool Iterate();
private: bool Accept(double deltacost) const;
public: double DebugNetCost();
public: void DisplayResults() const;
public: void _SetInstanceIdBin(unsigned instanceid, Bin* bin) { _instanceBins[instanceid] = bin; }
public: void _InvertNetIdFlag(unsigned netid) { _netFlags[netid] = !_netFlags[netid]; }
public: double ComputeCost(double rowcost, double bincost, double netcost) const;
public: void IncrImpossibleExchangeMovementNumber() { ++_impossibleExchangeMovementNumber; }
public: void IncrSourceEqualTargetMovementNumber() { ++_sourceEqualTargetMovementNumber; }
public: void IncrSurOccupationTargetMovementNumber() { ++_surOccupationTargetMovementNumber; }
public: void Init();
public: void Save() const;
private: void Plot(ofstream& out) const;
};
}
#endif /* __SIMANNEALINGPLACER_H */

114
mauka/src/mauka/SubRow.h Normal file
View File

@ -0,0 +1,114 @@
// 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
#ifndef __SUBROW_H
#define __SUBROW_H
#include "mauka/Container.h"
#include "mauka/Bin.h"
namespace Mauka {
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Cell;
using Hurricane::Instance;
class Surface;
class Row;
// ****************************************************************************************************
// SubRow declaration
// ****************************************************************************************************
class SubRow : public Container {
// *************************
friend class Surface;
friend class Bin;
friend class Row;
friend class BBPlacer;
// Types
// *****
public: typedef Container Inherit;
public: typedef std::vector<Bin*> BinVector;
public: typedef std::map<double, unsigned> BinXMax;
public: typedef std::vector<Instance*> InstanceVector; // for bbplacer
// Attributes
// **********
private: Surface* _surface;
private: Row* _row;
private: BinVector _binVector;
private: BinXMax _binXMax;
private: DbU::Unit _size; // sum of the bins size
private: DbU::Unit _capa; // ideal occupation of the subrow
// Constructors
// ************
protected: SubRow(Cell* cell, Surface* surface, const Box& box);
public: static SubRow* create(Cell* cell, Surface* surface, const Box& box, bool orientation);
// Accessors
// *********
public: virtual Cell* getCell() const;
public: Row* getRow() { return _row; }
public: Surface* getSurface() { return _surface; }
public: DbU::Unit getCapa() const { return _capa; }
public: DbU::Unit getSize() const { return _size; }
public: DbU::Unit getCapaVsSize() const { return (_capa - _size);}
public: DbU::Unit getWidthVsSize() const { return (getWidth() - _size);}
public: Bin* getBinBetween(DbU::Unit lowerX, DbU::Unit upperX, const Bin* srcbin);
// Updators
// ********
private: void _AddSize(DbU::Unit value);
// Others
// ******
private: void _computeCapacity(double margin);
private: bool _MergeBins();
public: void DisplayBinHits() const;
protected: virtual void _postCreate(bool orientation);
protected: virtual void _preDestroy();
public: double getBinCost() const;
public: DbU::Unit getBinsSize() const;
public: DbU::Unit getBinsCapa() const;
public: double getCost() const;
public: virtual std::string _getTypeName() const {return "SubRow";};
};
}
#endif // __SUBROW_H

View File

@ -0,0 +1,109 @@
// 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
#ifndef __SUBROW_H
#define __SUBROW_H
#include "Container.h"
#include "Bin.h"
namespace MAUKA {
class Surface;
class Row;
// ****************************************************************************************************
// SubRow declaration
// ****************************************************************************************************
class SubRow : public Container {
// *************************
friend class Surface;
friend class Bin;
friend class Row;
friend class BBPlacer;
// Types
// *****
public: typedef Container Inherit;
public: typedef vector<Bin*> BinVector;
public: typedef map <double, unsigned> BinXMax;
public: typedef vector<Instance*> InstanceVector; // for bbplacer
// Attributes
// **********
private: Surface* _surface;
private: Row* _row;
private: BinVector _binVector;
private: BinXMax _binXMax;
private: Unit _size; // sum of the bins size
private: Unit _capa; // ideal occupation of the subrow
// Constructors
// ************
protected: SubRow(const Cell* cell, Surface* surface, const Box& box);
public: static SubRow* Create(const Cell* cell, Surface* surface, const Box& box, bool orientation);
// Accessors
// *********
public: virtual Cell* GetCell() const;
public: Row* GetRow() { return _row; }
public: Surface* GetSurface() { return _surface; }
public: Unit GetCapa() const { return _capa; }
public: Unit GetSize() const { return _size; }
public: Unit GetCapaVsSize() const { return (_capa - _size);}
public: Unit GetWidthVsSize() const { return (GetWidth() - _size);}
public: Bin* GetBinBetween(Unit lowerX, Unit upperX, const Bin* srcbin);
// Updators
// ********
private: void _AddSize(Unit value);
// Others
// ******
private: void _ComputeCapacity(double margin);
private: bool _MergeBins();
public: void DisplayBinHits() const;
protected: virtual void _PostCreate(bool orientation);
protected: virtual void _PreDelete();
public: double GetBinCost() const;
public: Unit GetBinsSize() const;
public: Unit GetBinsCapa() const;
public: double GetCost() const;
public: virtual string _GetTypeName() const {return _TName("SubRow");};
};
}
#endif // __SUBROW_H

121
mauka/src/mauka/Surface.h Normal file
View File

@ -0,0 +1,121 @@
// 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
#ifndef __SURFACE_H
#define __SURFACE_H
#include "mauka/Container.h"
#include "mauka/MaukaEngine.h"
namespace Mauka {
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Cell;
class Bin;
class Row;
class SubRow;
class MaukaEngine;
class Surface: public Container {
// ****************************
friend class MaukaEngine;
friend class SimAnnealingPlacer;
friend class Row;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef Container Inherit;
public: typedef std::vector<Row*> RowVector;
public: typedef std::list<SubRow*> SubRowList;
public: typedef std::map<DbU::Unit, unsigned, std::less<DbU::Unit> > RowYMax;
public: typedef std::map<DbU::Unit, unsigned, std::greater<DbU::Unit> > RowYMinInv;
//public: typedef map<DbU::Unit, Row*> RowMap;
// Attributes
// **********
private: MaukaEngine* _mauka;
//private: RowMap _rowMap;
private: RowVector _rowVector;
private: RowYMax _rowYMax;
private: RowYMinInv _rowYMinInv;
private: bool _rowZeroOrientation;
private: double _margin;
private: DbU::Unit _binWidthMax;
private: DbU::Unit _binWidthMin;
private: DbU::Unit _searchWidth;
private: DbU::Unit _searchHeight;
// Constructors
// ************
protected: Surface(MaukaEngine* mauka, const Box& placementbox);
public: static Surface* create(MaukaEngine* mauka, const Box& placementbox);
// Accessors
// *********
public: virtual Cell* getCell() const { return _mauka->getCell(); }
public: Bin* getBinInSurface(Bin* srcbin, double dist);
public: double getBinCost() const;
public: double getRowCost() const;
public: DbU::Unit getBinsSize() const;
public: DbU::Unit getBinsCapa() const;
public: DbU::Unit getSubRowsCapa() const;
public: double getMargin() const { return _margin; };
public: MaukaEngine* getMauka() { return _mauka; };
// Others
// ******
public: void DisplayBinHits() const;
protected: virtual void _preDestroy();
private: void InsertRow(Row* row);
private: void removeRow(Row* row);
private: Row* InsertSubRow(SubRow* subrow, bool orientation);
private: void removeSubRow(SubRow* subrow);
private: void PlotBinsStats(std::ofstream& out) const;
private: void Plot(std::ofstream& out) const;
public: virtual std::string _getTypeName() const {return "Surface";};
public: virtual Record* _getRecord() const;
private: Row* InsertSubRowInRow(SubRow* subrow, bool orientation);
private: void _computeRowsAndSubRows();
private: void _DisplayInstances(MaukaEngine::UVector& instanceids, SubRowList& subrowlist);
private: void _computeCapacity();
private: void _postCreate();
};
}
#endif /* __SURFACE_H */

View File

@ -0,0 +1,118 @@
// 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
#ifndef __SURFACE_H
#define __SURFACE_H
#include "Container.h"
#include "Mauka.h"
namespace MAUKA{
class Bin;
class Row;
class SubRow;
class Mauka;
class Surface: public Container {
// ****************************
friend class Mauka;
friend class SimAnnealingPlacer;
friend class Row;
friend class SubRow;
friend class BBPlacer;
// Types
// *****
public: typedef Container Inherit;
public: typedef vector<Row*> RowVector;
public: typedef list<SubRow*> SubRowList;
public: typedef map<Unit, unsigned, less<Unit> > RowYMax;
public: typedef map<Unit, unsigned, greater<Unit> > RowYMinInv;
//public: typedef map<Unit, Row*> RowMap;
// Attributes
// **********
private: Mauka* _mauka;
//private: RowMap _rowMap;
private: RowVector _rowVector;
private: RowYMax _rowYMax;
private: RowYMinInv _rowYMinInv;
private: bool _rowZeroOrientation;
private: double _margin;
private: Unit _binWidthMax;
private: Unit _binWidthMin;
private: double _searchRatio;
private: Unit _searchWidth;
private: Unit _searchHeight;
// Constructors
// ************
protected: Surface(Mauka* mauka, const Box& placementbox, double searchratio);
public: static Surface* Create(Mauka* mauka, const Box& placementbox, double searchratio);
// Accessors
// *********
public: virtual Cell* GetCell() const { return _mauka->GetCell(); }
public: Bin* GetBinInSurface(Bin* srcbin, double dist);
public: double GetBinCost() const;
public: double GetRowCost() const;
public: Unit GetBinsSize() const;
public: Unit GetBinsCapa() const;
public: Unit GetSubRowsCapa() const;
public: double GetMargin() const { return _margin; };
public: Mauka* GetMauka() { return _mauka; };
// Others
// ******
public: void DisplayBinHits() const;
protected: virtual void _PreDelete();
private: void InsertRow(Row* row);
private: void RemoveRow(Row* row);
private: Row* InsertSubRow(SubRow* subrow, bool orientation);
private: void RemoveSubRow(SubRow* subrow);
private: void PlotBinsStats(ofstream& out) const;
private: void Plot(ofstream& out) const;
public: virtual string _GetTypeName() const {return _TName("Surface");};
public: virtual Record* _GetRecord() const;
private: Row* InsertSubRowInRow(SubRow* subrow, bool orientation);
private: void _ComputeRowsAndSubRows();
private: void _DisplayInstances(Mauka::UVector& instanceids, SubRowList& subrowlist);
private: void _ComputeCapacity();
private: void _PostCreate();
};
}
#endif /* __SURFACE_H */