* ./mauka:
- New: Initial port from Coriolis 1. Needs to re-introduce Nimbus :-(. Modificated to provide Configuration & standard ConfigurationWidget.
This commit is contained in:
parent
ab78dd054b
commit
a9808704a0
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
install ( FILES FindMAUKA.cmake DESTINATION share/cmake/Modules )
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 )
|
|
@ -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.
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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__
|
|
@ -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__
|
|
@ -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
|
|
@ -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
|
|
@ -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__
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
Loading…
Reference in New Issue