ocp is back ....
This commit is contained in:
parent
a79fd9b05c
commit
4f28ec1138
|
@ -0,0 +1,3 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = doc src
|
|
@ -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
|
|
@ -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
|
||||
])
|
|
@ -0,0 +1,4 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
man_MANS = ocp.1
|
||||
EXTRA_DIST = $(man_MANS)
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = common placer
|
|
@ -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
|
|
@ -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 << ')';
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __PCONSTANTS_H
|
||||
#define __PCONSTANTS_H
|
||||
|
||||
#define PITCH (5 * SCALE_X)
|
||||
#define ROWHEIGHT 10
|
||||
|
||||
#endif /* __PCONSTANTS_H */
|
|
@ -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 */
|
|
@ -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 << ')';
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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))];
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
Loading…
Reference in New Issue