ocp is back ....

This commit is contained in:
Christophe Alexandre 2002-03-13 18:57:22 +00:00
parent a79fd9b05c
commit 4f28ec1138
50 changed files with 5501 additions and 0 deletions

View File

@ -0,0 +1,3 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = doc src

View File

@ -0,0 +1,30 @@
AC_DEFUN(ALC_CXX_PROBLEMATIC_OLD_VERSION,
[
AC_REQUIRE([AC_PROG_CXX])
AC_MSG_CHECKING(if this is a problematic old ${CXX} version)
AC_CACHE_VAL(alc_cv_cxx_problematic_version,
[
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_CPP([
#ifdef __GNUC__
#if __GNUC__ < 2
#error ALC works best with GCC version 2.95.2 or higher
#endif /* __GNUC__ < 2 */
#ifdef __GNUC_MINOR__
#if __GNUC__ == 2 && __GNUC_MINOR__ < 95
#error ALC works only with GCC version 2.95.2 or higher
#endif /* __GNUC_MINOR__ < 95.2 */
#endif /* defined(__GNUC_MINOR__) */
#endif /* defined(__GNUC__) */
],
alc_cv_cxx_problematic_version=no, alc_cv_cxx_problematic_version=yes)
AC_LANG_RESTORE
])
AC_MSG_RESULT($alc_cv_cxx_problematic_version)
if test "$alc_cv_cxx_problematic_version" = yes; then
AC_MSG_ERROR(*** This package works only with ${CXX} version 2.95.2 or higher ... please install gcc 2.95.2 or higher or set the environment variable CC and CXX to the good gcc before running the configure script ***)
fi
])dnl
dnl
dnl

View File

@ -0,0 +1,62 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/placer/PIns.cpp)
OCP_MAJOR_VERSION=1
OCP_MINOR_VERSION=0
OCP_VERSION=$OCP_MAJOR_VERSION.$OCP_MINOR_VERSION
AC_SUBST(OCP_MAJOR_VERSION)
AC_SUBST(OCP_MINOR_VERSION)
AC_SUBST(OCP_VERSION)
# libtool versioning
LT_RELEASE=$OCP_MAJOR_VERSION.$OCP_MINOR_VERSION
AC_SUBST(LT_RELEASE)
# For automake.
VERSION=$OCP_VERSION
PACKAGE=ocp
dnl Initialize automake stuff
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
dnl Specify a configuration file
dnl AM_CONFIG_HEADER(config.h)
dnl Initialize libtool
AM_PROG_LIBTOOL
dnl Checks for programs.
AC_PROG_CXX
ALC_CXX_PROBLEMATIC_OLD_VERSION
AM_PROG_LEX
AC_PROG_YACC
AC_PROG_MAKE_SET
changequote(,)dnl
INCLUDES=-I${ALLIANCE_TOP}/include
LDFLAGS=-L${ALLIANCE_TOP}/lib
changequote([,])dnl
AC_SUBST(INCLUDES)
AC_SUBST(LDFLAGS)
dnl Checks for libraries.
dnl Check for -lm librarie. These should always be present.
AC_CHECK_LIB(m, exp, LIBM="-lm")
AC_SUBST(LIBM)
dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
dnl Checks for library functions.
AC_OUTPUT([
Makefile
doc/Makefile
src/Makefile
src/common/Makefile
src/placer/Makefile
])

View File

@ -0,0 +1,4 @@
## Process this file with automake to produce Makefile.in
man_MANS = ocp.1
EXTRA_DIST = $(man_MANS)

View File

@ -0,0 +1,95 @@
.\" $Id: ocp.1,v 1.1 2002/03/13 18:57:11 xtof Exp $
.\" @(#)Labo.l 0.0 92/09/24 UPMC; Author: Christophe ALEXANDRE
.pl -.4
.TH OCP 1 "September 27, 2001" "ASIM/LIP6" "CAO\-VLSI Reference Manual"
.SH NAME
.TP
ocp
- Standard Cell Placer
.so man1/alc_origin.1
.SH SYNOPSIS
.TP
\fBocp\fP
[\fBoptions\fP] \fInetlist\fP \fIoutputname\fP
.br
.SH DESCRIPTION
\fBocp\fP is an automatic place tool for standard-cells.
.br
\fBinput net-list\fP
.br
The \fInetlist\fP file describes the input net-list.
.br
\fBocp\fP supports a hierarchical net-list. In this case the net-list is flattened by the placer according to the catalog file. The net-list format can be : structural VHDL, EDIF, or ALLIANCE internal format according to the environment variable \fBMBK_IN_LO\fP.
.br
\fBoutput layout\fP
.br
The file containing the placed block will have the name \fIoutputname\fP. This name is not optionnal and must always be present. The output format is defined by the environment variable \fBMBK_OUT_PH\fP.
.br
.SH OPTIONS
.br
\fBOptional cells placement file\fP
.br
\fB-partial <NAME>\fP
.br
A user defined placement can be specified, thanks to a placement file.
.br
The optional placement file must be given by the user. It must have an extension that denotes the format defined by the environment variable \fBMBK_IN_PH\fP.
.br
\fBOptional connectors placement\fP
.br
The placement of connectors can be also specified.
.br
There are three ways to place connectors in a physical view :
.br
.br
\fB-c\fP option will automatically place the connectors randomly. The auto placement will set connectors on each side of the abutment box.
.br
\fB-ring\fP option will automatically place the connectors randomly but only on the north and south side. This option is temporary and is provided for the ring pad placement tool.
.br
\fB-ioc <NAME>\fP option will place connectors as specified by the <NAME>.ioc given file.
.br
\fBMargin\fP
.br
It is possible to force the free area of the physical view.
.br
The \fB-margin <MARGIN>\fP option allow to set The amount of free area added in percentage of the cells area.
.br
The resulting area will be equal to CELL_AREA * (1 + <MARGIN>).
.br
By default, the margin value is 0.2 (20%)
.br
\fBNumber of rows\fP
.br
\fB-rows <NR>\fP option forces the design to be placed in <NR> rows.
.br
The abutment box's width is automatically generated.
.br
This option won't be used if a defined placement file is given.
.br
\fBVerbose mode\fP
.br
\fB-v\fP set the verbose mode on
.br
\fBGnuplot\fP
.br
\fB-gnuplot\fP option allow to generate automatically gnuplot files, for editing statistics
.br
.SH ENVIRONMENT VARIABLES
.PP
\fBocp\fP uses the environment variables MBK_VDD and MBK_VSS to know
the name of the power signals vdd and vss.
.br
.SH SEE ALSO
.PP
ocr(1), MBK_IN_LO(1), MBK_IN_PH(1), MBK_OUT_PH(1), MBK_VDD(1), MBK_VSS(1)
.so man1/alc_bug_report.1

View File

@ -0,0 +1,3 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = common placer

View File

@ -0,0 +1,9 @@
## Process this file with automake to produce Makefile.in
INCLUDES = @INCLUDES@ -I$(top_srcdir)/src/common
noinst_LIBRARIES = libPCommon.a
libPCommon_a_SOURCES = PBBox.cpp PBBox.h PCommon.cpp \
PCommon.h PConstants.h PContainer.h \
PPos.cpp PPos.h

View File

@ -0,0 +1,125 @@
#include "PBBox.h"
PBBox&
PBBox::operator=(const PBBox& bbox)
{
Min = bbox.Min;
Max = bbox.Max;
return *this;
}
bool
PBBox::operator==(const PBBox& bbox) const
{
return (Min == bbox.Min) && (Max == bbox.Max);
}
bool
PBBox::operator!=(const PBBox& bbox) const
{
return (Min != bbox.Min) || (Max != bbox.Max);
}
PBBox&
PBBox::Merge(const PBBox& bbox)
{
if (bbox.Min.GetX() < Min.GetX()) Min.SetX(bbox.Min.GetX());
if (bbox.Max.GetX() > Max.GetX()) Max.SetX(bbox.Max.GetX());
if (bbox.Min.GetY() < Min.GetY()) Min.SetY(bbox.Min.GetY());
if (bbox.Max.GetY() > Max.GetY()) Max.SetY(bbox.Max.GetY());
return *this;
}
PBBox&
PBBox::Update(const PPos& src, const PPos& dst)
{
if (dst.GetX() > src.GetX()) {
if (src.GetX() == Min.GetX()) {
Clear();
return *this;
} else if (dst.GetX() > Max.GetX()) {
Max.SetX(dst.GetX());
}
} else if (dst.GetX() < src.GetX()) {
if (src.GetX() == Max.GetX()) {
Clear();
return *this;
} else if (dst.GetX() < Min.GetX()) {
Min.SetX(dst.GetX());
}
}
if (dst.GetY() > src.GetY()) {
if (src.GetY() == Min.GetY()) {
Clear();
return *this;
} else if (dst.GetY() > Max.GetY()) {
Max.SetY(dst.GetY());
}
} else if (dst.GetY() < src.GetY()) {
if (src.GetY() == Max.GetY()) {
Clear();
return *this;
} else if (dst.GetY() < Min.GetY()) {
Min.SetY(dst.GetY());
}
}
return *this;
}
PBBox&
PBBox::Update(const PBBox& src, const PBBox& dst)
{
if (dst.GetMinX() < src.GetMinX()) {
if (dst.GetMinX() < Min.GetX()) {
Min.SetX(dst.GetMinX());
}
} else if (dst.GetMinX() > src.GetMinX()) {
if (src.GetMinX() == Min.GetX()) {
Clear();
return *this;
}
}
if (dst.GetMinY() < src.GetMinY()) {
if (dst.GetMinY() < Min.GetY()) {
Min.SetY(dst.GetMinY());
}
} else if (dst.GetMinY() > src.GetMinY()) {
if (src.GetMinY() == Min.GetY()) {
Clear();
return *this;
}
}
if (dst.GetMaxX() > src.GetMaxX()) {
if (dst.GetMaxX() > Max.GetX()) {
Max.SetX(dst.GetMaxX());
}
} else if (dst.GetMaxX() < src.GetMaxX()) {
if (src.GetMaxX() == Max.GetX()) {
Clear();
return *this;
}
}
if (dst.GetMaxY() > src.GetMaxY()) {
if (dst.GetMaxY() > Max.GetY()) {
Max.SetY(dst.GetMaxY());
}
} else if (dst.GetMaxY() < src.GetMaxY()) {
if (src.GetMaxY() == Max.GetY()) {
Clear();
return *this;
}
}
return *this;
}
ostream&
PBBox::Print(ostream& os) const
{
return os << '(' << Min << ", " << Max << ')';
}

View File

@ -0,0 +1,82 @@
#ifndef __PBBox_h
#define __PBBox_h
#include <iostream>
#include <PPos.h>
using namespace std;
class PBBox {
protected:
PPos Min;
PPos Max;
public:
PBBox() : Min(PPos::Max), Max(PPos::Min) { }
PBBox(const PPos& min, const PPos& max) : Min(min), Max(max) { }
PBBox(const PBBox& box) : Min(box.Min), Max(box.Max) { }
PBBox& operator=(const PBBox& bbox);
bool operator==(const PBBox& bbox) const;
bool operator!=(const PBBox& bbox) const;
PPos GetMin() const { return Min; }
PPos GetMax() const { return Max; }
double GetMinX() const { return Min.GetX(); }
double GetMinY() const { return Min.GetY(); }
double GetMaxX() const { return Max.GetX(); }
double GetMaxY() const { return Max.GetY(); }
double GetWidth() const { return Max.GetX() - Min.GetX(); }
double GetHeight() const { return Max.GetY() - Min.GetY(); }
double GetCenterX() const { return GetMinX() + GetWidth() / 2; }
double GetCenterY() const { return GetMinY() + GetHeight() / 2; }
PPos GetCenter() const { return PPos(GetCenterX(), GetCenterY()); }
void SetMin(const PPos& min) { Min = min; }
void SetMax(const PPos& max) { Max = max; }
void SetMinX(const double& x) { Min.SetX(x); }
void SetMinY(const double& y) { Min.SetY(y); }
void SetMaxX(const double& x) { Max.SetX(x); }
void SetMaxY(const double& y) { Max.SetY(y); }
bool Empty() const { return Min > Max; }
void Clear() { Min = PPos::Max; Max = PPos::Min; }
PBBox& Merge(const PPos& pos)
{
if (pos.GetX() < Min.GetX()) Min.SetX(pos.GetX());
if (pos.GetX() > Max.GetX()) Max.SetX(pos.GetX());
if (pos.GetY() < Min.GetY()) Min.SetY(pos.GetY());
if (pos.GetY() > Max.GetY()) Max.SetY(pos.GetY());
return *this;
};
PBBox& Merge(const PBBox& bbox);
// Update une bbox suite a un mouvement. Si l'update est
// impossible, Clear() la bbox (on a alors bbox.Empty() == true).
// utilisation:
// if (bbox.Update(Src->GetPos(), Dst->GetPos()).Empty() == true) {
// foreach(Ins)
// bbox.Merge(Ins->GetPos());
// }
PBBox& Update(const PPos& src, const PPos& dst);
PBBox& Update(const PBBox& src, const PBBox& dst);
ostream& Print(ostream& os) const;
};
inline ostream& operator<<(ostream& os, const PBBox& bbox)
{
return bbox.Print(os);
}
inline ostream& operator<<(ostream& os, const PBBox* bbox)
{
return bbox ? bbox->Print(os) : os << ("nil");
}
#endif /* P_BBox_h */

View File

@ -0,0 +1,72 @@
#include "PCommon.h"
#include <iostream.h>
#include <math.h>
#include <string>
#include <assert.h>
#include "PConstants.h"
using namespace std;
bool IsSpecialNet(const losig* const sig)
{
return ( (isvdd((char*)sig->NAMECHAIN->DATA))
|| (isvss((char*)sig->NAMECHAIN->DATA)) );
}
const double SquareShape(const double margin,
const double sumwidth, const double minwidth, int& nrows)
{
if (!nrows)
nrows = (int)(sqrt((1.0 + margin) * sumwidth / ROWHEIGHT) + 0.5);
double RowWidth = (double)((int)(((1.0 + margin) * sumwidth / (double)nrows) + 0.5));
if (RowWidth < minwidth)
return minwidth;
return RowWidth;
}
unsigned NbCons(const losig* const sig)
{
//on compte le nombre de connecteurs sur un signal
//lofigchain doit avoir ete execute avant l'appel
unsigned nbcons = 0;
for (chain_list* it = (chain_list *)(getptype(sig->USER, (long)LOFIGCHAIN)->DATA);
it;
it = it->NEXT)
++nbcons;
return nbcons;
}
ostream& PrintLocon(ostream& os, const locon* const con)
{
if (con->TYPE == INTERNAL)
os << (static_cast<loins*>(con->ROOT))->INSNAME << " : " << con->NAME;
else
os << (static_cast<lofig*>(con->ROOT))->NAME << " : " << con->NAME;
os << endl;
return os;
}
ostream& PrintLosig(ostream& os, const losig* const sig)
{
if (!sig->NAMECHAIN)
return os;
for (struct chain* ch = sig->NAMECHAIN;
ch;
ch = ch->NEXT)
{
os << (char*)(ch->DATA) << " " ;
}
os << endl;
return os;
}
bool IsTie(const phins* ins)
{
phfig* fig = getphfig(ins->FIGNAME, 'P');
string figname(fig->NAME);
if (figname.find("tie_x0") != string::npos)
return true;
if (figname.find("rowend_x0") != string::npos)
return true;
return false;
}

View File

@ -0,0 +1,23 @@
#ifndef __PCOMMON_H
#define __PCOMMON_H
#include <iostream>
extern "C"{
#include "mut.h"
#include "mlo.h"
#include "mph.h"
}
using namespace std;
const double SquareShape(const double margin, const double sumwidth,
const double minwidth, int& nrows);
bool IsSpecialNet(const losig* const sig);
bool IsTie(const phins* ins);
ostream& PrintLocon(ostream& os, const locon* const con);
ostream& PrintLosig(ostream& os, const losig* const sig);
unsigned NbCons(const losig* const sig);
#define Max(i,j) (((i) > (j)) ? (i) : (j))
#define Min(i,j) (((i) < (j)) ? (i) : (j))
#endif /* __PCOMMON_H */

View File

@ -0,0 +1,7 @@
#ifndef __PCONSTANTS_H
#define __PCONSTANTS_H
#define PITCH (5 * SCALE_X)
#define ROWHEIGHT 10
#endif /* __PCONSTANTS_H */

View File

@ -0,0 +1,42 @@
#ifndef __PContainer_h
#define __PContainer_h
#include <iostream>
#include <fstream>
#include "PBBox.h"
using namespace std;
class PContainer
{
protected:
PBBox _bBox; // la bbox du container
public:
PContainer():
_bBox() {};
PContainer(PBBox bbox):
_bBox(bbox) {};
virtual ~PContainer() {};
double GetMinX() const { return _bBox.GetMinX(); }
double GetMinY() const { return _bBox.GetMinY(); }
double GetMaxX() const { return _bBox.GetMaxX(); }
double GetMaxY() const { return _bBox.GetMaxY(); }
double GetWidth() const { return _bBox.GetWidth(); }
double GetHeight() const { return _bBox.GetHeight(); }
PBBox GetBBox() const { return _bBox; };
void MergeBBox(const PBBox bbox) {_bBox.Merge(bbox); };
virtual ostream& Print(ostream& os) const = 0;
};
static inline ostream& operator<<(ostream& os, const PContainer& container) {
return container.Print(os);
}
static inline ostream& operator<<(ostream& os, const PContainer* container) {
return container ? container->Print(os) : os << "(nil)";
}
#endif /* __PContainer_h */

View File

@ -0,0 +1,31 @@
#include "PPos.h"
#include <float.h>
const PPos PPos::Min(-DBL_MAX, -DBL_MAX);
const PPos PPos::Max(+DBL_MAX, +DBL_MAX);
bool PPos::operator==(const PPos& pos) const
{
return (X == pos.X) && (Y == pos.Y);
}
bool PPos::operator!=(const PPos& pos) const
{
return (X != pos.X) || (Y != pos.Y);
}
bool PPos::operator<(const PPos& pos) const
{
return (X < pos.X) || ((X == pos.X) && (Y < pos.Y));
}
bool PPos::operator>(const PPos& pos) const
{
return (X > pos.X) || ((X == pos.X) && (Y > pos.Y));
}
ostream&
PPos::Print(ostream& os) const
{
return os << '(' << X << " , " << Y << ')';
}

View File

@ -0,0 +1,55 @@
#ifndef T_POS_H
#define T_POS_H
#include <iostream>
using namespace std;
class PPos {
protected:
double X;
double Y;
public:
static const PPos Min;
static const PPos Max;
PPos() : X(0), Y(0) {}
PPos(double x, double y) : X(x), Y(y) {}
PPos(const PPos& pos) : X(pos.X), Y(pos.Y) {}
PPos& operator=(const PPos& pos)
{
X = pos.X;
Y = pos.Y;
return *this;
};
bool operator==(const PPos& pos) const;
bool operator!=(const PPos& pos) const;
bool operator<(const PPos& pos) const;
bool operator<=(const PPos& pos) const { return pos > *this; }
bool operator>(const PPos& pos) const;
bool operator>=(const PPos& pos) const { return pos < *this; }
double GetX() const { return X; }
double GetY() const { return Y; }
void SetX(const double& x) { X = x; }
void SetY(const double& y) { Y = y; }
ostream& Print(ostream& os) const;
};
inline ostream& operator<<(ostream& os, const PPos& pos)
{
return pos.Print(os);
}
inline ostream& operator<<(ostream& os, const PPos* pos)
{
return pos ? pos->Print(os) : os << "(nil)";
}
#endif /* T_POS_H */

View File

@ -0,0 +1,48 @@
## Process this file with automake to produce Makefile.in
YACC = @YACC@ -d
INCLUDES = @INCLUDES@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/placer
bin_PROGRAMS = ocp
noinst_LIBRARIES = libOcp.a
libOcp_a_SOURCES = PElem.cpp PIns.cpp PNet.cpp \
PCon.cpp
ocp_LDADD = @LIBS@ @LIBM@ \
$(top_builddir)/src/common/libPCommon.a \
-lMpu -lMlu \
-lMcl -lMcp \
-lMal -lMap \
-lMsl \
-lMel -lMgl \
-lMhl \
-lMvl \
-lMmg \
-lMlo \
-lMph -lMut \
-lRcn
ocp_SOURCES = Ocp.cpp PBin.cpp PCon.cpp \
PIns.cpp PMove.cpp PNet.cpp PONet.cpp \
PFixedIns.cpp \
PDetToPlaceIns.cpp \
PPlacement.cpp \
PPlacementGlobal.cpp \
PSubRow.cpp PRow.cpp \
PDetSubRow.cpp PElem.cpp\
PToPlaceIns.cpp \
PPlacementFinal.cpp \
PDetPlacement.cpp \
iocgram.y iocscan.l \
iocheader.h \
PBin.h PCon.h PElem.h PIns.h \
PMove.h PNet.h PONet.h \
PFixedIns.h PPlacement.h \
PSubRow.h PRow.h PToPlaceIns.h \
PDetSubRow.h PDetToPlaceIns.h \
PDetPlacement.h
CLEANFILES = iocgram.c iocgram.h

View File

@ -0,0 +1,347 @@
#include "PPlacement.h"
#include <stdio.h>
#include <iostream>
#include <ctype.h>
extern "C" {
#include "mut.h"
#include "mph.h"
#include "mlo.h"
}
using namespace std;
static void
Usage()
{
cerr << "usage: ocp [options] <netlist> <filename>" << endl
<< "Options :" << endl
<< "o -help : display man page" << endl
<< "o -v : verbose mode" << endl
<< "o -gnuplot : create statistics files to use with gnuplot" << endl
<< "o -c : create connectors (placement randomly generated)" << endl
<< "o -ring : create connectors (placement randomly generated) suitable for ring pad placement tool" << endl
<< "o -ioc : create connectors and place it using .ioc file" << endl
<< "o -margin <MARGIN> : The amount of free area added " << endl
<< " in percentage of the cells area. " << endl
<< " The resulting area will be equal to " << endl
<< " CELL_AREA * (1 + <MARGIN>). Default value : 0.2" << endl
<< "o -partial <PARTIAL> : " << endl
<< " The design is already partially placed (there must be a" << endl
<< " physical view describing this partial placement)." << endl
<< "o -rows <NR> : the placement will have <NR> rows"<< endl
<< "o -mdl <NL> : maximum loop of final optimisation "
<< "default : <NL> = 2" << endl;
}
int
main(int argc, char **argv)
{
double BBoxOccCostRatio = 0.5;
double Margin = 0.2;
bool marginflag = false;
int MaxDetLoop = 2;
int NbRows = 0;
char PartialFile[256] ; //.ap file
char IocFile[256] ; //.ioc file
bool RowFlg = false;
bool HelpFlg = false; // display help
bool UsageFlg = false; // print usage
bool PartialFlg = false; // .ap file loaded
bool PlotFlg = false; // GnuPlot graphics
bool ConFlg = false; // Connectors
bool RingFlg = false; // Connectors
bool IocFlg = false; // file for Connectors
bool VerboseFlg = false; // verbose mode
double NetMult = 0.8 ;
double BinMult = 0.1 ;
double RowMult = 0.1 ;
/* ###------------------------------------------------------### */
/* analyse the command line, set option flags and find the */
/* first file in the argument list */
/* ###------------------------------------------------------### */
mbkenv();
alliancebanner ("OCP", VERSION, "Placer for Standards Cells", "2001", "5.0");
if (argc < 2)
{
Usage();
exit(0);
}
for (int i=1; i<argc; i++) {
if (!strcmp (argv[i], "-help")) {
HelpFlg = true;
}
else
if (!strcmp (argv[i], "-v")) {
if (i+2 < argc) VerboseFlg = true;
else UsageFlg = true;
}
else
if (!strcmp (argv[i], "-gnuplot")) {
if (i+2 < argc) PlotFlg = true;
else UsageFlg = true;
}
else
if (!strcmp (argv[i], "-c")) {
if (i+2 < argc) ConFlg = true;
else UsageFlg = true;
}
else
if (!strcmp (argv[i], "-ring")) {
if (i+2 < argc) RingFlg = true;
else UsageFlg = true;
}
else
if (!strcmp (argv[i], "-r")) {
if (i+3 < argc)
{
if (!sscanf(argv[i+1], "%lg", &BBoxOccCostRatio))
{
cout << "WARNING : invalid argument for -r" << endl;
UsageFlg = true;
}
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
}
else
if (!strcmp (argv[i], "-nbrmult")) {
if (i+5 < argc)
{
if (!sscanf(argv[i+1], "%lg", &NetMult))
{
cout << "WARNING : invalid argument for -nbrmult" << endl;
UsageFlg = true;
}
if (!sscanf(argv[i+2], "%lg", &RowMult))
{
cout << "WARNING : invalid argument for -nbrmult" << endl;
UsageFlg = true;
}
if (!sscanf(argv[i+3], "%lg", &BinMult))
{
cout << "WARNING : invalid argument for -nbrmult" << endl;
UsageFlg = true;
}
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
}
else
if (!strcmp (argv[i], "-margin")) {
if (i+3 < argc)
{
if (!sscanf(argv[i+1], "%lg", &Margin))
{
cout << "WARNING : invalid argument for -margin" << endl;
UsageFlg = true;
}
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
marginflag = true;
}
else
if (!strcmp (argv[i], "-partial")) {
if (i+3 < argc)
{
if (!sscanf(argv[i+1], "%s", PartialFile))
{
cout << "WARNING : invalid argument for -partial" << endl;
UsageFlg = true;
}
PartialFlg = true;
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
}
else
if (!strcmp (argv[i], "-ioc")) {
if (i+3 < argc)
{
if (!sscanf(argv[i+1], "%s", IocFile))
{
cout << "WARNING : invalid argument for -partial" << endl;
UsageFlg = true;
}
IocFlg = true;
strcat(IocFile,".ioc");
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
}
else
if (!strcmp (argv[i], "-mdl")) {
if (i+3 < argc)
{
if (!sscanf(argv[i+1], "%d", &MaxDetLoop))
{
cout << "WARNING : invalid argument for -mdl" << endl;
UsageFlg = true;
}
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
}
else
if (!strcmp (argv[i], "-rows")) {
if (i+3 < argc)
{
if (!sscanf(argv[i+1], "%d", &NbRows))
{
cout << "WARNING : invalid argument for -rows" << endl;
UsageFlg = true;
}
RowFlg = true;
} else {
cout << "WARNING : no file or argument given" << endl;
UsageFlg = true;
}
}
else
if (!strncmp (argv[i], "-", 1))
{
cout << "WARNING : unavailable option : " << argv[i] << endl;
UsageFlg = true;
}
}
/* ###------------------------------------------------------### */
/* cases of error in the command line: */
/* - no argument */
/* - argument unrecognized as an option */
/* - number of files do not match: */
/* ###------------------------------------------------------### */
if (HelpFlg == true) {
system("man ocp");
exit (0);
}
if (argc < 3) {
Usage();
exit(1);
}
if ( BBoxOccCostRatio < 0.0 || BBoxOccCostRatio > 1.0)
UsageFlg = true;
if ( Margin < 0 )
UsageFlg = true;
if ( Margin < 0.15 )
{
cerr << " o Ocp Warning : the value of margin: "
<< Margin << " cannot be respected..." << endl
<< " o value forced to 0.15 !!" << endl;
Margin = 0.15;
}
if ( Margin > 3 )
{
cerr << " o Ocp Warning : the value of margin: "
<< Margin << " cannot be respected..." << endl
<< " o value forced to 0.4 !!" << endl;
Margin = 0.4;
}
if ( marginflag && PartialFlg )
{
cerr << " o Ocp Warning : the switch margin and partial are not coherent "
<< "and should not be use together...." << endl
<< " o In case of a preplacement the margin is determined"
<< " by the value of the Abutment Box and the net netlist you give me." << endl
<< " o In consequence the switch margin has no sense and is bypassed ...."
<< endl;
}
if ((IocFlg && ConFlg) || (IocFlg && RingFlg))
{
cerr << " o You cannot have a connectors placement file and ask "
<< "for a automatic connectors placement at the same time ...." << endl
<< " o Use -ioc or -c or -ring" << endl;
exit(1);
}
if (UsageFlg) {
Usage();
exit (1);
}
// Initializations
// ***************
struct lofig* fig = NULL;
fig = getlofig(argv[argc-2],'A');
char *namefile = argv[argc-1];
struct phfig* physicalfig = NULL;
if (PartialFlg) physicalfig = getphfig(PartialFile,'A');
// On fait le placement
// ********************
PPlacement Placement(ConFlg, RingFlg, RowMult, BinMult, NetMult,
IocFlg, IocFile,PlotFlg, VerboseFlg,PartialFlg,physicalfig, namefile);
Placement.SetMargin(Margin);
Placement.SetMaxDetLoop(MaxDetLoop);
if (!RowFlg)
NbRows = 0;
Placement.Place(fig, NbRows);
// On sauve le resultat
// ********************
cout << endl << "Ocp : placement finished" << endl;
if (Placement.GetBoolPlot())
{
Placement.PlotFinal("view");
Placement.PlotStat();
cout << "gnuplot files created - in order to use them, please type :"
<< endl << "gnuplot afterglobal.gpl"
<< endl << "gnuplot binsafterglobal.gpl"
<< endl << "gnuplot init.gpl"
<< endl << "gnuplot instances-init.gpl"
<< endl << "gnuplot stat.gpl"
<< endl << "gnuplot view.gpl" << endl;
}
int superr = Placement.Save();
dellofig(fig->NAME);
return (superr);
}

View File

@ -0,0 +1,89 @@
#include "PBin.h"
#include <stdio.h>
#include <iomanip>
#include "PToPlaceIns.h"
PBin::PBin()
: PContainer(), _toPlaceInss(), _nHits(0)
{
}
void
PBin::Init(const PBBox bbox, const double capa, PSubRow &row)
{
_bBox = bbox;
_pos = _bBox.GetCenter();
_capa = capa;
_size = 0.0;
_subRow = &row;
}
bool
PBin::UnderOccupied(const double margin) 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 (_size <= (1.0 - margin - 0.2) * _capa);
}
void
PBin::AddIns(PToPlaceIns *ins)
{
_toPlaceInss.push_back(ins);
AddSize(ins->GetWidth());
ins->SetBin(this);
}
void
PBin::IncrNbHits()
{
_nHits++;
}
void
PBin::RemoveIns(PToPlaceIns* ins)
{
_toPlaceInss.remove(ins);
AddSize(-ins->GetWidth());
ins->SetBin(NULL);
}
ostream&
PBin::Print(ostream& os) const
{
return os << "PBin: " << GetMinX() << ',' << GetMinY() << " : " << GetMaxX() << ',' << GetMaxY();
}
// ==================================================
// ofstream& Plot(ofstream& out)
// ==================================================
ofstream&
PBin::Plot(ofstream& out) const
{
out << GetMinX() + 0.3 << " " << GetMinY() + 0.3 << endl
<< GetMinX() + 0.3 << " " << GetMaxY() - 0.3 << endl
<< GetMaxX() - 0.3 << " " << GetMaxY() - 0.3 << endl
<< GetMaxX() - 0.3 << " " << GetMinY() + 0.3 << endl
<< GetMinX() + 0.3 << " " << GetMinY() + 0.3 << endl << endl;
return out;
}
ofstream&
PBin::PlotLabel(ofstream& out, unsigned totalMoves) const
{
unsigned x = (unsigned)(GetMinX() + GetMaxX()) / 2;
unsigned y = (unsigned)(GetMinY() + GetMaxY()) / 2;
double percent;
if (totalMoves != 0)
{
percent = (_nHits * 100.0) / totalMoves;
out << "set label \""
<< percent << "%\" at " << x << "," << y << " center"
<< endl;
}
return out;
}

View File

@ -0,0 +1,50 @@
#ifndef __PBIN_H
#define __PBIN_H
#include <iostream>
#include <fstream>
#include <list>
#include "PSubRow.h"
using namespace std;
class PToPlaceIns;
class PBin : public PContainer{
friend class PSubRow;
public:
typedef list<PToPlaceIns*> PToPlaceInss;
private:
PSubRow* _subRow;
double _capa; // Objective Occupation of the bin
double _size; // Sum of instances widths
PToPlaceInss _toPlaceInss; // Instances of bin.
PPos _pos; // Position of the center of the bin
unsigned _nHits;
public:
PBin();
void Init(const PBBox bbox, const double capacity, PSubRow &subrow);
PSubRow* GetSubRow() const { return _subRow; }
bool GetOrientation() const { return _subRow->GetOrientation(); }
double GetCapa() const { return _capa; }
double GetSize() const { return _size; }
PToPlaceInss& GetToPlaceInss() { return _toPlaceInss; }
unsigned GetNIns() const { return _toPlaceInss.size(); }
PPos GetPos() const { return _pos; }
void IncrNbHits();
void AddSize(const double value) { _size += value; _subRow->AddSize(value); }
bool UnderOccupied(const double margin) const;
void AddIns(PToPlaceIns *ins);
void RemoveIns(PToPlaceIns *ins);
ostream& Print(ostream& os) const;
ofstream& Plot(ofstream& out) const;
ofstream& PlotLabel(ofstream& out, unsigned totalMoves) const;
};
#endif /* __PBIN_H */

View File

@ -0,0 +1,32 @@
#include "PCon.h"
extern "C"{
#include "mut.h"
#include "mph.h"
}
#include "PConstants.h"
PCon::PCon(const locon* con):
PElem(), _con(con), _pos()
{}
PCon::PCon(const locon* con, PPos pos, char orient):
PElem(), _con(con), _pos(pos), _orient(orient)
{}
void
PCon::Save(struct phfig *physicalfig, const double dx, const double dy) const
{
addphcon(physicalfig,
_orient,
_con->NAME,
(int)(GetPosX() * PITCH + dx),
(int)(GetPosY() * PITCH + dy),
((_orient==NORTH) || (_orient == SOUTH))?ALU2:ALU3,
((_orient==NORTH) || (_orient == SOUTH))?2 * (int)(PITCH/5):(int)(PITCH/5));
}
ostream&
PCon::Print(ostream& os) const
{
return os << _con->NAME << GetPos();
}

View File

@ -0,0 +1,28 @@
#ifndef __PCON_H
#define __PCON_H
#include "PElem.h"
extern "C" {
#include "mut.h"
#include "mlo.h"
}
class PCon: public PElem {
private:
const locon* _con;
PPos _pos;
char _orient;
public:
PCon(const locon* con);
PCon(const locon* con, PPos pos, char orient);
PPos GetPos() const { return _pos; }
const locon* GetLocon() const { return _con; }
void SetPos(const PPos pos) {_pos = pos;}
void SetOrient(const char orient) {_orient = orient;}
void Save(struct phfig *physicalfig, const double dx, const double dy) const;
ostream& Print(ostream& os) const;
};
#endif /* __PCON_H */

View File

@ -0,0 +1,197 @@
#include "PDetPlacement.h"
#include "PBin.h"
#include "PPlacement.h"
PDetPlacement::PDetPlacement(Problem& problem):
BBoxFlag(0),
_costFlag(0),
_saveFlag(0),
_problem(problem)
{}
bool
PDetPlacement::Optimize()
{
bool OptimizationResult = false;
const int NInss = _problem.size();
// Save Initial Solution
BestSolution.reserve(NInss);
Problem::iterator ifirst = _problem.begin();
Problem::iterator ilast = _problem.end();
vector<double>::iterator It = BestSolution.begin();
while (ifirst != ilast)
*It++ = (*ifirst++)->GetLeftCornerX();
for(Idx = 0; Idx != NInss; )
Queue.push_back(Idx++);
// Init Best Cost
BBoxFlag++;
BestCost = InitCost(BBoxFlag);
#ifdef PLACE_DEBUG
cout<<" Orig Cost: "<< BestCost << endl;
cout<<" Actual Cost: " << CurrentCost() << endl;
#endif
// Init Initial Cost
BBoxFlag++;
// Init Edges
LeftEdge = (*_problem.begin())->GetLeftCornerX();
RightEdge =(*_problem.rbegin())->GetLeftCornerX()
+ (*_problem.rbegin())->GetMarginWidth();
UnPlaceAll();
Cost = InitCost(BBoxFlag);
#ifdef PLACE_DEBUG
cout << " Init Cost: " << Cost << endl;
#endif
UVect.reserve(NInss + 2);
for (int id = 0; id < NInss + 2; id++)
UVect.push_back(0);
UVect[NInss] = NInss;
UVect[NInss + 1] = NInss + 1;
Stack.reserve(NInss);
Idx = NInss - 1;
unsigned NumAdds = 0;
while(Idx < NInss)
{
AddIns();
NumAdds++;
if(UVect[Idx] == 0 || Cost >= BestCost)
{
UVect[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;
BBoxFlag++;
cout << "Cost recalculated " << InitCost(BBoxFlag) << endl;
cout << "actual Cost" << CurrentCost() << endl;
#endif
ifirst = _problem.begin();
It = BestSolution.begin();
while (ifirst != ilast)
{
*It++ = (*ifirst++)->GetLeftCornerX();
}
}
while(UVect[Idx] == 0)
{
if(Idx < NInss)
RemoveIns();
UVect[++Idx]--;
}
}
Idx--;
}
ifirst = _problem.begin();
It = BestSolution.begin();
while (ifirst != ilast)
(*ifirst++)->SetLeftCornerX(*It++);
PlaceAll();
BestSolution.clear();
#ifdef PLACE_DEBUG
cout<<" Total Add Operations: "<< NumAdds<< endl;
cout<<" Final solution has cost: "<< BestCost << endl << endl;
#endif
UVect.clear();
Queue.clear();
Stack.clear();
return OptimizationResult;
}
void
PDetPlacement::AddIns()
{
BBoxFlag++;
Stack.push_back(Queue.front());
Queue.pop_front();
UVect[Idx] = Idx;
const unsigned cell = Stack.back();
if(Idx%2)
{
_problem[cell]->SetLeftCornerX(RightEdge - _problem[cell]->GetMarginWidth());
RightEdge -= _problem[cell]->GetMarginWidth();
}
else
{
_problem[cell]->SetLeftCornerX(LeftEdge);
LeftEdge += _problem[cell]->GetMarginWidth();
}
_problem[cell]->Place();
Cost += _problem[cell]->DetPlaceUpdateCost();
}
void
PDetPlacement::RemoveIns()
{
unsigned cell = Stack.back();
Queue.push_back(cell);
Stack.pop_back();
if(Idx%2)
RightEdge += _problem[cell]->GetMarginWidth();
else
LeftEdge -= _problem[cell]->GetMarginWidth();
_problem[cell]->UnPlace();
Cost += _problem[cell]->DetPlaceUpdateCost();
}
double
PDetPlacement::InitCost(const unsigned BBoxFlag)
{
++_costFlag;
++_saveFlag;
double Cost = 0.0;
for (Problem::iterator pit = _problem.begin(); pit != _problem.end(); pit++)
Cost += (*pit)->InitCost(BBoxFlag, _costFlag, _saveFlag);
return Cost;
}
double
PDetPlacement::CurrentCost()
{
++_costFlag;
double cost = 0.0;
for (Problem::iterator pit = _problem.begin(); pit != _problem.end(); pit++)
cost += (*pit)->CurrentCost(_costFlag);
return cost;
}
void
PDetPlacement::UnPlaceAll()
{
for (Problem::iterator pit = _problem.begin(); pit != _problem.end(); pit++)
(*pit)->UnPlace();
}
void
PDetPlacement::PlaceAll()
{
for (Problem::iterator pit = _problem.begin(); pit != _problem.end(); pit++)
(*pit)->Place();
}

View File

@ -0,0 +1,46 @@
#ifndef __PDETPLACEMENT_H
#define __PDETPLACEMENT_H
#include <vector>
#include <deque>
#include "PDetToPlaceIns.h"
using namespace std;
class PDetPlacement {
public:
typedef vector<PDetToPlaceIns*> Problem;
private:
unsigned BBoxFlag;
// le _costFlag sert lors de la consultation
// du cout des nets.
// Chaque net doit etre compte une seule fois
unsigned _costFlag;
unsigned _saveFlag;
Problem _problem;
double LeftEdge;
double RightEdge;
double OldCost;
double Cost;
double BestCost;
deque<unsigned> Queue; // ordering
vector<unsigned> Stack;
vector<unsigned> UVect; // use for loop
vector<double> BestSolution;
int Idx;
public:
PDetPlacement(Problem& problem);
bool Optimize();
private:
void AddIns();
void RemoveIns();
double InitCost(const unsigned BBoxFlag);
double CurrentCost();
void UnPlaceAll();
void PlaceAll();
};
#endif /* __PDETPLACEMENT_H */

View File

@ -0,0 +1,159 @@
#include "PDetSubRow.h"
#include "PSubRow.h"
#include "PBin.h"
#include "PDetPlacement.h"
#include <algorithm>
PDetSubRow::PDetSubRow(PSubRow& subrow):
PContainer(subrow.GetBBox()),
_orientation(subrow.GetOrientation())
{
unsigned nbins = 0;
// on compte le nombre d'instances dans la sousrow
for (PSubRow::PBins::iterator bit = subrow.GetBins().begin();
bit != subrow.GetBins().end();
bit++)
{
nbins += bit->GetToPlaceInss().size();
}
_detInsVector.reserve(nbins);
// maintenant on cree les instances
for (PSubRow::PBins::iterator bit = subrow.GetBins().begin();
bit != subrow.GetBins().end();
bit++)
{
for (PBin::PToPlaceInss::iterator iit = bit->GetToPlaceInss().begin();
iit != bit->GetToPlaceInss().end();
iit++)
{
_detInsVector.push_back(PDetToPlaceIns(*iit));
}
}
}
void
PDetSubRow::ExpandInstances()
{
unsigned nins = _detInsVector.size();
double totalinssize = 0;
for (PDetInsVector::iterator iit = _detInsVector.begin();
iit != _detInsVector.end();
iit++)
{
totalinssize += iit->GetWidth();
}
double whitespace = GetWidth() - totalinssize;
double inswhitespace = (double)(int)(whitespace / nins);
double whitespaceremain = (double)(int)(whitespace
- nins * inswhitespace + 0.5);
for (PDetInsVector::iterator iit = _detInsVector.begin();
iit != _detInsVector.end();
iit++)
{
iit->SetMarginWidth(iit->GetWidth() + inswhitespace);
}
PDetInsVector::iterator iit = _detInsVector.begin();
while (whitespaceremain-- > 0)
{
(iit++)->AddWhiteSpace();
}
double XPos = GetMinX();
for (PDetInsVector::iterator iit = _detInsVector.begin();
iit != _detInsVector.end();
iit++)
{
iit->SetLeftCornerX(XPos);
XPos += iit->GetMarginWidth();
}
}
class CompareInsPosition
{
vector<PDetToPlaceIns*>& _insvector;
public:
CompareInsPosition(vector<PDetToPlaceIns*>& insvector):
_insvector(insvector) {}
bool operator()(const PDetToPlaceIns* ins1, const PDetToPlaceIns* ins2) const
{ return ins1->GetLeftCornerX() < ins2->GetLeftCornerX(); }
};
bool
PDetSubRow::FinalOptimize()
{
unsigned ninsinproblem = 0;
unsigned nins = _detInsVector.size();
if (_detInsVector.size() == 0)
return false;
unsigned decal = 2;
bool optimisation = false;
vector<PDetToPlaceIns*> insvector;
insvector.reserve(nins);
for (PDetInsVector::iterator iit = _detInsVector.begin();
iit != _detInsVector.end(); iit++)
{
insvector.push_back(&(*iit));
}
sort(insvector.begin(), insvector.end(), CompareInsPosition(insvector));
PDetPlacement::Problem problem;
problem.reserve(6);
vector<PDetToPlaceIns*>::iterator ifirst = insvector.begin();
vector<PDetToPlaceIns*>::iterator ilast = insvector.end();
while (1)
{
while (1)
{
if (ifirst == ilast)
break;
problem.push_back(*ifirst++);
++ninsinproblem;
if (ninsinproblem >= 6)
{
ninsinproblem = 0;
break;
}
}
PDetPlacement detplace(problem);
if (detplace.Optimize())
optimisation = true;
if (ifirst == ilast)
break;
sort(insvector.begin(), insvector.end(), CompareInsPosition(insvector));
if ((6 + decal) <= nins)
{
ifirst = insvector.begin() + decal;
}
else
{
ifirst = insvector.begin() + decal - 1;
}
ilast = insvector.end();
decal += 2;
problem.clear();
}
return optimisation;
}
ofstream&
PDetSubRow::Plot(ofstream& out) const
{
out << GetMinX() + 0.2 << " " << GetMinY() + 0.2 << endl
<< GetMinX() + 0.2 << " " << GetMaxY() - 0.2 << endl
<< GetMaxX() - 0.2 << " " << GetMaxY() - 0.2 << endl
<< GetMaxX() - 0.2 << " " << GetMinY() + 0.2 << endl
<< GetMinX() + 0.2 << " " << GetMinY() + 0.2 << endl << endl;
return out;
}
ostream&
PDetSubRow::Print(ostream& os) const
{
return os << "PDetSubRow: " << GetMinX() << ',' << GetMinY() << " : " << GetMaxX() << ',' << GetMaxY();
}

View File

@ -0,0 +1,33 @@
#ifndef __PDETSUBROW_H
#define __PDETSUBROW_H
#include <iostream>
#include <fstream>
#include <vector>
#include "PContainer.h"
#include "PDetToPlaceIns.h"
class PSubRow;
class PDetSubRow : public PContainer {
public:
typedef vector<PDetToPlaceIns> PDetInsVector;
private:
PDetInsVector _detInsVector;
bool _orientation;
public:
PDetSubRow(PSubRow& subrow);
bool GetOrientation() const { return _orientation; }
PDetInsVector& GetInssVector() { return _detInsVector; }
const PDetInsVector& GetConstInssVector() const { return _detInsVector; }
void ExpandInstances();
bool FinalOptimize();
ostream& Print(ostream& os) const;
ofstream& Plot(ofstream& out) const;
};
#endif /* __PDETSUBROW_H */

View File

@ -0,0 +1,97 @@
#include "PDetToPlaceIns.h"
extern "C"{
#include "mut.h"
#include "mph.h"
}
#include "PConstants.h"
#include "PToPlaceIns.h"
#include "PDetSubRow.h"
#include "PONet.h"
#include <algorithm>
PDetToPlaceIns::PDetToPlaceIns(PToPlaceIns* toplaceins):
PIns(toplaceins->GetInstance()),
_pos(toplaceins->GetPos()),
_marginWidth(toplaceins->GetWidth()),
_leftCorner(PPos(_pos.GetX() - toplaceins->GetWidth() / 2.0,
_pos.GetY() - toplaceins->GetHeight() / 2.0)),
_placed(true)
{
// initialisation des vecteurs de nets,
// les adresses ne sont pas modifiees
for (PElem::PNets::iterator nit = toplaceins->GetNets().begin();
nit != toplaceins->GetNets().end();
nit++)
{
_nets.push_back(*nit);
}
}
void
PDetToPlaceIns::Save(struct phfig *physicalfig, const double dx, const double dy) const
{
addphins(physicalfig, _instance->FIGNAME, _instance->INSNAME,
GetOrientation()?NOSYM:SYM_Y,
(int)(_leftCorner.GetX() * PITCH + dx),
(int)(_leftCorner.GetY() * PITCH + dy));
}
double
PDetToPlaceIns::GetHeight() const
{
return _subRow->GetHeight();
}
bool
PDetToPlaceIns::GetOrientation() const
{
return _subRow->GetOrientation();
}
void
PDetToPlaceIns::SetLeftCornerX(const double x)
{
_leftCorner.SetX(x);
_pos.SetX(x + GetWidth() / 2.0);
}
double
PDetToPlaceIns::InitCost(const unsigned BBoxFlag, const unsigned CostFlag, const unsigned SaveFlag)
{
double Cost = 0.0;
for (PNets::const_iterator nit = _nets.begin(); nit != _nets.end(); nit++)
{
PONet* ponet = static_cast<PONet*>(*nit);
(ponet)->DetPlaceComputeBBox(BBoxFlag);
(ponet)->SaveTemp(SaveFlag);
Cost += (ponet)->CurrentCost(CostFlag);
}
return Cost;
}
double
PDetToPlaceIns::DetPlaceUpdateCost()
{
double DeltaCost = 0.0;
for (PNets::iterator nit = _nets.begin(); nit != _nets.end(); nit++)
DeltaCost += (static_cast<PONet*>(*nit))->DetPlaceUpdateCost();
return DeltaCost;
}
double
PDetToPlaceIns::CurrentCost(const unsigned costflag)
{
double cost = 0.0;
for (PNets::iterator nit = _nets.begin(); nit != _nets.end(); nit++)
{
cost += (static_cast<PONet*>(*nit))->CurrentCost(costflag);
}
return cost;
}
ostream&
PDetToPlaceIns::Print(ostream& os) const
{
return os << "PDetToPlaceIns: " <<
_instance->FIGNAME << ':' << _instance->INSNAME << ':' << GetPos();
}

View File

@ -0,0 +1,43 @@
#ifndef __PDETTOPLACEINS_H
#define __PDETTOPLACEINS_H
#include "PIns.h"
class PToPlaceIns;
class PDetSubRow;
class PDetToPlaceIns : public PIns {
private:
PDetSubRow* _subRow;
PPos _pos;
double _marginWidth;
PPos _leftCorner;
bool _placed;
public:
PDetToPlaceIns(PToPlaceIns* toplaceins);
~PDetToPlaceIns() {}
PPos GetPos() const { return _pos; }
double GetHeight() const;
bool GetOrientation() const;
void SetMarginWidth(const double mwidth) { _marginWidth = mwidth; }
double GetMarginWidth() const { return _marginWidth; }
void SetLeftCornerX(const double x);
double GetLeftCornerX() const { return _leftCorner.GetX(); }
void SetSubRow(PDetSubRow* subrow) { _subRow = subrow; }
void AddWhiteSpace() { ++_marginWidth; }
void UnPlace() { _placed = false; }
void Place() { _placed = true; }
bool IsPlaced() const { return _placed; }
double InitCost(const unsigned BBoxFlag, const unsigned CostFlag, const unsigned SaveFlag);
double DetPlaceUpdateCost();
double CurrentCost(const unsigned costflag);
ostream& Print(ostream& os) const;
void Save(struct phfig *physicalfig, const double dx, const double dy) const;
};
#endif /* __PDETTOPLACEINS_H */

View File

@ -0,0 +1,13 @@
#include "PElem.h"
#include "PNet.h"
void
PElem::DescribeOn(ostream& os) const
{
os << this << endl;
for (PNets::const_iterator nit = _nets.begin();
nit != _nets.end(); nit++)
{
os << *nit << endl;
}
}

View File

@ -0,0 +1,44 @@
#ifndef __PELEM_H
#define __PELEM_H
#include <iostream>
#include <fstream>
#include <vector>
#include "PPos.h"
using namespace std;
class PNet;
class PElem {
public:
typedef vector <PNet*> PNets;
protected:
PNets _nets;
public:
PElem() : _nets() {}
PNets& GetNets() { return _nets; }
const PNets& GetConstNets() const { return _nets; }
virtual PPos GetPos() const = 0;
virtual ~PElem() {}
double GetPosX() const { return GetPos().GetX(); }
double GetPosY() const { return GetPos().GetY(); }
virtual ostream& Print(ostream& os) const = 0;
void DescribeOn(ostream& os) const;
};
static inline ostream& operator<<(ostream& os, const PElem& elem) {
return elem.Print(os);
}
static inline ostream& operator<<(ostream& os, const PElem* elem) {
return elem ? elem->Print(os) : os << "(nil)";
}
#endif /* __PELEM_H */

View File

@ -0,0 +1,22 @@
#include "PFixedIns.h"
#include "PConstants.h"
PFixedIns::PFixedIns(const loins *instance, const phins* pins, int dx, int dy):
PIns(instance),
_pins(pins),
_pos(), _height(0.0)
{
phfig* phmodel = getphfig(pins->FIGNAME, '0');
double pinsheight = (double)(phmodel->YAB2 - phmodel->YAB1);
_height = (double)(int)(pinsheight / PITCH + 0.5);
double x = (double)((_pins->XINS - dx) / PITCH) + _width / 2.0;
double y = (double)((_pins->YINS - dy) / PITCH) + _height / 2.0;
_pos = PPos(x, y);
}
ostream&
PFixedIns::Print(ostream& os) const
{
return os << "PFixedIns: " <<
_instance->FIGNAME << ':' << _instance->INSNAME << ':' << GetPos();
}

View File

@ -0,0 +1,28 @@
#ifndef __PFIXEDINS_H
#define __PFIXEDINS_H
#include "PIns.h"
#include "PPos.h"
extern "C"{
#include "mut.h"
#include "mph.h"
}
class PFixedIns : public PIns {
private:
const phins* _pins;
PPos _pos;
double _height;
public:
PFixedIns(const loins* ins, const phins* pins, int dx, int dy);
~PFixedIns() {}
double GetHeight() const { return _height; }
PPos GetPos() const { return _pos; }
ostream& Print(ostream& os) const;
};
#endif /* __PFIXEDINS_H */

View File

@ -0,0 +1,33 @@
#include "PIns.h"
extern "C"{
#include "mut.h"
#include "mph.h"
}
#include "PConstants.h"
PIns::PIns(const loins *instance):
PElem(), _instance(instance)
{
phfig* phmodel = getphfig(instance->FIGNAME, '0');
double InsWidth = (double)(phmodel->XAB2 - phmodel->XAB1);
_width = (double)(int)(InsWidth / PITCH + 0.5);
}
PBBox
PIns::GetBBox() const
{
return PBBox(PPos(GetPosX() - GetWidth() / 2.0, GetPosY() - GetHeight() / 2.0),
PPos(GetPosX() + GetWidth() / 2.0, GetPosY() + GetHeight() / 2.0));
}
ofstream&
PIns::Plot(ofstream& out) const
{
out << GetBBox().GetMinX()+0.4 << " " << GetBBox().GetMinY()+0.4 << endl
<< GetBBox().GetMinX()+0.4 << " " << GetBBox().GetMaxY()-0.4 << endl
<< GetBBox().GetMaxX()-0.4 << " " << GetBBox().GetMaxY()-0.4 << endl
<< GetBBox().GetMaxX()-0.4 << " " << GetBBox().GetMinY()+0.4 << endl
<< GetBBox().GetMinX()+0.4 << " " << GetBBox().GetMinY()+0.4 << endl << endl;
return out;
}

View File

@ -0,0 +1,32 @@
#ifndef __PINS_H
#define __PINS_H
#include "PElem.h"
#include "PBBox.h"
extern "C" {
#include "mut.h"
#include "mlo.h"
}
class PIns: public PElem {
protected:
const loins* _instance;
double _width;
public:
PIns(const loins* ins);
const loins* GetInstance() const { return _instance; }
double GetWidth() const { return _width; }
virtual double GetHeight() const { return 0; }
virtual ~PIns() {}
PBBox GetBBox() const;
virtual ostream& Print(ostream& os) const = 0;
ofstream& Plot(ofstream& out) const;
};
#endif /* __PINS_H */

View File

@ -0,0 +1,259 @@
#include "PMove.h"
#include <stdlib.h>
#include <limits.h>
#include <PBin.h>
#ifndef Abs
#define Abs(x) ((x) < 0.0 ? -(x) : (x))
#endif
static double
PositionRand(const double Position, const double Distance, const double Max, const double Min)
{
double BorneInf, BorneSup;
if ((BorneSup = Position + (double)(int)(Distance * Max + 0.5) ) > Max )
BorneSup = Max;
if ((BorneInf = Position - (double)(int)(Distance * Max + 0.5) ) < Min )
BorneInf = Min;
return BorneInf + (double)(int)((BorneSup - BorneInf) * rand() / (RAND_MAX+1.0));
}
PMove::PMove(PPlacement& placement)
: Placement(placement)
, SrcIns(0)
, DstIns(0)
{
}
double
PMove::GetDeltaRowCost()
{
double DeltaRowCost = -SrcRowInitCost;
DeltaRowCost -= DstRowInitCost;
DeltaRowCost += Abs(_srcSubRow->GetCapa() - _srcSubRow->GetSize());
DeltaRowCost += Abs(_dstSubRow->GetCapa() - _dstSubRow->GetSize());
return DeltaRowCost;
}
double
PMove::GetDeltaBinCost()
{
double DeltaBinCost = -SrcBinInitCost;
DeltaBinCost -= DstBinInitCost;
DeltaBinCost += Abs(SrcBin->GetCapa() - SrcBin->GetSize());
DeltaBinCost += Abs(DstBin->GetCapa() - DstBin->GetSize());
return DeltaBinCost;
}
static const unsigned PONetSrc = 1;
static const unsigned PONetDst = 2;
static const unsigned PONetSrcDst = 3;
double
PMove::GetDeltaNetCost()
{
// Find affected nets
// ==================
AffectedNets.clear();
for (PIns::PNets::const_iterator net = SrcIns->GetNets().begin(); net != SrcIns->GetNets().end(); ++net)
AffectedNets[static_cast<PONet*>(*net)] = PONetSrc;
if (DstIns != NULL)
for (PIns::PNets::const_iterator net = DstIns->GetNets().begin(); net != DstIns->GetNets().end(); ++net)
{
PONet* ponet = static_cast<PONet*>(*net);
if (AffectedNets.find(ponet) == AffectedNets.end())
AffectedNets[ponet] = PONetDst;
else
AffectedNets[ponet] = PONetSrcDst;
}
// Compute delta
// =============
double Delta = 0;
for (map<PONet*, unsigned>::iterator it = AffectedNets.begin(); it != AffectedNets.end(); ++it) {
PONet* net = (*it).first;
unsigned Flag = (*it).second;
if (Flag == PONetSrc) {
net->TempBBox() = net->CurrentBBox();
if (net->TempBBox().Update(SrcBin->GetPos(), DstBin->GetPos()).Empty()) {
for (vector<PElem*>::iterator elem = net->GetElems().begin(); elem != net->GetElems().end(); ++elem) {
net->TempBBox().Merge((*elem)->GetPos());
}
}
double width = net->TempBBox().GetWidth();
if (width == 0.0)
{
width = SrcBin->GetWidth() / 2.0;
}
net->TempCost() = net->TempBBox().GetHeight() + width;
Delta += net->TempCost() - net->CurrentCost();
#ifdef CHECK_COST
PBBox check_bbox;
vector<PElem*>::iterator efirst = net->GetElems().begin();
vector<PElem*>::iterator elast = net->GetElems().end();
while (efirst != elast)
check_bbox.Merge((*efirst++)->GetPos());
if (check_bbox != net->TempBBox()) {
cout << "error: mauvaise bbox : PONetSrc" << endl;
cout << " check_bbox = " << check_bbox << endl;
cout << " TempBBox = " << net->TempBBox() << endl;
cout << " CurrentBBox = " << net->CurrentBBox() << endl;
cout << " SrcPos = " << SrcBin->GetPos() << endl;
cout << " DstPos = " << DstBin->GetPos() << endl;
}
#endif
} else if (Flag == PONetDst) {
net->TempBBox() = net->CurrentBBox();
if (net->TempBBox().Update(DstBin->GetPos(), SrcBin->GetPos()).Empty()) {
for (vector<PElem*>::iterator elem = net->GetElems().begin(); elem != net->GetElems().end(); ++elem) {
net->TempBBox().Merge((*elem)->GetPos());
}
}
double width = net->TempBBox().GetWidth();
if (width == 0.0)
{
width = DstBin->GetWidth() / 2.0;
}
net->TempCost() = net->TempBBox().GetHeight() + width;
Delta += net->TempCost() - net->CurrentCost();
#ifdef CHECK_COST
PBBox check_bbox;
vector<PElem*>::iterator efirst = net->GetElems().begin();
vector<PElem*>::iterator elast = net->GetElems().end();
while (efirst != elast)
check_bbox.Merge((*efirst++)->GetPos());
if (check_bbox != net->TempBBox()) {
cout << "error: mauvaise bbox : PONetDst" << endl;
cout << " check_bbox = " << check_bbox << endl;
cout << " TempBBox = " << net->TempBBox() << endl;
cout << " CurrentBBox = " << net->CurrentBBox() << endl;
cout << " SrcPos = " << DstBin->GetPos() << endl;
cout << " DstPos = " << SrcBin->GetPos() << endl;
}
#endif
}
}
return Delta;
}
void
PMove::Move()
{
if (DstIns == NULL) {
SrcBin->RemoveIns(SrcIns);
DstBin->AddIns(SrcIns);
} else {
SrcBin->RemoveIns(SrcIns);
DstBin->AddIns(SrcIns);
DstBin->RemoveIns(DstIns);
SrcBin->AddIns(DstIns);
}
}
bool
PMove::Next(double Dist)
{
bool MoveCondition;
unsigned nbrefused = 0;
// Choisi un mouvement
// ===================
do {
PPos SrcPos;
double DstX;
SrcIns = NULL;
DstIns = NULL;
MoveCondition = true;
SrcIns = &Placement.GetRandIns();
SrcBin = &(SrcIns->GetBin());
_srcSubRow = SrcBin->GetSubRow();
_srcRow = _srcSubRow->GetRow();
SrcPos = SrcBin->GetPos();
SrcWidth = SrcIns->GetWidth();
SrcBinInitCost = Abs(SrcBin->GetCapa() - SrcBin->GetSize());
SrcRowInitCost = Abs(_srcSubRow->GetCapa() - _srcSubRow->GetSize());
_dstRow = &Placement.GetRow(_srcRow, Dist);
DstX = PositionRand(SrcPos.GetX(), Dist, _dstRow->GetMaxX(), _dstRow->GetMinX());
_dstSubRow = &(_dstRow->GetSubRow(DstX));
DstBin = &(_dstSubRow->GetBin(DstX));
DstBinInitCost = Abs(DstBin->GetCapa() - DstBin->GetSize());
DstRowInitCost = Abs(_dstSubRow->GetCapa() - _dstSubRow->GetSize());
if (DstBin == SrcBin)
MoveCondition = false;
if (DstBin->UnderOccupied(Placement.GetMargin())) {
// Le bin destination est sous-occupé
// On déplace l'instance
if (_dstSubRow->GetMax() - _dstSubRow->GetSize() < SrcWidth)
MoveCondition = false;
} else {
DstIns = DstBin->GetToPlaceInss().front();
DstWidth = DstIns->GetWidth();
if (_srcSubRow->GetMax() - _srcSubRow->GetSize() < DstWidth - SrcWidth)
MoveCondition = false;
if (_dstSubRow->GetMax() - _dstSubRow->GetSize() < SrcWidth - DstWidth)
MoveCondition = false;
}
if (!MoveCondition)
++nbrefused;
if (nbrefused > (unsigned)(1.5 * Placement.GetNInsToPlace()))
return false;
} while (!MoveCondition);
// Deplace les instances
// =====================
DstBin->IncrNbHits();
Move();
return true;
}
void
PMove::Accept()
{
// Sauvegarde des cout des nets
for (map<PONet*, unsigned>::iterator it = AffectedNets.begin(); it != AffectedNets.end(); ++it) {
PONet* net = (*it).first;
unsigned Flag = (*it).second;
if (Flag == PONetSrc || Flag == PONetDst) {
net->SaveTemp();
}
}
}
void
PMove::Reject()
{
if (DstIns == NULL) {
DstBin->RemoveIns(SrcIns);
SrcBin->AddIns(SrcIns);
} else {
SrcBin->RemoveIns(DstIns);
DstBin->AddIns(DstIns);
DstBin->RemoveIns(SrcIns);
SrcBin->AddIns(SrcIns);
}
}

View File

@ -0,0 +1,44 @@
#ifndef __PMove_h
#define __PMove_h
#include <PPlacement.h>
#include <PPos.h>
#include <map>
class PMove {
private:
PPlacement& Placement;
PToPlaceIns* SrcIns;
PBin* SrcBin;
double SrcBinInitCost;
PSubRow* _srcSubRow;
PRow* _srcRow;
double SrcRowInitCost;
double SrcWidth;
PBin* DstBin;
double DstBinInitCost;
PSubRow* _dstSubRow;
PRow* _dstRow;
double DstRowInitCost;
PToPlaceIns* DstIns;
double DstWidth;
map<PONet*, unsigned> AffectedNets;
public:
PMove(PPlacement& placement);
double GetDeltaRowCost();
double GetDeltaBinCost();
double GetDeltaNetCost();
bool Next(const double dist);
void Accept();
void Reject();
void Move();
};
#endif /* __PMove_h */

View File

@ -0,0 +1,62 @@
#include "PNet.h"
#include "PElem.h"
PNet::PNet(const losig* sig):
_sig(sig), _elems()
{}
// ======================================================================
// ostream& Print(ostream& os) const;
// ======================================================================
ostream&
PNet::Print(ostream& os) const
{
if (!_sig->NAMECHAIN)
return os << "(noname) Index: " << _sig->INDEX;
struct chain* cit = _sig->NAMECHAIN;
if (!cit->NEXT)
return os << (char*)cit->DATA;
for (struct chain* cit = _sig->NAMECHAIN; cit; cit = cit->NEXT)
os << (char*)cit->DATA << " ";
return os;
}
void
PNet::DescribeOn(ostream& os) const
{
os << this << endl;
for (PElems::const_iterator eit = _elems.begin();
eit != _elems.end(); eit++)
{
os << *eit << endl;
}
}
ofstream&
PNet::Plot(ofstream& out) const
{
int nbElems = 0;
double baryX = 0;
double baryY = 0;
for (vector<PElem*>::const_iterator ElemIt = _elems.begin();
ElemIt != _elems.end(); ElemIt++)
{
++nbElems;
baryX += (*ElemIt)->GetPosX();
baryY += (*ElemIt)->GetPosY();
}
baryX = baryX / nbElems;
baryY = baryY / nbElems;
for (vector<PElem*>::const_iterator ElemIt = _elems.begin();
ElemIt != _elems.end(); ElemIt++)
{
out << baryX << " " << baryY << endl
<< (*ElemIt)->GetPosX() << " " << (*ElemIt)->GetPosY() << endl << endl;
}
return out;
}

View File

@ -0,0 +1,48 @@
#ifndef __PNET_H
#define __PNET_H
#include <iostream>
#include <fstream>
#include <vector>
extern "C" {
#include "mut.h"
#include "mlo.h"
}
using namespace std;
class PElem;
class PNet {
public:
typedef vector <PElem*> PElems;
protected:
const losig* _sig;
PElems _elems;
public:
PNet(const losig* sig);
const losig* GetSig() const { return _sig; }
PElems& GetElems() { return _elems; }
const PElems& GetConstElems() const { return _elems; }
ostream& Print(ostream& os) const;
void DescribeOn(ostream& os) const;
ofstream& Plot(ofstream& out) const;
};
static inline ostream& operator<<(ostream& os, const PNet& net) {
return net.Print(os);
}
static inline ostream& operator<<(ostream& os, const PNet* net) {
return net ? net->Print(os) : os << "(nil)";
}
#endif /* __PNET_H */

View File

@ -0,0 +1,103 @@
#include "PONet.h"
#include "PDetToPlaceIns.h"
PONet::PONet(const losig* sig):
PNet(sig),
_bBoxMark(0), _currCostMark(0),
_saveMark(0), _curr(0)
{
BBox[0].Clear();
BBox[1].Clear();
Cost[0] = 0.0;
Cost[1] = 0.0;
}
// ======================================================================
// double CurrentCost(const unsigned Flag)
// ======================================================================
double
PONet::CurrentCost(const unsigned Flag)
{
if (_currCostMark != Flag)
{
_currCostMark = Flag;
return Cost[_curr];
}
return 0.0;
}
void
PONet::SaveTemp(const unsigned saveflag)
{
if (_saveMark != saveflag)
{
_curr = !_curr;
}
return;
}
// ======================================================================
// void DetPlaceComputeBBox(const unsigned Flag)
// ======================================================================
void
PONet::DetPlaceComputeBBox(const unsigned Flag)
{
#if 0
if (Flag != _bBoxMark)
{
_bBoxMark = Flag;
#endif
BBox[!_curr].Clear();
for (PElems::iterator eit = _elems.begin(); eit != _elems.end(); eit++)
{
PDetToPlaceIns* detins = dynamic_cast<PDetToPlaceIns*>(*eit);
if (detins)
{
if (detins->IsPlaced())
{
BBox[!_curr].Merge(detins->GetPos());
}
}
else
BBox[!_curr].Merge((*eit)->GetPos());
}
Cost[!_curr] = DetPlaceComputeCost(BBox[!_curr]);
#if 0
}
#endif
}
// ======================================================================
// double DetPlaceComputeCost(PBBox &Box) const
// ======================================================================
double
PONet::DetPlaceComputeCost(PBBox &Box) const
{
if (!Box.Empty())
return Box.GetMaxY() - Box.GetMinY()
+ Box.GetMaxX() - Box.GetMinX();
else
return 0.0;
}
double
PONet::DetPlaceUpdateCost()
{
double save = Cost[_curr];
BBox[_curr].Clear();
for (PElems::iterator eit = _elems.begin(); eit != _elems.end(); eit++)
{
PDetToPlaceIns* detins = dynamic_cast<PDetToPlaceIns*>(*eit);
if (detins)
{
if (detins->IsPlaced())
{
BBox[_curr].Merge(detins->GetPos());
}
}
else
BBox[_curr].Merge((*eit)->GetPos());
}
Cost[_curr] = DetPlaceComputeCost(BBox[_curr]);
return (Cost[_curr] - save);
}

View File

@ -0,0 +1,36 @@
#ifndef __PONET_H
#define __PONET_H
#include "PNet.h"
#include "PBBox.h"
class PONet: public PNet {
private:
unsigned _bBoxMark;
unsigned _currCostMark;
unsigned _saveMark;
double Cost[2];
PBBox BBox[2];
unsigned _curr;
public:
PONet(const losig* sig);
double& CurrentCost() { return Cost[_curr]; }
double CurrentCost(const unsigned Flag);
double& TempCost() { return Cost[!_curr]; }
PBBox& CurrentBBox() { return BBox[_curr]; }
PBBox& TempBBox() { return BBox[!_curr]; }
void SaveTemp() { _curr = !_curr; }
void SaveTemp(const unsigned saveflag);
void DetPlaceComputeBBox(const unsigned Flag);
double DetPlaceUpdateCost();
private:
double DetPlaceComputeCost(PBBox &Box) const;
};
#endif /* __PONET_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
#ifndef __PPLACEMENT_H
#define __PPLACEMENT_H
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <hash_map.h>
#include "PToPlaceIns.h"
#include "PFixedIns.h"
#include "PCon.h"
#include "PONet.h"
#include "PBBox.h"
#include "PDetSubRow.h"
extern "C" {
#include "mut.h"
#include "mlo.h"
}
#include "iocheader.h"
using namespace std;
struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};
class PPlacement {
public:
typedef vector<PRow> PRows;
typedef vector<PONet*> PONets;
typedef vector<PToPlaceIns*> PToPlaceInss;
typedef vector<PFixedIns*> PFixedInss;
typedef vector<PCon*> PCons;
typedef vector <bool> PrePlaceRow;
typedef vector<PrePlaceRow> PrePlaceTab;
typedef vector<PDetSubRow> PDetSubRows;
private:
typedef map<double, unsigned, less<double> > PRowsYMax;
typedef map<double, unsigned, greater<double> > PRowsYMinInv;
typedef hash_map<long, PONet*> PNetMap;
typedef hash_map<const char*, PIns*, hash<const char *>, eqstr>PInsMap;
typedef hash_map<const char*, PCon*, hash<const char *>, eqstr> PConMap;
typedef hash_map<const char*, locon*, hash<const char *>, eqstr> PLoconMap;
typedef hash_map<const char*, int, hash<const char *>, eqstr> PFixedMap;
typedef hash_map<const char*, PDetToPlaceIns*, hash<const char*>, eqstr> PDetInsMap;
PBBox BBox;
int _dx;
int _dy;
lofig* _fig;
phfig* _prePlaceFig;
PToPlaceInss _toPlaceInss;
PFixedInss _fixedInss;
PCons _cons;
PONets _nets;
PRows _rows;
PRowsYMax _rowsYMax;
PRowsYMinInv _rowsYMinInv;
// placement detaille
PDetSubRows _detSubRows;
double _detInitNetCost;
bool _rowZeroOrientation;
double _initNetCost;
double _initRowCost;
double _initBinCost;
// parametres
double _margin;
int _maxDetLoop; // Maximum nb of loops for detailed placement
double RowMult;
double BinMult;
double NetMult;
bool _placeCons;
bool _ringPlaceCons;
con_list* _PtList;
bool _iocFile;
char* _iocFileName;
bool _boolPlot;
bool _verbose;
bool _prePlace;
unsigned _totalMoves;
// Placement caracteristics
char* _fileName;
unsigned _elems;
unsigned _nIns;
unsigned _nInsToPlace;
double _binsWidth;
double _binsCapa;
double _binsMinWidth;
double _binsMaxWidth;
double _sumToPlaceInssWidth;
double _biggestToPlaceInsWidth;
void Init(lofig* cell, int NbRows);
double GetRowCost();
double GetBinCost();
double GetNetCost();
double GetCost(double RowCost, double BinCost, double NetCost);
void PlaceGlobal();
void PlaceFinal();
public:
PPlacement(bool conflg, bool ringflg, double rowmult, double binmult, double netmult,
bool iocfile, char *iocfilename, bool plotflg,
bool verbose, bool preflg, struct phfig* physfig,
char* filename):
_prePlaceFig(physfig),
RowMult(rowmult), BinMult(binmult), NetMult(netmult),
_placeCons(conflg), _ringPlaceCons(ringflg), _iocFile(iocfile), _iocFileName(iocfilename),
_boolPlot(plotflg), _verbose(verbose), _prePlace(preflg),
_totalMoves(0),_fileName(filename)
{}
~PPlacement();
void SetMargin(const double Value) { _margin = Value; }
double GetMargin() const { return _margin; }
void SetMaxDetLoop(const int loop) { _maxDetLoop = loop; }
void SetRowMult(const double Value) { RowMult = Value; }
double GetRowMult() const { return RowMult; }
void SetBinMult(const double Value) { BinMult = Value; }
double GetBinMult() const { return BinMult; }
void SetNetMult(const double Value) { NetMult = Value; }
double GetNetMult() const { return NetMult; }
void Place(lofig* cell, int NbRows);
void PlotAll(char* output) const;
void PlotFinal(char* output) const;
void PlotOnlyInstances(char* output) const;
void PlotStat();
void PlotOnlyBins(char* output) const;
double GetMinX() const { return BBox.GetMinX(); }
double GetMinY() const { return BBox.GetMinY(); }
double GetMaxX() const { return BBox.GetMaxX(); }
double GetMaxY() const { return BBox.GetMaxY(); }
double GetWidth() const { return BBox.GetWidth(); }
double GetHeight() const { return BBox.GetHeight(); }
int GetNInsToPlace() const { return _nInsToPlace; }
bool GetBoolPlot() const { return _boolPlot; }
void SetBoolPlot(bool value) { _boolPlot = value; }
double GetOccCost() const;
void InitBBoxCost();
double TempBBoxCost();
void ParseIocFile(PLoconMap& ploconmap);
void SetPosIocFile(PConMap& pconmap);
PToPlaceIns& GetRandIns();
PRow& GetRow(const PRow* row, const double distance);
void FinalInitialize();
bool FinalOptimize();
ostream& Print(ostream& os) const;
int Save();
// Debug Methods
double DetPlaceDebugNetCost();
double GlobalPlaceDebugNetCost();
double DebugRowCost();
double DebugBinCost();
private:
PFixedIns* InsertFixedIns(const loins* ins, const phins* pins, const int dx, const int dy);
PToPlaceIns* InsertToPlaceIns(const loins* ins);
PCon* InsertCon(const locon* con);
PCon* InsertCon(const locon* con, PPos position, const char orientation);
PONet* InsertNet(const losig* sig);
int AddRowend(struct phfig* physicalfig);
double DetPlaceNetCost();
void GenerateConsPlacement();
void GenerateRingConsPlacement();
void InitPlace(int nbrows);
void InitPlaceWithPrePlace();
void CreateSubRows(PRow* row, PrePlaceTab& tabpreplace,int coordy, int nbsubrows, int Width);
int CheckCreateRow(PrePlaceTab& tabpreplace, int coordy, int Width);
void PlotInstances(ofstream& out) const;
};
static inline ostream& operator<<(ostream& os, const PPlacement& placement)
{
return placement.Print(os);
}
static inline ostream& operator<<(ostream& os, const PPlacement* placement)
{
return placement ? placement->Print(os) : os << "(nil)";
}
#endif /* __PPLACEMENT_H */

View File

@ -0,0 +1,380 @@
#include "PPlacement.h"
#include <math.h>
#include <unistd.h>
#include <algorithm>
#include <hash_map.h>
#include "PMove.h"
#include "PConstants.h"
#include "PDetPlacement.h"
extern "C"{
#include "mut.h"
#include "mph.h"
#include "mpu.h"
#include "mlo.h"
#include "mlu.h"
}
double
PPlacement::DetPlaceDebugNetCost()
{
double NetCost = 0.0;
vector<PONet*>::iterator nfirst = _nets.begin();
vector<PONet*>::iterator nlast = _nets.end();
while (nfirst != nlast) {
PONet& net = **nfirst++;
PBBox bbox;
vector<PElem*>::iterator ifirst = net.GetElems().begin();
vector<PElem*>::iterator ilast = net.GetElems().end();
if (ifirst != ilast)
{
while (ifirst != ilast)
bbox.Merge((*ifirst++)->GetPos());
double width = bbox.GetWidth();
NetCost += bbox.GetHeight() + width;
}
}
return NetCost;
}
void
PPlacement::PlaceFinal()
{
// Detailed Placement
if (_verbose) cout << " o Final Optimization in process ..." << endl;
FinalInitialize();
if (_verbose)
{
if (FinalOptimize())
cout << " o Final Optimization succeeded ..." << endl;
else
cout << " o No Optimization possible" << endl;
}
double NewCost = DetPlaceDebugNetCost();
if (_verbose)
{
cout << " o Final Net Cost ..... " << NewCost << endl;
cout << " o Final Net Cost Optimization ..... "
<< 100.0 * (_detInitNetCost - NewCost) / _detInitNetCost << "%" << endl;
cout << " o Total Net Optimization .... "
<< 100.0 * (_initNetCost - NewCost) / _initNetCost << "%" << endl;
}
}
// ======================================================================
// double FinalInitialize()
// ======================================================================
void
PPlacement::FinalInitialize()
{
// on compte le nombre de subrow
// on prend uniquement celle qui ont des instances
unsigned nbsubrows = 0;
for (PRows::iterator rit = _rows.begin(); rit != _rows.end(); rit++)
{
for (PRow::PSubRows::iterator srit = rit->GetSubRows().begin();
srit != rit->GetSubRows().end();
srit++)
{
if (srit->GetNIns() > 0)
++nbsubrows;
}
}
_detSubRows.reserve(nbsubrows);
for (PRows::iterator rit = _rows.begin(); rit != _rows.end(); rit++)
{
for (PRow::PSubRows::iterator srit = rit->GetSubRows().begin();
srit != rit->GetSubRows().end();
srit++)
{
if (srit->GetNIns() > 0)
_detSubRows.push_back(PDetSubRow(*srit));
}
}
PDetInsMap pdetinsmap;
for (PDetSubRows::iterator dsrit = _detSubRows.begin();
dsrit != _detSubRows.end(); dsrit++)
{
for (PDetSubRow::PDetInsVector::iterator it = dsrit->GetInssVector().begin();
it != dsrit->GetInssVector().end(); it++)
{
pdetinsmap[it->GetInstance()->INSNAME] = &(*it);
it->SetSubRow(&(*dsrit));
}
}
for (PONets::iterator nit = _nets.begin(); nit != _nets.end(); nit++)
{
for (PONet::PElems::iterator eit = (*nit)->GetElems().begin();
eit != (*nit)->GetElems().end();
eit++)
{
PToPlaceIns* ptoplaceins = dynamic_cast<PToPlaceIns*>(*eit);
if (ptoplaceins)
{
PDetInsMap::iterator iit =
pdetinsmap.find(ptoplaceins->GetInstance()->INSNAME);
if (iit == pdetinsmap.end())
{
cerr << "det ins " << ptoplaceins->GetInstance()->INSNAME
<< "is not present in data... " << endl;
exit(1);
}
*eit = iit->second;
}
}
}
//verification
for (PONets::iterator nit = _nets.begin(); nit != _nets.end(); nit++)
{
for (PONet::PElems::iterator eit = (*nit)->GetElems().begin();
eit != (*nit)->GetElems().end();
eit++)
{
assert(!dynamic_cast<PToPlaceIns*>(*eit));
}
}
// on efface ce qui ne nous sert plus.
//_rows.clear();
//_toPlaceInss.clear();
//_rowsYMax.clear();
//_rowsYMinInv.clear();
//expanding instances in subrows
for (PDetSubRows::iterator dsrit = _detSubRows.begin();
dsrit != _detSubRows.end(); dsrit++)
{
dsrit->ExpandInstances();
}
// Updating All _nets BBoxs
DetPlaceNetCost();
}
// ======================================================================
// double DetPlaceNetCost();
// ======================================================================
double
PPlacement::DetPlaceNetCost()
{
double NetCost = 0.0;
vector<PONet*>::iterator nfirst = _nets.begin();
vector<PONet*>::iterator nlast = _nets.end();
while (nfirst != nlast) {
PONet& net = **nfirst++;
PBBox& bbox = net.CurrentBBox();
vector<PElem*>::iterator ifirst = net.GetElems().begin();
vector<PElem*>::iterator ilast = net.GetElems().end();
while (ifirst != ilast)
bbox.Merge((*ifirst++)->GetPos());
NetCost += bbox.GetHeight() + bbox.GetWidth();
}
return NetCost;
}
// ======================================================================
// bool FinalOptimize()
// ======================================================================
bool
PPlacement::FinalOptimize()
{
int Loop = 0;
double NewCost;
double InitCost = DetPlaceDebugNetCost();
_detInitNetCost = InitCost;
if (_verbose)
cout << " o Net Cost before Final Optimization... "
<< InitCost << endl;
bool ContinueCondition = true;
bool OptimizationResult = false;
while (ContinueCondition && (Loop < _maxDetLoop)) {
ContinueCondition = false;
for (PDetSubRows::iterator dsrit = _detSubRows.begin();
dsrit != _detSubRows.end(); dsrit++)
{
if (dsrit->FinalOptimize())
{
ContinueCondition = true;
OptimizationResult = true;
}
NewCost = DetPlaceDebugNetCost();
InitCost = NewCost;
}
++Loop;
}
return OptimizationResult;
}
// ======================================================================
// int Save()
// ======================================================================
int
PPlacement::Save()
{
char* phfigname;
struct phfig* physicalfig;
if (!_prePlaceFig)
{
physicalfig = addphfig(_fileName);
phfigname = _fileName;
if (_verbose) cout << "NO PREPLACEMENT GIVEN" << endl;
physicalfig->XAB1 =(int)(BBox.GetMinX() * PITCH);
physicalfig->XAB2 =(int)(BBox.GetMaxX() * PITCH);
physicalfig->YAB1 =(int)(BBox.GetMinY() * PITCH);
physicalfig->YAB2 =(int)(BBox.GetMaxY() * PITCH);
}
else
{
if (_verbose) cout << "PREPLACEMENT GIVEN" << endl;
physicalfig = _prePlaceFig;
phfigname = physicalfig->NAME;
physicalfig->NAME = _fileName;
}
for (PDetSubRows::iterator dsrit = _detSubRows.begin();
dsrit != _detSubRows.end(); dsrit++)
{
for (PDetSubRow::PDetInsVector::iterator it = dsrit->GetInssVector().begin();
it != dsrit->GetInssVector().end(); it++)
{
it->Save(physicalfig, _dx, _dy);
}
}
for (PCons::const_iterator cit = _cons.begin(); cit != _cons.end(); cit++)
{
(*cit)->Save(physicalfig, _dx, _dy);
}
int superr = AddRowend(physicalfig);
savephfig(physicalfig);
physicalfig->NAME = phfigname;
return superr;
}
// ======================================================================
// void AddRowend(struct phfig* physicalfig)
// ======================================================================
int PPlacement::AddRowend(struct phfig* physicalfig)
{
int superr = 0;
long xmax = (long) (BBox.GetMaxX());
long ymax = (long) (BBox.GetMaxY() / ROWHEIGHT);
// tab represents the circuit
bool tab[xmax][ymax];
for (long tabx = 0 ; tabx < xmax ; tabx++)
for (long taby = 0 ; taby < ymax ; taby++)
tab[tabx][taby] = false;
// look for rowend instances already present
// if any, we save the highest number of them
// we will then create instances whith a bigger number
// this prevents having two instances with the same name
int rowendcount = 0;
int tiecount = 0;
for (struct phins* It = physicalfig->PHINS ; It ; It = It->NEXT)
{
if ( strncmp(It->INSNAME,"rowendx0_",9) == 0 )
{
char *nb = strdup(It->INSNAME + 9);
if ( atoi(nb) > rowendcount ) rowendcount = atoi(nb);
}
if ( strncmp(It->INSNAME,"tiex0_",6) == 0 )
{
char *nb = strdup(It->INSNAME + 6);
if ( atoi(nb) > tiecount ) tiecount = atoi(nb);
}
// fill the tab with instances (true = instance is present)
struct phfig* insfig = getphfig(It->FIGNAME, '0');
long width = (long) ((insfig->XAB2 - insfig->XAB1) / PITCH);
long height = (long) ((insfig->YAB2 - insfig->YAB1) / (PITCH * ROWHEIGHT));
long posx = (long) ((It->XINS - _dx) / PITCH);
long posy = (long)((It->YINS - _dy)/ (PITCH * ROWHEIGHT));
for (long ydecal=0 ; ydecal < height ; ydecal++)
{
for (long xdecal=0 ; xdecal < width ; xdecal++)
{
if (tab[posx + xdecal][posy + ydecal] == true)
{
cerr << "ERROR : instances superposed : " << It->INSNAME << endl;
superr = 1;
}
tab[posx + xdecal][posy + ydecal] = true;
}
}
}
++rowendcount;
++tiecount;
for (long tabx = 0 ; tabx < xmax ; tabx++)
{
for (long taby = 0 ; taby < ymax ; taby++)
{
if (tab[tabx][taby] == false)
{
// add tie cell?
if ((tabx + 1 < xmax) && (tab[tabx+1][taby] == false))
{
char buf[256];
char sym;
sprintf(buf,"tiex0_%d",rowendcount++);
if (taby%2 == 0)
{
if (_rowZeroOrientation) sym = NOSYM;
else sym = SYM_Y;
}
else // taby%2 == 1
{
if (_rowZeroOrientation) sym = SYM_Y;
else sym = NOSYM;
}
addphins(physicalfig,"tie_x0",buf,sym,(long) (tabx * PITCH + _dx),(long) (taby * ROWHEIGHT * PITCH + _dy));
tab[tabx][taby]= true;
tab[tabx+1][taby]= true;
} else
// add rowend cell
{
char buf[256];
char sym;
sprintf(buf,"rowendx0_%d",rowendcount++);
if (taby%2 == 0)
{
if (_rowZeroOrientation) sym = NOSYM;
else sym = SYM_Y;
}
else // taby%2 == 1
{
if (_rowZeroOrientation) sym = SYM_Y;
else sym = NOSYM;
}
addphins(physicalfig,"rowend_x0",buf,sym,(long) (tabx * PITCH + _dx),(long) (taby * ROWHEIGHT * PITCH + _dy));
tab[tabx][taby]= true;
}
}
}
}
return superr;
}

View File

@ -0,0 +1,420 @@
#include "PPlacement.h"
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include "PMove.h"
#include "PConstants.h"
static double
DoubleRand(void)
{
return (double) rand() / (RAND_MAX + 1.0);
}
static bool
Accept(double Temperature, double DeltaCost)
{
if ((DeltaCost <= 0.0) || ((Temperature != 0.0) && (exp(-DeltaCost / Temperature) > DoubleRand())))
return true;
else
return false;
}
static double
GetStdDev(double Sum, double Square, double n)
{
if (n <= 1.0)
return 0.0;
double StdDev = (Square - Sum * Sum / n) / (n - 1.0);
if (StdDev > 0.0)
StdDev = sqrt(StdDev);
else
StdDev = 0.0;
return StdDev;
}
#ifdef PLACE_DEBUG
double
PPlacement::GlobalPlaceDebugNetCost()
{
double NetCost = 0.0;
vector<PNet>::iterator nfirst = _nets.begin();
vector<PNet>::iterator nlast = _nets.end();
while (nfirst != nlast) {
PNet& net = *nfirst++;
PBBox bbox;
vector<PElem*>::iterator ifirst = net.GetElems().begin();
vector<PElem*>::iterator ilast = net.GetElems().end();
if (ifirst != ilast)
{
while (ifirst != ilast)
bbox.Merge((*ifirst++)->GetPos());
double width = bbox.GetWidth();
if (width == 0.0)
{
//toutes les instances dans le meme bin
//on prend comme largeur la moitie du bin
ifirst = net.GetElems().begin();
PToPlaceIns* toplaceins = NULL;
while (ifirst != ilast)
{
toplaceins = dynamic_cast<PToPlaceIns*>(*ifirst++);
if (toplaceins)
break;
}
if (!toplaceins)
width = 0;
else
width = toplaceins->GetBin().GetWidth() / 2.0;
}
NetCost += bbox.GetHeight() + width;
}
}
return NetCost;
}
#endif
#ifndef Abs
#define Abs(x) ((x) < 0.0 ? -(x) : (x))
#endif
double
PPlacement::GetRowCost()
{
double RowCost = 0.0;
for (PRows::iterator RowIt = _rows.begin(); RowIt != _rows.end(); RowIt++)
{
RowCost += RowIt->GetSubRowCost();
}
return RowCost;
}
double
PPlacement::GetBinCost()
{
double BinCost = 0.0;
for (PRows::iterator RowIt = _rows.begin(); RowIt != _rows.end(); RowIt++)
{
BinCost += RowIt->GetBinCost();
}
return BinCost;
}
double
PPlacement::GetNetCost()
{
double NetCost = 0.0;
vector<PONet*>::iterator nfirst = _nets.begin();
vector<PONet*>::iterator nlast = _nets.end();
while (nfirst != nlast) {
PONet& net = **nfirst++;
PBBox& bbox = net.CurrentBBox();
vector<PElem*>::iterator ifirst = net.GetElems().begin();
vector<PElem*>::iterator ilast = net.GetElems().end();
if (ifirst == ilast)
{
cout << " o Placer Warning : Net " << net << " is not connected..." << endl;
}
else
{
while (ifirst != ilast)
bbox.Merge((*ifirst++)->GetPos());
double width = bbox.GetWidth();
if (width == 0.0)
{
//toutes les instances dans le meme bin
//on prend comme largeur la moitie du bin
ifirst = net.GetElems().begin();
PToPlaceIns* toplaceins = NULL;
while (ifirst != ilast)
{
toplaceins = dynamic_cast<PToPlaceIns*>(*ifirst++);
if (toplaceins)
break;
}
if (!toplaceins)
width = 0;
else
width = toplaceins->GetBin().GetWidth() / 2.0;
}
net.CurrentCost() = bbox.GetHeight() + width;
NetCost += net.CurrentCost();
}
}
return NetCost;
}
double
PPlacement::GetCost(double RowCost, double BinCost, double NetCost)
{
return RowCost / _initRowCost * RowMult + BinCost / _initBinCost * BinMult + NetCost / _initNetCost * NetMult;
}
void
PPlacement::PlaceGlobal()
{
int Iteration;
double Cost, RowCost, BinCost, NetCost;
double InitCost;
double Temperature = 1e30, OldTemperature = 1e30;
int Loop = 0;
double StdDev = 0, StdDevRow = 0, StdDevBin = 0, StdDevNet = 0;
double SumCost = 0, SumCostRow = 0, SumCostBin = 0, SumCostNet = 0;
double SumSquare = 0, SumSquareRow = 0, SumSquareBin = 0, SumSquareNet = 0;
int Accepted = 0;
double SucRatio = 1.0;
double Dist = 1.0;
double maxTemperature = 0;
double maxCost = 0;
double maxRowCost = 0;
double maxBinCost = 0;
double maxNetCost = 0;
double maxSucRatio = 0;
double maxDelta = 0;
ofstream ofout("alldata.dat");
if (_verbose)
cout << " o Beginning global placement ...." << endl;
PMove Move(*this);
_initRowCost = RowCost = GetRowCost();
_initBinCost = BinCost = GetBinCost();
_initNetCost = NetCost = GetNetCost();
InitCost = Cost = GetCost(RowCost, BinCost, NetCost);
if (_verbose)
{
cout << " o Initial RowCost = " << RowCost << endl;
cout << " o Initial BinCost = " << BinCost << endl;
cout << " o Initial NetCost = " << NetCost << endl;
cout << " o Initial Cost = " << Cost << endl;
cout << " o Computing Initial Temperature ..." << endl;
}
// Calcul de la temperature initiale
for (int i = 0; i < GetNInsToPlace(); ++i) {
if (!Move.Next(Dist))
{
cout << " o No More Mouvement Possible ....." << endl;
return;
}
double DeltaRowCost = Move.GetDeltaRowCost();
double DeltaBinCost = Move.GetDeltaBinCost();
double DeltaNetCost = Move.GetDeltaNetCost();
double DeltaCost = GetCost(DeltaRowCost, DeltaBinCost, DeltaNetCost);
if (Accept(Temperature, DeltaCost)) {
Move.Accept();
Accepted += 1;
RowCost += DeltaRowCost;
BinCost += DeltaBinCost;
NetCost += DeltaNetCost;
Cost += DeltaCost;
SumCost += Cost; SumSquare += Cost * Cost;
SumCostRow += RowCost; SumSquareRow += RowCost * RowCost;
SumCostBin += BinCost; SumSquareBin += BinCost * BinCost;
SumCostNet += NetCost; SumSquareNet += NetCost * NetCost;
} else {
Move.Reject();
}
_totalMoves += 1;
}
StdDev = GetStdDev(SumCost, SumSquare, Accepted);
StdDevRow = GetStdDev(SumCostRow, SumSquareRow, Accepted);
StdDevBin = GetStdDev(SumCostBin, SumSquareBin, Accepted);
StdDevNet = GetStdDev(SumCostNet, SumSquareNet, Accepted);
Temperature = 20.0 * StdDev;
Iteration = (int)(5.0 * pow(GetNInsToPlace(), 1.33));
#ifdef PLACE_DEBUG
double Debug = GlobalPlaceDebugNetCost();
cout << "Debug = " << Debug << endl;
cout << "NetCost = " << NetCost << endl << endl;
//assert((NetCost - 1.0 <= Debug) && (Debug <= NetCost + 1.0));
#endif
// Placement
double firstTemperature = Temperature;
double firstCost = Cost;
double firstRowCost = RowCost;
double firstBinCost = BinCost;
double firstNetCost = NetCost;
double firstSucRatio = SucRatio;
double firstDist = Dist;
bool stucked = false;
do {
Accepted = 0;
SumCost = 0, SumCostRow = 0, SumCostBin = 0, SumCostNet = 0;
SumSquare = 0, SumSquareRow = 0, SumSquareBin = 0, SumSquareNet = 0;
for (int i = 0; i < Iteration; ++i) {
if (!Move.Next(Dist))
{
cout << " o No More Mouvement Possible ....." << endl;
stucked = true;
break;
}
double DeltaRowCost = Move.GetDeltaRowCost();
double DeltaBinCost = Move.GetDeltaBinCost();
double DeltaNetCost = Move.GetDeltaNetCost();
double DeltaCost = GetCost(DeltaRowCost, DeltaBinCost, DeltaNetCost);
if (Accept(Temperature, DeltaCost)) {
Move.Accept();
Accepted += 1;
RowCost += DeltaRowCost;
BinCost += DeltaBinCost;
NetCost += DeltaNetCost;
Cost += DeltaCost;
SumCost += Cost; SumSquare += Cost * Cost;
SumCostRow += RowCost; SumSquareRow += RowCost * RowCost;
SumCostBin += BinCost; SumSquareBin += BinCost * BinCost;
SumCostNet += NetCost; SumSquareNet += NetCost * NetCost;
} else {
Move.Reject();
}
_totalMoves += 1;
}
if (stucked)
break;
Loop += 1;
OldTemperature = Temperature;
StdDev = GetStdDev(SumCost, SumSquare, Accepted);
StdDevRow = GetStdDev(SumCostRow, SumSquareRow, Accepted);
StdDevBin = GetStdDev(SumCostBin, SumSquareBin, Accepted);
StdDevNet = GetStdDev(SumCostNet, SumSquareNet, Accepted);
if (StdDev == 0.0)
Temperature = 0.0;
else
Temperature = Temperature * max(0.5, exp(-0.7 * Temperature / StdDev));
SucRatio = Accepted / (double)Iteration;
Dist = max(0.1, min(Dist * (1.0 - 0.44 + SucRatio), 1.0));
if (_verbose)
{
cout << "Loop = " << Loop << ", Temperature = " << Temperature << ", Cost = " << Cost << endl;
cout << " RowCost = " << RowCost << ", BinCost = " << BinCost << ", NetCost = " << NetCost << endl;
cout << " Success Ratio = " << SucRatio * 100.0 << "%, Dist = " << Dist << ", Delta = " << Temperature / OldTemperature << endl;
}
else cerr << ".";
if (_boolPlot)
{
if (Loop == 1)
{
maxTemperature = Temperature;
maxCost = Cost;
maxRowCost = firstRowCost;
maxBinCost = BinCost;
maxNetCost = NetCost;
maxSucRatio = SucRatio*100.0;
maxDelta = Temperature / OldTemperature * 2;
ofout << 0 << " " << log10(((firstTemperature/maxTemperature)+1.0)) << " "
<< firstCost/maxCost << " "<< firstRowCost/maxRowCost << " "
<< firstBinCost/maxBinCost << " " << firstNetCost/maxNetCost << " "
<< (firstSucRatio*100.0)/maxSucRatio << " "
<< firstDist << " "
<< 1 << endl;
}
ofout << Loop << " " << log10(Temperature/maxTemperature+1.0) << " "
<< Cost/maxCost << " " << RowCost/maxRowCost << " "
<< BinCost/maxBinCost << " " << NetCost/maxNetCost << " "
<< (SucRatio*100.0)/maxSucRatio << " " << Dist
<< " " << (Temperature/OldTemperature)/maxDelta << endl;
}
#ifdef PLACE_DEBUG
double Debug = GlobalPlaceDebugNetCost();
cout << "Debug = " << Debug << endl;
cout << "NetCost = " << NetCost << endl << endl;
// assert ((NetCost - 1.0 <= Debug) && (Debug <= NetCost + 1.0));
#endif
} while (Temperature != 0.0 && StdDev > 0.0001 / Cost);
if (!stucked)
{
// Freeze out
Accepted = 0;
SumCost = 0, SumCostRow = 0, SumCostBin = 0, SumCostNet = 0;
SumSquare = 0, SumSquareRow = 0, SumSquareBin = 0, SumSquareNet = 0;
for (int i = 0; i < Iteration; ++i) {
if (!Move.Next(Dist))
{
cout << " o No More Mouvement Possible ....." << endl;
stucked = true;
break;
}
double DeltaRowCost = Move.GetDeltaRowCost();
double DeltaBinCost = Move.GetDeltaBinCost();
double DeltaNetCost = Move.GetDeltaNetCost();
double DeltaCost = GetCost(DeltaRowCost, DeltaBinCost, DeltaNetCost);
if (Accept(Temperature, DeltaCost)) {
Move.Accept();
Accepted += 1;
RowCost += DeltaRowCost;
BinCost += DeltaBinCost;
NetCost += DeltaNetCost;
Cost += DeltaCost;
SumCost += Cost; SumSquare += Cost * Cost;
SumCostRow += RowCost; SumSquareRow += RowCost * RowCost;
SumCostBin += BinCost; SumSquareBin += BinCost * BinCost;
SumCostNet += NetCost; SumSquareNet += NetCost * NetCost;
} else {
Move.Reject();
}
_totalMoves += 1;
}
}
if (_verbose)
{
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;
}
}
PToPlaceIns&
PPlacement::GetRandIns()
{
return *_toPlaceInss[(int) ((double)_nInsToPlace * rand() / (RAND_MAX + 1.0))];
}

View File

@ -0,0 +1,127 @@
#include "PRow.h"
#include "PPlacement.h"
#include "PConstants.h"
#include "PBBox.h"
PRow::PRow(unsigned nbofsubrows)
: PContainer(), _subRows(nbofsubrows)
{
}
PRow::PRow(PPlacement& placement,
const double ymin, const double xmax,
const unsigned nbofsubrows,
const bool orientation)
: PContainer(PBBox(PPos(0.0, ymin), PPos(xmax, ymin + ROWHEIGHT))),
_placement(&placement),
_subRows(nbofsubrows),
_orientation(orientation)
{
}
void
PRow::Init(double y, double minx, PPlacement &placement, const bool orientation)
{
_placement = &placement;
_orientation = orientation;
_bBox.SetMinY(y);
_bBox.SetMaxY(y);
_bBox.SetMinX(minx);
_bBox.SetMaxX(minx);
}
#ifndef Abs
#define Abs(x) ((x) < 0.0 ? -(x) : (x))
#endif
double
PRow::GetBinCost() const
{
double bincost = 0.0;
for (PSubRows::const_iterator srit = _subRows.begin(); srit != _subRows.end(); srit++)
{
bincost += srit->GetBinCost();
}
return bincost;
}
double
PRow::GetSubRowCost() const
{
double subrowcost = 0.0;
for (PSubRows::const_iterator srit = _subRows.begin(); srit != _subRows.end(); srit++)
{
subrowcost += Abs(srit->GetSize() - srit->GetCapa());
}
return subrowcost;
}
PSubRow&
PRow::GetSubRow(const double X)
{
// s'il y a un seul subrow on le renvoie direct
if (_subRows.size() == 1)
return _subRows[0];
// si il n'y a rien a droite
PSubRowsXMax::iterator right = _subRowsXMax.lower_bound(X);
PSubRowsXMax::iterator left = _subRowsXMaxInv.lower_bound(X);
if (right == _subRowsXMax.end())
{
assert(left != _subRowsXMaxInv.end());
return _subRows[left->second];
}
// si on est tombe direct dans un subrow...
double rightminx = _subRows[right->second].GetMinX();
if (X > rightminx)
return _subRows[right->second];
// si il n'y a rien a gauche...
if (left == _subRowsXMaxInv.end())
{
assert(right != _subRowsXMax.end());
return _subRows[right->second];
}
// on est au milieu de deux subrows, on
// renvoie le plus proche.
if ((X - _subRows[left->second].GetMaxX())
> (_subRows[right->second].GetMinX() - X))
{
return _subRows[right->second];
}
else
{
return _subRows[left->second];
}
}
ofstream&
PRow::Plot(ofstream& out) const
{
for (PSubRows::const_iterator srit=_subRows.begin(); srit!=_subRows.end(); srit++)
{
srit->Plot(out);
}
return out;
}
ofstream&
PRow::PlotLabel(ofstream& out, unsigned TotalMoves) const
{
for (PSubRows::const_iterator srit=_subRows.begin(); srit!=_subRows.end(); srit++)
{
srit->PlotLabel(out, TotalMoves);
}
return out;
}
ostream&
PRow::Print(ostream& os) const
{
return os << "PRow: " << GetMinX() << ',' << GetMinY() << " : " << GetMaxX() << ',' << GetMaxY();
}

View File

@ -0,0 +1,55 @@
#ifndef __PROW_H
#define __PROW_H
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include "PContainer.h"
using namespace std;
class PSubRow;
class PPlacement;
class PRow : public PContainer
{
friend class PPlacement;
public:
typedef vector <PSubRow> PSubRows;
typedef map<double, unsigned, less<double> > PSubRowsXMax;
typedef map<double, unsigned, greater<double> > PSubRowsXMaxInv;
private:
PPlacement* _placement;
PSubRows _subRows;
PSubRowsXMax _subRowsXMax;
PSubRowsXMaxInv _subRowsXMaxInv;
bool _orientation; // false -> sym/Y ; true -> no sym/Y
public:
PRow(unsigned nbofsubrows);
PRow(PPlacement& placement, const double ymin, const double xmax,
const unsigned nbofsubrows, const bool orientation);
void Init(double Y, double MinX, PPlacement &Placement, const bool RowOrientation);
bool GetOrientation() const { return _orientation; }
PSubRows& GetSubRows() { return _subRows; }
PSubRow& GetSubRow(const double X);
double GetSubRowCost() const;
double GetBinCost() const;
ostream& Print(ostream& os) const;
ofstream& Plot(ofstream& out) const;
ofstream& PlotLabel(ofstream& out, unsigned TotalMoves) const;
};
static inline ostream& operator<<(ostream& os, const PRow& row) {
return row.Print(os);
}
static inline ostream& operator<<(ostream& os, const PRow* row) {
return row ? row->Print(os) : os << "(nil)";
}
#endif /* __PROW_H */

View File

@ -0,0 +1,153 @@
#include "PSubRow.h"
#include "PBin.h"
#include "PToPlaceIns.h"
#include "PConstants.h"
PSubRow::PSubRow()
: PContainer(), _bins(),
_binsXMax()
{}
PSubRow::~PSubRow()
{}
unsigned
PSubRow::GetNBins() const
{
return _bins.size();
}
void
PSubRow::Init(PRow* row, double y, double minx, double maxx, double margin, double maxbinwidth, double minbinwidth)
{
_row = row;
PBBox binbbox;
double xpos;
int binswidth;
int binscapa;
int modulo = 0;
_bBox.SetMinY(y);
_bBox.SetMaxY(y + ROWHEIGHT);
_bBox.SetMinX(minx);
_bBox.SetMaxX(maxx);
_size = 0.0;
_capa = (maxx - minx) * (1.0 - margin);
_max = maxx - minx;
binbbox.SetMinY(_bBox.GetMinY());
binbbox.SetMaxY(_bBox.GetMaxY());
xpos = minx;
if ( ((int)(maxx - minx) % (int)(maxbinwidth)) > 0)
_nBins = (unsigned)((maxx - minx)/maxbinwidth) + 1;
else
_nBins = (unsigned)((maxx - minx)/maxbinwidth);
modulo = ((int)(maxx - minx) % _nBins);
binswidth = (int)((maxx - minx) / _nBins);
binscapa = (int)(binswidth * ( 1 - margin));
_bins.reserve(_nBins);
for (unsigned binnumber = 0; binnumber < _nBins; binnumber++)
{
_bins.push_back(PBin());
binbbox.SetMinX(xpos);
if (modulo > 0)
{
xpos += (binswidth+1);
binbbox.SetMaxX(xpos);
modulo--;
}
else
{
xpos += binswidth;
binbbox.SetMaxX(xpos);
}
_binsXMax[xpos] = binnumber;
_bins.back().Init(binbbox, binscapa, *this);
}
_row->MergeBBox(_bBox);
}
PBin&
PSubRow::GetBin(const double X)
{
if (X >= _bins.rbegin()->GetMaxX())
return *(_bins.rbegin());
if (X <= _bins.begin()->GetMinX())
return *(_bins.begin());
PBinsXMax::iterator srpos = _binsXMax.upper_bound(X);
return _bins[srpos->second];
}
bool
PSubRow::InsertIns(PToPlaceIns& Ins, int BinNumber)
{
if ((_bins[BinNumber].GetCapa() - _bins[BinNumber].GetSize())
< Ins.GetWidth())
return false;
else
{
_bins[BinNumber].AddIns(&Ins);
return true;
}
}
unsigned
PSubRow::GetNIns() const
{
unsigned nins = 0;
for (PBins::const_iterator BinIt=_bins.begin(); BinIt!=_bins.end(); BinIt++)
nins += BinIt->GetNIns();
return nins;
}
void
PSubRow::ForceIns(PToPlaceIns& Ins, int BinNumber)
{
_bins[BinNumber].AddIns(&Ins);
}
#ifndef Abs
#define Abs(x) ((x) < 0.0 ? -(x) : (x))
#endif
double
PSubRow::GetBinCost() const
{
double BinCost = 0.0;
for (PBins::const_iterator BinIt = _bins.begin(); BinIt != _bins.end(); BinIt++)
{
BinCost += Abs(BinIt->GetSize() - BinIt->GetCapa());
}
return BinCost;
}
ofstream&
PSubRow::Plot(ofstream& out) const
{
for (PBins::const_iterator BinIt=_bins.begin(); BinIt!=_bins.end(); BinIt++)
{
BinIt->Plot(out);
}
return out;
}
ofstream&
PSubRow::PlotLabel(ofstream& out, unsigned TotalMoves) const
{
for (PBins::const_iterator BinIt=_bins.begin(); BinIt!=_bins.end(); BinIt++)
{
BinIt->PlotLabel(out, TotalMoves);
}
return out;
}
ostream&
PSubRow::Print(ostream& os) const
{
return os << "PSubRow: " << GetMinX() << ',' << GetMinY() << " : " << GetMaxX() << ',' << GetMaxY();
}

View File

@ -0,0 +1,54 @@
#ifndef __PSubRow_h
#define __PSubRow_h
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include "PContainer.h"
#include "PRow.h"
class PBin;
class PToPlaceIns;
class PSubRow : public PContainer {
friend class PRow;
public:
typedef vector <PBin> PBins;
typedef map <double, unsigned> PBinsXMax;
private:
PRow* _row;
PBins _bins;
PBinsXMax _binsXMax;
double _size; // somme des Width des bins de la row
double _capa; // l'occupation ideale de la row
double _max; // seuil de la ligne !!ne pas dépasser
unsigned _nBins; // Bins.size();
public:
PSubRow();
~PSubRow();
void Init(PRow* row, double y, double minx, double maxx, double margin, double maxbinwidth, double minbinwidth);
bool InsertIns(PToPlaceIns& Ins, int BinNumber);
void ForceIns(PToPlaceIns& Ins, int BinNumber);
bool GetOrientation() const { return _row->GetOrientation(); }
PRow* GetRow() { return _row; }
PBin& GetBin(const double X);
PBins& GetBins() { return _bins; }
double GetCapa() const { return _capa; }
double GetSize() const { return _size; }
double GetMax() const { return _max; }
unsigned GetNIns() const;
double GetBinCost() const;
void AddSize(const double Value) { _size += Value; }
unsigned GetNBins() const;
ostream& Print(ostream& os) const;
ofstream& Plot(ofstream& out) const;
ofstream& PlotLabel(ofstream& out, unsigned TotalMoves) const;
};
#endif /* __PSubRow_h */

View File

@ -0,0 +1,18 @@
#include "PToPlaceIns.h"
extern "C"{
#include "mut.h"
#include "mph.h"
}
#include "PConstants.h"
PToPlaceIns::PToPlaceIns(const loins *instance):
PIns(instance),
_bin(0)
{}
ostream&
PToPlaceIns::Print(ostream& os) const
{
return os << "PToPlaceIns: " <<
_instance->FIGNAME << ':' << _instance->INSNAME << ':' << GetPos();
}

View File

@ -0,0 +1,25 @@
#ifndef __PTOPLACEINS_H
#define __PTOPLACEINS_H
#include "PIns.h"
#include "PBin.h"
class PToPlaceIns : public PIns {
private:
PBin* _bin;
public:
PToPlaceIns(const loins* ins);
void SetBin(PBin* NewBin) { _bin = NewBin; }
PBin& GetBin() const { return *_bin; }
PPos GetPos() const { return _bin->GetPos(); }
double GetHeight() const { return _bin->GetHeight(); }
bool GetOrientation() const { return _bin->GetOrientation(); }
ostream& Print(ostream& os) const;
};
#endif /* __PTOPLACEINS_H */

View File

@ -0,0 +1,24 @@
#ifndef __IOC_HEADER_H
#define __IOC_HEADER_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct connector
{
struct connector *NEXT ;
char ORIENT ;
char *NAME ;
int VALUE ; // in case of SPACE
} con_list;
extern con_list* add_con(con_list* ptlist, char orient, char* name);
extern con_list* add_space(con_list* ptlist, char orient, char* value);
extern con_list* iocparse(char *file);
#ifdef __cplusplus
}
#endif
#endif /* __IOC_HEADER_H */