Ca roule.

This commit is contained in:
Hugo Clement 2002-03-15 14:37:27 +00:00
parent bd71a62dc6
commit f891c4a8e6
54 changed files with 13340 additions and 0 deletions

View File

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

View File

@ -0,0 +1,48 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/rout/ocrRouter.c)
OCR_MAJOR_VERSION=1
OCR_MINOR_VERSION=0
OCR_VERSION=$OCR_MAJOR_VERSION.$OCR_MINOR_VERSION
AC_SUBST(OCR_MAJOR_VERSION)
AC_SUBST(OCR_MINOR_VERSION)
AC_SUBST(OCR_VERSION)
# For automake.
VERSION=$OCR_VERSION
PACKAGE=ocr
dnl Initialize automake stuff
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_MAKE_SET
dnl Checks for libraries.
AC_CHECK_LIB(m, sqrt)
dnl Checks for alliance.
changequote(,)dnl
INCLUDES=-I${ALLIANCE_TOP}/include
LDFLAGS=-L${ALLIANCE_TOP}/lib
changequote([,])dnl
AC_SUBST(INCLUDES)
AC_SUBST(LDFLAGS)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
dnl Checks for library functions.
AC_OUTPUT([
Makefile
src/Makefile
src/rout/Makefile
src/seg/Makefile
src/util/Makefile
doc/Makefile
])

View File

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

View File

@ -0,0 +1,85 @@
on veut
ne calculer qu'une fois l'heuristique / segment :
-> stocker la valeur dans la struct ocrWSegment
-> maintenir une table de correspondance <-
garder le cout total du chemin :
-> liste ordonnee de couple (segment, valeur),
l'information concernant le chemin est obtenue par retour recursif.
->
struct path_list {
ocrWSegment *seg;
ocrNaturalInt cost;
struct path_list *NEXT;
} path_list;
Insertion triee ->
insert (elem, list)
si list == NULL
return elem
si list->cost > elem->cost
elem->NEXT = list
return elem
list->NEXT = insert (elem, list->NEXT)
pop (list) -> renvoie
---------
Heuristique : distance de manhattan
struct toto {
ocrNaturalInt cost;
struct toto *NEXT;
} toto;
gmake | grep -v "^d "
int fonc (toto *truc)
int fonc (toto **truc)
int fonc (toto &truc)
{
toto *chose;
chose = malloc (...);
fonc (chose)
ocrWSegment

View File

@ -0,0 +1,68 @@
.\" $Id: ocr.1,v 1.1 2002/03/15 14:37:10 hcl Exp $
.\" @(#)Labo.l 0.0 92/09/24 UPMC; Author: Hugo CLEMENT
.pl -.4
.TH OCR 1 "January 11, 2002" "ASIM/LIP6" "CAO\-VLSI Reference Manual"
.SH NAME
.TP
ocr
- An over-the-cell router
.so man1/alc_origin.1
.SH SYNOPSIS
.TP
\fBocr\fP
[\fBoptions\fP] -L <\fIlogical_view\fP> -P <\fIplaced_view\fP> -O <\fIrouted_view\fP>
.br
.SH DESCRIPTION
\fBocr\fP is an automatic router tool for standard-cells.
.br
\fBinput net-list\fP
.br
The \fIlogical_view\fP and \fIplaced_view\fP files describe the input net-list.
.br
\fBocr\fP supports a hierarchical net-list. In this case the net-list is flattened by the router according to the catalog file. The file format of the input files is set respectively by the environment variable \fBMBK_IN_LO\fP and \fBMBK_IN_PH\fP.
.br
\fBoutput layout\fP
.br
The file containing the routed block will have the name \fIrouted_view\fP. The output format is defined by the environment variable \fBMBK_OUT_PH\fP.
.br
.SH OPTIONS
.br
\fBNumber of layers\fP
.br
\fB-l [0-9]+\fP
.br
This paramaters sets how many layers the router is allowed to use. The maximun is 5 (ie up to, and including, ALU6). The default is the minimum : 2, ie use only ALU2 and ALU3.
.br
\fBIterations\fP
.br
\fB-i [0-9]+\fP
.br
Tells the router to stop its main loop when it reaches N iterations. The default is to loop till core dump.
.br
\fBVerbose mode\fP
.br
\fB-v\fP set the verbose mode on
.br
\fB-vv\fP produces a lot of output
.br
\fB-d\fP for debugging purpose
.br
.SH ENVIRONMENT VARIABLES
.PP
\fBocr\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
ocp(1), MBK_IN_LO(1), MBK_IN_PH(1), MBK_OUT_PH(1), MBK_VDD(1), MBK_VSS(1)
.so man1/alc_bug_report.1

View File

@ -0,0 +1,5 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = seg util rout
EXTRA_DIST = include/*.h

View File

@ -0,0 +1,61 @@
# Alliance VLSI CAD System
#
# Product : OVER-THE-CELL ROUTER
# File : Makefile
#
# Author(s) : Mael NAGAT Date : 27/05/1999
# Modified by : Date : ../../....
# Modified by : Date : ../../....
# Modified by : Date : ../../....
# Alliance Shared Libraries and Include Files for Makefiles
include $(ALLIANCE_TOP)/etc/$(ALLIANCE_OS).mk
include $(ALLIANCE_TOP)/etc/libraries.mk
# Sources
OCR_SRC_FILE =
# Include Flags for Alliance Shared Libraries
OCR_ALC_INCLUDE = -I$(ALLIANCE_INCLUDE) \
-DMLU_H='<$(MLU_H)>' \
-DMPU_H='<$(MPU_H)>' \
-DMLO_H='<$(MLO_H)>' \
-DMPH_H='<$(MPH_H)>' \
-DMUT_H='<$(MUT_H)>'
# Libraries Flags for Alliance Shared Libraries
OCR_ALC_LIB = -L$(ALLIANCE_LIB) \
$(MLU_L) \
$(MPU_L) \
$(MCP_L) \
$(MAP_L) \
$(MMG_L) \
$(MCL_L) \
$(MGL_L) \
$(MAL_L) \
$(MVL_L) \
$(MEL_L) \
$(MSL_L) \
$(MHL_L) \
$(RCN_L) \
$(MLO_L) \
$(MPH_L) \
$(MUT_L)
# Compilation Flags
OCR_CFLAGS = -Wall -O4 -pg
# Non file targets
.PHONY: clean
TARGET_DIR = $(HOME)/local/$(ALLIANCE_OS)/bin
# Rules
$(TARGET_DIR)/densite : densite.c
ctags *.c
$(CC) $(OCR_CFLAGS) $(OCR_ALC_INCLUDE) $< $(OCR_ALC_LIB) -o $@
clean :
-$(RM) -f $(TARGET_DIR)/densite *.o
-$(RM) -f *~

View File

@ -0,0 +1,221 @@
#include <stdlib.h>
#include MUT_H
#include MLO_H
#include MLU_H
#include MPH_H
#include MPU_H
#include <string.h>
//#define SITE_SIZE 300.0
#define SITE_SIZE 100.0
#define SCALE_X 100.0
#define PITCH 5.0
#define FEN (SITE_SIZE / PITCH)
#define FEN2 (FEN * FEN)
phfig_list *l_pPhFig;
#define DHOR(x,y) l_tDensHor[x+(y)*(l_nXMax-0)]
#define DVER(x,y) l_tDensVert[x+(y)*(l_nXMax-0)]
long
getX (long i_nX)
{
return (i_nX - l_pPhFig->XAB1) / SCALE_X / SITE_SIZE;
}
long
getY (long i_nY)
{
return (i_nY - l_pPhFig->YAB1) / SCALE_X / SITE_SIZE;
}
long
getMin (int i_nXY)
{
return i_nXY * SITE_SIZE * SCALE_X;
}
long
getMax (int i_nXY)
{
return (i_nXY + 1) * SITE_SIZE * SCALE_X - 1;
}
int
main (int argc, char **argv)
{
FILE *l_pDataFile;
phseg_list *l_pPhSeg;
long i = 0;
long j = 0;
double *l_tDensHor;
double *l_tDensVert;
char l_sName[50];
long l_nXMax;
long l_nYMax;
if (argc != 3)
{
fprintf (stderr, "usage : densite src dest\n");
fprintf (stderr, "src : fichier ap\n");
fprintf (stderr, "dest : fichier gp\n");
exit (1);
}
// initialisation de MBK
mbkenv ();
// Lecture de la vue physique
l_pPhFig = getphfig (argv[1], 'A');
for (l_pPhSeg = l_pPhFig->PHSEG;
l_pPhSeg;
l_pPhSeg = l_pPhSeg->NEXT)
i++;
printf ("%ld segments\n", i);
printf ("(%ld,%ld) (%ld,%ld)\n", l_pPhFig->XAB1, l_pPhFig->YAB1,
l_pPhFig->XAB2, l_pPhFig->YAB2);
l_nXMax = getX (l_pPhFig->XAB2) + 1;
l_nYMax = getY (l_pPhFig->YAB2) + 1;
printf ("XMax = %ld\n", l_nXMax);
printf ("YMax = %ld\n", l_nYMax);
l_tDensHor = (double *) mbkalloc (sizeof (double) * l_nXMax * l_nYMax);
l_tDensVert = (double *) mbkalloc (sizeof (double) * l_nXMax * l_nYMax);
for (i = 0; i < l_nXMax; i++)
for (j = 0; j < l_nYMax; j++)
{
DHOR (i, j) = 0.0;
DVER (i, j) = 0.0;
}
for (l_pPhSeg = l_pPhFig->PHSEG;
l_pPhSeg;
l_pPhSeg = l_pPhSeg->NEXT)
{
switch (l_pPhSeg->LAYER)
{
case ALU2:
case ALU4:
case ALU6:
/*
viewphseg(l_pPhSeg);
printf("f1 : (%ld,%ld) f2 : (%ld,%ld)\n",
getX (l_pPhSeg->X1),getX (l_pPhSeg->Y1),
getX (l_pPhSeg->X2),getX (l_pPhSeg->Y2));
*/
for (i = getX (l_pPhSeg->X1); i <= getX (l_pPhSeg->X2); i++)
{
double res;
if (i == getX (l_pPhSeg->X1))
{
if (i == getX (l_pPhSeg->X2))
{
res = ((double) (l_pPhSeg->X2 - l_pPhSeg->X1)
/ SCALE_X / PITCH + 1) / FEN2;
}
else
{
res = ((double) (getMax (i) - l_pPhSeg->X1)
/ SCALE_X / PITCH + 1) / FEN2;
}
}
else
{
if (i == getX (l_pPhSeg->X2))
{
res = ((double) (l_pPhSeg->X2 - getMin (i))
/ SCALE_X / PITCH + 1) / FEN2;
}
else
{
res = 1.0 / FEN;
}
}
DHOR (i, getY (l_pPhSeg->Y1)) += res;
}
break;
case ALU3:
case ALU5:
case ALU7:
/*
viewphseg(l_pPhSeg);
printf("f1 : (%ld,%ld) f2 : (%ld,%ld)\n",
getX (l_pPhSeg->X1),getX (l_pPhSeg->Y1),
getX (l_pPhSeg->X2),getX (l_pPhSeg->Y2));
*/
for (i = getY (l_pPhSeg->Y1); i <= getY (l_pPhSeg->Y2); i++)
{
double res;
if (i == getY (l_pPhSeg->Y1))
{
if (i == getY (l_pPhSeg->Y2))
{
res = ((double) (l_pPhSeg->Y2 - l_pPhSeg->Y1)
/ SCALE_X / PITCH + 1) / FEN2;
}
else
{
res = ((double) (getMax (i) - l_pPhSeg->Y1)
/ SCALE_X / PITCH + 1) / FEN2;
}
}
else
{
if (i == getY (l_pPhSeg->Y2))
{
res = ((double) (l_pPhSeg->Y2 - getMin (i))
/ SCALE_X / PITCH + 1) / FEN2;
}
else
{
res = 1.0 / FEN;
}
}
DVER (getX (l_pPhSeg->X1), i) += res;
}
}
}
strcpy (l_sName, argv[2]);
strcat (l_sName, ".gp");
l_pDataFile = fopen (l_sName, "w");
if (!l_pDataFile)
{
printf ("Impossible d'écrire le fichier %s\n", argv[2]);
exit (1);
}
fprintf (l_pDataFile, "# densite de %s.ap\n\n", argv[1]);
for (i = 0; i < l_nXMax; i++)
{
for (j = 0; j < l_nYMax; j++)
{
fprintf (l_pDataFile, "%ld\t%ld\t%f\t%f\n",
i, j, DHOR (i, j), DVER (i, j));
}
fprintf (l_pDataFile, "\n");
}
fclose (l_pDataFile);
mbkfree (l_tDensHor);
mbkfree (l_tDensVert);
delphfig (*argv);
exit (0);
}

View File

@ -0,0 +1,31 @@
#ifndef _OCR_DISPLAY_H_
#define _OCR_DISPLAY_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:13 $
$Log: display.h,v $
Revision 1.1 2002/03/15 14:37:13 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:11 hcl
First commit in the new tree.
Revision 1.3 2002/02/12 15:13:59 hcl
verbosity fix.
Revision 1.2 2002/01/14 10:34:27 hcl
OCR should be MBK_SCALE_X - compliant
Revision 1.1 2001/09/26 14:27:44 hcl
premier commit....
### -------------------------------------------------- ###
*/
// Type
enum {ERROR,WARNING,INFO,DEBUG,VERBOSE,VVERB};
void display (int i_nLevel, int i_nType, char *fmt,...);
#endif /* _OCR_DISPLAY_H_ */

View File

@ -0,0 +1,25 @@
#ifndef _GETOPTION_H_
#define _GETOPTION_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:14 $
$Log: getOption.h,v $
Revision 1.1 2002/03/15 14:37:14 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:11 hcl
First commit in the new tree.
Revision 1.2 2001/11/20 09:39:56 hcl
du bo, du bon, prefet dubonnet
Revision 1.1 2001/09/26 14:27:44 hcl
premier commit....
### -------------------------------------------------- ###
*/
ocrOption * getOption (int argc, char **argv);
#endif /*_GETOPTION_H_*/

View File

@ -0,0 +1,46 @@
#ifndef _MBK_TREE_H_
#define _MBK_TREE_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:14 $
$Log: mbk_tree.h,v $
Revision 1.1 2002/03/15 14:37:14 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:11 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 16:05:07 root
*** empty log message ***
### -------------------------------------------------- ###
*/
extern rbtree rbtreeNil;
#define RBTREENULL &rbtreeNil /* Nil sentinel */
extern rbtree *getrbtree(rbtree *root, void *key, int (*cmp) (void *, void *));
extern rbtree *getrbtree2(rbtree *root, void *key, rbtree **previous, rbtree **next, int (*cmp) (void *, void *));
extern rbtree *getmostrbtree(rbtree *root);
extern rbtree *getleastrbtree(rbtree *root);
extern rbtree *getpreviousrbtree(rbtree *node);
extern rbtree *getnextrbtree(rbtree *node);
extern rbtree *addrbtree(rbtree *root, void *key, void *data, int (*cmp) (void *, void *));
extern rbtree *addrbtree2(rbtree *root, rbtree *parent, void *key, void *data, int (*cmp) (void *, void *));
extern rbtree *delrbtree(rbtree *root, rbtree *node);
extern void freerbtree(rbtree *root, void (*freekey) (void *), void (*freedata) (void *));
/* Fonctions static internes !
extern void mapmosttoleastrbtree(rbtree *root, void (*fun) (rbtree *));
extern void mapleasttomostrbtree(rbtree *root, void (*fun) (rbtree *));
extern void *mapmosttoleastrbtree2(rbtree *root, void *(*fun) (rbtree *, void *), void *seed);
extern void *mapleasttomostrbtree2(rbtree *root, void *(*fun) (rbtree *, void *), void *seed);
*/
#endif /* _MBK_TREE_H_ */

View File

@ -0,0 +1,45 @@
#ifndef _OCR_H_
#define _OCR_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:14 $
$Log: ocr.h,v $
Revision 1.1 2002/03/15 14:37:14 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:11 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.3 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#define OCRNATURALINT_MAX 0xFFFFFFFF
#define OCRNATURALSHORT_MAX 0xFF
#define OCR_OK 1
typedef unsigned long ocrNaturalInt;
typedef unsigned char ocrNaturalShort;
typedef long ocrInt;
typedef enum ocrRoutingDirection {
ocrVertical = 0,
ocrHorizontal = 1
} ocrRoutingDirection;
typedef struct ocrRoutingParameters {
ocrNaturalShort PITCH_H;
ocrNaturalShort PITCH_V;
ocrNaturalShort VIA_COST;
ocrRoutingDirection EVEN_LAYERS_DIRECTION;
} ocrRoutingParameters;
#endif /* _OCR_H_ */

View File

@ -0,0 +1,36 @@
#ifndef _OCRASTAR_H
#define _OCRASTAR_H
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:14 $
$Log: ocrAstar.h,v $
Revision 1.1 2002/03/15 14:37:14 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:11 hcl
First commit in the new tree.
Revision 1.1 2002/02/12 15:13:59 hcl
verbosity fix.
### -------------------------------------------------- ###
*/
#define AS_K_SEG 0
#define AS_K_EQUI 1
ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
ocrWRoutingGrid * p_grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget,
ocrNaturalInt signal_index,
ocrSignal * i_pSignal,
ocrNaturalInt mode);
#endif

View File

@ -0,0 +1,73 @@
#ifndef _OCRCONNECTORUTIL_H_
#define _OCRCONNECTORUTIL_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:14 $
$Log: ocrConnectorUtil.h,v $
Revision 1.1 2002/03/15 14:37:14 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:12 hcl
First commit in the new tree.
Revision 1.2 2001/11/20 09:39:57 hcl
du bo, du bon, prefet dubonnet
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#define OCR_BAD_CON1 2
#define OCR_BAD_CON2 3
ocrNaturalInt distBetween2VirCon (
ocrVirtualConnector * l_pVirCon1,
ocrVirtualConnector * l_pVirCon2);
void ChooseExtConnector (
ocrRoutingDataBase * i_pDataBase);
void ChooseIntConnector (
ocrRoutingDataBase * i_pDataBase);
void createHashTable (
ocrRoutingDataBase * i_pDataBase,
phfig_list * i_pPhFig);
void deleteHashTable (
ocrRoutingDataBase * i_pDataBase);
ocrNaturalInt isFreePoint (ocrConnector *l_pCon, ocrWRoutingGrid * i_pGrid,
ocrVirtualConnector * l_pVirCon);
ocrNaturalShort chooseInternalConnector (ocrWRoutingGrid * i_pGrid,
ocrConnector * i_pCon,
ocrConnector * i_pCon2,
int mode);
ocrNaturalShort
chooseInternalConnector2(ocrWRoutingGrid * i_pGrid,
ocrConnector * i_pCon);
void initConnectorList (ocrRoutingDataBase * i_pDataBase,
phfig_list * i_pPhFig,
lofig_list * i_pLoFig);
ocrNaturalInt
distBetween2VirCon (ocrVirtualConnector * l_pVirCon1,
ocrVirtualConnector * l_pVirCon2);
void
deleteConVirInConVirList (ocrVirtualConnector ** io_VirConList,
ocrVirtualConnector * i_pConVir);
ocrNaturalInt
isCriticalConnector (ocrWRoutingGrid * i_pGrid,
ocrConnector * i_pCon);
#endif /* _OCRCONNECTORUTIL_H_ */

View File

@ -0,0 +1,24 @@
#ifndef _OCRGLOBALROUTING_H_
#define _OCRGLOBALROUTING_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:15 $
$Log: ocrGlobalRouting.h,v $
Revision 1.1 2002/03/15 14:37:15 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:12 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
### -------------------------------------------------- ###
*/
ocrNaturalInt globalRouting (ocrRoutingDataBase * i_pDataBase);
#endif /* _OCRGLOBALROUTING_H_ */

View File

@ -0,0 +1,28 @@
#ifndef _OCRINITDATABASE_H_
#define _OCRINITDATABASE_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:15 $
$Log: ocrInitDataBase.h,v $
Revision 1.1 2002/03/15 14:37:15 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:12 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
### -------------------------------------------------- ###
*/
ocrRoutingDataBase *initDataBase (
phfig_list * i_pPhFig,
lofig_list * i_pLoFig);
#endif /* _OCRINITDATABASE_H */

View File

@ -0,0 +1,36 @@
#ifndef _OCRMST_H_
#define _OCRMST_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:15 $
$Log: ocrMst.h,v $
Revision 1.1 2002/03/15 14:37:15 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:12 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
### -------------------------------------------------- ###
*/
#define ocrNode ocrVirtualConnector
typedef struct ocrEdge
{
struct ocrEdge *NEXT;
ocrNaturalInt COST;
ocrNode *N1;
ocrNode *N2;
}
ocrEdge;
// Fonctions de base
ocrEdge * makingMst (ocrSignal * i_pSignal);
#endif /* _OCRMST_H_ */

View File

@ -0,0 +1,40 @@
#ifndef _OCRNPOINTS_H_
#define _OCRNPOINTS_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:15 $
$Log: ocrNpoints.h,v $
Revision 1.1 2002/03/15 14:37:15 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:12 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
### -------------------------------------------------- ###
*/
ocrNaturalInt
findPathNPoints (ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid,
ocrSignal * i_pSignal, ocrWindow * i_pWindow);
void
unifyPoint (ocrWRoutingGrid * i_pGrid,
ocrRoutingParameters * i_pParam,
ocrSignal * i_pSignal,
ocrNaturalInt i_uXPoint,
ocrNaturalInt i_uYPoint, ocrNaturalInt i_uZPoint);
ocrVirtualConnector *makeEquipotentielle (ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid,
ocrSignal * i_pSignal);
void
deleteEquipotentielle (ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid, ocrSignal * i_pSignal);
#endif /* _OCRNPOINTS_H_ */

View File

@ -0,0 +1,62 @@
ocrWSegment * getWSegmentCV (ocrWRoutingGrid * grid,
ocrVirtualConnector * i_pVirCon);
ocrWSegment * getWSegment (ocrWRoutingGrid * grid,
ocrNaturalInt x,
ocrNaturalInt y,
ocrNaturalInt z);
ocrRoutingDirection getWSegDirection (ocrRoutingParameters * i_param,
ocrWSegment * i_segment);
ocrWSegment * createWSegment (ocrNaturalInt offset,
ocrNaturalInt layer,
ocrNaturalInt p_min,
ocrNaturalInt p_max,
ocrNaturalInt signal_index);
void setWGrid (ocrWRoutingGrid * grid,
ocrWSegment * segment,
ocrNaturalInt x,
ocrNaturalInt y,
ocrNaturalInt z);
ocrNaturalInt findPathBetween2Points (ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget,
ocrNaturalInt signal_index,
ocrSignal * i_pSignal);
ocrRoutingParameters *
setParameters (ocrNaturalShort pitch_h,
ocrNaturalShort pitch_v,
ocrNaturalShort via_cost,
ocrRoutingDirection dir_of_even_layers);
ocrWRoutingGrid *createWGrid (ocrNaturalInt size_h,
ocrNaturalInt size_v,
ocrNaturalInt nb_of_layers);
void initWGrid (ocrWRoutingGrid * i_pGrid,
ocrRoutingParameters * i_pParam);
void dumpIntExtConToPhFig (ocrRoutingDataBase * i_pDataBase,
ocrRoutingParameters * i_pParam,
phfig_list * i_pPhFig);
ocrNaturalInt dumpGridToPhFig (ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid,
phfig_list * i_pPhFig);
void freeWGrid (ocrWRoutingGrid * i_pGrid);

View File

@ -0,0 +1,39 @@
#ifndef _OCRSIGNALUTIL_H_
#define _OCRSIGNALUTIL_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:15 $
$Log: ocrSignalUtil.h,v $
Revision 1.1 2002/03/15 14:37:15 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:13 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
### -------------------------------------------------- ###
*/
#define ORDER_RANDOM 1
#define ORDER_CON 2
#define ORDER_PRIORITY 3
#define ORDER_PRIORITY_CON 4
#define ORDER_PRIORITY_RANDOM 5
void initGlobalSignalList (ocrRoutingDataBase * i_pDataBase,
lofig_list * i_pLoFig);
void orderingSignals (ocrSignal ** i_pSignal,
ocrNaturalInt i_uNbSig, ocrNaturalShort i_uType);
ocrNaturalInt
isCriticalSignal (ocrRoutingDataBase * i_pDataBase, ocrNaturalInt i_uRang);
void linkSignal (ocrRoutingDataBase * i_pDataBase,
ocrSignal * i_pSignal);
#endif /* _OCRSIGNALUTIL_H_ */

View File

@ -0,0 +1,62 @@
#ifndef _OCRTOPHFIG_H_
#define _OCRTOPHFIG_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:16 $
$Log: ocrToPhFig.h,v $
Revision 1.1 2002/03/15 14:37:16 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:13 hcl
First commit in the new tree.
Revision 1.2 2002/01/14 10:34:27 hcl
OCR should be MBK_SCALE_X - compliant
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
void addViaToPhFig (
ocrRoutingParameters * i_pParam,
ocrNaturalInt i_uX,
ocrNaturalInt i_uY,
int i_uLayer,
phfig_list * io_pPhFig);
void dumpIntExtConToPhFig (
ocrRoutingDataBase * i_pDataBase,
ocrRoutingParameters * i_pParam,
phfig_list * i_pPhFig);
void dumpAlimToPhFig (
ocrRoutingDataBase * i_pDataBase,
phfig_list * i_pPhFig);
ocrNaturalInt dumpGridToPhFig (
ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid,
phfig_list * i_pPhFig);
void
addViaToPhFig (ocrRoutingParameters * i_pParam,
ocrNaturalInt i_uX,
ocrNaturalInt i_uY,
int i_nLayer,
phfig_list * io_pPhFig);
void
addSegmentToPhFig (ocrRoutingParameters * i_pParam,
ocrWSegment * i_pSegment,
phfig_list * io_pPhFig,
char *i_pName);
void
dumpPhFigToDisk (char *i_sName,
phfig_list * i_pPhFig);
#endif /* _OCRTOPHFIG_H_ */

View File

@ -0,0 +1,49 @@
#ifndef _OCRUTIL_H_
#define _OCRUTIL_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:16 $
$Log: ocrUtil.h,v $
Revision 1.1 2002/03/15 14:37:16 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:13 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#define ABSDIFF(a,b) ( (a) > (b) ? (a) - (b) : (b) - (a) )
#define MIN(a,b) ( (a) <= (b) ? (a) : (b) )
#define MAX(a,b) ( (a) >= (b) ? (a) : (b) )
extern ocrRoutingParameters *setParameters(ocrNaturalShort pitch_h,
ocrNaturalShort pitch_v,
ocrNaturalShort via_cost,
ocrRoutingDirection dir_of_even_layers);
extern ocrNaturalInt manhattan3Distance(ocrRoutingParameters *param,
ocrNaturalInt x1,
ocrNaturalInt y1,
ocrNaturalInt z1,
ocrNaturalInt x2,
ocrNaturalInt y2,
ocrNaturalInt z2);
extern ocrNaturalInt manhattan2Distance(ocrRoutingParameters *param,
ocrNaturalInt x1,
ocrNaturalInt y1,
ocrNaturalInt x2,
ocrNaturalInt y2);
extern ocrRoutingDirection getDirection(ocrRoutingParameters *param,
ocrNaturalInt z);
#endif /* _OCRUTIL_H_ */

View File

@ -0,0 +1,70 @@
#ifndef _OCRWPLANELABELING_H_
#define _OCRWPLANELABELING_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:16 $
$Log: ocrWPlaneLabeling.h,v $
Revision 1.1 2002/03/15 14:37:16 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:13 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
extern void freeNextDeltaSubWSegList(chain_list **list,
ocrNaturalInt *nb_of_elements,
ocrNaturalInt layer);
extern ocrNaturalInt processNextDelta(ocrRoutingParameters *param,
ocrWRoutingGrid *grid,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta,
chain_list **labeled_segment_list,
chain_list **next_delta_sub_segment_list,
ocrNaturalInt *nb_of_sub_segments,
chain_list **segment_garbage);
extern void labelPlane(ocrRoutingParameters *param,
ocrWRoutingGrid *grid,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget,
ocrNaturalInt delta_sce,
ocrNaturalInt plane_sce,
ocrNaturalInt plane_dest,
chain_list **next_delta_sub_segment_list,
ocrNaturalInt *nb_of_sub_segments,
chain_list **labeled_segment_list);
extern void initNextDeltaSubWSegList(ocrRoutingParameters *param,
ocrWRoutingGrid *grid,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
chain_list ***list,
ocrNaturalInt **nb_of_elements,
ocrWSegment *segment_source,
ocrNaturalInt xsource,
ocrNaturalInt ysource);
extern void initLabeledWSegList(ocrWRoutingGrid *grid,
chain_list ***list,
ocrWSegment *segment_source);
extern void cleanLabeledWSegments(ocrWRoutingGrid *grid,
chain_list **labeled_segment_list,
chain_list **segment_garbage);
extern int isNextDeltaSubWSegListNotEmpty(ocrWRoutingGrid *grid,
chain_list **list);
#endif /* _OCRWPLANELABELING_H_ */

View File

@ -0,0 +1,43 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:16 $
$Log: ocrWRouting.h,v $
Revision 1.1 2002/03/15 14:37:16 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:13 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#ifndef _OCRWROUTING_H_
#define _OCRWROUTING_H_
extern ocrNaturalInt findPathBetween2Points(ocrRoutingParameters *param,
ocrWRoutingGrid *grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget,
ocrNaturalInt signal_index,
ocrSignal * i_pSignal);
extern void displayPath(ocrRoutingParameters *param,
ocrWRoutingGrid *grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget);
#endif /* _OCRWROUTING_H_ */

View File

@ -0,0 +1,329 @@
#ifndef _OCRWROUTINGDATABASE_H_
#define _OCRWROUTINGDATABASE_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:16 $
$Log: ocrWRoutingDataBase.h,v $
Revision 1.1 2002/03/15 14:37:16 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:14 hcl
First commit in the new tree.
Revision 1.5 2002/02/21 13:17:46 hcl
Introducing a new algo (A*, dont yet work...)
Revision 1.4 2002/02/12 15:14:00 hcl
verbosity fix.
Revision 1.3 2001/12/03 14:31:11 hcl
Pour la route.
Revision 1.2 2001/11/20 09:39:57 hcl
du bo, du bon, prefet dubonnet
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#define WSEGMENT_FREE OCRNATURALINT_MAX
#define WSEGMENT_OBSTACLE (OCRNATURALINT_MAX - 1)
typedef enum rbtreecolour
{
rbtreered,
rbtreeblack,
}
rbtreecolour;
typedef struct rbtree
{
void *KEY;
void *DATA;
rbtreecolour COLOUR;
struct rbtree *PARENT;
struct rbtree *Left;
struct rbtree *Right;
}
rbtree;
/**
* TYPE CONNECTEUR
**/
#define OCR_TYPE_FACE 1
#define OCR_TYPE_PONC 2
#define OCR_TYPE_LINKED 4
#define MARK_AS_LINKED(x) (x)->TYPE |= OCR_TYPE_LINKED
#define IS_MARK_AS_LINKED(x) ((x)->TYPE & OCR_TYPE_LINKED)
#define MARK_AS_FACE_CON(x) (x)->TYPE |= OCR_TYPE_FACE
#define IS_MARK_AS_FACE_CON(x) ((x)->TYPE & OCR_TYPE_FACE)
#define OCR_FACE_NORTH 1
#define OCR_FACE_SOUTH 2
#define OCR_FACE_EAST 4
#define OCR_FACE_WEST 8
/**
* TYPE SIGNAL
**/
// signal n'ayant pas de conecteurs ds la window
#define OCR_SIG_THROW 1
#define MARK_AS_SIG_THROW(x) (x)->TYPE |= OCR_SIG_THROW
#define IS_MARK_AS_SIG_THROW(x) ((x)->TYPE & OCR_SIG_THROW)
/*
Enrichir cette structure pour tenir compte d'un cout intrisinseque ?
*/
typedef struct ocrWSegment
{
ocrNaturalInt OFFSET;
ocrNaturalInt LAYER;
ocrNaturalInt P_MIN;
ocrNaturalInt P_MAX;
ocrNaturalInt SIGNAL_INDEX;
ocrNaturalInt TAG;
ocrNaturalInt H, COST, HCOST;
/* list of pointers to associated obstacle segments */
//struct ocrWSegment *OBSTACLE;
/* list of pointer used for backtracking */
struct ocrWSegment *ROOT;
/* temporarily chaining */
struct ocrWSegment *AUX;
/* Pointer used for chaining equi */
struct ocrWSegment *NEXT;
ocrNaturalInt LT, RB;
rbtree *LABELS_LEFT_TOP;
rbtree *LABELS_RIGHT_BOTTOM;
}
ocrWSegment;
// Grille de routage
typedef struct ocrWRoutingGrid
{
ocrWSegment **DATA;
ocrNaturalInt SIZE_H;
ocrNaturalInt SIZE_V;
ocrNaturalInt NB_OF_LAYERS;
}
ocrWRoutingGrid;
typedef struct ocrVirtualConnector
{
ocrNaturalInt WIDTH;
ocrNaturalShort ORIENT;
ocrNaturalShort TAG;
ocrNaturalShort WIN;
ocrNaturalInt DIST;
ocrNaturalInt X;
ocrNaturalInt Y;
ocrNaturalInt Z;
struct ocrVirtualConnector *NEXT;
}
ocrVirtualConnector;
typedef struct ocrConnector
{
char *NAME;
char *INSNAME;
struct ocrConnector *NEXT;
ocrNaturalShort TYPE;
ocrNaturalShort INTEXT;
ocrVirtualConnector *VIR_CON_LIST;
ocrVirtualConnector *CON;
ocrNaturalInt ORDER;
ocrNaturalShort FACE;
ocrNaturalShort WIN;
ocrNaturalInt DIST;
/* XXX HCl */
ocrNaturalInt NB_VC;
ocrVirtualConnector *critVC;
}
ocrConnector;
/* ajout HCl */
typedef struct ocrPoint {
ocrNaturalInt X;
ocrNaturalInt Y;
ocrNaturalInt Z;
ocrNaturalInt SIGNAL_INDEX;
struct ocrPoint *NEXT;
} ocrPoint;
typedef struct ocrSignal
{
char *NAME;
ocrNaturalInt INDEX;
char ROUTED;
struct ocrSignal *NEXT;
ocrWSegment *SEGMENT;
ocrVirtualConnector *VIA;
ocrVirtualConnector *GLOBAL;
ocrNaturalShort WIN;
ocrNaturalInt NB_CON;
ocrNaturalInt TYPE;
ocrNaturalShort PRIORITY;
ocrNaturalShort INTEXT;
ocrConnector *CON_LIST;
/* HCl XXX */
ocrNaturalInt NICHT_ZU_ROUTIEREN;
}
ocrSignal;
typedef struct ocrWindow
{
ocrNaturalInt XMIN, XMAX;
ocrNaturalInt YMIN, YMAX;
ocrNaturalInt NUM;
ocrNaturalInt NB_SIG_FACE[9];
ocrNaturalInt NB_SIG;
ocrNaturalInt NB_SIG_THROW;
}
ocrWindow;
typedef struct ocrObstacle
{
}
ocrObstacle;
typedef struct ocrRoutingDataBase
{
char *NAME;
ocrNaturalInt XAB1, YAB1, XAB2, YAB2;
ocrNaturalShort NB_OF_LAYERS;
ocrNaturalInt NB_IT;
ocrNaturalInt NB_UNROUTED;
ocrNaturalInt NB_ROUTED;
ocrNaturalInt NB_F;
ocrSignal **GSIGNAL;
ocrSignal **SIGNAL;
ocrSignal **FSIGNAL;
ocrNaturalInt NB_GSIGNAL;
ocrNaturalInt NB_SIGNAL;
ocrNaturalInt *NB_FSIGNAL;
ocrWindow **WINDOWS;
ocrPoint *POINTS;
ocrObstacle *GOBSTACLE;
ocrObstacle **MFOBSTACLE;
ocrObstacle **FOBSTACLE;
ht *HTABLE;
ocrWRoutingGrid *GRID;
ocrRoutingParameters *PARAM;
chain_list *RIPUP;
}
ocrRoutingDataBase;
#define OCR_NORM 1
#define OCR_RIPUP 2
#define OCR_ODYN 4
typedef struct ocrOption
{
ocrNaturalInt LEVEL;
ocrNaturalInt ORDER;
ocrNaturalInt PRIORITY;
ocrNaturalInt WINDOW;
ocrNaturalInt ALGO;
}
ocrOption;
/* Fonctions de base */
ocrRoutingDataBase *createDataBase (
phfig_list * i_pPhFig);
void deleteDataBase (
ocrRoutingDataBase * i_pDataBase);
ocrSignal *createSignal (
losig_list * i_pLoSig);
ocrSignal *dupSignal (
ocrSignal * i_pSignal);
void createGlobalSignalList (
ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uNbSignaux);
void addSignalGlobal (
ocrRoutingDataBase * i_pDataBase,
ocrSignal * i_pSignal);
ocrConnector *createConnector (
char *i_sName,
char *i_sInsName,
ocrNaturalShort i_uType,
ocrNaturalShort i_uIntExt,
ocrNaturalShort i_uFace,
ocrNaturalInt i_uOrder,
ocrNaturalInt i_uNumFMF);
void addConnector (
ocrSignal * i_pSignal,
ocrConnector * i_pCon);
ocrVirtualConnector *createVirtualConnector (
ocrNaturalInt i_uX,
ocrNaturalInt i_uY,
ocrNaturalInt i_uZ,
ocrNaturalInt i_uWidth,
ocrNaturalShort i_uOrient);
ocrVirtualConnector *dupVirtualConnector (
ocrVirtualConnector * i_pVirCon);
void addVirtualConnector (
ocrVirtualConnector ** i_pVirConList,
ocrVirtualConnector * i_pVirCon);
void deleteVirtualConnectorList (ocrVirtualConnector * i_pVirCon);
void deleteSegmentSignalList (ocrSignal * i_pSignal,
ocrWSegment * i_pSegment);
void addSegmentSignalList (ocrSignal * i_pSignal,
ocrWSegment * i_pSegment);
void dumpDataBase (ocrRoutingDataBase * i_pDataBase,
FILE * i_pFile);
#endif /* _OCRWROUTINGDATABASE_H_ */

View File

@ -0,0 +1,108 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:17 $
$Log: ocrWRoutingUtil.h,v $
Revision 1.1 2002/03/15 14:37:17 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:14 hcl
First commit in the new tree.
Revision 1.2 2001/11/20 09:39:57 hcl
du bo, du bon, prefet dubonnet
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#ifndef _OCRWROUTINGUTIL_H_
#define _OCRWROUTINGUTIL_H_
extern ocrWRoutingGrid *createWGrid (ocrNaturalInt size_h,
ocrNaturalInt size_v,
ocrNaturalInt nb_of_layers);
void initWGrid (ocrWRoutingGrid * i_pGrid,
ocrRoutingParameters * i_pParam);
extern void freeWGrid (ocrWRoutingGrid * grid);
extern void setWSegmentName (ocrWSegment *segment, char *NAME);
extern ocrWSegment *createWSegment (ocrNaturalInt offset,
ocrNaturalInt layer,
ocrNaturalInt p_min,
ocrNaturalInt p_max,
ocrNaturalInt signal_index);
extern void freeWSegment (ocrWSegment * segment);
extern ocrWSegment *getWSegment (ocrWRoutingGrid * grid,
ocrNaturalInt x,
ocrNaturalInt y,
ocrNaturalInt z);
extern ocrWSegment *getWSegmentCV (ocrWRoutingGrid * grid,
ocrVirtualConnector * i_pVirCon);
extern void setWGrid (ocrWRoutingGrid * grid,
ocrWSegment * segment,
ocrNaturalInt x,
ocrNaturalInt y,
ocrNaturalInt z);
extern int isLabeled (ocrWSegment * segment);
extern int isObstructed (ocrWSegment * segment);
extern ocrRoutingDirection getWSegDirection (ocrRoutingParameters * param,
ocrWSegment * segment);
extern ocrNaturalInt getWSegXCoord (ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt point);
extern ocrNaturalInt getWSegYCoord (ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt point);
extern ocrWSegment *splitWSegment (ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrWSegment * segment,
ocrNaturalInt first_point,
ocrNaturalInt second_point,
ocrNaturalInt index);
extern ocrNaturalInt manhattan1Distance (ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt p1,
ocrNaturalInt p2);
#define DELTA(x) ( (ocrNaturalInt)(x)->KEY )
#define POINT(x) ( (ocrNaturalInt)(x)->DATA )
extern ocrNaturalInt inducedDelta (ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
rbtree * node,
ocrNaturalInt point);
extern rbtree *getLabel (ocrRoutingParameters * param,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrWSegment * segment,
ocrNaturalInt delta,
ocrNaturalInt point);
extern ocrNaturalInt getNextPlane (ocrWRoutingGrid * grid,
ocrNaturalInt ztarget,
ocrNaturalInt plane);
#endif /* _OCRWROUTINGUTIL_H_ */

View File

@ -0,0 +1,32 @@
#ifndef _OCRWSEGLABELING_H_
#define _OCRWSEGLABELING_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:17 $
$Log: ocrWSegLabeling.h,v $
Revision 1.1 2002/03/15 14:37:17 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:14 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:45 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
extern int labelWSegment(ocrRoutingParameters *param,
ocrWSegment *segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta,
ocrNaturalInt point);
extern void unlabelWSegment(ocrWSegment *segment);
#endif /* _OCRWSEGLABELING_H_ */

View File

@ -0,0 +1,28 @@
#ifndef _OCRWEIGTHEDTREE_H_
#define _OCRWEIGTHEDTREE_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:17 $
$Log: ocrWeightedTree.h,v $
Revision 1.1 2002/03/15 14:37:17 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:14 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:46 hcl
premier commit....
### -------------------------------------------------- ###
*/
void makingWeightedTree (ocrRoutingDataBase *,
ocrSignal *,
ocrEdge *);
void initWeightedTree (ocrRoutingDataBase * i_pDataBase);
void freeWeightedTree ();
void dumpDensityTable ();
#endif /* _OCRWEIGTHEDTREE_H_ */

View File

@ -0,0 +1,69 @@
#ifndef _OCRWINDOW_H_
#define _OCRWINDOW_H_
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:17 $
$Log: ocrWindow.h,v $
Revision 1.1 2002/03/15 14:37:17 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:14 hcl
First commit in the new tree.
Revision 1.1 2001/09/26 14:27:46 hcl
premier commit....
### -------------------------------------------------- ###
*/
/*
typedef struct ocrWindow
{
ocrNaturalInt XMIN, XMAX;
ocrNaturalInt YMIN, YMAX;
ocrNaturalInt NUM;
ocrNaturalInt NB_SIG_FACE[9];
ocrNaturalInt NB_SIG;
ocrNaturalInt NB_SIG_THROW;
}
ocrWindow;
*/
ocrWindow *newWindow (ocrNaturalInt i_nNumWin);
void deleteWindow (ocrWindow * i_pWindow);
void createWindow (ocrRoutingDataBase * i_pDataBase);
void translatingRealToWindows (ocrRoutingDataBase * i_pDataBase);
void
createWindowArray (ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uWinNum);
void
deleteWindowArray (ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uWinNum);
void
translatingWindowsToReal (ocrRoutingDataBase * i_pDataBase);
void
WintoXY (ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt * o_pX,
ocrNaturalInt * o_pY,
ocrNaturalInt i_uWin);
void
XYtoWin (ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uX,
ocrNaturalInt i_uY,
ocrNaturalInt * o_pWin);
void
insertSignalWindow (ocrRoutingDataBase * i_pDataBase,
ocrSignal * i_pSignal);
void
linkConnector (ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uIndex,
ocrConnector * i_pCon);
#endif /* _OCRWINDOW_H_ */

View File

@ -0,0 +1,16 @@
## Process this file with automake to produce Makefile.in
INCLUDES = @INCLUDES@ -I$(top_srcdir)/src/include
bin_PROGRAMS = ocr
ocr_LDADD = @LIBS@ \
$(top_builddir)/src/seg/libocrPath.a \
$(top_builddir)/src/util/libocrUtil.a \
-lMlu -lMlo -lMal -lMcl -lMel -lMhl \
-lMgl -lMsl -lMvl -lMpu -lMph -lMap \
-lMcp -lMmg -lMut -lRcn
ocr_SOURCES = display.c findNPointsPath.c getOption.c\
ocrGlobalRouting.c ocrMst.c ocrRouter.c\
ocrWeightedTree.c ocrAstar.c

View File

@ -0,0 +1,64 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:18 $
$Log: display.c,v $
Revision 1.1 2002/03/15 14:37:18 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:16 hcl
First commit in the new tree.
Revision 1.3 2002/02/12 15:14:14 hcl
New algo.
Revision 1.2 2001/12/14 15:58:35 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.1 2001/09/26 14:27:48 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "display.h"
static char *res_id = "$Id: display.c,v 1.1 2002/03/15 14:37:18 hcl Exp $";
/**
* fonction d'affichage standard
* avec 5 niveaux
**/
void display(int i_nLevel, int i_nType, char *fmt, ...)
{
va_list l_pParam;
va_start(l_pParam, fmt);
switch (i_nType) {
case ERROR:
fprintf(stderr, "ERROR : ");
vfprintf(stderr, fmt, l_pParam);
break;
case WARNING:
fprintf(stderr, "WARNING : ");
vfprintf(stderr, fmt, l_pParam);
break;
case INFO:
vfprintf(stdout, fmt, l_pParam);
break;
case VVERB:
if ((i_nLevel == DEBUG) || (i_nLevel == VVERB))
vfprintf(stdout, fmt, l_pParam);
break;
case VERBOSE:
if ((i_nLevel == VERBOSE) || (i_nLevel == DEBUG) || (i_nLevel == VVERB))
vfprintf(stdout, fmt, l_pParam);
break;
case DEBUG:
if (i_nLevel == DEBUG)
vfprintf(stdout, fmt, l_pParam);
}
va_end(l_pParam);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
#include <stdio.h>
#include <stdlib.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "getOption.h"
#include "display.h"
extern ocrNaturalInt g_OptLayer;
extern ocrNaturalInt g_OptOrder;
/**
* Gestion de la ligne de commande
**/
ocrOption *getOption(int argc, char **argv)
{
}

View File

@ -0,0 +1,864 @@
#include <assert.h>
#include <stdlib.h>
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:19 $
$Log: ocrAstar.c,v $
Revision 1.1 2002/03/15 14:37:19 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:16 hcl
First commit in the new tree.
Revision 1.5 2002/02/25 11:41:13 hcl
A la chasse au bug bug bug
Revision 1.4 2002/02/22 15:20:49 hcl
A* is ready
Revision 1.3 2002/02/21 13:17:57 hcl
Introducing a new algo (A*, dont yet work...)
Revision 1.2 2002/02/15 12:06:31 hcl
First attempt
Revision 1.1 2002/02/12 15:14:14 hcl
New algo.
### -------------------------------------------------- ###
*/
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "mbk_tree.h"
#include "ocrWRoutingUtil.h"
#include "ocrWRouting.h"
#include "display.h"
#include "ocrAstar.h"
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
/*********************************************************************/
#define TAG_UNDEF 0
#define TAG_KEEP 1
#define TAG_CLEAN 2
#define TAG_FREED 4
#define TAG_TERRA 8
#define TAG_VISITED 16
/*********************************************************************/
/**
* Variables globales
**/
ocrWRoutingGrid *grid = NULL;
ocrRoutingParameters *param = NULL;
ocrNaturalInt xs = 0, ys = 0, zs = 0;
ocrNaturalInt CUR_SIG_INDEX = 0;
//ocrNaturalInt (*kost)(ocrWSegment *, ocrWSegment *);
/*********************************************************************/
/**
*
* Local data structures
*
**/
/*********************************************************************/
/**
* Functions
*/
/* Cost function (Manhattan distance) */
ocrNaturalInt eval (ocrWSegment *segment_source, ocrWSegment *segment_dest) {
ocrNaturalInt x1s, x2s, y1s, y2s, x1d, x2d, y1d, y2d, dx, dy, dz;
x1s = getWSegXCoord (param, segment_source, segment_source->P_MIN);
y1s = getWSegYCoord (param, segment_source, segment_source->P_MIN);
x2s = getWSegXCoord (param, segment_source, segment_source->P_MAX);
y2s = getWSegYCoord (param, segment_source, segment_source->P_MAX);
x1d = getWSegXCoord (param, segment_dest, segment_dest->P_MIN);
y1d = getWSegYCoord (param, segment_dest, segment_dest->P_MIN);
x2d = getWSegXCoord (param, segment_dest, segment_dest->P_MAX);
y2d = getWSegYCoord (param, segment_dest, segment_dest->P_MAX);
dx = ( (x2s < x1d)? (x1d - x2s) : ( (x1s > x2d) ? (x1s - x2d) : 0 ) );
dy = ( (y2s < y1d)? (y1d - y2s) : ( (y1s > y2d) ? (y1s - y2d) : 0 ) );
dz = (
(segment_dest->LAYER > segment_source->LAYER) ?
segment_dest->LAYER - segment_source->LAYER :
segment_source->LAYER - segment_dest->LAYER
)
;
return (dx + dy) + dz * param->VIA_COST;
}
/* Distance between segment and nearest segment of an equi */
ocrNaturalInt eval_equi (ocrWSegment *segment_source, ocrWSegment *equi) {
ocrNaturalInt res = OCRNATURALINT_MAX;
ocrNaturalInt aux;
/*return 0;*/
while (equi) {
aux = eval (segment_source, equi);
if (aux < res) {
res = aux;
}
equi = equi->NEXT;
}
return res;
}
/* kost of the path from segment_source to segment_dest */
ocrNaturalInt kost (ocrWSegment *segment_source, ocrWSegment *segment_dest) {
ocrWSegment *ps;
ocrNaturalInt dest_offset, p;
ocrNaturalInt res;
ps = segment_source->ROOT;
dest_offset = segment_dest->OFFSET;
if (
getWSegDirection (param, segment_source)
==
getWSegDirection (param, segment_dest)
)
{
return 0;
} else if (ps) {
res = (
(ps->OFFSET > dest_offset) ?
(ps->OFFSET - dest_offset) :
(dest_offset - ps->OFFSET)
)
;
res += (
(segment_dest->LAYER > segment_source->LAYER) ?
1000 + segment_dest->LAYER - segment_source->LAYER :
segment_source->LAYER - segment_dest->LAYER
)
* param->VIA_COST
;
return res;
} else {
p = (getWSegDirection (param, segment_source) == ocrHorizontal) ?
xs : ys;
return
(
(p > dest_offset) ?
(p - dest_offset) :
(dest_offset - p)
)
+
(
(zs > segment_source->LAYER) ?
(zs - segment_source->LAYER) :
(segment_source->LAYER - zs)
)
*
param->VIA_COST
;
}
}
void tag_keep (ocrWSegment *path) {
while (path) {
path->TAG = TAG_KEEP;
path = path->ROOT;
}
return;
}
/**
* stack
**/
ocrWSegment *pop (ocrWSegment **list) {
ocrWSegment *res;
assert (*list);
res = (*list);
(*list) = ( (*list)->AUX );
res->AUX = NULL;
return res;
}
void push (ocrWSegment **list, ocrWSegment *elem) {
assert (elem);
elem->AUX = (*list);
(*list) = elem;
return;
}
/**
* clean_mem
**/
void clean_tag () {
ocrWSegment *seg;
int i, j, k;
for (k = 0 ; k < grid->NB_OF_LAYERS ; k += 2)
for (j = 0 ; j < grid->SIZE_V ; j++)
for (i = 0 ; i < grid->SIZE_H ; i++) {
seg = getWSegment (grid, i, j, k);
seg->TAG = TAG_UNDEF;
i = seg->P_MAX;
#if 0
if (
(seg->SIGNAL_INDEX != WSEGMENT_FREE)
&&
(seg->SIGNAL_INDEX != WSEGMENT_OBSTACLE)
)
{
if (seg->AUX) {
display (LEVEL, DEBUG, "AUX not NULL for free or obstacle segment\n");
seg->AUX = NULL;
}
}
#endif
}
for (k = 1 ; k < grid->NB_OF_LAYERS ; k += 2)
for (i = 0 ; i < grid->SIZE_H ; i++)
for (j = 0 ; j < grid->SIZE_V ; j++) {
seg = getWSegment (grid, i, j, k);
seg->TAG = TAG_UNDEF;
j = seg->P_MAX;
#if 0
if (
(seg->SIGNAL_INDEX != WSEGMENT_FREE)
&&
(seg->SIGNAL_INDEX != WSEGMENT_OBSTACLE)
)
{
if (seg->AUX) {
display (LEVEL, DEBUG, "AUX not NULL for free or obstacle segment\n");
seg->AUX = NULL;
}
}
#endif
}
return;
}
void clean_tag_list (ocrWSegment *list) {
while (list) {
list->TAG = TAG_UNDEF;
list = list->AUX;
}
return;
}
/**
* insert elem keeping the list sorted by increasing cost+h
**/
ocrWSegment *insert (ocrWSegment *list, ocrWSegment *elem) {
assert (elem);
if (!list) {
elem->AUX = NULL;
return elem;
/*} else if ( (elem->HCOST) > (list->HCOST) ) {*/
} else if ( (elem->COST) > (list->COST) ) {
list->AUX = insert (list->AUX, elem);
return list;
} else if ( ((elem->HCOST) == (list->HCOST)) && ((elem->COST) > (list->COST)) ){
/*} else if ( ((elem->COST) == (list->COST)) && ((elem->H) > (list->H)) ){*/
list->AUX = insert (list->AUX, elem);
return list;
} else {
elem->AUX = list;
return elem;
}
}
ocrWSegment *_remove (ocrWSegment *list, ocrWSegment *elem) {
assert (elem);
if (!list)
return list;
if (elem == list) {
ocrWSegment *res = elem->AUX;
elem->AUX = NULL;
return res;
}
list->AUX = _remove (list->AUX, elem);
return list;
}
#define XPLORE \
{\
if (isObstructed (seg))\
if (seg->SIGNAL_INDEX != CUR_SIG_INDEX)\
continue;\
\
cost = node->COST + kost (node, seg); /* XXX cout du chemin parcouru ??? */\
\
switch (seg->TAG) {\
case TAG_UNDEF: /* not yet seen segment */\
seg->ROOT = node;\
seg->COST = cost;\
seg->H = eval_equi (seg, segment_target);\
seg->HCOST = seg->H + cost;\
seg->TAG = TAG_TERRA;\
terra_incognita = insert (terra_incognita, seg);\
break;\
case TAG_TERRA:\
if (cost < seg->COST) {\
seg->COST = cost;\
seg->HCOST = seg->H + cost;\
seg->ROOT = node;\
terra_incognita = _remove (terra_incognita, seg);\
terra_incognita = insert (terra_incognita, seg);\
} else {\
/* rien */\
}\
break;\
case TAG_VISITED:\
if (cost < seg->COST) {\
seg->COST = cost;\
seg->HCOST = seg->H + cost;\
seg->ROOT = node;\
visited = _remove (visited, seg);\
seg->TAG = TAG_TERRA;\
terra_incognita = insert (terra_incognita, seg);\
} else {\
/* rien */\
}\
break;\
default:\
display (LEVEL, ERROR, "*** unexpected TAG !!!\n");\
abort ();\
}\
}
ocrWSegment *explore (ocrWSegment *segment_source, ocrWSegment *segment_target) {
ocrWSegment *visited = NULL;
ocrWSegment *terra_incognita = NULL;
ocrNaturalInt p, cost;
int i;
assert (segment_source != segment_target);
display (LEVEL, DEBUG, "d starting exploration\n");
terra_incognita = segment_source;
terra_incognita->COST = 0;
terra_incognita->H = eval (segment_source, segment_target);
terra_incognita->HCOST = terra_incognita->H;
terra_incognita->TAG = TAG_TERRA;
terra_incognita->ROOT = NULL;
terra_incognita->AUX = NULL;
while (terra_incognita) {
ocrWSegment *node = NULL;
ocrWSegment *seg = NULL;
node = pop (&terra_incognita);
if (node == segment_target) {
/* bingo ! */
clean_tag_list (visited);
clean_tag_list (terra_incognita);
node->TAG = TAG_UNDEF;
return node;
}
node->TAG = TAG_VISITED;
push (&visited, node);
/* expansion */
for (i = -1 ; i <= 1 ; i += 2) {
switch (i) {
case -1: if ( ((node->LAYER) ) == 0 )
continue;
break;
case 1: if ( ((node->LAYER) + 1) >= (grid->NB_OF_LAYERS) )
continue;
break;
default:
/*display (LEVEL, ERROR, __FILE__ ":" __LINE__ "exand_eval Oops\n");*/
abort ();
}
for (p = node->P_MIN ; p <= node->P_MAX ; p++) {
/*display (LEVEL, DEBUG, "d expanding %ld\n", i);*/
seg = getWSegment(grid,
getWSegXCoord (param, node, p),
getWSegYCoord (param, node, p),
node->LAYER + i
);
#ifdef DEBUG
if (!seg) {
display (LEVEL, DEBUG, "oddity: null seg at (%ld, %ld, %ld)\n", getWSegXCoord(param, node, p), getWSegXCoord(param, node, p), node->LAYER + i);
continue;
}
#endif
if (isObstructed (seg))
continue;
cost = node->COST + kost (node, seg); /* XXX cout du chemin parcouru ??? */
switch (seg->TAG) {
case TAG_UNDEF: /* not yet seen segment */
seg->ROOT = node;
seg->COST = cost;
seg->H = eval (seg, segment_target);
seg->HCOST = seg->H + cost;
seg->TAG = TAG_TERRA;
terra_incognita = insert (terra_incognita, seg);
break;
case TAG_TERRA:
if (cost < seg->COST) {
seg->COST = cost;
seg->HCOST = seg->H + cost;
seg->ROOT = node;
terra_incognita = _remove (terra_incognita, seg);
terra_incognita = insert (terra_incognita, seg);
} else {
/* rien */
}
break;
case TAG_VISITED:
if (cost < seg->COST) {
seg->COST = cost;
seg->HCOST = seg->H + cost;
seg->ROOT = node;
visited = _remove (visited, seg);
seg->TAG = TAG_TERRA;
terra_incognita = insert (terra_incognita, seg);
} else {
/* rien */
}
break;
default:
display (LEVEL, ERROR, "*** unexpected TAG !!!\n");
abort ();
}
}
} /* end for i */
} /* while */
/* Failed */
clean_tag ();
/*isplay (LEVEL, DEBUG, "d exploration failed\n");*/
return NULL;
}
#if 0
void addseglist (ocrSignal *s, ocrWSegment *l2) {
ocrWSegment *l1;
if (!(s->SEGMENT))
s->SEGMENT = l2;
else {
l1 = s->SEGMENT;
while (l1->NEXT)
l1 = l1->NEXT;
l1->NEXT = l2;
}
return;
}
#endif
ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_target) {
ocrWSegment *visited = NULL;
ocrWSegment *terra_incognita = NULL;
ocrNaturalInt p, cost;
int i;
assert (segment_source != segment_target);
display (LEVEL, DEBUG, "d starting exploration\n");
terra_incognita = segment_source;
terra_incognita->COST = 0;
terra_incognita->H = eval_equi (segment_source, segment_target);
terra_incognita->HCOST = terra_incognita->H;
terra_incognita->TAG = TAG_TERRA;
terra_incognita->ROOT = NULL;
terra_incognita->AUX = NULL;
while (terra_incognita) {
ocrWSegment *node = NULL;
ocrWSegment *seg = NULL;
node = pop (&terra_incognita);
if (node->SIGNAL_INDEX == CUR_SIG_INDEX) {
/* on a gagne */
clean_tag_list (visited);
clean_tag_list (terra_incognita);
node->TAG = TAG_UNDEF;
return node;
}
node->TAG = TAG_VISITED;
push (&visited, node);
/* expansion */
if (getWSegDirection (param, node) == ocrHorizontal) {
if ( (node->P_MIN) > 0 ) {
seg = getWSegment (grid, node->P_MIN - 1, node->OFFSET, node->LAYER);
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
XPLORE
}
if ( (node->P_MAX) < (grid->SIZE_H - 2) ) {
seg = getWSegment (grid, node->P_MAX + 1, node->OFFSET, node->LAYER);
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
XPLORE
}
} else { /* vertical */
if ( (node->P_MIN) > 0 ) {
seg = getWSegment (grid, node->OFFSET, node->P_MIN - 1, node->LAYER);
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
XPLORE
}
if ( (node->P_MAX) < (grid->SIZE_V - 2) ) {
seg = getWSegment (grid, node->OFFSET, node->P_MAX + 1, node->LAYER);
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
XPLORE
}
}
for (i = -1 ; i <= 1 ; i += 2) {
switch (i) {
case -1: if ( ((node->LAYER) ) == 0 )
continue;
break;
case 1: if ( ((node->LAYER) + 1) >= (grid->NB_OF_LAYERS) )
continue;
break;
default:
/*display (LEVEL, ERROR, __FILE__ ":" __LINE__ "exand_eval Oops\n");*/
abort ();
}
for (p = node->P_MIN ; p <= node->P_MAX ; p++) {
/*display (LEVEL, DEBUG, "d expanding %ld\n", i);*/
seg = getWSegment(grid,
getWSegXCoord (param, node, p),
getWSegYCoord (param, node, p),
node->LAYER + i
);
#ifdef DEBUG
if (!seg) {
display (LEVEL, DEBUG, "oddity: null seg at (%ld, %ld, %ld)\n", getWSegXCoord(param, node, p), getWSegXCoord(param, node, p), node->LAYER + i);
continue;
}
#endif
XPLORE
}
} /* end for i */
} /* while */
/* Failed */
clean_tag ();
/*isplay (LEVEL, DEBUG, "d exploration failed\n");*/
return NULL;
}
ocrNaturalInt make_segments (ocrWSegment *segment_dest,
ocrWSegment *segment_source,
ocrNaturalInt xdest,
ocrNaturalInt ydest,
ocrNaturalInt zdest,
ocrNaturalInt signal_index,
ocrSignal * i_pSignal
)
{
ocrWSegment *seg, *nseg, *root, *aux;
ocrNaturalInt xp, yp, xn, yn;
ocrNaturalInt p1, p2, pp1, pp2;
ocrNaturalInt pi;
ocrNaturalInt distance = 0;
ocrNaturalInt nb_segs = 0;
/* initialisation */
aux = i_pSignal->SEGMENT;
seg = segment_dest;
display (LEVEL, DEBUG, "c dest (%ld, %ld, %ld)\n", xdest, ydest, zdest);
xp = xdest;
yp = ydest;
if (seg->SIGNAL_INDEX == signal_index) {
display (LEVEL, DEBUG, "c joining equi at seg (off=%ld, p_min=%ld, p_max=%ld)\n", seg->OFFSET, seg->P_MIN, seg->P_MAX);
if (
getWSegDirection (param, seg)
==
getWSegDirection (param, seg->ROOT)
)
{
xp = getWSegXCoord (param, seg, seg->P_MIN);
yp = getWSegYCoord (param, seg, seg->P_MIN);
} else {
xp = getWSegXCoord (param, seg, seg->ROOT->OFFSET);
yp = getWSegYCoord (param, seg, seg->ROOT->OFFSET);
}
nseg = seg->ROOT;
seg->ROOT = NULL;
seg = nseg;
}
nseg = NULL;
/*
seg, seg->ROOT
nseg <= split (seg)
nseg -> NEXT = prevseg;
prevseg = nseg;
*/
while (seg->ROOT) {
root = seg->ROOT;
xn = getWSegXCoord (param, root, xp);
yn = getWSegYCoord (param, root, yp);
display (LEVEL, DEBUG, "p (%ld, %ld, %ld) -> (%ld, %ld, %ld) : d=%ld, c=%ld, h=%ld, hc=%ld\n", xp, yp, seg->LAYER, xn, yn, seg->LAYER, distance, seg->COST, seg->H, seg->HCOST);
((getWSegDirection(param, seg) == ocrHorizontal) ? (pi = param->PITCH_H, p1 = xp, p2 = xn) : (pi = param->PITCH_V, p1 = yp, p2 = yn) );
( (p1 < p2) ? (pp1 = p1, pp2 = p2) : (pp1 = p2, pp2 = p1) );
nseg = splitWSegment (param, grid, seg,
pp1, pp2,
signal_index
);
nseg->NEXT = aux;
aux = nseg;
distance += pi * (pp2 - pp1);
nb_segs ++;
xp = xn;
yp = yn;
/*seg->SIGNAL_INDEX = signal_index;*/
seg = root;
}
/*assert (nseg == segment_source);*/
xn = xs;
yn = ys;
/*root = seg->ROOT;*/
((getWSegDirection(param, seg) == ocrHorizontal) ? (pi = param->PITCH_H, p1 = xp, p2 = xn) : (pi = param->PITCH_V, p1 = yp, p2 = yn) );
( (p1 < p2) ? (pp1 = p1, pp2 = p2) : (pp1 = p2, pp2 = p1) );
nseg = splitWSegment (param, grid, seg,
pp1, pp2,
signal_index
);
nseg->NEXT = aux;
i_pSignal->SEGMENT = nseg;
distance += pi * (pp2 - pp1);
nb_segs ++;
display (LEVEL, DEBUG, "p (%ld, %ld, %ld) -> (%ld, %ld, %ld) : %ld\n", xp, yp, seg->LAYER, xn, yn, zs, distance);
display (LEVEL, DEBUG, "c source (%ld, %ld, %ld)\n", xs, ys, zs);
display (LEVEL, DEBUG, "p num of segments : %ld\n", nb_segs);
/*seg->SIGNAL_INDEX = signal_index;*/
display (LEVEL, DEBUG, "i path length : %ld\n", distance);
return distance;
}
ocrNaturalInt check_path (ocrSignal *i_pSignal) {
ocrWSegment *seg;
ocrNaturalInt dist;
seg = i_pSignal->SEGMENT;
dist = 0;
while (seg) {
if ( (seg->SIGNAL_INDEX) != (i_pSignal->INDEX) ) {
display (LEVEL, ERROR, " ---INVALID Segment->SIGNAL_INDEX\n");
abort ();
}
display (LEVEL, DEBUG, "(%ld, %ld, %ld, %ld)\n", seg->OFFSET, seg->P_MIN, seg->P_MAX, seg->LAYER);
dist += seg->P_MAX - seg->P_MIN;
seg = seg->NEXT;
}
display (LEVEL, DEBUG, "DIST CHECK --- %ld\n", dist);
return dist;
}
ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
ocrWRoutingGrid * p_grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget,
ocrNaturalInt signal_index,
ocrSignal * i_pSignal,
ocrNaturalInt mode)
{
ocrWSegment *path = NULL;
ocrWSegment *segment_source = NULL;
ocrWSegment *segment_dest = NULL;
ocrNaturalInt dist, check_dist;
grid = p_grid;
param = p_param;
xs = xsource;
ys = ysource;
zs = zsource;
CUR_SIG_INDEX = signal_index;
/*clean_tag ();*/
/*kost = (
(mode == AS_K_EQUI) ?
&eval :
&eval_equi
)
;*/
segment_source = getWSegment (grid,
xsource,
ysource,
zsource
);
/* display (LEVEL, DEBUG, "d source : %p\n", segment_source); */
switch (mode) {
case AS_K_SEG:
segment_dest = getWSegment (grid,
xtarget,
ytarget,
ztarget
);
break;
case AS_K_EQUI:
segment_dest = i_pSignal->SEGMENT;
break;
}
/*display (LEVEL, DEBUG, "d dest : %p\n", segment_dest);*/
if ((segment_source != segment_dest) && (!isObstructed(segment_source))) {
switch (mode) {
case AS_K_SEG: path = explore (segment_source, segment_dest);
break;
case AS_K_EQUI: assert (i_pSignal->SEGMENT);
path = explore_equi (segment_source, segment_dest);
break;
}
} else {
path = segment_source;
path->ROOT = NULL;
path->NEXT = NULL;
/*display (LEVEL, DEBUG, "o direct link\n");*/
}
if (!path) {
display (LEVEL, DEBUG, "o A* failed\n");
return OCRNATURALINT_MAX;
}
display (LEVEL, DEBUG, "o A* succeeded\n");
/*clean_tag ();*/
dist = make_segments (
path,
segment_source,
xtarget,
ytarget,
ztarget,
signal_index,
i_pSignal
);
/*assert (((check_dist = check_path (i_pSignal)), dist == check_dist));*/
return dist;
}
/**
*
**/
/*void init_Astar (ocrRoutingDataBase *db) {
assert (db);
grid = db->GRID;
param = db->PARAM;
return;
}
*/

View File

@ -0,0 +1,442 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:19 $
$Log: ocrGlobalRouting.c,v $
Revision 1.1 2002/03/15 14:37:19 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:17 hcl
First commit in the new tree.
Revision 1.6 2002/01/25 13:45:48 hcl
Bug affichage.
Revision 1.5 2001/12/20 13:04:03 hcl
Cosmetique.
Revision 1.4 2001/12/14 15:58:36 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.3 2001/12/12 14:50:58 hcl
Prise en compte du placement des connecteurs par OCP.
Revision 1.2 2001/11/20 09:41:09 hcl
chez Francis, on y route le mips ...
Revision 1.1 2001/09/26 14:27:49 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrUtil.h"
#include "ocrPath.h"
#include "ocrMst.h"
#include "ocrWeightedTree.h"
#include "display.h"
#include "ocrGlobalRouting.h"
#include "ocrConnectorUtil.h"
#include "ocrNpoints.h"
#define SCALE_X 100
#define PITCH 5
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
void makeGlobalSignals(ocrRoutingDataBase * i_pDataBase)
{
ocrSignal *l_pSignal;
ocrConnector *l_pCon;
ocrVirtualConnector *l_pVirConGlobal;
ocrNaturalShort *l_pGrille;
ocrNaturalInt i;
// Création d'une grille de fenetre pour créer 1 seul connecteur
// Virtuel par fenetre.
l_pGrille = (ocrNaturalShort *) mbkalloc((i_pDataBase->NB_F + 1) *
sizeof(ocrNaturalShort));
// les connecteurs virtuels (CV) pour le routage global, sont
// placés dans une liste : GLOBAL.
for (l_pSignal = i_pDataBase->FSIGNAL[0];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
// dumpSignalToFile (l_pSignal, stdout);
// Initialise la grille
for (i = 1; i <= i_pDataBase->NB_F; i++)
l_pGrille[i] = 0;
for (l_pCon = l_pSignal->CON_LIST; l_pCon; l_pCon = l_pCon->NEXT) {
if (l_pCon->INTEXT == INTERNAL) {
// existe-t-il un CV dans cette fenetre
if (!l_pGrille[l_pCon->VIR_CON_LIST->WIN]) {
// Calcul pour chaque CV les coordonnées de sa fenetre
l_pVirConGlobal =
dupVirtualConnector(l_pCon->VIR_CON_LIST);
l_pVirConGlobal->X =
(l_pVirConGlobal->WIN -
1) % ((int) sqrt(i_pDataBase->NB_F));
l_pVirConGlobal->Y =
(l_pVirConGlobal->WIN -
1) / ((int) sqrt(i_pDataBase->NB_F));
// ajout du CV à la liste
addVirtualConnector(&l_pSignal->GLOBAL,
l_pVirConGlobal);
// notifie que la fenetre possede alors un CV
l_pGrille[l_pVirConGlobal->WIN] = 1;
l_pCon->CON = NULL;
#if 0
display(LEVEL, DEBUG, "%ld %ld %d %ld %ld\n",
l_pCon->VIR_CON_LIST->X,
l_pCon->VIR_CON_LIST->Y,
l_pCon->WIN, l_pVirConGlobal->X,
l_pVirConGlobal->Y);
#endif
}
} else {
// existe-t-il un CV dans cette fenetre
if (!l_pGrille[l_pCon->WIN]) {
ocrNaturalInt l_uX, l_uY;
WintoXY(i_pDataBase, &l_uX, &l_uY, l_pCon->WIN);
l_pVirConGlobal =
createVirtualConnector(l_uX, l_uY, 0, 0, 0);
// ajout du CV à la liste
addVirtualConnector(&l_pSignal->GLOBAL,
l_pVirConGlobal);
// notifie que la fenetre possede alors un CV
l_pGrille[l_pVirConGlobal->WIN] = 1;
}
}
}
}
mbkfree(l_pGrille);
}
ocrVirtualConnector *chooseConInEqui(ocrVirtualConnector * i_pEqui,
ocrVirtualConnector * i_pVirCon)
{
ocrVirtualConnector *l_pVirCon, *l_pRes = NULL;
ocrNaturalInt l_uDistMin = OCRNATURALINT_MAX;
ocrNaturalInt l_uDist = 0;
for (l_pVirCon = i_pEqui;
l_pVirCon; l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
l_uDist = distBetween2VirCon(l_pVirCon, i_pVirCon);
if (l_uDist < l_uDistMin) {
l_uDistMin = l_uDist;
l_pRes = l_pVirCon;
}
}
return l_pRes;
}
void routingGlobalSignals(ocrRoutingDataBase * i_pDataBase)
{
ocrSignal *l_pSignal;
ocrVirtualConnector *l_pVirCon, *l_pVirCon2;
ocrVirtualConnector *l_pEqui = NULL;
// allocation de la grille
i_pDataBase->GRID = createWGrid(i_pDataBase->NB_F + 1,
i_pDataBase->NB_F + 1, 2);
for (l_pSignal = i_pDataBase->FSIGNAL[0];
l_pSignal; l_pSignal = l_pSignal->NEXT)
// if (l_pSignal->INTEXT == INTERNAL)
{
// Initialiation de la Grille
initWGrid(i_pDataBase->GRID, i_pDataBase->PARAM);
l_pVirCon = l_pSignal->GLOBAL;
l_pVirCon2 = (ocrVirtualConnector *) l_pVirCon->NEXT;
while (l_pVirCon2) {
if (isFreePoint(NULL, i_pDataBase->GRID, l_pVirCon2)) {
findPathBetween2Points(i_pDataBase->PARAM,
i_pDataBase->GRID,
l_pVirCon->X,
l_pVirCon->Y,
l_pVirCon->Z,
l_pVirCon2->X,
l_pVirCon2->Y,
l_pVirCon2->Z, l_pSignal->INDEX,
l_pSignal);
//if ( ((l_pVirCon->Z) > 0) || ((l_pVirCon2->Z) > 0) )
unifyPoint(i_pDataBase->GRID,
i_pDataBase->PARAM,
l_pSignal,
l_pVirCon->X, l_pVirCon->Y, l_pVirCon->Z);
unifyPoint(i_pDataBase->GRID,
i_pDataBase->PARAM,
l_pSignal, l_pVirCon2->X, l_pVirCon2->Y,
l_pVirCon2->Z);
l_pEqui = makeEquipotentielle(i_pDataBase->PARAM,
i_pDataBase->GRID,
l_pSignal);
}
l_pVirCon2 = (ocrVirtualConnector *) l_pVirCon2->NEXT;
if (l_pVirCon2) {
l_pVirCon = chooseConInEqui(l_pEqui, l_pVirCon2);
}
}
deleteEquipotentielle(i_pDataBase->PARAM,
i_pDataBase->GRID, l_pSignal);
}
// libération de la grille
freeWGrid(i_pDataBase->GRID);
i_pDataBase->GRID = NULL;
}
/**
* makeSubSignal : crée un signal local à une window
* le rajoute à la fenetre en question en début de liste.
**/
void
makeSubSignal(ocrRoutingDataBase * i_pDataBase,
ocrSignal * i_pSignal, ocrNaturalInt i_uWindow)
{
ocrSignal *l_pLocalSignal;
l_pLocalSignal = dupSignal(i_pSignal);
l_pLocalSignal->WIN = i_uWindow;
l_pLocalSignal->PRIORITY = 1;
insertSignalWindow(i_pDataBase, l_pLocalSignal);
}
/**
* makeLocalSignals : "découpe" les signaux globaux en signaux locaux.
**/
void makeLocalSignals(ocrRoutingDataBase * i_pDataBase)
{
ocrSignal *l_pSignal;
ocrConnector *l_pCon;
ocrConnector *l_pConNext;
ocrWSegment *l_pSegment;
ocrNaturalInt i, l_uWin;
char l_sName[50];
// découpage en signaux locaux :
// un sous signal dans chaque window.
// les connecteurs dans les bonnes window.
// ajouter les connecteurs de face.
for (l_pSignal = i_pDataBase->FSIGNAL[0];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
// Chaque connecteur est ajouté au bon signal local
l_pConNext = l_pCon = l_pSignal->CON_LIST;
while (l_pConNext) {
l_pConNext = l_pCon->NEXT;
// Création du sous signal dans la Window l_pCon->WIN ?
if (i_pDataBase->FSIGNAL[l_pCon->WIN]->INDEX !=
l_pSignal->INDEX) {
makeSubSignal(i_pDataBase, l_pSignal, l_pCon->WIN);
}
addConnector(i_pDataBase->FSIGNAL[l_pCon->WIN], l_pCon);
l_pCon = l_pConNext;
}
// Ajout des connecteurs Faciaux
for (l_pSegment = l_pSignal->SEGMENT;
l_pSegment; l_pSegment = l_pSegment->NEXT) {
if (getWSegDirection(i_pDataBase->PARAM,
l_pSegment) == ocrHorizontal) {
for (i = l_pSegment->P_MIN; i < l_pSegment->P_MAX; i++) {
XYtoWin(i_pDataBase, i, l_pSegment->OFFSET, &l_uWin);
sprintf(l_sName, "%ld_%ld", l_pSignal->INDEX, l_uWin);
l_pCon = createConnector(l_sName, NULL, //INSNAME
OCR_TYPE_FACE, // TYPE
EXTERNAL, // INTEXT
OCR_FACE_EAST, // FACE
0, // ORDER
l_uWin); // NUM F
if (i_pDataBase->FSIGNAL[l_pCon->WIN]->INDEX !=
l_pSignal->INDEX) {
makeSubSignal(i_pDataBase, l_pSignal, l_pCon->WIN);
MARK_AS_SIG_THROW(i_pDataBase->
FSIGNAL[l_pCon->WIN]);
i_pDataBase->WINDOWS[l_pCon->WIN]->NB_SIG_THROW++;
}
addConnector(i_pDataBase->FSIGNAL[l_pCon->WIN],
l_pCon);
XYtoWin(i_pDataBase, i + 1, l_pSegment->OFFSET,
&l_uWin);
sprintf(l_sName, "%ld_%ld", l_pSignal->INDEX, l_uWin);
l_pCon = createConnector(l_sName, NULL, //INSNAME
OCR_TYPE_FACE, // TYPE
EXTERNAL, // INTEXT
OCR_FACE_WEST, // FACE
0, // ORDER
l_uWin); // NUM F
if (i_pDataBase->FSIGNAL[l_pCon->WIN]->INDEX !=
l_pSignal->INDEX) {
makeSubSignal(i_pDataBase, l_pSignal, l_pCon->WIN);
MARK_AS_SIG_THROW(i_pDataBase->
FSIGNAL[l_pCon->WIN]);
i_pDataBase->WINDOWS[l_pCon->WIN]->NB_SIG_THROW++;
}
addConnector(i_pDataBase->FSIGNAL[l_pCon->WIN],
l_pCon);
}
} else {
for (i = l_pSegment->P_MIN; i < l_pSegment->P_MAX; i++) {
XYtoWin(i_pDataBase, l_pSegment->OFFSET, i, &l_uWin);
sprintf(l_sName, "%ld_%ld", l_pSignal->INDEX, l_uWin);
l_pCon = createConnector(l_sName, NULL, //INSNAME
OCR_TYPE_FACE, // TYPE
EXTERNAL, // INTEXT
OCR_FACE_NORTH, // FACE
0, // ORDER
l_uWin); // NUM F
if (i_pDataBase->FSIGNAL[l_pCon->WIN]->INDEX !=
l_pSignal->INDEX) {
makeSubSignal(i_pDataBase, l_pSignal, l_pCon->WIN);
MARK_AS_SIG_THROW(i_pDataBase->
FSIGNAL[l_pCon->WIN]);
i_pDataBase->WINDOWS[l_pCon->WIN]->NB_SIG_THROW++;
}
addConnector(i_pDataBase->FSIGNAL[l_pCon->WIN],
l_pCon);
XYtoWin(i_pDataBase, l_pSegment->OFFSET, i + 1,
&l_uWin);
sprintf(l_sName, "%ld_%ld", l_pSignal->INDEX, l_uWin);
l_pCon = createConnector(l_sName, NULL, //INSNAME
OCR_TYPE_FACE, // TYPE
EXTERNAL, // INTEXT
OCR_FACE_SOUTH, 0, // ORDER
l_uWin); // NUM F
if (i_pDataBase->FSIGNAL[l_pCon->WIN]->INDEX !=
l_pSignal->INDEX) {
makeSubSignal(i_pDataBase, l_pSignal, l_pCon->WIN);
MARK_AS_SIG_THROW(i_pDataBase->
FSIGNAL[l_pCon->WIN]);
i_pDataBase->WINDOWS[l_pCon->WIN]->NB_SIG_THROW++;
}
addConnector(i_pDataBase->FSIGNAL[l_pCon->WIN],
l_pCon);
}
}
}
}
}
/**
* Evaluation du Routage Global
* Donne les contraintes sur les faces de tous les window
**/
void evalGlobalRouting(ocrRoutingDataBase * i_pDataBase)
{
ocrSignal *l_pSignal;
ocrConnector *l_pCon;
ocrNaturalInt i;
ocrNaturalInt n[10];
display(LEVEL, DEBUG, "o Eval ...\n");
for (i = 1; i <= i_pDataBase->NB_F; i++) {
n[OCR_FACE_EAST] = 0;
n[OCR_FACE_NORTH] = 0;
n[OCR_FACE_SOUTH] = 0;
n[OCR_FACE_WEST] = 0;
for (l_pSignal = i_pDataBase->FSIGNAL[i];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
for (l_pCon = l_pSignal->CON_LIST; l_pCon;
l_pCon = l_pCon->NEXT) {
if (IS_MARK_AS_FACE_CON(l_pCon))
n[l_pCon->FACE]++;
}
}
i_pDataBase->WINDOWS[i]->NB_SIG_FACE[OCR_FACE_EAST] =
n[OCR_FACE_EAST];
i_pDataBase->WINDOWS[i]->NB_SIG_FACE[OCR_FACE_WEST] =
n[OCR_FACE_WEST];
i_pDataBase->WINDOWS[i]->NB_SIG_FACE[OCR_FACE_NORTH] =
n[OCR_FACE_NORTH];
i_pDataBase->WINDOWS[i]->NB_SIG_FACE[OCR_FACE_SOUTH] =
n[OCR_FACE_SOUTH];
display(LEVEL, DEBUG,
"win %ld : N %ld, S %ld, E %ld, W %ld. Through = %ld, loc sig %ld\n",
i, n[OCR_FACE_NORTH], n[OCR_FACE_SOUTH], n[OCR_FACE_EAST],
n[OCR_FACE_WEST], i_pDataBase->WINDOWS[i]->NB_SIG_THROW,
i_pDataBase->WINDOWS[i]->NB_SIG);
}
}
/**
* Routage Global
* 1. Agrégation des connecteurs de la meme fenetre
* Préparation des signaux globaux pour le routage
* 2. Routage des signaux globaux
* 3. Création des signaux locaux
**/
ocrNaturalInt globalRouting(ocrRoutingDataBase * i_pDataBase)
{
ocrEdge *l_pEdge;
ocrSignal *l_pSignal;
display(LEVEL, VERBOSE, "o Global routing ...\n");
//return;
makeGlobalSignals(i_pDataBase);
#if 1
initWeightedTree(i_pDataBase);
//dumpDensityTable();
for (l_pSignal = i_pDataBase->FSIGNAL[0];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
l_pSignal->SEGMENT = NULL;
l_pEdge = makingMst(l_pSignal);
makingWeightedTree(i_pDataBase, l_pSignal, l_pEdge);
}
//dumpDensityTable();
freeWeightedTree();
#else
routingGlobalSignals(i_pDataBase);
// dumpDataBase (i_pDataBase, stdout);
#endif
makeLocalSignals(i_pDataBase);
evalGlobalRouting(i_pDataBase);
return 1;
}

View File

@ -0,0 +1,210 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:20 $
$Log: ocrMst.c,v $
Revision 1.1 2002/03/15 14:37:20 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:17 hcl
First commit in the new tree.
Revision 1.3 2001/12/20 13:04:03 hcl
Cosmetique.
Revision 1.2 2001/12/14 15:58:36 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.1 2001/09/26 14:27:49 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrUtil.h"
#include "ocrPath.h"
#include "display.h"
#include "ocrConnectorUtil.h"
#include "ocrMst.h"
#define SCALE_X 100
#define PITCH 5
extern ocrOption *g_pOption;
ocrEdge **g_tEdge;
ocrNaturalInt g_uNode;
#define LEVEL (g_pOption->LEVEL)
ocrEdge *createEdge(ocrNode * i_pNode1, ocrNode * i_pNode2)
{
ocrEdge *l_pEdge;
l_pEdge = (ocrEdge *) mbkalloc(sizeof(ocrEdge));
l_pEdge->N1 = i_pNode1;
l_pEdge->N2 = i_pNode2;
l_pEdge->COST = distBetween2VirCon(i_pNode1, i_pNode2);
return l_pEdge;
}
void deleteEdge(ocrEdge * i_pEdge)
{
if (i_pEdge)
mbkfree(i_pEdge);
}
ocrNaturalInt nbOfEdge(ocrNaturalInt i_uNode)
{
return i_uNode * (i_uNode - 1) / 2;
}
ocrNaturalInt isNodeInSet(ocrNode * i_pNode, chain_list * i_pNodeList)
{
if (i_pNodeList == NULL)
return 0;
else if (i_pNode == i_pNodeList->DATA)
return 1;
else
return isNodeInSet(i_pNode, i_pNodeList->NEXT);
}
ocrNaturalInt computeEdge(ocrEdge * i_pEdge, chain_list ** i_pSet)
{
ocrNaturalInt i;
ocrNaturalInt l_uNode1 = 0, l_uNode2 = 0;
chain_list *l_pTmpList, *l_pList1;
for (i = 0; i < g_uNode; i++) {
if (isNodeInSet(i_pEdge->N1, i_pSet[i]))
l_uNode1 = i;
if (isNodeInSet(i_pEdge->N2, i_pSet[i]))
l_uNode2 = i;
}
if (l_uNode1 != l_uNode2) {
// Merge des 2 Set
l_pList1 = i_pSet[l_uNode1];
i_pSet[l_uNode1] = NULL;
for (l_pTmpList = i_pSet[l_uNode2]; l_pTmpList->NEXT;
l_pTmpList = l_pTmpList->NEXT);
l_pTmpList->NEXT = l_pList1;
return 1;
}
return 0;
}
void dumpCost()
{
ocrNaturalInt i;
printf("Nodes : %ld -> : Edges %ld\n", g_uNode, nbOfEdge(g_uNode));
for (i = 0; i < nbOfEdge(g_uNode); i++)
printf("%ld\n", g_tEdge[i]->COST);
}
int costSort(const void *a, const void *b)
{
return (*(ocrEdge **) a)->COST - (*(ocrEdge **) b)->COST;
}
void makingEdges(ocrNode * i_NodeList)
{
ocrNaturalInt n = 0;
ocrNode *l_pNode, *l_pFirst, *l_pSecond;
for (l_pNode = i_NodeList, g_uNode = 0; l_pNode;
l_pNode = (ocrNode *) l_pNode->NEXT, g_uNode++);
g_tEdge = (ocrEdge **) mbkalloc(sizeof(ocrEdge *) * nbOfEdge(g_uNode));
for (l_pFirst = i_NodeList; l_pFirst->NEXT; l_pFirst = l_pFirst->NEXT)
for (l_pSecond = l_pFirst->NEXT; l_pSecond;
l_pSecond = l_pSecond->NEXT)
g_tEdge[n++] = createEdge(l_pFirst, l_pSecond);
qsort(g_tEdge, nbOfEdge(g_uNode), sizeof(ocrEdge *), costSort);
// dumpCost ();
}
void dumpSet()
{
}
ocrEdge *chooseEdges(ocrNode * i_NodeList)
{
chain_list **l_pSet;
ocrNode *l_pNode = i_NodeList;
ocrNaturalInt i;
ocrEdge *l_pReturnEdge = NULL;
ocrEdge *l_pEdge = NULL;
// Initialisation
l_pSet = (chain_list **) mbkalloc(g_uNode * sizeof(chain_list *));
for (i = 0; i < g_uNode; i++) {
l_pSet[i] = NULL;
l_pSet[i] = addchain(l_pSet[i], l_pNode);
l_pNode = l_pNode->NEXT;
}
// construction du MST
for (i = 0; i < nbOfEdge(g_uNode); i++)
if (computeEdge(g_tEdge[i], l_pSet)) {
if (!l_pEdge) {
l_pEdge = g_tEdge[i];
l_pEdge->NEXT = NULL;
l_pReturnEdge = l_pEdge;
} else {
l_pEdge->NEXT = g_tEdge[i];
l_pEdge = l_pEdge->NEXT;
l_pEdge->NEXT = NULL;
}
} else {
deleteEdge(g_tEdge[i]);
g_tEdge[i] = NULL;
}
// Free Set
for (i = 0; i < g_uNode; i++)
freechain(l_pSet[i]);
mbkfree(l_pSet);
l_pSet = NULL;
// Return
return l_pReturnEdge;
}
/**
* Construit le Minimum Spaning Tree
**/
ocrEdge *makingMst(ocrSignal * i_pSignal)
{
ocrEdge *l_pEdge = NULL;
// Construction de toutes les arretes
makingEdges(i_pSignal->GLOBAL);
// Choix des arretes pour le MST
l_pEdge = chooseEdges(i_pSignal->GLOBAL);
// mbkfree (g_tEdge);
// g_tEdge = NULL;
return l_pEdge;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,524 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:20 $
$Log: ocrWeightedTree.c,v $
Revision 1.1 2002/03/15 14:37:20 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:18 hcl
First commit in the new tree.
Revision 1.3 2001/12/20 13:04:03 hcl
Cosmetique.
Revision 1.2 2001/12/14 15:58:36 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.1 2001/09/26 14:27:49 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrUtil.h"
#include "ocrPath.h"
#include "display.h"
#include "ocrConnectorUtil.h"
#include "ocrMst.h"
#include "ocrWeightedTree.h"
#define SCALE_X 100
#define PITCH 5
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
static ocrNaturalInt g_uNbF;
static float g_fMaxCost;
// Table de Densité
static float *g_tCostGrid;
static ocrNaturalInt *g_tEdge;
static ocrNaturalInt *g_tEdgeCopy;
static ocrNaturalInt *g_tSignal;
static ocrNaturalInt *g_tMerge;
/**
* calcul le cout d'un arbre
**/
float getCost(ocrNaturalInt * i_tGrid, float *i_tCostGrid)
{
ocrNaturalInt i;
float som = 0.0;
for (i = 0; i < g_uNbF; i++)
som += i_tGrid[i] * i_tCostGrid[i];
return som;
}
/**
* Merge 2 arbres
**/
void
mergeGrid(ocrNaturalInt * o_tMerge,
ocrNaturalInt * i_tGrid1, ocrNaturalInt * i_tGrid2)
{
ocrNaturalInt i;
for (i = 0; i < g_uNbF; i++)
o_tMerge[i] = i_tGrid1[i] || i_tGrid2[i];
}
/**
* Copy un arbre
**/
void makeCopy(ocrNaturalInt * i_tGridDest, ocrNaturalInt * i_tGridSrc)
{
ocrNaturalInt i;
for (i = 0; i < g_uNbF; i++)
i_tGridDest[i] = i_tGridSrc[i];
}
/**
* Initialise un arbre
**/
void initialiseGrid(ocrNaturalInt * i_tGrid)
{
ocrNaturalInt i;
for (i = 0; i < g_uNbF; i++)
i_tGrid[i] = 0;
}
/**
* renvoie les 2 noeuds qui définissent le halfPerimeter
**/
void
halfPerimeter(ocrNode ** o_pNode1,
ocrNode ** o_pNode2, ocrSignal * i_pSignal)
{
ocrNode *l_pNode;
ocrNode l_NodeMin = *(i_pSignal->GLOBAL);
ocrNode l_NodeMax = *(i_pSignal->GLOBAL);
for (l_pNode = i_pSignal->GLOBAL; l_pNode; l_pNode = l_pNode->NEXT) {
if (l_pNode->X < l_NodeMin.X)
l_NodeMin.X = l_pNode->X;
if (l_pNode->Y < l_NodeMin.Y)
l_NodeMin.Y = l_pNode->Y;
if (l_pNode->X > l_NodeMax.X)
l_NodeMax.X = l_pNode->X;
if (l_pNode->Y > l_NodeMax.Y)
l_NodeMax.Y = l_pNode->Y;
}
*o_pNode1 = dupVirtualConnector(&l_NodeMin);
*o_pNode2 = dupVirtualConnector(&l_NodeMax);
}
/**
* renvoie le cout d'un noeud
**/
float computeDensity(ocrNode * i_pNodeMin, ocrNode * i_pNodeMax)
{
float l_fX, l_fY;
l_fX = i_pNodeMax->X - i_pNodeMin->X;
l_fY = i_pNodeMax->Y - i_pNodeMin->Y;
return ((float) (l_fX + l_fY + 1)) / ((float) (l_fX + 1) * (l_fY + 1));
}
/**
* Incrémente/Décrémente la grille de Densité avec l'incrément +1/-1
* sur toute la surface du demi périmetre.
**/
void
incDensityTable(ocrNode * i_pNodeMin, ocrNode * i_pNodeMax, int i_nInc)
{
ocrNaturalInt i, j;
ocrNaturalInt l_uFace = sqrt(g_uNbF);
float l_fDens;
l_fDens = computeDensity(i_pNodeMin, i_pNodeMax);
for (i = i_pNodeMin->X; i <= i_pNodeMax->X; i++)
for (j = i_pNodeMin->Y; j <= i_pNodeMax->Y; j++)
g_tCostGrid[j * l_uFace + i] = g_tCostGrid[j * l_uFace + i] +
(float) i_nInc *l_fDens;
}
void adjustDensityTable(ocrNaturalInt * i_pSignalGrid)
{
ocrNaturalInt i;
for (i = 0; i < g_uNbF; i++)
g_tCostGrid[i] += i_pSignalGrid[i];
}
/**
* Affiche la grille de Densité
**/
void dumpDensityTable()
{
int i, j;
for (i = 0; i < sqrt(g_uNbF); i++) {
for (j = 0; j < sqrt(g_uNbF); j++)
printf("%f ", g_tCostGrid[i * (int) (sqrt(g_uNbF)) + j]);
puts("");
}
}
/**
* Affiche la un signal
**/
void dumpSignalTable(ocrNaturalInt * i_tGrid)
{
int i, j;
for (i = 0; i < sqrt(g_uNbF); i++) {
for (j = 0; j < sqrt(g_uNbF); j++)
printf("%ld ", i_tGrid[i * (int) (sqrt(g_uNbF)) + j]);
puts("");
}
puts("");
}
/**
* Création de la Grille de Densité
**/
void makeDensityTable(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt i;
ocrSignal *l_pSignal;
ocrNode *l_pNodeMin, *l_pNodeMax;
// Création
g_tCostGrid = (float *) mbkalloc(sizeof(float) * i_pDataBase->NB_F);
// Initialisation
for (i = 0; i < i_pDataBase->NB_F; i++)
g_tCostGrid[i] = 0.0;
// Calcul pour chaque signal
for (l_pSignal = i_pDataBase->FSIGNAL[0];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
// Calcul du demi prérimetre
halfPerimeter(&l_pNodeMin, &l_pNodeMax, l_pSignal);
// Incrémente sur la surface du demi périmetre
incDensityTable(l_pNodeMin, l_pNodeMax, +1);
// free les 2 noeuds
deleteVirtualConnectorList(l_pNodeMin);
deleteVirtualConnectorList(l_pNodeMax);
}
}
/**
* Initialisation pour WeightedTree
**/
void initWeightedTree(ocrRoutingDataBase * i_pDataBase)
{
g_uNbF = i_pDataBase->NB_F;
// Création de la grille de Densité
makeDensityTable(i_pDataBase);
// Création & Initialisation des grilles
g_tEdge =
(ocrNaturalInt *) mbkalloc(sizeof(ocrNaturalInt) *
i_pDataBase->NB_F);
g_tEdgeCopy =
(ocrNaturalInt *) mbkalloc(sizeof(ocrNaturalInt) *
i_pDataBase->NB_F);
g_tSignal =
(ocrNaturalInt *) mbkalloc(sizeof(ocrNaturalInt) *
i_pDataBase->NB_F);
g_tMerge =
(ocrNaturalInt *) mbkalloc(sizeof(ocrNaturalInt) *
i_pDataBase->NB_F);
initialiseGrid(g_tEdge);
initialiseGrid(g_tEdgeCopy);
initialiseGrid(g_tSignal);
initialiseGrid(g_tMerge);
}
/**
* free pour WeightedTree
**/
void freeWeightedTree()
{
mbkfree(g_tEdge);
mbkfree(g_tEdgeCopy);
mbkfree(g_tSignal);
mbkfree(g_tMerge);
mbkfree(g_tCostGrid);
g_tCostGrid = NULL;
g_tEdge = NULL;
g_tEdgeCopy = NULL;
g_tSignal = NULL;
g_tMerge = NULL;
}
void
searchingStairCase(ocrNaturalInt i_uX1,
ocrNaturalInt i_uY1,
ocrNaturalInt i_uX2, ocrNaturalInt i_uY2)
{
float l_fCost;
ocrNaturalInt l_uNbFace = sqrt(g_uNbF);
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 1;
if ((i_uX1 == i_uX2) && (i_uY1 == i_uY2)) {
mergeGrid(g_tMerge, g_tEdge, g_tSignal);
l_fCost = getCost(g_tMerge, g_tCostGrid);
if (l_fCost < g_fMaxCost) {
makeCopy(g_tEdgeCopy, g_tEdge);
g_fMaxCost = l_fCost;
}
} else {
if (i_uX1 < i_uX2) {
i_uX1++;
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 1;
searchingStairCase(i_uX1, i_uY1, i_uX2, i_uY2);
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 0;
i_uX1--;
}
if (i_uX2 < i_uX1) {
i_uX1--;
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 1;
searchingStairCase(i_uX1, i_uY1, i_uX2, i_uY2);
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 0;
i_uX1++;
}
if (i_uY1 < i_uY2) {
i_uY1++;
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 1;
searchingStairCase(i_uX1, i_uY1, i_uX2, i_uY2);
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 0;
i_uY1--;
}
if (i_uY2 < i_uY1) {
i_uY1--;
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 1;
searchingStairCase(i_uX1, i_uY1, i_uX2, i_uY2);
g_tEdge[i_uY1 * l_uNbFace + i_uX1] = 0;
i_uY1++;
}
}
}
/**
* Supprime les doublons des segments
**/
void clearSegList(ocrSignal * i_pSignal)
{
ocrWSegment *l_pSegment;
ocrWSegment *l_pSegment2;
if (i_pSignal->SEGMENT == NULL)
return;
for (l_pSegment = i_pSignal->SEGMENT; l_pSegment->NEXT;
l_pSegment = l_pSegment->NEXT) {
for (l_pSegment2 = l_pSegment->NEXT; l_pSegment2;
l_pSegment2 = l_pSegment2->NEXT) {
if (l_pSegment->LAYER == l_pSegment2->LAYER)
if (l_pSegment->OFFSET == l_pSegment2->OFFSET) {
if ((l_pSegment->P_MAX <= l_pSegment2->P_MIN) ||
(l_pSegment2->P_MAX <= l_pSegment->P_MIN)) {
} else {
addSegmentSignalList(i_pSignal,
createWSegment(l_pSegment->
OFFSET,
l_pSegment->
LAYER,
MIN
(l_pSegment2->
P_MIN,
l_pSegment->
P_MIN),
MAX
(l_pSegment2->
P_MAX,
l_pSegment->
P_MAX),
i_pSignal->
INDEX));
deleteSegmentSignalList(i_pSignal, l_pSegment);
deleteSegmentSignalList(i_pSignal, l_pSegment2);
}
}
}
}
}
#define GET_NEXT_X(x) (x+1)
#define GET_PREV_X(x) (x-1)
#define GET_NEXT_Y(y) (ocrNaturalInt)(y+sqrt (g_uNbF))
#define GET_PREV_Y(y) (ocrNaturalInt)(y-sqrt (g_uNbF))
/**
* Recherche des segments hor dans la grille
**/
void
translateGridToHorSegments(ocrSignal * i_pSignal, ocrNaturalInt * i_tGrid)
{
ocrNaturalInt y, ok = 0, max, x;
ocrNaturalInt l_uXMin = 0, l_uXMax = 0;
ocrWSegment *l_pSegment;
for (y = 0; y < g_uNbF; y = GET_NEXT_Y(y)) {
ok = 0;
x = y;
max = x + sqrt(g_uNbF) - 1;
while ((x < max) && (i_tGrid[x] == 0))
x = GET_NEXT_X(x);
if ((x != max) && (i_tGrid[x]) && (i_tGrid[GET_NEXT_X(x)])) {
ok = 1;
l_uXMin = x;
while ((x < max) && (i_tGrid[x]))
x = GET_NEXT_X(x);
if (x < max)
l_uXMax = GET_PREV_X(x);
else {
if (i_tGrid[x])
l_uXMax = x;
else
l_uXMax = GET_PREV_X(x);
}
}
if (ok) {
// création du segment [ l_uXMin, l_uXMax] hor
l_pSegment =
createWSegment(y / (int) sqrt(g_uNbF), 0,
l_uXMin % (int) sqrt(g_uNbF),
l_uXMax % (int) sqrt(g_uNbF), 0);
// insertion dans la liste
addSegmentSignalList(i_pSignal, l_pSegment);
}
}
}
void
translateGridToVerSegments(ocrSignal * i_pSignal, ocrNaturalInt * i_tGrid)
{
ocrNaturalInt x, ok = 0, max, y;
ocrNaturalInt l_uYMin = 0, l_uYMax = 0;
ocrWSegment *l_pSegment;
for (x = 0; x < sqrt(g_uNbF); x = GET_NEXT_X(x)) {
ok = 0;
y = x;
max = y + (sqrt(g_uNbF) - 1) * sqrt(g_uNbF);
while ((y < max) && (i_tGrid[y] == 0))
y = GET_NEXT_Y(y);
if ((y != max) && (i_tGrid[y]) && (i_tGrid[GET_NEXT_Y(y)])) {
ok = 1;
l_uYMin = y;
while ((y < max) && (i_tGrid[y]))
y = GET_NEXT_Y(y);
if (y < max)
l_uYMax = GET_PREV_Y(y);
else {
if (i_tGrid[y])
l_uYMax = y;
else
l_uYMax = GET_PREV_Y(y);
}
}
if (ok) {
// création du segment [ l_uYMin, l_uYMax] hor
l_pSegment = createWSegment(x % (int) sqrt(g_uNbF), 1,
l_uYMin / (int) sqrt(g_uNbF),
l_uYMax / (int) sqrt(g_uNbF), 0);
// insertion dans la liste
l_pSegment->NEXT = i_pSignal->SEGMENT;
i_pSignal->SEGMENT = l_pSegment;
}
}
}
/**
* ajoute dans le champ SEGMENT du signal
* les segments issus du routage global d'une arrete
**/
void
translateGridToSegments(ocrSignal * i_pSignal, ocrNaturalInt * i_tGrid)
{
translateGridToHorSegments(i_pSignal, i_tGrid);
translateGridToVerSegments(i_pSignal, i_tGrid);
}
/**
* Création du WeightedTree
**/
void
makingWeightedTree(ocrRoutingDataBase * i_pDataBase,
ocrSignal * i_pSignal, ocrEdge * i_pEdge)
{
ocrEdge *l_pEdge;
ocrNode *l_pNodeMin, *l_pNodeMax;
initialiseGrid(g_tSignal);
initialiseGrid(g_tEdge);
initialiseGrid(g_tEdgeCopy);
g_fMaxCost = OCRNATURALINT_MAX;
// dumpVirConList (i_pSignal->GLOBAL, stdout);
// dumpSignalTable (g_tSignal);
for (l_pEdge = i_pEdge; l_pEdge; l_pEdge = l_pEdge->NEXT) {
// initialiseGrid (g_tEdgeCopy);
initialiseGrid(g_tEdge);
searchingStairCase(l_pEdge->N1->X, l_pEdge->N1->Y,
l_pEdge->N2->X, l_pEdge->N2->Y);
// grille vers segments
translateGridToSegments(i_pSignal, g_tEdgeCopy);
// Merge des arretes
mergeGrid(g_tSignal, g_tEdgeCopy, g_tSignal);
g_fMaxCost = OCRNATURALINT_MAX;
// dumpSignalTable (g_tSignal);
clearSegList(i_pSignal);
// dumpSegList (i_pSignal->SEGMENT, stdout);
}
// Calcul du demi prérimetre
halfPerimeter(&l_pNodeMin, &l_pNodeMax, i_pSignal);
// Décrémente sur la surface du demi périmetre
incDensityTable(l_pNodeMin, l_pNodeMax, -1);
// Ajustement de la table de densité avec le signal réel
adjustDensityTable(g_tSignal);
// Création des segments
}

View File

@ -0,0 +1,10 @@
## Process this file with automake to produce Makefile.in
INCLUDES = @INCLUDES@ -I$(top_srcdir)/src/include
noinst_LIBRARIES = libocrPath.a
libocrPath_a_SOURCES = mbk_tree.c ocrUtil.c \
ocrWRoutingUtil.c ocrWSegLabeling.c \
ocrWPlaneLabeling.c \
ocrWRouting.c ocrToPhFig.c

View File

@ -0,0 +1,650 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:22 $
$Log: mbk_tree.c,v $
Revision 1.1 2002/03/15 14:37:22 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:20 hcl
First commit in the new tree.
Revision 1.3 2001/12/20 13:04:03 hcl
Cosmetique.
Revision 1.2 2001/12/14 15:58:39 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.1 2001/09/26 14:27:51 hcl
premier commit....
Revision 1.2 2000/01/25 16:05:07 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include <stdio.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "mbk_tree.h"
static char *res_id =
"$Id: mbk_tree.c,v 1.1 2002/03/15 14:37:22 hcl Exp $";
/*****************************************************************************/
/* Global variables */
/*****************************************************************************/
rbtree rbtreeNil = { NULL, /* KEY */
NULL, /* DATA */
rbtreeblack, /* COLOUR */
&rbtreeNil, /* PARENT */
&rbtreeNil, /* Left */
&rbtreeNil
}; /* Right */
rbtree *HEAD_RBTREE = NULL; /* red-black tree buffer head */
/*****************************************************************************/
/* Static functions */
/*****************************************************************************/
// WARNING : no mbk_free !
/** default comparison function **/
static inline int static_defaultcompare(void *first, void *second)
{
return ((int) first ==
(int) second) ? 0 : (((int) first > (int) second) ? 1 : -1);
}
/** red-black tree node creation function **/
static inline rbtree *static_createrbtreeelement(void *key,
void *data,
rbtreecolour colour,
rbtree * parent,
rbtree * left,
rbtree * right)
{
rbtree *pt;
register unsigned long i;
// allocation blocs par blocs
if (HEAD_RBTREE == NULL) {
pt = (rbtree *) mbkalloc(BUFSIZE * sizeof(rbtree));
HEAD_RBTREE = pt;
for (i = 1; i < BUFSIZE; i++) {
pt->PARENT = pt + 1;
pt++;
}
pt->PARENT = NULL;
}
// mise à jour du noeud
pt = HEAD_RBTREE;
HEAD_RBTREE = HEAD_RBTREE->PARENT;
pt->KEY = key;
pt->DATA = data;
pt->COLOUR = colour;
pt->PARENT = parent;
pt->Left = left;
pt->Right = right;
return pt;
}
/** red-black tree node destruction function **/
static inline void static_freerbtreeelement(rbtree * node)
{
// libère le noeud
// pas de free voir static_createrbtreeelement
node->PARENT = HEAD_RBTREE;
HEAD_RBTREE = node;
}
/** red-black tree left rotate function **/
static inline rbtree *static_leftrotaterbtree(rbtree * root, rbtree * node)
{
rbtree *son = node->Right;
node->Right = son->Left;
if (son->Left != RBTREENULL)
son->Left->PARENT = node;
son->PARENT = node->PARENT;
son->Left = node;
node->PARENT = son;
if (son->PARENT == RBTREENULL)
return son;
else {
if (son->PARENT->Left == node)
son->PARENT->Left = son;
else
son->PARENT->Right = son;
return root;
}
}
/** red-black tree right rotate function **/
static inline rbtree *static_rightrotaterbtree(rbtree * root,
rbtree * node)
{
rbtree *son = node->Left;
node->Left = son->Right;
if (son->Right != RBTREENULL)
son->Right->PARENT = node;
son->PARENT = node->PARENT;
son->Right = node;
node->PARENT = son;
if (son->PARENT == RBTREENULL)
return son;
else {
if (son->PARENT->Left == node)
son->PARENT->Left = son;
else
son->PARENT->Right = son;
return root;
}
}
/** balance red-black tree after adding node **/
static inline rbtree *static_balanceaddrbtree(rbtree * root, rbtree * node)
{
rbtree *uncle;
while ((node != root) && (node->PARENT->COLOUR == rbtreered)) {
if (node->PARENT == node->PARENT->PARENT->Left) {
uncle = node->PARENT->PARENT->Right;
if (uncle->COLOUR == rbtreered) {
node->PARENT->COLOUR = rbtreeblack;
uncle->COLOUR = rbtreeblack;
node->PARENT->PARENT->COLOUR = rbtreered;
node = node->PARENT->PARENT;
} else {
if (node == node->PARENT->Right) {
node = node->PARENT;
root = static_leftrotaterbtree(root, node);
}
node->PARENT->COLOUR = rbtreeblack;
node->PARENT->PARENT->COLOUR = rbtreered;
root =
static_rightrotaterbtree(root, node->PARENT->PARENT);
}
} else {
uncle = node->PARENT->PARENT->Left;
if (uncle->COLOUR == rbtreered) {
node->PARENT->COLOUR = rbtreeblack;
uncle->COLOUR = rbtreeblack;
node->PARENT->PARENT->COLOUR = rbtreered;
node = node->PARENT->PARENT;
} else {
if (node == node->PARENT->Left) {
node = node->PARENT;
root = static_rightrotaterbtree(root, node);
}
node->PARENT->COLOUR = rbtreeblack;
node->PARENT->PARENT->COLOUR = rbtreered;
root = static_leftrotaterbtree(root, node->PARENT->PARENT);
}
}
}
root->COLOUR = rbtreeblack;
return root;
}
/** balance red-black tree after deleting node **/
static inline rbtree *static_balancedelrbtree(rbtree * root, rbtree * node)
{
rbtree *brother;
while ((node != root) && (node->COLOUR == rbtreeblack)) {
if (node == node->PARENT->Left) {
brother = node->PARENT->Right;
if (brother->COLOUR == rbtreered) {
brother->COLOUR = rbtreeblack;
node->PARENT->COLOUR = rbtreered;
root = static_leftrotaterbtree(root, node->PARENT);
brother = node->PARENT->Right;
}
if ((brother->Left->COLOUR == rbtreeblack)
&& (brother->Right->COLOUR == rbtreeblack)) {
brother->COLOUR = rbtreered;
node = node->PARENT;
} else {
if (brother->Right->COLOUR == rbtreeblack) {
brother->Left->COLOUR = rbtreeblack;
brother->COLOUR = rbtreered;
root = static_rightrotaterbtree(root, brother);
brother = node->PARENT->Right;
}
brother->COLOUR = node->PARENT->COLOUR;
node->PARENT->COLOUR = rbtreeblack;
brother->Right->COLOUR = rbtreeblack;
root = static_leftrotaterbtree(root, node->PARENT);
node = root; /* in order to break off looping */
}
} else {
brother = node->PARENT->Left;
if (brother->COLOUR == rbtreered) {
brother->COLOUR = rbtreeblack;
node->PARENT->COLOUR = rbtreered;
root = static_rightrotaterbtree(root, node->PARENT);
brother = node->PARENT->Left;
}
if ((brother->Left->COLOUR == rbtreeblack)
&& (brother->Right->COLOUR == rbtreeblack)) {
brother->COLOUR = rbtreered;
node = node->PARENT;
} else {
if (brother->Left->COLOUR == rbtreeblack) {
brother->Right->COLOUR = rbtreeblack;
brother->COLOUR = rbtreered;
root = static_leftrotaterbtree(root, brother);
brother = node->PARENT->Left;
}
brother->COLOUR = node->PARENT->COLOUR;
node->PARENT->COLOUR = rbtreeblack;
brother->Left->COLOUR = rbtreeblack;
root = static_rightrotaterbtree(root, node->PARENT);
node = root; /* in order to break off looping */
}
}
}
node->COLOUR = rbtreeblack;
return root;
}
/*****************************************************************************/
/* Library functions */
/*****************************************************************************/
/** find a red-black tree node **/
rbtree *getrbtree(rbtree * root, void *key, int (*cmp) (void *, void *))
{
int res;
if (!cmp)
cmp = static_defaultcompare;
if (!root)
return RBTREENULL;
while ((root != RBTREENULL) && ((res = cmp(key, root->KEY)) != 0)) {
if (res < 0)
root = root->Left;
else
root = root->Right;
}
return root;
}
/** find a red-black tree node and previous and next nodes **/
rbtree *getrbtree2(rbtree * root, void *key, rbtree ** previous,
rbtree ** next, int (*cmp) (void *, void *))
{
int res;
*previous = RBTREENULL;
*next = RBTREENULL;
if (!cmp)
cmp = static_defaultcompare;
if (!root)
return RBTREENULL;
while ((root != RBTREENULL) && ((res = cmp(key, root->KEY)) != 0)) {
if (res < 0) {
*next = root;
root = root->Left;
} else {
*previous = root;
root = root->Right;
}
}
if (root != RBTREENULL) {
if (root->Left != RBTREENULL)
for (*previous = root->Left; (*previous)->Right != RBTREENULL;
*previous = (*previous)->Right);
if (root->Right != RBTREENULL)
for (*next = root->Right; (*next)->Left != RBTREENULL;
*next = (*next)->Left);
}
return root;
}
/** get the most significant red-black tree node **/
rbtree *getmostrbtree(rbtree * root)
{
rbtree *parent = RBTREENULL;
if (!root)
return RBTREENULL;
while (root != RBTREENULL) {
parent = root;
root = root->Left;
}
return parent;
}
/** get the least significant red-black tree node **/
rbtree *getleastrbtree(rbtree * root)
{
rbtree *parent = RBTREENULL;
if (!root)
return RBTREENULL;
while (root != RBTREENULL) {
parent = root;
root = root->Right;
}
return parent;
}
/** get previous red-black tree node **/
rbtree *getpreviousrbtree(rbtree * node)
{
rbtree *parent;
if ((!node) || (node == RBTREENULL))
return RBTREENULL;
if (node->Left != RBTREENULL) {
for (node = node->Left; node->Right != RBTREENULL;
node = node->Right);
return node;
}
parent = node->PARENT;
while ((parent != RBTREENULL) && (node == parent->Left)) {
node = parent;
parent = node->PARENT;
}
return parent;
}
/** get next red-black tree node **/
rbtree *getnextrbtree(rbtree * node)
{
rbtree *parent;
if ((!node) || (node == RBTREENULL))
return RBTREENULL;
if (node->Right != RBTREENULL) {
for (node = node->Right; node->Left != RBTREENULL;
node = node->Left);
return node;
}
parent = node->PARENT;
while ((parent != RBTREENULL) && (node == parent->Right)) {
node = parent;
parent = node->PARENT;
}
return parent;
}
/** add a node in a red-black tree **/
rbtree *addrbtree(rbtree * root, void *key, void *data,
int (*cmp) (void *, void *))
{
rbtree *node = (root ? root : RBTREENULL);
rbtree *parent = RBTREENULL;
int res = 0; /* warning: `res' might be used uninitialized in this function */
if (!cmp)
cmp = static_defaultcompare;
while (node != RBTREENULL) {
parent = node;
if ((res = cmp(key, node->KEY)) < 0)
node = node->Left;
else
node = node->Right;
}
if (parent == RBTREENULL)
return static_createrbtreeelement(key, data, rbtreeblack,
RBTREENULL, RBTREENULL,
RBTREENULL);
else {
node =
static_createrbtreeelement(key, data, rbtreered, parent,
RBTREENULL, RBTREENULL);
if (res < 0)
parent->Left = node;
else
parent->Right = node;
return static_balanceaddrbtree(root, node);
}
}
/** add a son to a node in a red-black tree **/
rbtree *addrbtree2(rbtree * root, rbtree * parent, void *key, void *data,
int (*cmp) (void *, void *))
{
rbtree *node;
if (!cmp)
cmp = static_defaultcompare;
if ((!root || (root == RBTREENULL)) && parent
&& (parent != RBTREENULL)) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" addrbtree2() impossible : root pointer = NULL/RBTREENULL and parent pointer != NULL/RBTREENULL !\n");
exit(1);
}
if (root && (root != RBTREENULL)
&& (!parent || (parent == RBTREENULL))) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" addrbtree2() impossible : parent pointer = NULL/RBTREENULL and root pointer != NULL/RBTREENULL !\n");
exit(1);
}
if (!parent || (parent == RBTREENULL))
return static_createrbtreeelement(key, data, rbtreeblack,
RBTREENULL, RBTREENULL,
RBTREENULL);
else {
node =
static_createrbtreeelement(key, data, rbtreered, parent,
RBTREENULL, RBTREENULL);
if (cmp(key, parent->KEY) < 0) {
if (parent->Left == RBTREENULL)
parent->Left = node;
else {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" addrbtree2() impossible : son pointer field != RBTREENULL !\n");
exit(1);
}
} else {
if (parent->Right == RBTREENULL)
parent->Right = node;
else {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" addrbtree2() impossible : son pointer field != RBTREENULL !\n");
exit(1);
}
}
return static_balanceaddrbtree(root, node);
}
}
/** delete a node in a red-black tree **/
rbtree *delrbtree(rbtree * root, rbtree * node)
{
rbtree *del;
rbtree *son;
if (!root || !node) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr, " delrbtree() impossible : pointer = NULL !\n");
exit(1);
}
if ((root == RBTREENULL) || (node == RBTREENULL)) {
//fflush(stdout);
//fprintf(stderr, "*** mbk error ***");
//fprintf(stderr,
// " delrbtree() impossible : pointer = RBTREENULL !\n");
/*
son = NULL;
del = son->Left;
*/
return root;
}
if ((node->Left == RBTREENULL) || (node->Right == RBTREENULL))
del = node;
else {
del = getnextrbtree(node);
node->KEY = del->KEY;
node->DATA = del->DATA;
}
if (del->Left != RBTREENULL)
son = del->Left;
else
son = del->Right;
son->PARENT = del->PARENT;
if (del->PARENT == RBTREENULL) {
static_freerbtreeelement(del);
son->COLOUR = rbtreeblack;
return son;
} else {
if (del == del->PARENT->Left)
del->PARENT->Left = son;
else
del->PARENT->Right = son;
if (del->COLOUR == rbtreeblack)
root = static_balancedelrbtree(root, son);
static_freerbtreeelement(del);
return root;
}
}
/** free a red-black tree **/
void freerbtree(rbtree * root, void (*freekey) (void *),
void (*freedata) (void *))
{
rbtree *left;
rbtree *right;
if (root && (root != RBTREENULL)) {
left = root->Left;
right = root->Right;
if (freekey)
freekey(root->KEY);
if (freedata)
freedata(root->DATA);
static_freerbtreeelement(root);
freerbtree(left, freekey, freedata); /* TAG : RECURSIVE */
freerbtree(right, freekey, freedata); /* TAG : RECURSIVE */
}
}
/** map a void function on a red-black tree from the most significant node to
the least significant node **/
void mapmosttoleastrbtree(rbtree * root, void (*fun) (rbtree *))
{
if (!fun) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" mapmosttoleastrbtree() impossible : function = NULL !\n");
exit(1);
}
if (root && (root != RBTREENULL)) {
mapmosttoleastrbtree(root->Left, fun); /* TAG : RECURSIVE */
fun(root);
mapmosttoleastrbtree(root->Right, fun); /* TAG : RECURSIVE */
}
}
/** map a void function on a red-black tree from the least significant node to
the most significant node **/
void mapleasttomostrbtree(rbtree * root, void (*fun) (rbtree *))
{
if (!fun) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" mapleasttomostrbtree() impossible : function = NULL !\n");
exit(1);
}
if (root && (root != RBTREENULL)) {
mapleasttomostrbtree(root->Right, fun); /* TAG : RECURSIVE */
fun(root);
mapleasttomostrbtree(root->Left, fun); /* TAG : RECURSIVE */
}
}
/** map a function on a red-black tree from the most significant node to the
least significant node **/
void *mapmosttoleastrbtree2(rbtree * root, void *(*fun) (rbtree *, void *),
void *seed)
{
if (!fun) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" mapmosttoleastrbtree2() impossible : function = NULL !\n");
exit(1);
}
if (root && (root != RBTREENULL)) {
seed = mapmosttoleastrbtree2(root->Left, fun, seed); /* TAG : RECURSIVE */
seed = fun(root, seed);
seed = mapmosttoleastrbtree2(root->Right, fun, seed); /* TAG : RECURSIVE */
}
return seed;
}
/** map a function on a red-black tree from the least significant node to the
most significant node **/
void *mapleasttomostrbtree2(rbtree * root, void *(*fun) (rbtree *, void *),
void *seed)
{
if (!fun) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***");
fprintf(stderr,
" mapleasttomostrbtree2() impossible : function = NULL !\n");
exit(1);
}
if (root && (root != RBTREENULL)) {
seed = mapleasttomostrbtree2(root->Right, fun, seed); /* TAG : RECURSIVE */
seed = fun(root, seed);
seed = mapleasttomostrbtree2(root->Left, fun, seed); /* TAG : RECURSIVE */
}
return seed;
}

View File

@ -0,0 +1,557 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:22 $
$Log: ocrToPhFig.c,v $
Revision 1.1 2002/03/15 14:37:22 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:20 hcl
First commit in the new tree.
Revision 1.8 2002/01/18 14:04:48 hcl
Bug connector
Revision 1.7 2002/01/14 10:34:34 hcl
OCR should be MBK_SCALE_X - compliant
Revision 1.6 2001/12/20 13:04:03 hcl
Cosmetique.
Revision 1.5 2001/12/19 14:22:49 hcl
Moult petits changements.
Revision 1.4 2001/12/17 14:29:36 hcl
VDD/VSS rail bug, new ripUp.
Revision 1.3 2001/12/14 15:58:39 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.2 2001/11/20 09:41:34 hcl
segmentation fault
Revision 1.1 2001/09/26 14:27:51 hcl
premier commit....
Revision 1.3 2000/02/26 00:24:09 root
2 points OK
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include <string.h>
#include <stdlib.h>
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "mbk_tree.h"
#include "ocrWRoutingUtil.h"
#include "ocrToPhFig.h"
#include "display.h"
#define PITCH 5
static char *res_id =
"$Id: ocrToPhFig.c,v 1.1 2002/03/15 14:37:22 hcl Exp $";
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
/*
### --------------------------- ###
### Internal Functions
### --------------------------- ###
*/
/**
* Retourne le VIA physique correspondant à la coordonée z
**/
int getPhVia(int i_uZ)
{
switch (i_uZ) {
case -1:
return CONT_VIA;
case 0:
return CONT_VIA2;
case 1:
return CONT_VIA3;
case 2:
return CONT_VIA4;
case 3:
return CONT_VIA5;
case 4:
return CONT_VIA6;
case 5:
return CONT_VIA7;
}
display(LEVEL, ERROR, "getPhVia in %s:%d\n", __FILE__, __LINE__);
exit(1);
// pour éviter un Warning ...
return 0;
}
/**
* Retourne le LAYER physique correspondant à la coordonée z
**/
ocrNaturalInt getPhLayer(ocrNaturalInt i_uZ)
{
switch (i_uZ) {
case 0:
return ALU2;
case 1:
return ALU3;
case 2:
return ALU4;
case 3:
return ALU5;
case 4:
return ALU6;
case 5:
return ALU7;
case 6:
return ALU8;
}
display(LEVEL, ERROR, "getPhLayer in %s:%d\n", __FILE__, __LINE__);
exit(1);
// pour éviter un Warning ...
return 0;
}
/**
* Ajoute un via dans la io_pPhFig
* i_uLayer est le Layer de niveau le plus bas par rapport au via
**/
void
addViaToPhFig(ocrRoutingParameters * i_pParam,
ocrNaturalInt i_uX,
ocrNaturalInt i_uY, int i_nLayer, phfig_list * io_pPhFig)
{
#if 0
addphvia(io_pPhFig,
getPhVia(i_nLayer),
i_uX * i_pParam->PITCH_H * SCALE_X,
i_uY * i_pParam->PITCH_H * SCALE_X);
//printf ("Add via %d en %ld %ld\n",i_nLayer,i_uX,i_uY);
#else
addphvia(io_pPhFig,
getPhVia(i_nLayer),
i_uX * i_pParam->PITCH_H * SCALE_X,
i_uY * i_pParam->PITCH_H * SCALE_X, 0, 0, NULL);
#endif
}
/**
* Ajoute un segment dans la io_pPhFig
**/
void
addSegmentToPhFig(ocrRoutingParameters * i_pParam,
ocrWSegment * i_pSegment, phfig_list * io_pPhFig,
char *i_pName)
{
char l_sName[7];
sprintf(l_sName, "seg%ld", i_pSegment->SIGNAL_INDEX);
if (getWSegDirection(i_pParam, i_pSegment) == ocrHorizontal) {
addphseg(io_pPhFig,
getPhLayer(i_pSegment->LAYER),
i_pParam->PITCH_V * 4 * SCALE_X / 10,
i_pSegment->P_MIN * i_pParam->PITCH_H * SCALE_X,
i_pSegment->OFFSET * i_pParam->PITCH_V * SCALE_X,
i_pSegment->P_MAX * i_pParam->PITCH_H * SCALE_X,
i_pSegment->OFFSET * i_pParam->PITCH_V * SCALE_X,
(i_pName ? i_pName : l_sName));
//l_sName);
} else {
addphseg(io_pPhFig, getPhLayer(i_pSegment->LAYER),
// FIXME width of phseg ??? 2 or 1 ?
i_pParam->PITCH_H * 4 * SCALE_X / 10,
i_pSegment->OFFSET * i_pParam->PITCH_H * SCALE_X,
i_pSegment->P_MIN * i_pParam->PITCH_V * SCALE_X,
i_pSegment->OFFSET * i_pParam->PITCH_H * SCALE_X,
i_pSegment->P_MAX * i_pParam->PITCH_V * SCALE_X,
(i_pName ? i_pName : l_sName));
//l_sName);
}
}
/**
* Dump le signal en (x,y,z) en segment physique
**/
/*
a implanter un jour ou l'autre...
changer dumpSignal et addSegmentToPhFig :
* utiliser les TAGs plutot que le champ SIGNAL_INDEX
* tenir compte des ocrWSegment de longueur 1 :
pas de VIA si les segment precedents et suivants sont sur
le meme layer.
=-> IDEE
dans l'expansion des segments, autoriser le saut d'une piste a une
autre piste immediatement voisine dans le meme layer.
-> pour expansion : assez immediat
-> pour kost : c'est plus delicat...
-> pour make_segments : argh !
ATTENTION ! ne pas autoriser trop de ce genre de propagation !
1/
--------|
|-------------------- ok
2/
--------|
|
|-------------------- not ok
3/
--------|
-|
-|
------------------- not ok
====> comment faire ?
post-traitement lors du make_segments ?
lors de l'expansion : ne pas etendre aux pistes adjacentes par le P d'arrivee. (P_MIN < P_MAX)
le cas 3 n'arrivera pas (ou peu) car il est probable que soient preferes des segments amenant
plus rapidement au but.
*/
void
dumpSignal(ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid,
phfig_list * io_pPhFig,
ocrNaturalInt x, ocrNaturalInt y, ocrNaturalInt z)
{
ocrWSegment *l_pSegment;
ocrWSegment *l_pSegmentVoisin;
ocrNaturalInt l_uNoSignal;
// segment concerné
l_pSegment = getWSegment(i_pGrid, x, y, z);
// sauvegarde du numéro du signal
l_uNoSignal = l_pSegment->SIGNAL_INDEX;
// printf("dumpSignal %ld %ld %ld\n",x,y,z);
// printf("Index = %ld\n",l_uNoSignal);
// quand on parcours un signal il devient libre
// pour ne pas parcourir 2 fois le meme signal
l_pSegment->SIGNAL_INDEX = WSEGMENT_FREE;
if (getWSegDirection(i_pParam, l_pSegment) == ocrHorizontal) {
ocrNaturalInt i;
for (i = l_pSegment->P_MIN; i <= l_pSegment->P_MAX; i++) {
if (z > 0) {
l_pSegmentVoisin = getWSegment(i_pGrid, i, y, z - 1);
// connexion avec LAYER - 1 ?
if (l_pSegmentVoisin /*&& (!l_pSegmentVoisin->TAG) */ )
if (l_pSegmentVoisin->SIGNAL_INDEX == l_uNoSignal) {
//l_pSegmentVoisin->TAG = 1;
dumpSignal(i_pParam, i_pGrid, io_pPhFig, i, y,
z - 1);
// ajout d'un via
addViaToPhFig(i_pParam, i, y, z - 1, io_pPhFig);
}
}
if (z < i_pGrid->NB_OF_LAYERS - 1) {
l_pSegmentVoisin = getWSegment(i_pGrid, i, y, z + 1);
// connexion avec LAYER + 1 ?
if (l_pSegmentVoisin /* && (!l_pSegmentVoisin->TAG) */ )
if (l_pSegmentVoisin->SIGNAL_INDEX == l_uNoSignal) {
//l_pSegmentVoisin->TAG = 1;
dumpSignal(i_pParam, i_pGrid, io_pPhFig, i, y,
z + 1);
// ajout d'un via
addViaToPhFig(i_pParam, i, y, z, io_pPhFig);
}
}
}
} else {
ocrNaturalInt i;
for (i = l_pSegment->P_MIN; i <= l_pSegment->P_MAX; i++) {
if (z > 0) {
l_pSegmentVoisin = getWSegment(i_pGrid, x, i, z - 1);
// printf(" VERT %ld %ld %ld index = %ld TAG = %ld\n",
// x,i,z-1,l_pSegmentVoisin->SIGNAL_INDEX,
// l_pSegmentVoisin->TAG);
if (l_pSegmentVoisin /*&& (!l_pSegmentVoisin->TAG) */ )
if (l_pSegmentVoisin->SIGNAL_INDEX == l_uNoSignal) {
//l_pSegmentVoisin->TAG = 1;
dumpSignal(i_pParam, i_pGrid, io_pPhFig, x, i,
z - 1);
// ajout d'un via
addViaToPhFig(i_pParam, x, i, z - 1, io_pPhFig);
}
}
if (z < i_pGrid->NB_OF_LAYERS - 1) {
l_pSegmentVoisin = getWSegment(i_pGrid, x, i, z + 1);
if (l_pSegmentVoisin /*&& (!l_pSegmentVoisin->TAG) */ )
if (l_pSegmentVoisin->SIGNAL_INDEX == l_uNoSignal) {
//l_pSegmentVoisin->TAG = 1;
dumpSignal(i_pParam, i_pGrid, io_pPhFig, x, i,
z + 1);
// ajout d'un via
addViaToPhFig(i_pParam, x, i, z, io_pPhFig);
}
}
}
}
// ajoute le segment ainsi parcouru avec comme nom le numéro du signal
l_pSegment->SIGNAL_INDEX = l_uNoSignal;
addSegmentToPhFig(i_pParam, l_pSegment, io_pPhFig, NULL);
l_pSegment->SIGNAL_INDEX = WSEGMENT_FREE;
}
char *indexSignal(char *i_sRacine, ocrNaturalInt i_uIndex)
{
char l_sSignal[40];
sprintf(l_sSignal, "%s %ld", i_sRacine, i_uIndex);
return namealloc(l_sSignal);
}
void
dumpIntExtConToPhFig(ocrRoutingDataBase * i_pDataBase,
ocrRoutingParameters * i_pParam,
phfig_list * i_pPhFig)
{
ocrNaturalInt i;
ocrConnector *l_pCon;
for (i = 0; i < i_pDataBase->NB_GSIGNAL; i++) {
for (l_pCon = i_pDataBase->GSIGNAL[i]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT) {
if (l_pCon->INTEXT == INTERNAL) {
if (l_pCon->CON)
addViaToPhFig(i_pParam, l_pCon->CON->X, l_pCon->CON->Y, l_pCon->CON->Z - 1, // VIA ALUx<->ALU(x-1)
i_pPhFig);
} else {
if (l_pCon->CON)
addphcon(i_pPhFig,
l_pCon->CON->ORIENT,
l_pCon->NAME,
l_pCon->CON->X * 500,
l_pCon->CON->Y * 500, ALU2, 2 * SCALE_X);
}
}
}
}
void
dumpAlimToPhFig(ocrRoutingDataBase * i_pDataBase, phfig_list * i_pPhFig)
{
ocrNaturalInt l_uIndex = 0;
ocrNaturalInt i;
ocrNaturalInt start_with_vss = 0;
ocrNaturalInt sym_y = 0;
char *vss = namealloc ("vss");
char *vdd = namealloc ("vdd");
display(LEVEL, VERBOSE, "o Dumping Alim to PhFig...\n");
// Routage des alimentations ...
// ajout des connecteurs vdd vss
// VDD-VSS
sym_y = (
(i_pPhFig->PHINS->TRANSF == SYM_Y)
||
(i_pPhFig->PHINS->TRANSF == SYMXY)
)
;
start_with_vss = (
(
((i_pPhFig->PHINS->YINS / SCALE_X) % SCALE_X) == 0
)
^
(
sym_y
)
)
;
// start_with_vss = (
// (!((i_pPhFig->PHINS->YINS == 0) && (i_pPhFig->PHINS->TRANSF == SYM_Y)))
// ||
// (
// (i_pPhFig->PHINS->YINS != 0)
// &&
// (
// (
// (i_pPhFig->PHINS->YINS % 100)
// &&(!(i_pPhFig->PHINS->YINS % 50))
// && (i_pPhFig->PHINS->TRANSF == SYM_Y)
// )
// ||
// (
// (!(i_pPhFig->PHINS->YINS % 100))
// && (i_pPhFig->PHINS->TRANSF == NOSYM)
// )
// )
// )
// )
// ;
//
addphseg(i_pPhFig, ALU1, 6 * SCALE_X,
i_pDataBase->XAB1, i_pDataBase->YAB2 - 3 * SCALE_X,
i_pDataBase->XAB2, i_pDataBase->YAB2 - 3 * SCALE_X, NULL);
addphseg(i_pPhFig, ALU1, 6 * SCALE_X,
i_pDataBase->XAB1, 3 * SCALE_X, i_pDataBase->XAB2, 300, NULL);
addphcon(i_pPhFig, WEST,
(start_with_vss ? vss : vdd), i_pDataBase->XAB1, 3 * SCALE_X, ALU1, 600);
addphcon(i_pPhFig, EAST,
(start_with_vss ? vss : vdd), i_pDataBase->XAB2, 3 * SCALE_X, ALU1, 600);
l_uIndex++;
for (i = 2 * PITCH * 10 * SCALE_X; i < i_pDataBase->YAB2;
i += 2 * PITCH * 10 * SCALE_X) {
addphseg(i_pPhFig, ALU1, 12 * SCALE_X,
i_pDataBase->XAB1, i,
i_pDataBase->XAB2, i, (start_with_vss ? vss : vdd) );
addphcon(i_pPhFig, WEST,
(start_with_vss ? vss : vdd), i_pDataBase->XAB1, i, ALU1, 12 * SCALE_X);
//addphcon(i_pPhFig, WEST,
// (start_with_vss ? vss : vdd), i_pDataBase->XAB1, i + 3 * SCALE_X, ALU1, 600);
addphcon(i_pPhFig, EAST,
(start_with_vss ? vss : vdd), i_pDataBase->XAB2, i, ALU1, 12 * SCALE_X);
//addphcon(i_pPhFig, EAST,
// (start_with_vss ? vss : vdd), i_pDataBase->XAB2, i + 3 * SCALE_X, ALU1, 600);
l_uIndex++;
}
for (i = PITCH * 10 * SCALE_X; i < i_pDataBase->YAB2;
i += 2 * PITCH * 10 * SCALE_X) {
addphseg(i_pPhFig, ALU1, 12 * SCALE_X,
i_pDataBase->XAB1, i,
i_pDataBase->XAB2, i, (start_with_vss ? vdd : vss) );
addphcon(i_pPhFig, WEST,
(start_with_vss ? vdd : vss), i_pDataBase->XAB1, i, ALU1, 12 * SCALE_X);
//addphcon(i_pPhFig, WEST,
// (start_with_vss ? vdd : vss), i_pDataBase->XAB1, i + 3 * SCALE_X, ALU1, 600);
addphcon(i_pPhFig, EAST,
(start_with_vss ? vdd : vss), i_pDataBase->XAB2, i, ALU1, 12 * SCALE_X);
//addphcon(i_pPhFig, EAST,
// (start_with_vss ? vdd : vss), i_pDataBase->XAB2, i + 3 * SCALE_X, ALU1, 600);
l_uIndex++;
}
addphcon(i_pPhFig, WEST,
( (
start_with_vss
^ (((i_pDataBase->YAB2 - i_pDataBase->YAB1) / (5 * SCALE_X) / 10) % 2)
) ? vss : vdd),
i_pDataBase->XAB1,
i_pDataBase->YAB2 - 3 * SCALE_X,
ALU1, 6 * SCALE_X);
addphcon(i_pPhFig, EAST,
( (
start_with_vss
^ (((i_pDataBase->YAB2 - i_pDataBase->YAB1) / (5 * SCALE_X) / 10) % 2)
) ? vss : vdd),
i_pDataBase->XAB2,
i_pDataBase->YAB2 - 3 * SCALE_X,
ALU1, 6 * SCALE_X);
}
void dumpPhFigToDisk(char *i_sName, phfig_list * i_pPhFig)
{
char l_sName[50];
strcpy(l_sName, i_sName);
//strcat(l_sName, "_ocr");
i_pPhFig->NAME = namealloc(l_sName);
savephfig(i_pPhFig);
// viewphfig(i_pPhFig);
display(LEVEL, VERBOSE, "o Dumping PhFig to %s.ap ...\n", l_sName);
}
ocrNaturalInt
dumpGridToPhFig(ocrRoutingParameters * i_pParam,
ocrWRoutingGrid * i_pGrid, phfig_list * i_pPhFig)
{
ocrNaturalInt x, y, z;
ocrNaturalInt n = 0;
ocrWSegment *l_pSegment;
display(LEVEL, VERBOSE, "o Dumping Grid in phfig ...\n");
// parcours de la grille à la recherche des segments ...
for (x = 0; x < i_pGrid->SIZE_H; x++)
for (y = 0; y < i_pGrid->SIZE_V; y++)
for (z = 0; z < i_pGrid->NB_OF_LAYERS; z++) {
l_pSegment = getWSegment(i_pGrid, x, y, z);
if (l_pSegment
&& (l_pSegment->SIGNAL_INDEX != WSEGMENT_FREE)
&& (l_pSegment->SIGNAL_INDEX != WSEGMENT_OBSTACLE)) {
// parcours le signal pour le stocker dans i_pPhFig
dumpSignal(i_pParam, i_pGrid, i_pPhFig, x, y, z);
// incrémentation
n++;
}
}
display(LEVEL, VERBOSE, "o %ld signals\n", n);
return 0;
}

View File

@ -0,0 +1,88 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:22 $
$Log: ocrUtil.c,v $
Revision 1.1 2002/03/15 14:37:22 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:20 hcl
First commit in the new tree.
Revision 1.2 2001/12/14 15:58:39 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.1 2001/09/26 14:27:51 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#define LAYER_PARITY_MASK (ocrNaturalInt)1
static char *res_id = "$Id: ocrUtil.c,v 1.1 2002/03/15 14:37:22 hcl Exp $";
ocrRoutingParameters *setParameters(ocrNaturalShort pitch_h,
ocrNaturalShort pitch_v,
ocrNaturalShort via_cost,
ocrRoutingDirection dir_of_even_layers)
{
ocrRoutingParameters *pt =
(ocrRoutingParameters *) mbkalloc(sizeof(ocrRoutingParameters));
pt->PITCH_H = pitch_h;
pt->PITCH_V = pitch_v;
pt->VIA_COST = via_cost;
pt->EVEN_LAYERS_DIRECTION = dir_of_even_layers;
return pt;
}
/** get L1 distance (manhattan distance) in a 3D space **/
ocrNaturalInt
manhattan3Distance(ocrRoutingParameters * param,
ocrNaturalInt x1,
ocrNaturalInt y1,
ocrNaturalInt z1,
ocrNaturalInt x2, ocrNaturalInt y2, ocrNaturalInt z2)
{
return (param->PITCH_H * ABSDIFF(x1, x2) +
param->PITCH_V * ABSDIFF(y1, y2) +
param->VIA_COST * ABSDIFF(z1, z2));
}
/** get L1 distance (manhattan distance) in a plane **/
ocrNaturalInt
manhattan2Distance(ocrRoutingParameters * param,
ocrNaturalInt x1,
ocrNaturalInt y1, ocrNaturalInt x2, ocrNaturalInt y2)
{
return (param->PITCH_H * ABSDIFF(x1, x2) +
param->PITCH_V * ABSDIFF(y1, y2));
}
/** get direction of a layer **/
ocrRoutingDirection
getDirection(ocrRoutingParameters * param, ocrNaturalInt z)
{
return ((z & LAYER_PARITY_MASK) ?
(ocrRoutingDirection) (!(param->EVEN_LAYERS_DIRECTION))
: param->EVEN_LAYERS_DIRECTION);
}

View File

@ -0,0 +1,981 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:22 $
$Log: ocrWPlaneLabeling.c,v $
Revision 1.1 2002/03/15 14:37:22 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:21 hcl
First commit in the new tree.
Revision 1.7 2002/02/12 15:14:29 hcl
*** empty log message ***
Revision 1.6 2001/12/20 13:04:03 hcl
Cosmetique.
Revision 1.5 2001/12/19 14:22:49 hcl
Moult petits changements.
Revision 1.4 2001/12/14 15:58:39 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.3 2001/12/03 16:45:23 hcl
Corrections dans ripUp2
Revision 1.2 2001/12/03 14:31:23 hcl
Pour la route.
Revision 1.1 2001/09/26 14:27:51 hcl
premier commit....
Revision 1.3 2000/02/26 00:24:09 root
2 points OK
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#include "stdlib.h"
#include <assert.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "mbk_tree.h"
#include "ocrWRoutingUtil.h"
#include "ocrWSegLabeling.h"
#include "ocrWPlaneLabeling.h"
#define SEGMENT(x) ( (ocrWSegment *) (x)->DATA )
#define OFFSET(x) ( (ocrNaturalInt) (x)->KEY )
static char *res_id =
"$Id: ocrWPlaneLabeling.c,v 1.1 2002/03/15 14:37:22 hcl Exp $";
typedef struct ocrSubWSegment {
ocrWSegment *SEGMENT;
ocrNaturalInt P_MIN;
ocrNaturalInt P_MAX;
} ocrSubWSegment;
typedef enum ocrPlaneLabelingEventType {
ocrAddSegment,
ocrDelSegment,
} ocrPlaneLabelingEventType;
typedef struct ocrPlaneLabelingEvent {
ocrPlaneLabelingEventType TYPE;
ocrNaturalInt DATE;
ocrWSegment *SEGMENT;
} ocrPlaneLabelingEvent;
ocrSubWSegment *HEAD_OCRSUBWSEGMENT = NULL; /* sub segment buffer head */
/** **/
static int offsetCompare(void *first, void *second)
{
return ((ocrNaturalInt) first == (ocrNaturalInt) second) ?
0 : (((ocrNaturalInt) first > (ocrNaturalInt) second) ? 1 : -1);
}
/** **/
static int eventCompare(const void *e1, const void *e2)
{
return (((ocrPlaneLabelingEvent *) e1)->DATE ==
((ocrPlaneLabelingEvent *) e2)->
DATE) ? 0 : ((((ocrPlaneLabelingEvent *) e1)->DATE >
((ocrPlaneLabelingEvent *) e2)->DATE) ? 1 : -1);
}
/** create a sub segment **/
static inline ocrSubWSegment *createSubWSegment(ocrWSegment * segment,
ocrNaturalInt first_point,
ocrNaturalInt second_point)
{
ocrSubWSegment *pt;
register int i;
if (HEAD_OCRSUBWSEGMENT == NULL) {
pt = (ocrSubWSegment *) mbkalloc(BUFSIZE * sizeof(ocrSubWSegment));
HEAD_OCRSUBWSEGMENT = pt;
for (i = 1; i < BUFSIZE; i++) {
(ocrSubWSegment *) pt->SEGMENT = pt + 1;
pt++;
}
(ocrSubWSegment *) pt->SEGMENT = NULL;
}
pt = HEAD_OCRSUBWSEGMENT;
HEAD_OCRSUBWSEGMENT = (ocrSubWSegment *) HEAD_OCRSUBWSEGMENT->SEGMENT;
pt->SEGMENT = segment;
pt->P_MIN = first_point;
pt->P_MAX = second_point;
return pt;
}
/** free a sub segment **/
static inline void freeSubWSegment(ocrSubWSegment * sub_segment)
{
(ocrSubWSegment *) sub_segment->SEGMENT = HEAD_OCRSUBWSEGMENT;
HEAD_OCRSUBWSEGMENT = sub_segment;
}
/** add a segment to labeled segment list **/
static inline void
addWSegToLabeledWSegList(chain_list ** list, ocrWSegment * segment)
{
list[segment->LAYER] = addchain(list[segment->LAYER],
(void *) segment);
}
/** delete a segment from labeled segment list to add it to segment garbage
list **/
static inline chain_list *delWSegFromLabeledWSegList(chain_list ** list,
chain_list *
prev_element,
chain_list * element,
chain_list * garbage)
{
if (prev_element == NULL)
list[((ocrWSegment *) element->DATA)->LAYER] = element->NEXT;
else
prev_element->NEXT = element->NEXT;
element->NEXT = garbage;
return element;
}
/** add a sub segment chain to sub segment list (sub segments are labeled
with next delta) **/
static inline void
addSubWSegToNextDeltaSubWSegList(chain_list ** list,
ocrNaturalInt * nb_of_elements,
chain_list * sub_segment_chain)
{
ocrNaturalInt layer;
chain_list *pt = sub_segment_chain;
// XXX pourquoi sub_segment_chain peut etre NULL ?
assert(sub_segment_chain);
layer = ((ocrSubWSegment *) sub_segment_chain->DATA)->SEGMENT->LAYER;
nb_of_elements[layer]++;
if (sub_segment_chain->NEXT) {
pt = sub_segment_chain->NEXT;
nb_of_elements[layer]++;
}
pt->NEXT = list[layer];
list[layer] = sub_segment_chain;
}
/** free sub segment list because next delta has just changed **/
void
freeNextDeltaSubWSegList(chain_list ** list,
ocrNaturalInt * nb_of_elements,
ocrNaturalInt layer)
{
ocrNaturalInt i;
for (i = 0; i <= layer; i++) {
nb_of_elements[i] = 0;
while (list[i]) {
freeSubWSegment((ocrSubWSegment *) list[i]->DATA);
list[i] = delchain(list[i], list[i]);
}
}
}
/** **/
static inline ocrSubWSegment *nextDeltaLeftTopLabels(ocrRoutingParameters *
param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta,
ocrNaturalInt *
next_delta)
{
rbtree *node = segment->LABELS_LEFT_TOP;
rbtree *parent = RBTREENULL;
rbtree *inf = NULL;
rbtree *sup = NULL;
ocrNaturalInt point;
ocrNaturalInt delta_inf;
ocrNaturalShort pitch =
(getWSegDirection(param, segment) ==
ocrHorizontal) ? param->PITCH_H : param->PITCH_V;
while (node != RBTREENULL) {
parent = node;
if (delta == DELTA(node)) {
inf = node;
sup = getnextrbtree(node);
break;
}
if (delta < DELTA(node))
node = node->Left;
else
node = node->Right; /* TAG ERROR */
}
if (parent == RBTREENULL) {
*next_delta = OCRNATURALINT_MAX;
return NULL;
}
if (node == RBTREENULL) {
if (delta < DELTA(parent)) {
inf = getpreviousrbtree(parent);
sup = parent;
} else {
inf = parent;
sup = getnextrbtree(parent);
}
}
if (inf == RBTREENULL) {
*next_delta = DELTA(sup);
if (getWSegDirection(param, segment) == ocrHorizontal)
return createSubWSegment(segment,
POINT(sup),
MIN(xtarget, segment->P_MAX));
else
return createSubWSegment(segment,
POINT(sup),
MIN(ytarget, segment->P_MAX));
} else {
point = -((delta - DELTA(inf)) / (2 * pitch)) + POINT(inf) - 1;
delta_inf = DELTA(inf) - 2 * pitch * (point - POINT(inf));
if (sup == RBTREENULL) { /* TAG UNDERFLOW */
if ((point < POINT(inf)) && (point >= segment->P_MIN)) {
*next_delta = delta_inf;
return createSubWSegment(segment, point, point);
} else {
*next_delta = OCRNATURALINT_MAX;
return NULL;
}
} else {
if (delta_inf < DELTA(sup)) {
*next_delta = delta_inf;
return createSubWSegment(segment, point, point);
} else {
*next_delta = DELTA(sup);
return createSubWSegment(segment, POINT(sup), point);
}
}
}
}
/** **/
static inline ocrSubWSegment
*nextDeltaRightBottomLabels(ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget, ocrNaturalInt delta,
ocrNaturalInt * next_delta)
{
rbtree *node = segment->LABELS_RIGHT_BOTTOM;
rbtree *parent = RBTREENULL;
rbtree *inf = NULL;
rbtree *sup = NULL;
ocrNaturalInt point;
ocrNaturalInt delta_inf;
ocrNaturalShort pitch =
(getWSegDirection(param, segment) ==
ocrHorizontal) ? param->PITCH_H : param->PITCH_V;
while (node != RBTREENULL) {
parent = node;
if (delta == DELTA(node)) {
inf = node;
sup = getnextrbtree(node);
break;
}
if (delta < DELTA(node))
node = node->Left; /* TAG ERROR */
else
node = node->Right;
}
if (parent == RBTREENULL) {
*next_delta = OCRNATURALINT_MAX;
return NULL;
}
if (node == RBTREENULL) {
if (delta < DELTA(parent)) {
inf = getpreviousrbtree(parent);
sup = parent;
} else {
inf = parent;
sup = getnextrbtree(parent);
}
}
if (inf == RBTREENULL) {
*next_delta = DELTA(sup);
if (getWSegDirection(param, segment) == ocrHorizontal)
return createSubWSegment(segment,
MAX(xtarget + 1, segment->P_MIN),
POINT(sup));
else
return createSubWSegment(segment,
MAX(ytarget + 1, segment->P_MIN),
POINT(sup));
} else {
point = (delta - DELTA(inf)) / (2 * pitch) + POINT(inf) + 1;
delta_inf = DELTA(inf) + 2 * pitch * (point - POINT(inf));
if (sup == RBTREENULL) {
if ((point > POINT(inf)) && (point <= segment->P_MAX)) {
*next_delta = delta_inf;
return createSubWSegment(segment, point, point);
} else {
*next_delta = OCRNATURALINT_MAX;
return NULL;
}
} else {
if (delta_inf < DELTA(sup)) {
*next_delta = delta_inf;
return createSubWSegment(segment, point, point);
} else {
*next_delta = DELTA(sup);
return createSubWSegment(segment, point, POINT(sup));
}
}
}
}
/** **/
static inline chain_list *processNextDeltaInWSeg(ocrRoutingParameters *
param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta,
ocrNaturalInt *
next_delta)
{
ocrSubWSegment *sub_segment_LT;
ocrSubWSegment *sub_segment_RB;
ocrNaturalInt next_delta_LT;
ocrNaturalInt next_delta_RB;
sub_segment_LT = nextDeltaLeftTopLabels(param,
segment,
xtarget,
ytarget,
delta, &next_delta_LT);
sub_segment_RB = nextDeltaRightBottomLabels(param,
segment,
xtarget,
ytarget,
delta, &next_delta_RB);
if (!sub_segment_LT) {
*next_delta = next_delta_RB;
if (!sub_segment_RB)
return NULL;
else
return addchain(NULL, (void *) sub_segment_RB);
}
if (!sub_segment_RB) {
*next_delta = next_delta_LT;
return addchain(NULL, (void *) sub_segment_LT);
}
if (next_delta_LT < next_delta_RB) {
freeSubWSegment(sub_segment_RB);
*next_delta = next_delta_LT;
return addchain(NULL, (void *) sub_segment_LT);
}
if (next_delta_LT > next_delta_RB) {
freeSubWSegment(sub_segment_LT);
*next_delta = next_delta_RB;
return addchain(NULL, (void *) sub_segment_RB);
}
*next_delta = next_delta_LT; /* next_delta_LT == next_delta_RB */
if (sub_segment_LT->P_MAX + 1 == sub_segment_RB->P_MIN) {
sub_segment_LT->P_MAX = sub_segment_RB->P_MAX;
freeSubWSegment(sub_segment_RB);
return addchain(NULL, (void *) sub_segment_LT);
} else
return addchain(addchain(NULL, (void *) sub_segment_RB),
(void *) sub_segment_LT);
}
/** **/
ocrNaturalInt
processNextDelta(ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta,
chain_list ** labeled_segment_list,
chain_list ** next_delta_sub_segment_list,
ocrNaturalInt * nb_of_sub_segments,
chain_list ** segment_garbage)
{
chain_list *segment_chain;
chain_list *prev_segment_chain;
chain_list *pt;
chain_list *sub_segment_chain;
ocrNaturalInt next_delta_current = OCRNATURALINT_MAX;
ocrNaturalInt next_delta;
ocrNaturalInt layer;
freeNextDeltaSubWSegList(next_delta_sub_segment_list,
nb_of_sub_segments, grid->NB_OF_LAYERS - 1);
for (layer = 0; layer < grid->NB_OF_LAYERS; layer++) {
prev_segment_chain = NULL;
segment_chain = labeled_segment_list[layer];
while (segment_chain) {
sub_segment_chain = processNextDeltaInWSeg(param,
(ocrWSegment *)
segment_chain->DATA,
xtarget, ytarget,
delta, &next_delta);
if (!sub_segment_chain) {
pt = segment_chain->NEXT;
*segment_garbage =
delWSegFromLabeledWSegList(labeled_segment_list,
prev_segment_chain,
segment_chain,
*segment_garbage);
segment_chain = pt;
} else {
if (next_delta < next_delta_current) {
next_delta_current = next_delta;
freeNextDeltaSubWSegList(next_delta_sub_segment_list,
nb_of_sub_segments, layer);
}
if (next_delta == next_delta_current) {
addSubWSegToNextDeltaSubWSegList
(next_delta_sub_segment_list, nb_of_sub_segments,
sub_segment_chain);
} else {
freeSubWSegment((ocrSubWSegment *) sub_segment_chain->
DATA);
sub_segment_chain =
delchain(sub_segment_chain, sub_segment_chain);
if (sub_segment_chain) {
freeSubWSegment((ocrSubWSegment *)
sub_segment_chain->DATA);
freechain(sub_segment_chain);
}
}
prev_segment_chain = segment_chain;
segment_chain = segment_chain->NEXT;
}
}
}
return next_delta_current;
}
/****************************************************************************/
/**
**/
static inline ocrPlaneLabelingEvent *makeSchedule(chain_list *
sub_segment_chain_list,
ocrNaturalInt
nb_of_events)
{
ocrPlaneLabelingEvent *schedule =
(ocrPlaneLabelingEvent *) mbkalloc(nb_of_events *
sizeof(ocrPlaneLabelingEvent));
ocrNaturalInt i = 0;
for (; sub_segment_chain_list;
sub_segment_chain_list = sub_segment_chain_list->NEXT) {
schedule[i].TYPE = ocrAddSegment;
schedule[i].DATE =
((ocrSubWSegment *) sub_segment_chain_list->DATA)->P_MIN;
schedule[i].SEGMENT =
((ocrSubWSegment *) sub_segment_chain_list->DATA)->SEGMENT;
i++;
schedule[i].TYPE = ocrDelSegment;
schedule[i].DATE =
((ocrSubWSegment *) sub_segment_chain_list->DATA)->P_MAX + 1;
schedule[i].SEGMENT =
((ocrSubWSegment *) sub_segment_chain_list->DATA)->SEGMENT;
i++;
}
qsort((void *) schedule,
(size_t) nb_of_events,
(size_t) sizeof(ocrPlaneLabelingEvent), eventCompare);
return schedule;
}
/**
*
* Mise à jour des segments du calendrier
* de schedule_index jusqu'à nb_of_events
*
**/
// labeling_line sauvegarde de event_line
static inline rbtree *labelPlaneUpdate(rbtree * labeling_status,
ocrPlaneLabelingEvent *
event_schedule,
ocrNaturalInt * schedule_index,
ocrNaturalInt nb_of_events,
ocrNaturalInt * event_line,
ocrNaturalInt * labeling_line)
{
*labeling_line = *event_line; /* update labeling line */
while ((*schedule_index < nb_of_events) && /* update labeling status */
(event_schedule[*schedule_index].DATE == *event_line)) {
if (event_schedule[*schedule_index].TYPE == ocrAddSegment)
labeling_status = addrbtree(labeling_status,
(void *)
event_schedule[*schedule_index].
SEGMENT->OFFSET,
(void *)
event_schedule[*schedule_index].
SEGMENT, offsetCompare);
else if (event_schedule[*schedule_index].TYPE == ocrDelSegment)
if (labeling_status)
labeling_status = delrbtree(labeling_status,
getrbtree(labeling_status,
(void *)
event_schedule
[*schedule_index].
SEGMENT->OFFSET,
offsetCompare));
else {
fprintf(stderr, "OCR internal error : event not ADD nor DEL\n");
exit(1);
}
(*schedule_index)++;
}
if (*schedule_index < nb_of_events) /* update event_line */
*event_line = event_schedule[*schedule_index].DATE;
return labeling_status;
}
/** **/
static inline void
processNextDeltaAgain(ocrRoutingParameters * param,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta,
chain_list ** next_delta_sub_segment_list,
ocrNaturalInt * nb_of_sub_segments,
ocrWSegment * segment)
{
ocrNaturalInt delta_tmp;
chain_list *sub_segment_chain = processNextDeltaInWSeg(param,
segment,
xtarget,
ytarget,
delta - 1,
&delta_tmp);
addSubWSegToNextDeltaSubWSegList(next_delta_sub_segment_list,
nb_of_sub_segments,
sub_segment_chain);
}
/**
*
*
*
**/
static inline void labelPlaneProcess(ocrRoutingParameters * param, ocrWRoutingGrid * grid, ocrNaturalInt xtarget, ocrNaturalInt ytarget, rbtree * labeling_status, ocrNaturalInt event_line, ocrNaturalInt labeling_line, // ligne courante du scheduler
ocrNaturalInt delta_sce, ocrNaturalInt delta_dest, ocrNaturalInt plane_dest, // z
chain_list ** labeled_segment_list,
chain_list **
next_delta_sub_segment_list,
ocrNaturalInt * nb_of_sub_segments)
{
ocrWSegment *segment_dest;
rbtree *first_segment_tree = getmostrbtree(labeling_status);
rbtree *segment_tree1;
rbtree *segment_tree2;
rbtree *previous;
rbtree *next;
if (labeling_status == RBTREENULL)
return;
// effectue les opérations jusqu'a la date courante ?
while (labeling_line < event_line) {
segment_tree1 = first_segment_tree;
while (segment_tree1 != RBTREENULL) {
segment_dest = getWSegment(grid,
getWSegXCoord(param,
SEGMENT
(segment_tree1),
labeling_line),
getWSegYCoord(param,
SEGMENT
(segment_tree1),
labeling_line),
plane_dest);
segment_tree2 = getrbtree2(labeling_status,
(void *) segment_dest->P_MAX,
&previous, &next, offsetCompare);
if (!isObstructed(segment_dest)) {
if (!isLabeled(segment_dest))
addWSegToLabeledWSegList(labeled_segment_list,
segment_dest);
if ((segment_tree2 == RBTREENULL) &&
(OFFSET(previous) != OFFSET(segment_tree1)))
segment_tree2 = previous;
if (segment_tree2 == RBTREENULL) {
if ((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree1))) &&
(delta_dest == delta_sce))
processNextDeltaAgain(param,
xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
} else {
if (getWSegDirection(param, segment_dest) ==
ocrHorizontal) {
if (xtarget <= OFFSET(segment_tree1)) {
if ((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree2))) &&
(delta_dest == delta_sce))
processNextDeltaAgain(param,
xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
} else {
if (xtarget >= OFFSET(segment_tree2)) {
if ((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree1)))
&& (delta_dest == delta_sce))
processNextDeltaAgain(param, xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
} else {
if (((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree1)))
|
/* warning not || ! */
(labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET
(segment_tree2))))
&& (delta_dest == delta_sce))
processNextDeltaAgain(param, xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
}
}
} else {
if (ytarget <= OFFSET(segment_tree1)) {
if ((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree2))) &&
(delta_dest == delta_sce))
processNextDeltaAgain(param,
xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
} else {
if (ytarget >= OFFSET(segment_tree2)) {
if ((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree1)))
&& (delta_dest == delta_sce))
processNextDeltaAgain(param, xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
} else {
if (((labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET(segment_tree1)))
|
/* warning not || ! */
(labelWSegment(param,
segment_dest,
xtarget,
ytarget,
delta_dest,
OFFSET
(segment_tree2))))
&& (delta_dest == delta_sce))
processNextDeltaAgain(param, xtarget,
ytarget,
delta_dest,
next_delta_sub_segment_list,
nb_of_sub_segments,
segment_dest);
}
}
}
}
}
while ((next != RBTREENULL)
&& (OFFSET(next) == segment_dest->P_MAX))
next = getnextrbtree(next);
segment_tree1 = next;
}
labeling_line++;
}
}
/** **/
void labelPlane(ocrRoutingParameters * param, ocrWRoutingGrid * grid, ocrNaturalInt xtarget, ocrNaturalInt ytarget, ocrNaturalInt ztarget, ocrNaturalInt delta_sce, // delta
ocrNaturalInt plane_sce, // z courant
ocrNaturalInt plane_dest, // new z
chain_list ** next_delta_sub_segment_list,
ocrNaturalInt * nb_of_sub_segments,
chain_list ** labeled_segment_list)
{
ocrNaturalInt nb_of_events = 2 * nb_of_sub_segments[plane_sce];
ocrPlaneLabelingEvent *event_schedule;
ocrNaturalInt schedule_index = 0;
rbtree *labeling_status = RBTREENULL;
ocrNaturalInt event_line;
ocrNaturalInt labeling_line;
ocrNaturalInt delta_dest;
if (nb_of_events == 0)
return;
// création d'un échéancier pour pouvoir faire un UNDO en cas de pbm
event_schedule =
makeSchedule(next_delta_sub_segment_list[plane_sce], nb_of_events);
event_line = event_schedule->DATE; // = date courante ?
delta_dest = (((plane_dest > plane_sce) && (plane_dest <= ztarget)) ||
((plane_dest < plane_sce) && (plane_dest >= ztarget))) ?
delta_sce : delta_sce + 2 * param->VIA_COST;
while (schedule_index < nb_of_events) {
/* update */
labeling_status = labelPlaneUpdate(labeling_status,
event_schedule,
&schedule_index,
nb_of_events,
&event_line, &labeling_line);
/* process */
labelPlaneProcess(param,
grid,
xtarget,
ytarget,
labeling_status,
event_line,
labeling_line,
delta_sce,
delta_dest,
plane_dest,
labeled_segment_list,
next_delta_sub_segment_list, nb_of_sub_segments);
}
mbkfree(event_schedule);
}
/** **/
void
initNextDeltaSubWSegList(ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
chain_list *** list,
ocrNaturalInt ** nb_of_elements,
ocrWSegment * segment_source,
ocrNaturalInt xsource, ocrNaturalInt ysource)
{
ocrNaturalInt i;
*list =
(chain_list **) mbkalloc(grid->NB_OF_LAYERS *
sizeof(chain_list *));
*nb_of_elements =
(ocrNaturalInt *) mbkalloc(grid->NB_OF_LAYERS *
sizeof(ocrNaturalInt));
// Initialisation
for (i = 0; i < grid->NB_OF_LAYERS; i++) {
(*list)[i] = NULL;
(*nb_of_elements)[i] = 0;
}
// Ajout du segment source
(*nb_of_elements)[segment_source->LAYER] = 1;
if (getWSegDirection(param, segment_source) == ocrHorizontal) {
if (xsource < xtarget)
(*list)[segment_source->LAYER] =
addchain((*list)[segment_source->LAYER],
(void *) createSubWSegment(segment_source,
xsource,
MIN(segment_source->
P_MAX, xtarget)));
else
(*list)[segment_source->LAYER] =
addchain((*list)[segment_source->LAYER],
(void *) createSubWSegment(segment_source,
MAX(segment_source->
P_MIN, xtarget),
xsource));
} else // Vertical
{
if (ysource < ytarget)
(*list)[segment_source->LAYER] =
addchain((*list)[segment_source->LAYER],
(void *) createSubWSegment(segment_source,
ysource,
MIN(segment_source->
P_MAX, ytarget)));
else
(*list)[segment_source->LAYER] =
addchain((*list)[segment_source->LAYER],
(void *) createSubWSegment(segment_source,
MAX(segment_source->
P_MIN, ytarget),
ysource));
}
}
/** **/
void
initLabeledWSegList(ocrWRoutingGrid * grid,
chain_list *** list, ocrWSegment * segment_source)
{
ocrNaturalInt i;
*list =
(chain_list **) mbkalloc(grid->NB_OF_LAYERS *
sizeof(chain_list *));
for (i = 0; i < grid->NB_OF_LAYERS; i++)
(*list)[i] = NULL;
(*list)[segment_source->LAYER] =
addchain((*list)[segment_source->LAYER], (void *) segment_source);
}
/** **/
void
cleanLabeledWSegments(ocrWRoutingGrid * grid,
chain_list ** labeled_segment_list,
chain_list ** segment_garbage)
{
ocrNaturalInt i;
while (*segment_garbage) {
unlabelWSegment((ocrWSegment *) (*segment_garbage)->DATA);
*segment_garbage = delchain(*segment_garbage, *segment_garbage);
}
for (i = 0; i < grid->NB_OF_LAYERS; i++)
while (labeled_segment_list[i]) {
unlabelWSegment((ocrWSegment *) labeled_segment_list[i]->DATA);
labeled_segment_list[i] =
delchain(labeled_segment_list[i], labeled_segment_list[i]);
}
}
int
isNextDeltaSubWSegListNotEmpty(ocrWRoutingGrid * grid, chain_list ** list)
{
ocrNaturalInt i;
for (i = 0; i < grid->NB_OF_LAYERS; i++)
if (list[i])
return 1;
return 0;
}

View File

@ -0,0 +1,500 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:23 $
$Log: ocrWRouting.c,v $
Revision 1.1 2002/03/15 14:37:23 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:21 hcl
First commit in the new tree.
Revision 1.6 2002/01/14 10:34:34 hcl
OCR should be MBK_SCALE_X - compliant
Revision 1.5 2001/12/14 15:58:39 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.4 2001/12/10 13:09:02 hcl
Un bigbug en moins.
Revision 1.3 2001/12/03 14:31:23 hcl
Pour la route.
Revision 1.2 2001/11/20 09:41:34 hcl
segmentation fault
Revision 1.1 2001/09/26 14:27:51 hcl
premier commit....
Revision 1.3 2000/02/26 00:24:09 root
2 points OK
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "mbk_tree.h"
#include "ocrWRoutingUtil.h"
#include "ocrWSegLabeling.h"
#include "ocrWPlaneLabeling.h"
#include "ocrWRouting.h"
//#define DEBUG
static char *res_id =
"$Id: ocrWRouting.c,v 1.1 2002/03/15 14:37:23 hcl Exp $";
#ifdef DEBUG
void func(rbtree * r)
{
printf("key = %d\n", (int) (r->KEY));
printf("data = %d\n", (int) (r->DATA));
}
#endif
static ocrNaturalInt
backtrack(ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrWSegment * segment_target,
ocrWSegment * segment_source,
ocrNaturalInt delta,
ocrNaturalInt signal_index, ocrSignal * i_pSignal)
{
ocrWSegment *l_pSegList = i_pSignal->SEGMENT;
// ocrVirtualConnector *l_pViaList = i_pSignal->VIA;
// ocrVirtualConnector *l_pVia;
rbtree *label;
ocrWSegment *segment = segment_target;
ocrWSegment *l_pOldSegment = segment_target;
ocrWSegment *neighbouring_segment;
ocrNaturalInt neighbouring_segment_delta;
ocrNaturalInt point1 =
(getWSegDirection(param, segment_target) ==
ocrHorizontal) ? xtarget : ytarget;
ocrNaturalInt point2 = POINT(getLabel(param,
xtarget,
ytarget,
segment_target,
delta,
point1));
#ifdef DEBUG
printf("segment Source %p\n", segment_target);
dumpSeg(segment_target);
printf("segment Target %p\n", segment_source);
dumpSeg(segment_source);
#endif
/*
// ajout d'un VIA
l_pVia = createVirtualConnector (xtarget * 500,
ytarget * 500,
segment_target->LAYER,
0,
0);
addVirtualConnector (&l_pViaList, l_pVia);
*/
while (segment != segment_source) {
if (point1 < point2)
segment = splitWSegment(param,
grid,
segment, point1, point2, signal_index);
else
segment = splitWSegment(param,
grid,
segment, point2, point1, signal_index);
point1 = segment->OFFSET;
// Ajout du nouveau segment de l'équipotentielle dans la liste
segment->NEXT = l_pSegList;
l_pSegList = segment;
#ifdef DEBUG
dumpSeg(segment);
// printf ("LAYER = %ld\n", segment->LAYER);
fflush(stdout);
#endif
if (segment->LAYER < grid->NB_OF_LAYERS - 1) {
neighbouring_segment = getWSegment(grid,
getWSegXCoord(param,
segment,
point2),
getWSegYCoord(param,
segment,
point2),
segment->LAYER + 1);
neighbouring_segment_delta =
(segment->LAYER <
segment_target->LAYER) ? delta -
2 * param->VIA_COST : delta;
#ifdef DEBUG
printf("point1 %d, point2 %d delta %d\n", point1, point2,
delta);
#endif
if ((label = getLabel(param,
xtarget,
ytarget,
neighbouring_segment,
neighbouring_segment_delta,
point1)) != RBTREENULL) {
/*
// ajout d'un VIA
if (getWSegDirection (param, segment) == ocrHorizontal)
l_pVia = createVirtualConnector (point2 * 500,
segment->OFFSET * 500,
neighbouring_segment->LAYER, 0, 0);
else
l_pVia = createVirtualConnector (segment->OFFSET * 500,
point2 * 500,
neighbouring_segment->LAYER, 0, 0);
addVirtualConnector (&l_pViaList, l_pVia);
*/
delta = neighbouring_segment_delta;
point2 = POINT(label);
segment = neighbouring_segment;
#ifdef DEBUG
mapleasttomostrbtree(segment->LABELS_LEFT_TOP, func);
mapleasttomostrbtree(segment->LABELS_RIGHT_BOTTOM, func);
printf("point1 %d, point2 %d delta %d\n", point1, point2,
delta);
printf("#########delta = %ld\n", DELTA(label));
#endif
delta = DELTA(label);
continue;
}
}
delta = (segment->LAYER > segment_target->LAYER) ?
delta - 2 * param->VIA_COST : delta;
l_pOldSegment = segment;
if (segment->LAYER == 0) {
// impossible de continuer a router
return 1;
}
segment = getWSegment(grid,
getWSegXCoord(param, segment, point2),
getWSegYCoord(param, segment, point2),
segment->LAYER - 1);
/*
// ajout d'un VIA
if (getWSegDirection (param, l_pOldSegment) == ocrHorizontal)
l_pVia = createVirtualConnector (point2 * 500,
l_pOldSegment->OFFSET * 500,
MAX (segment->LAYER, l_pOldSegment->LAYER), 0, 0);
else
l_pVia = createVirtualConnector (l_pOldSegment->OFFSET * 500,
point2 * 500,
MAX (segment->LAYER, l_pOldSegment->LAYER), 0, 0);
addVirtualConnector (&l_pViaList, l_pVia);
*/
#ifdef OCR_DEBUG
printf("segment %p\n", segment);
//dumpSeg (segment);
fflush(stdout);
printf("point1 %d, point2 %d delta %d\n", point1, point2, delta);
printf("Target x=%d, y=%d\n", xtarget, ytarget);
//mapleasttomostrbtree (segment->LABELS_LEFT_TOP, func);
//mapleasttomostrbtree (segment->LABELS_RIGHT_BOTTOM, func);
#endif
point2 = POINT(getLabel(param,
xtarget, ytarget, segment, delta, point1));
#ifdef DEBUG
printf("#########delta = %ld\n", DELTA(getLabel(param,
xtarget,
ytarget,
segment,
delta, point1)));
#endif
delta = DELTA(getLabel(param,
xtarget, ytarget, segment, delta, point1));
#ifdef DEBUG
// WARNING ....
if (point2 == 0)
puts("ZERO");
printf("point1 %d, point2 %d\n", point1, point2);
fflush(stdout);
#endif
}
if (segment->SIGNAL_INDEX != signal_index) {
if (point1 < point2) {
segment =
splitWSegment(param, grid, segment, point1, point2,
signal_index);
// if (segment->LAYER > 2) {
// if (getWSegDirection (param, segment) == ocrHorizontal) {
// splitWSegment(param, grid
// } else {
//
// }
// }
} else {
segment =
splitWSegment(param, grid, segment, point2, point1,
signal_index);
}
// Ajout du dernier segment de l'équipotentielle dans la liste
segment->NEXT = l_pSegList;
i_pSignal->SEGMENT = segment;
/*
// ajout d'un VIA
if (getWSegDirection (param, segment) == ocrHorizontal)
l_pVia = createVirtualConnector (point2 * 500,
segment->OFFSET * 500,
segment->LAYER, 0, 0);
else
l_pVia = createVirtualConnector (segment->OFFSET * 500,
point2 * 500,
segment->LAYER, 0, 0);
addVirtualConnector (&l_pViaList, l_pVia);
i_pSignal->VIA = l_pViaList;
*/
}
return 0;
}
ocrNaturalInt
findPathBetween2Points(ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt ztarget,
ocrNaturalInt signal_index, ocrSignal * i_pSignal)
{
chain_list **labeledSegmentList;
chain_list **nextDeltaSubSegmentList;
ocrNaturalInt *nbOfNextDeltaSubSegments;
ocrNaturalInt l_uNbIt = 0;
ocrNaturalInt delta =
manhattan3Distance(param, xsource, ysource, zsource,
xtarget, ytarget, ztarget);
ocrWSegment *segmentSource =
getWSegment(grid, xsource, ysource, zsource);
ocrNaturalInt pointSource =
(getWSegDirection(param, segmentSource) ==
ocrHorizontal) ? xsource : ysource;
ocrWSegment *segmentTarget =
getWSegment(grid, xtarget, ytarget, ztarget);
chain_list *segmentGarbage = NULL;
ocrNaturalInt plane = ztarget;
//printf ("2points\n");
labelWSegment(param, segmentSource, xtarget, ytarget, delta,
pointSource);
// initialise le tableau de liste et ajoute segmentSource
initLabeledWSegList(grid, &labeledSegmentList, segmentSource);
// initialise le tableau de liste des sub segment
// Ajoute le premier
initNextDeltaSubWSegList(param,
grid,
xtarget,
ytarget,
&nextDeltaSubSegmentList,
&nbOfNextDeltaSubSegments,
segmentSource, xsource, ysource);
do {
do {
plane = getNextPlane(grid, ztarget, plane);
if (plane < grid->NB_OF_LAYERS - 1) // via vers le haut ?
//printf (" o * labelPlane vers le haut\n");
labelPlane(param,
grid,
xtarget,
ytarget,
ztarget,
delta,
plane,
plane + 1,
nextDeltaSubSegmentList,
nbOfNextDeltaSubSegments, labeledSegmentList);
if (plane > 0) // via vers le bas ?
//printf (" o * labelPlane vers le bas\n");
labelPlane(param,
grid,
xtarget,
ytarget,
ztarget,
delta,
plane,
plane - 1,
nextDeltaSubSegmentList,
nbOfNextDeltaSubSegments, labeledSegmentList);
}
while (plane != ztarget);
if (isLabeled(segmentTarget)) // fin
{
if (backtrack(param,
grid,
xtarget,
ytarget,
segmentTarget,
segmentSource, delta, signal_index, i_pSignal)
) {
cleanLabeledWSegments(grid, labeledSegmentList,
&segmentGarbage);
mbkfree(labeledSegmentList);
freeNextDeltaSubWSegList(nextDeltaSubSegmentList,
nbOfNextDeltaSubSegments,
grid->NB_OF_LAYERS - 1);
mbkfree(nextDeltaSubSegmentList);
mbkfree(nbOfNextDeltaSubSegments);
return OCRNATURALINT_MAX;
}
cleanLabeledWSegments(grid, labeledSegmentList,
&segmentGarbage);
mbkfree(labeledSegmentList);
freeNextDeltaSubWSegList(nextDeltaSubSegmentList,
nbOfNextDeltaSubSegments,
grid->NB_OF_LAYERS - 1);
mbkfree(nextDeltaSubSegmentList);
mbkfree(nbOfNextDeltaSubSegments);
//printf("IT : %ld\n",l_uNbIt);
return delta;
}
l_uNbIt++;
if (l_uNbIt > 50)
goto fin;
delta = processNextDelta(param,
grid,
xtarget,
ytarget,
delta,
labeledSegmentList,
nextDeltaSubSegmentList,
nbOfNextDeltaSubSegments,
&segmentGarbage);
}
while (isNextDeltaSubWSegListNotEmpty(grid, nextDeltaSubSegmentList));
fin:
cleanLabeledWSegments(grid, labeledSegmentList, &segmentGarbage);
mbkfree(labeledSegmentList);
mbkfree(nextDeltaSubSegmentList);
mbkfree(nbOfNextDeltaSubSegments);
// printf ("It : %ld\n", l_uNbIt);
return OCRNATURALINT_MAX;
}
void
displayPath(ocrRoutingParameters * param,
ocrWRoutingGrid * grid,
ocrNaturalInt xsource,
ocrNaturalInt ysource,
ocrNaturalInt zsource,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget, ocrNaturalInt ztarget)
{
ocrWSegment *segment = getWSegment(grid, xsource, ysource, zsource);
ocrWSegment *segment_target =
getWSegment(grid, xtarget, ytarget, ztarget);
ocrWSegment *neighbouring_segment;
ocrNaturalInt point1 =
(getWSegDirection(param, segment) ==
ocrHorizontal) ? xsource : ysource;
ocrNaturalInt point2 =
(point1 == segment->P_MIN) ? segment->P_MAX : segment->P_MIN;
printf("source point : <%lu,%lu,%lu>\n", xsource, ysource, zsource);
printf("target point : <%lu,%lu,%lu>\n", xtarget, ytarget, ztarget);
printf("path : ");
while (segment != segment_target) {
printf("<%lu,%lu,%lu> to <%lu,%lu,%lu> via ", getWSegXCoord(param, segment, point1), // si HORZ -> point1
getWSegYCoord(param, segment, point1), // si HORZ -> OFFSET
segment->LAYER,
getWSegXCoord(param, segment, point2),
getWSegYCoord(param, segment, point2), segment->LAYER);
point1 = segment->OFFSET;
// suite vers le haut ?
if ((segment->LAYER < grid->NB_OF_LAYERS - 1) &&
((neighbouring_segment = getWSegment(grid,
getWSegXCoord(param,
segment,
point2),
getWSegYCoord(param,
segment,
point2),
segment->LAYER +
1))->SIGNAL_INDEX ==
segment_target->SIGNAL_INDEX)) {
point2 =
(point1 ==
neighbouring_segment->P_MIN) ? neighbouring_segment->
P_MAX : neighbouring_segment->P_MIN;
segment = neighbouring_segment;
} else // suite vers le bas ?
{
segment = getWSegment(grid,
getWSegXCoord(param, segment, point2),
getWSegYCoord(param, segment, point2),
segment->LAYER - 1);
point2 =
(point1 ==
segment->P_MIN) ? segment->P_MAX : segment->P_MIN;
}
}
printf("<%lu,%lu,%lu> to <%lu,%lu,%lu>\n",
getWSegXCoord(param, segment_target, point1),
getWSegYCoord(param, segment_target, point1),
segment_target->LAYER, xtarget, ytarget, ztarget);
fflush(stdout);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:24 $
$Log: ocrWSegLabeling.c,v $
Revision 1.1 2002/03/15 14:37:24 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:22 hcl
First commit in the new tree.
Revision 1.2 2001/12/14 15:58:39 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.1 2001/09/26 14:27:51 hcl
premier commit....
Revision 1.2 2000/01/25 15:49:00 root
*** empty log message ***
### -------------------------------------------------- ###
*/
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "mbk_tree.h"
#include "ocrWRoutingUtil.h"
#include "ocrWSegLabeling.h"
static char *res_id =
"$Id: ocrWSegLabeling.c,v 1.1 2002/03/15 14:37:24 hcl Exp $";
/** delta comparison function for red-black tree **/
static int deltaCompare(void *first, void *second)
{
return ((ocrNaturalInt) first == (ocrNaturalInt) second) ?
0 : (((ocrNaturalInt) first > (ocrNaturalInt) second) ? 1 : -1);
}
/** remove redundant next labels **/
static rbtree *removeRedundantLabels(ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
rbtree * root, rbtree * node)
{
rbtree *next_node = getnextrbtree(node);
rbtree *del;
while ((next_node != RBTREENULL) &&
(DELTA(next_node) >=
inducedDelta(param,
segment,
xtarget, ytarget, node, POINT(next_node)))) {
del = next_node;
next_node = getnextrbtree(next_node);
if (root)
root = delrbtree(root, del);
}
return root;
}
/** add a label in a segment **/
static int
addLabel(ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
rbtree ** ptroot, ocrNaturalInt delta, ocrNaturalInt point)
{
rbtree *node = *ptroot;
rbtree *parent = RBTREENULL;
rbtree *previous_node = RBTREENULL;
while (node != RBTREENULL) {
parent = node;
if (delta == DELTA(node)) {
if (delta <
inducedDelta(param, segment, xtarget, ytarget, node,
point)) {
node->DATA = (void *) point;
*ptroot = removeRedundantLabels(param,
segment,
xtarget,
ytarget, *ptroot, node);
return 1;
} else
return 0;
}
if (delta < DELTA(node))
node = node->Left;
else {
previous_node = node;
node = node->Right;
}
}
if (parent == RBTREENULL) { // ajoute delta au segment
*ptroot =
addrbtree(RBTREENULL, (void *) delta, (void *) point,
deltaCompare);
return 1;
}
if ((previous_node == RBTREENULL) ||
(delta < inducedDelta(param,
segment,
xtarget, ytarget, previous_node, point))) {
*ptroot =
addrbtree2(*ptroot, parent, (void *) delta, (void *) point,
deltaCompare);
if (delta < DELTA(parent))
*ptroot = removeRedundantLabels(param,
segment,
xtarget,
ytarget,
*ptroot, parent->Left);
else
*ptroot = removeRedundantLabels(param,
segment,
xtarget,
ytarget,
*ptroot, parent->Right);
return 1;
}
return 0;
}
/** label segment function **/
int
labelWSegment(ocrRoutingParameters * param,
ocrWSegment * segment,
ocrNaturalInt xtarget,
ocrNaturalInt ytarget,
ocrNaturalInt delta, ocrNaturalInt point)
{
int ret_LT = 0;
int ret_RB = 0;
if (getWSegDirection(param, segment) == ocrHorizontal) {
if (point <= xtarget) {
ret_LT = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_LEFT_TOP, delta, point);
if (segment->P_MAX > xtarget)
ret_RB = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_RIGHT_BOTTOM,
delta + param->PITCH_H * 2, xtarget + 1);
} else {
ret_RB = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_RIGHT_BOTTOM, delta, point);
if (segment->P_MIN <= xtarget)
ret_LT = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_LEFT_TOP,
delta, xtarget);
}
} else // VERTICAL
{
if (point <= ytarget) {
ret_LT = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_LEFT_TOP, delta, point);
if (segment->P_MAX > ytarget)
ret_RB = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_RIGHT_BOTTOM,
delta + param->PITCH_V * 2, ytarget + 1);
} else {
ret_RB = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_RIGHT_BOTTOM, delta, point);
if (segment->P_MIN <= ytarget)
ret_LT = addLabel(param,
segment,
xtarget,
ytarget,
&segment->LABELS_LEFT_TOP,
delta, ytarget);
}
}
return MAX(ret_LT, ret_RB);
}
/** unlabel segment function **/
void unlabelWSegment(ocrWSegment * segment)
{
freerbtree(segment->LABELS_LEFT_TOP, NULL, NULL);
freerbtree(segment->LABELS_RIGHT_BOTTOM, NULL, NULL);
segment->LABELS_LEFT_TOP = RBTREENULL;
segment->LABELS_RIGHT_BOTTOM = RBTREENULL;
}

View File

@ -0,0 +1,60 @@
# Alliance VLSI CAD System
#
# Product : OVER-THE-CELL ROUTER
# File : Makefile
#
# Author(s) : Mael NAGAT Date : 27/05/1999
# Modified by : Date : ../../....
# Modified by : Date : ../../....
# Modified by : Date : ../../....
# Alliance Shared Libraries and Include Files for Makefiles
include $(ALLIANCE_TOP)/etc/$(ALLIANCE_OS).mk
include $(ALLIANCE_TOP)/etc/libraries.mk
# include $(TOP)/etc/libraries_labo.mk
# Sources
OCR_SRC_FILE =
# Include Flags for Alliance Shared Libraries
OCR_ALC_INCLUDE = -I$(ALLIANCE_INCLUDE) \
-DMLU_H='<$(MLU_H)>' \
-DMPU_H='<$(MPU_H)>' \
-DMLO_H='<$(MLO_H)>' \
-DMPH_H='<$(MPH_H)>' \
-DMUT_H='<$(MUT_H)>'
# Libraries Flags for Alliance Shared Libraries
OCR_ALC_LIB = -L$(ALLIANCE_LIB) \
$(MLU_L) \
$(MPU_L) \
$(MCP_L) \
$(MAP_L) \
$(MMG_L) \
$(MCL_L) \
$(MGL_L) \
$(MAL_L) \
$(MVL_L) \
$(MEL_L) \
$(MSL_L) \
$(MHL_L) \
$(RCN_L) \
$(MLO_L) \
$(MPH_L) \
$(MUT_L)
# Compilation Flags
OCR_CFLAGS = -Wall -O4 -pg
# Non file targets
.PHONY: clean
# Rules
TARGET_DIR = $(HOME)/local/$(ALLIANCE_OS)/bin
$(TARGET_DIR)/stat_netlist : stat_netlist.c
$(CC) $(OCR_CFLAGS) $(OCR_ALC_INCLUDE) $< $(OCR_ALC_LIB) -o $@
clean :
-$(RM) -rf $(TARGET_BIN)/stat_netlist *.o

View File

@ -0,0 +1,57 @@
#include <stdlib.h>
#include MUT_H
#include MLO_H
#include MLU_H
int main (int argc, char **argv) {
lofig_list *ptlofig;
losig_list *ptsignal;
chain_list *ptchain;
int nsignal[10] = {0,0,0,0,0,0,0,0,0,0};
int nb_of_signal = 0;
int nb_of_con;
int nb_of_con_max = 2;
int i;
if (argc != 2) {
fprintf(stderr, "usage : stat_netlist file\n");
exit(1);
}
argv++;
mbkenv();
ptlofig = getlofig(*argv, 'A');
lofigchain(ptlofig);
for (ptsignal = ptlofig->LOSIG; ptsignal; ptsignal = ptsignal->NEXT) {
if (!naturalstrcmp(getsigname(ptsignal), "vdd") || !naturalstrcmp(getsigname(ptsignal), "vss"))
continue;
nb_of_signal++;
nb_of_con = 0;
ptchain = (chain_list *)((getptype(ptsignal->USER, (long)LOFIGCHAIN))->DATA);
while (ptchain) {
nb_of_con++;
ptchain = ptchain->NEXT;
}
if (nb_of_con > nb_of_con_max)
nb_of_con_max = nb_of_con;
if (nb_of_con <= 10)
nsignal[nb_of_con-2]++;
else
nsignal[9]++;
}
printf("netlist : %s\n\n", *argv);
printf("vdd et vss sont ecartés du recensement\n");
printf("nombre total de signal : %d\n", nb_of_signal);
for (i = 0; i < 9; i++)
printf("nombre de %d-signal : %d\n", i+2, nsignal[i]);
printf("nombre de 11&+-signal : %d\n", nsignal[9]);
printf("nombre maximum de connecteurs pour un signal : %d\n\n", nb_of_con_max);
dellofig(*argv);
exit(0);
}

View File

@ -0,0 +1,9 @@
## Process this file with automake to produce Makefile.in
INCLUDES = @INCLUDES@ -I$(top_srcdir)/src/include
noinst_LIBRARIES = libocrUtil.a
libocrUtil_a_SOURCES = ocrConnectorUtil.c ocrDataBaseUtil.c \
ocrInitDataBase.c ocrSignalUtil.c \
ocrWindow.c

View File

@ -0,0 +1,968 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:26 $
$Log: ocrConnectorUtil.c,v $
Revision 1.1 2002/03/15 14:37:26 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:24 hcl
First commit in the new tree.
Revision 1.10 2002/01/14 10:34:35 hcl
OCR should be MBK_SCALE_X - compliant
Revision 1.9 2001/12/20 15:44:22 hcl
ALU5 et ALU6 : distance min respectee.
Revision 1.8 2001/12/20 13:04:04 hcl
Cosmetique.
Revision 1.7 2001/12/19 14:22:49 hcl
Moult petits changements.
Revision 1.6 2001/12/14 15:58:40 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.5 2001/12/12 14:51:09 hcl
Prise en compte du placement des connecteurs par OCP.
Revision 1.4 2001/12/10 13:09:03 hcl
Un bigbug en moins.
Revision 1.3 2001/12/03 14:31:24 hcl
Pour la route.
Revision 1.2 2001/11/20 09:42:06 hcl
last but not least
Revision 1.1 2001/09/26 14:27:56 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include <string.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrPath.h"
#include "display.h"
#include "ocrConnectorUtil.h"
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
#define MAX_HT 500
#define PITCH 5
ocrNaturalInt
distBetween2VirCon(ocrVirtualConnector * l_pVirCon1,
ocrVirtualConnector * l_pVirCon2)
{
return ABSDIFF(l_pVirCon1->X, l_pVirCon2->X) +
ABSDIFF(l_pVirCon1->Y, l_pVirCon2->Y);
}
/** XXX HCl
*
* protection des connecteurs qui n'ont plus qu'un seul
* connecteur virtuel libre
*
**/
//void
//connectorProtect (ocrConnector * i_pCon)
//
//{
// ocrVirtualConnector *l_pVirConList;
//
// for (l_pCon = i_pCon ;
// l_pCon ; l_pCon = l_pCon->NEXT)
// {
// if (l_pCon)
//
// }
//}
//
/**
* supprime le connecteur virtuel i_pConVir de
* la liste io_pVirConList
**/
void
deleteConVirInConVirList(ocrVirtualConnector ** io_VirConList,
ocrVirtualConnector * i_pConVir)
{
ocrVirtualConnector *l_pVirConList;
ocrVirtualConnector *l_pVirConListOld = NULL;
for (l_pVirConList = *io_VirConList;
l_pVirConList; l_pVirConList = l_pVirConList->NEXT) {
if (l_pVirConList == i_pConVir) {
if (l_pVirConListOld == NULL) {
*io_VirConList = l_pVirConList->NEXT;
} else {
l_pVirConListOld->NEXT = l_pVirConList->NEXT;
}
}
l_pVirConListOld = l_pVirConList;
}
}
/**
* segment HORIZONTAL
**/
// FIXME
ocrNaturalInt isFreeLine( /*ocrConnector i_pCon, */
ocrWRoutingGrid * i_pGrid,
ocrVirtualConnector * l_pVirCon1,
ocrVirtualConnector * l_pVirCon2)
{
ocrWSegment *l_pSegment;
ocrWSegment *l_pSegment2;
l_pSegment =
getWSegment(i_pGrid, l_pVirCon1->X /*/ SCALE_X / PITCH */ ,
l_pVirCon1->Y /*/ SCALE_X / PITCH */ ,
l_pVirCon1->Z);
l_pSegment2 =
getWSegment(i_pGrid, l_pVirCon2->X /*/ SCALE_X / PITCH */ ,
l_pVirCon2->Y /*/ SCALE_X / PITCH */ ,
l_pVirCon2->Z);
if ((l_pSegment == l_pSegment2) &&
(l_pSegment->SIGNAL_INDEX == WSEGMENT_FREE)) {
return 1;
}
return 0;
}
ocrNaturalInt
isFreePoint(ocrConnector * i_pCon,
ocrWRoutingGrid * i_pGrid, ocrVirtualConnector * l_pVirCon)
// FIXME
{
ocrWSegment *seg;
if (l_pVirCon->Z)
seg = getWSegment(i_pGrid, l_pVirCon->X /* / SCALE_X / PITCH */ ,
l_pVirCon->Y /* / SCALE_X / PITCH */ ,
l_pVirCon->Z - 1);
else
seg = getWSegment(i_pGrid, l_pVirCon->X /* / SCALE_X / PITCH */ ,
l_pVirCon->Y /* / SCALE_X / PITCH */ ,
l_pVirCon->Z);
if (seg->SIGNAL_INDEX == WSEGMENT_FREE)
return 1;
// if (seg->NAME)
// if (instr(seg->NAME, i_pCon->NAME, '\0'))
// return 1;
//printf ("Pas libre : (%ld, %ld, %ld)\n", l_pVirCon->X, l_pVirCon->Y, l_pVirCon->Z);
return 0;
}
/**
* création d'un table de hash
* correspondance : nom de l'instance <-> ptr sur l'instance
**/
void
createHashTable(ocrRoutingDataBase * i_pDataBase, phfig_list * i_pPhFig)
{
phins_list *l_pInst;
// Init Tables de HASH
i_pDataBase->HTABLE = addht(MAX_HT);
display(LEVEL, DEBUG, "%s", "o HashTable initialization...");
// parcours des instances physiques
// sauvegarde des pointeurs dans la table de Hash
for (l_pInst = i_pPhFig->PHINS; l_pInst; l_pInst = l_pInst->NEXT) {
addhtitem(i_pDataBase->HTABLE,
(void *) l_pInst->INSNAME, (int) (l_pInst));
}
display(LEVEL, DEBUG, "%s\n", " done");
}
/**
* suppression de la table de hash
**/
void deleteHashTable(ocrRoutingDataBase * i_pDataBase)
{
delht(i_pDataBase->HTABLE);
i_pDataBase->HTABLE = NULL;
display(LEVEL, DEBUG, "%s\n", "o Delete HashTable ...");
}
#if 0
//xtof --- pas utilise
/**
* renvoie les coordonnées absolue du connecteur en tenant
* compte des transformations de l'instance
**/
void
getPhConCoord(phins_list * i_pPhIns,
phfig_list * i_pPhModel,
phref_list * i_pPhRef,
ocrNaturalInt * o_uXAbsCon, ocrNaturalInt * o_uYAbsCon)
{
switch (i_pPhIns->TRANSF) {
case NOSYM:
{
*o_uXAbsCon = i_pPhIns->XINS + i_pPhRef->XREF;
*o_uYAbsCon = i_pPhIns->YINS + i_pPhRef->YREF;
break;
}
case SYM_Y:
{
*o_uXAbsCon = i_pPhIns->XINS + i_pPhRef->XREF;
*o_uYAbsCon =
i_pPhIns->YINS + i_pPhModel->YAB2 - i_pPhRef->YREF;
break;
}
case SYM_X:
{
*o_uXAbsCon =
i_pPhIns->XINS + i_pPhModel->XAB2 - i_pPhRef->XREF;
*o_uYAbsCon = i_pPhIns->YINS + i_pPhRef->YREF;
break;
}
case SYMXY:
{
*o_uXAbsCon =
i_pPhIns->XINS + i_pPhModel->XAB2 - i_pPhRef->XREF;
*o_uYAbsCon =
i_pPhIns->YINS + i_pPhModel->YAB2 - i_pPhRef->YREF;
break;
}
default:
{
puts("Error getPhConCoord");
exit(1);
}
}
}
#endif
ocrNaturalShort
chooseInternalConnectorLine(ocrWRoutingGrid * i_pGrid,
ocrConnector * i_pCon, ocrConnector * i_pCon2)
{
ocrVirtualConnector *l_pVirCon;
ocrVirtualConnector *l_pVirCon2;
ocrNaturalShort l_bOk = 0;
i_pCon->CON = NULL;
i_pCon2->CON = NULL;
// recherche de connecteurs virtuels sur une meme rangée
// non utilisée des 2 instances physiques
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon && !l_bOk;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
for (l_pVirCon2 = i_pCon2->VIR_CON_LIST;
l_pVirCon2 && !l_bOk;
l_pVirCon2 = (ocrVirtualConnector *) l_pVirCon2->NEXT) {
if ((l_pVirCon2->Y == l_pVirCon->Y) &&
(isFreeLine(i_pGrid, l_pVirCon, l_pVirCon2))) {
if ((l_pVirCon2->TAG == 0) && (l_pVirCon->TAG == 0)) {
l_bOk = 1;
i_pCon->CON = l_pVirCon;
i_pCon2->CON = l_pVirCon2;
}
}
}
}
// Echec, les deux connecteurs ne peuvent pas etre
// sur la meme ligne. On recherche les deux connecteurs les
// plus proches et disponibles ...
if (!i_pCon->CON) {
ocrNaturalInt l_uDistMin = OCRNATURALINT_MAX;
ocrNaturalInt l_uDist;
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
if ((isFreePoint(i_pCon, i_pGrid, l_pVirCon))
&& (l_pVirCon->TAG == 0)) {
for (l_pVirCon2 = i_pCon2->VIR_CON_LIST; l_pVirCon2;
l_pVirCon2 =
(ocrVirtualConnector *) l_pVirCon2->NEXT) {
/*
if ((isFreePoint (i_pGrid, l_pVirCon)) &&
(isFreePoint (i_pGrid, l_pVirCon2)))
{
if ((l_pVirCon2->TAG == 0) &&
(l_pVirCon->TAG == 0))
*/
if ((isFreePoint(i_pCon2, i_pGrid, l_pVirCon2)) &&
(l_pVirCon2->TAG == 0)) {
l_uDist =
distBetween2VirCon(l_pVirCon, l_pVirCon2);
if (l_uDist < l_uDistMin) {
l_uDistMin = l_uDist;
i_pCon->CON = l_pVirCon;
i_pCon2->CON = l_pVirCon2;
}
}
// else
// printf (".");
}
}
}
}
if (i_pCon->CON != NULL) {
i_pCon->CON->TAG = 1;
i_pCon2->CON->TAG = 1;
}
return (i_pCon->CON != NULL);
}
/**
* Détermine si un connecteur possède tous sauf un de ses connecteurs
* virtuels de pris. (Urgent à router)
*
* retourne 1 : OUI, 0 : NON.
**/
ocrNaturalInt
isCriticalConnector(ocrWRoutingGrid * i_pGrid, ocrConnector * i_pCon)
{
ocrVirtualConnector *l_pConVir;
ocrNaturalInt l_uConLibre = 0;
for (l_pConVir = i_pCon->VIR_CON_LIST;
l_pConVir; l_pConVir = (ocrVirtualConnector *) l_pConVir->NEXT) {
if (isFreePoint(i_pCon, i_pGrid, l_pConVir))
l_uConLibre++;
}
return (l_uConLibre <= 2);
}
/**
* Choisit 1 connecteur dans chacune des listes i_pCon i_pCon2
*
* Return
* OCR_OK : OK
* OCR_BAD_CON1 : si l_uCon = 0
* OCR_BAD_CON2 : si l_uCon2 = 0
**/
ocrNaturalShort
chooseInternalConnector(ocrWRoutingGrid * i_pGrid,
ocrConnector * i_pCon, ocrConnector * i_pCon2,
int mode)
{
ocrVirtualConnector *l_pVirCon;
ocrVirtualConnector *l_pVirCon2;
ocrNaturalInt l_uDistMin = OCRNATURALINT_MAX;
ocrNaturalInt l_uDist;
ocrNaturalInt l_uCon = 0;
ocrNaturalInt l_uCon2 = 0;
if (!IS_MARK_AS_LINKED(i_pCon))
i_pCon->CON = NULL;
if (!IS_MARK_AS_LINKED(i_pCon2))
i_pCon2->CON = NULL;
if (mode == 1) {
if (i_pCon2->VIR_CON_LIST) {
if (i_pCon2->VIR_CON_LIST->NEXT == NULL) {
mode = 3;
} else {
mode = 0;
}
}
}
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon; l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
if (((isFreePoint(i_pCon, i_pGrid, l_pVirCon)))
&& (l_pVirCon->TAG == 0)) {
l_uCon++;
for (l_pVirCon2 = i_pCon2->VIR_CON_LIST;
l_pVirCon2;
l_pVirCon2 = (ocrVirtualConnector *) l_pVirCon2->NEXT) {
if ((isFreePoint(i_pCon2, i_pGrid, l_pVirCon2)) &&
(((l_pVirCon2->TAG == 0) && (mode == 0))
|| ((l_pVirCon2->TAG < 5) && (mode == 3))
//||
//(mode == 3)
)
) {
l_uCon2++;
l_uDist = distBetween2VirCon(l_pVirCon, l_pVirCon2);
if (l_uDist < l_uDistMin) {
l_uDistMin = l_uDist;
i_pCon->CON = l_pVirCon;
i_pCon2->CON = l_pVirCon2;
}
}
// else
// printf (".");
}
}
}
if (i_pCon->CON != NULL)
i_pCon->CON->TAG = 1;
if (i_pCon2->CON != NULL)
//i_pCon2->CON->TAG = 1;
i_pCon2->CON->TAG++;
// printf ("con : %ld con2 : %ld\n", l_uCon, l_uCon2);
if (!l_uCon)
return OCR_BAD_CON1;
if (!l_uCon2)
return OCR_BAD_CON2;
return OCR_OK;
}
ocrNaturalShort
chooseInternalConnector2(ocrWRoutingGrid * i_pGrid,
ocrConnector * i_pCon)
{
ocrVirtualConnector *l_pVirCon;
ocrNaturalInt l_uCon = 0;
if (!IS_MARK_AS_LINKED(i_pCon))
i_pCon->CON = NULL;
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon; l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
if (((isFreePoint(i_pCon, i_pGrid, l_pVirCon)))
&& (l_pVirCon->TAG == 0)) {
l_uCon++;
i_pCon->CON = l_pVirCon;
}
}
if (i_pCon->CON != NULL)
i_pCon->CON->TAG = 1;
if (!l_uCon)
return OCR_BAD_CON1;
return OCR_OK;
}
/* Marquage de segments */
// XXX XXX XXX XXX XXX XXX XXX XXX
void
markSegmentAsFree(ocrRoutingDataBase * i_pDataBase, ocrSignal * i_pSignal,
ocrNaturalInt INDEX)
{
ocrWSegment *l_pSeg;
ocrConnector *l_pCon;
ocrVirtualConnector *l_pVirCon;
ocrWRoutingGrid *l_pGrid = i_pDataBase->GRID;
ocrNaturalInt z;
for (l_pCon = i_pSignal->CON_LIST; l_pCon; l_pCon = l_pCon->NEXT) {
for (l_pVirCon = l_pCon->VIR_CON_LIST; l_pVirCon;
l_pVirCon = l_pVirCon->NEXT) {
if (l_pVirCon->Z == 0)
continue;
z = l_pVirCon->Z - 1;
l_pSeg =
getWSegment(i_pDataBase->GRID, l_pVirCon->X, l_pVirCon->Y,
z);
if ((l_pSeg->SIGNAL_INDEX == WSEGMENT_OBSTACLE)
) {
// marquer comme libre
if (l_pCon->INTEXT == INTERNAL) {
l_pSeg->SIGNAL_INDEX = WSEGMENT_FREE;
mergeWSegment(i_pDataBase->PARAM, l_pGrid, l_pSeg);
} else {
// EXTERNAL
if (getWSegDirection(i_pDataBase->PARAM, l_pSeg) ==
ocrHorizontal) {
splitWSegment(i_pDataBase->PARAM, l_pGrid,
l_pSeg, l_pVirCon->X, l_pVirCon->X,
WSEGMENT_FREE);
} else {
splitWSegment(i_pDataBase->PARAM,
l_pGrid,
l_pSeg,
l_pVirCon->Y,
l_pVirCon->Y, WSEGMENT_FREE);
}
}
}
} // for l_pVirCon
} // for l_pCon
//printf ("%d segments libere(s)\n", bloum);
return;
}
void
unMarkSegmentAsFree(ocrRoutingDataBase * i_pDataBase,
ocrSignal * i_pSignal, ocrNaturalInt INDEX)
{
ocrWSegment *l_pSeg;
ocrConnector *l_pCon;
ocrVirtualConnector *l_pVirCon;
ocrNaturalInt z;
for (l_pCon = i_pSignal->CON_LIST; l_pCon; l_pCon = l_pCon->NEXT) {
//if (l_pCon->NB_VC <= 1)
// continue;
for (l_pVirCon = l_pCon->VIR_CON_LIST; l_pVirCon;
l_pVirCon = l_pVirCon->NEXT) {
if (l_pVirCon->Z == 0)
continue;
z = l_pVirCon->Z - 1;
l_pSeg = getWSegment(i_pDataBase->GRID, l_pVirCon->X, l_pVirCon->Y, z);
if (l_pSeg->SIGNAL_INDEX == WSEGMENT_FREE) {
// marquer comme occupe
if (l_pCon->INTEXT == INTERNAL) {
if (getWSegDirection(i_pDataBase->PARAM, l_pSeg) ==
ocrHorizontal) {
splitWSegment(i_pDataBase->PARAM, i_pDataBase->GRID,
l_pSeg, l_pVirCon->X, l_pVirCon->X,
WSEGMENT_OBSTACLE);
} else {
splitWSegment(i_pDataBase->PARAM,
i_pDataBase->GRID,
l_pSeg,
l_pVirCon->Y,
l_pVirCon->Y, WSEGMENT_OBSTACLE);
}
} else {
l_pSeg->SIGNAL_INDEX = WSEGMENT_OBSTACLE;
mergeWSegment(i_pDataBase->PARAM, i_pDataBase->GRID, l_pSeg);
}
}
} // for l_pVirCon
} // for l_pCon
return;
}
/*
conversion CALU -> CV
*/
ocrNaturalInt add_calu_cv(ocrConnector * i_pCon, phfig_list * i_pPhModel,
phins_list * i_pPhIns, phseg_list * i_pPhSeg,
ocrNaturalInt INDEX,
ocrRoutingDataBase * i_pDataBase)
{
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, z = 0;
int i, j;
int check;
#ifdef OCR_DEBUG
printf("Checkpoint UN\n");
#endif
switch (i_pPhSeg->LAYER) {
case CALU1:
z = 0;
break;
case CALU2:
z = 1;
break;
case CALU3:
z = 2;
break;
case CALU4:
z = 3;
break;
case CALU5:
z = 4;
break;
case CALU6:
z = 5;
break;
//case CALU7:
// z = 6;
// break;
default:
/* rien a faire */
#ifdef OCR_DEBUG
printf("HOUBA !\n");
#endif
display(LEVEL, ERROR,
" o %s : should not be in the interface of %s:%s\n",
i_pPhSeg->NAME, i_pPhIns->INSNAME, i_pPhModel->NAME,
i_pCon->NAME);
//exit (-1);
return 1;
}
#ifdef OCR_DEBUG
printf("Checkpoint DEUX\n");
#endif
switch (i_pPhIns->TRANSF) {
case NOSYM:
#ifdef OCR_DEBUG
printf("NOSYM\n");
#endif
x1 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhSeg->X1;
y1 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhSeg->Y1;
x2 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhSeg->X2;
y2 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhSeg->Y2;
break;
case SYM_Y:
#ifdef OCR_DEBUG
printf("SYM_Y\n");
#endif
x1 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhSeg->X1;
y1 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhModel->YAB2 - i_pPhSeg->Y1;
x2 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhSeg->X2;
y2 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhModel->YAB2 - i_pPhSeg->Y2;
break;
case SYM_X:
#ifdef OCR_DEBUG
printf("SYM_X\n");
#endif
x1 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhModel->XAB2 - i_pPhSeg->X1;
y1 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhSeg->Y1;
x2 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhModel->XAB2 - i_pPhSeg->X2;
y2 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhSeg->Y2;
break;
case SYMXY:
#ifdef OCR_DEBUG
printf("SYMXY\n");
#endif
x1 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhModel->XAB2 - i_pPhSeg->X1;
y1 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhModel->YAB2 - i_pPhSeg->Y1;
x2 = (i_pPhIns->XINS - i_pPhModel->XAB1) + i_pPhModel->XAB2 - i_pPhSeg->X2;
y2 = (i_pPhIns->YINS - i_pPhModel->YAB1) + i_pPhModel->YAB2 - i_pPhSeg->Y2;
break;
default:
display(LEVEL, ERROR, "o Error add_calu_cv\n");
exit(1);
}
#ifdef OCR_DEBUG
printf("Checkpoint TROIS\n");
#endif
#ifdef OCR_DEBUG
printf("1/ x1=%d; y1=%d; x2=%d; y2=%d; layer=%d\n", x1, y1, x2, y2, z);
#endif
switch (i_pPhSeg->TYPE) {
case LEFT:
// y1 = y1 - (i_pPhSeg->WIDTH / 2);
// y2 = y2 + (i_pPhSeg->WIDTH / 2);
//tmp = x1;
//x1 = x2 ; x2 = tmp;
break;
case RIGHT:
// y1 = y1 - (i_pPhSeg->WIDTH / 2);
// y2 = y1 + (i_pPhSeg->WIDTH / 2);
break;
case UP:
// x1 = x1 - (i_pPhSeg->WIDTH / 2);
// x2 = x2 + (i_pPhSeg->WIDTH / 2);
break;
case DOWN:
//tmp = y1;
//y1 = y2 ; y2 = tmp;
// x1 = x1 - (i_pPhSeg->WIDTH / 2);
// x2 = x2 + (i_pPhSeg->WIDTH / 2);
break;
default:
exit(1);
break;
}
#ifdef OCR_DEBUG
printf("Checkpoint QUATRE\n");
#endif
// conversion des coord
#ifdef OCR_DEBUG
printf("2/ x1=%d; y1=%d; x2=%d; y2=%d\n", x1, y1, x2, y2);
#endif
x1 = x1 / (5 * SCALE_X);
x2 = x2 / (5 * SCALE_X);
y1 = y1 / (5 * SCALE_X);
y2 = y2 / (5 * SCALE_X);
#ifdef OCR_DEBUG
printf("3/ X1=%d; Y1=%d; X2=%d; Y2=%d\n", x1, y1, x2, y2);
#endif
// connecteurs virtuels
// BIG FIXME HERE ?
//if (!( (((z % 2)) && (i_pDataBase->PARAM->EVEN_LAYERS_DIRECTION == ocrHorizontal))
// || ((!(z % 2) && (i_pDataBase->PARAM->EVEN_LAYERS_DIRECTION == ocrVertical))) ))
//{ // layer horiz
// ocrNaturalInt tmpx1, tmpx2;
// tmpx1 = y1 ; y1 = x1 ; x1 = tmpx1;
// tmpx2 = y2 ; y2 = x2 ; x2 = tmpx2;
//}
if (x1 > x2) {
ocrNaturalInt tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y1 > y2) {
ocrNaturalInt tmp = y2;
y2 = y1;
y1 = tmp;
}
check = 1;
for (i = x1; i <= x2; i++)
for (j = y1; j <= y2; j++) {
ocrVirtualConnector *i_pVirCon;
check = 0;
i_pVirCon = createVirtualConnector(i, j, z, 0, 0);
addVirtualConnector(&(i_pCon->VIR_CON_LIST), i_pVirCon);
(i_pCon->NB_VC)++;
// if (z) {
// pt = malloc (sizeof (struct ocrPoint));
// pt->X = i;
// pt->Y = j;
// pt->Z = z;
// pt->SIGNAL_INDEX = INDEX;
// pt->NEXT = i_pDataBase->POINTS;
// i_pDataBase->POINTS = pt;
// }
#ifdef OCR_DEBUG
printf("VC for :%s, x=%d, y=%d, z=%d\n", i_pCon->NAME, i, j,
z);
#endif
}
#ifdef OCR_DEBUG
printf("Checkpoint CINQ\n");
#endif
return check; // add_calu_cv
}
/**
* Création des connecteurs de la bd
*/
void
initConnectorList(ocrRoutingDataBase * i_pDataBase,
phfig_list * i_pPhFig, lofig_list * i_pLoFig)
{
ocrNaturalInt l_nNbSig;
losig_list *l_pLoSig;
ocrConnector *l_pCon;
locon_list *l_pLoCon;
chain_list *l_pChain;
phfig_list *l_pPhModel;
phins_list *l_pPhInst;
phseg_list *l_pPhSeg;
ocrNaturalInt l_uNbExternal = 0;
ocrNaturalInt check;
// Création d'une table de Hash sur les instances physiques
createHashTable(i_pDataBase, i_pPhFig);
l_nNbSig = 0;
for (l_pLoSig = i_pLoFig->LOSIG; l_pLoSig; l_pLoSig = l_pLoSig->NEXT) {
if ((!isvss(l_pLoSig->NAMECHAIN->DATA)) &&
(!isvdd(l_pLoSig->NAMECHAIN->DATA))) {
ocrNaturalInt nb_con;
l_pChain = getptype(l_pLoSig->USER, (long) LOFIGCHAIN)->DATA;
// parcours des connecteurs du signal
nb_con = 0;
while (l_pChain) {
// nouveau connecteur
l_pLoCon = (locon_list *) l_pChain->DATA;
nb_con++;
// Instance physique du connecteur
// ROOT est une lofig ou une loins ?
if (l_pLoCon->ROOT == i_pLoFig) { // lofig
phcon_list *l_pPhCon = NULL;
//l_pCon =
// createConnector (l_pLoCon->NAME, i_pLoFig->NAME,
// OCR_TYPE_PONC, EXTERNAL, 0, // FACE
// 0, // ORDER
// 0); // NumFMF
// On ne cherche pas a placer les connecteurs !
l_pCon = createConnector(l_pLoCon->NAME, i_pLoFig->NAME, OCR_TYPE_PONC, EXTERNAL, 0, // FACE
0, // ORDER
0); // NumFMF
addConnector(i_pDataBase->GSIGNAL[l_nNbSig], l_pCon);
for (l_pPhCon = i_pPhFig->PHCON; l_pPhCon;
l_pPhCon = l_pPhCon->NEXT) {
if (l_pPhCon->NAME == l_pLoCon->NAME) {
ocrVirtualConnector *l_pVirCon;
//printf ("coucou\n");
l_pVirCon =
createVirtualConnector(l_pPhCon->XCON /
(5 * SCALE_X),
l_pPhCon->YCON /
(5 * SCALE_X), 1, 0, 0);
addVirtualConnector(&(l_pCon->VIR_CON_LIST),
l_pVirCon);
}
}
//l_uNbExternal++;
#ifdef OCR_DEBUG
printf("treating external connector :%s\n",
l_pLoCon->NAME);
#endif
} else // loins
{
l_pPhInst =
(phins_list *) gethtitem(i_pDataBase->HTABLE,
(void *) ((loins_list *)
l_pLoCon->
ROOT)->INSNAME);
if (l_pPhInst == (phins_list *) EMPTYHT) {
display (LEVEL, ERROR,
"cannot find the right instance: %s !\n",
((loins_list *) l_pLoCon->ROOT)->INSNAME);
exit(1);
}
#ifdef OCR_DEBUG
printf
("treating the connector %s of the instance %s of model %s\n",
l_pLoCon->NAME,
((loins_list *) l_pLoCon->ROOT)->INSNAME,
((loins_list *) l_pLoCon->ROOT)->FIGNAME);
#endif
// Ajout du connecteur interne
l_pCon = createConnector(l_pLoCon->NAME, ((loins_list *) l_pLoCon->ROOT)->INSNAME, OCR_TYPE_PONC, INTERNAL, 0, // FACE
0, // ORDER
0); // NumFMF
addConnector(i_pDataBase->GSIGNAL[l_nNbSig], l_pCon);
#ifdef OCR_DEBUG
printf("treating internal connector :%s\n",
l_pLoCon->NAME);
#endif
// récupérer les coordonnées des connecteurs grace
// au nom du model
l_pPhModel = getphfig(l_pPhInst->FIGNAME, 'P');
// parcours des connecteurs du model ...
// ajout de tous les connecteurs virutels ...
check = 0;
//if (!check)
for (l_pPhSeg = l_pPhModel->PHSEG; l_pPhSeg;
l_pPhSeg = l_pPhSeg->NEXT) {
if (l_pPhSeg->NAME == l_pLoCon->NAME) {
// ajouter les CV.
check = 1;
#ifdef OCR_DEBUG
printf("ajout d'un segm en CALU pour :%s\n",
l_pLoCon->NAME);
#endif
add_calu_cv(l_pCon, l_pPhModel, l_pPhInst,
l_pPhSeg, l_nNbSig, i_pDataBase);
} // end for
} // end if
}
l_pChain = l_pChain->NEXT;
}
l_nNbSig++;
if (nb_con < 2) {
display (LEVEL, WARNING,
"net with only one connector : %s\n",
i_pDataBase->GSIGNAL[l_nNbSig - 1]->NAME);
i_pDataBase->GSIGNAL[l_nNbSig - 1]->NICHT_ZU_ROUTIEREN = 1;
//exit (-1);
}
}
}
// dumpConnectors ();
// un petit peu de ménage ...
deleteHashTable(i_pDataBase);
}

View File

@ -0,0 +1,505 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:26 $
$Log: ocrDataBaseUtil.c,v $
Revision 1.1 2002/03/15 14:37:26 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:25 hcl
First commit in the new tree.
Revision 1.5 2001/12/20 13:04:04 hcl
Cosmetique.
Revision 1.4 2001/12/14 15:58:40 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.3 2001/11/20 11:02:04 hcl
Derecursivation de deleteVirtualConnectorList
Revision 1.2 2001/11/20 09:42:06 hcl
last but not least
Revision 1.1 2001/09/26 14:27:56 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrPath.h"
#include "display.h"
static char *res_id =
"$Id: ocrDataBaseUtil.c,v 1.1 2002/03/15 14:37:26 hcl Exp $";
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
/*
* Base de donnée du routage
*/
void dumpVirCon(ocrVirtualConnector * i_pVirConList, FILE * i_pFile)
{
if (i_pVirConList) {
fprintf(i_pFile, " X : %ld Y : %ld Z : %ld TAG : %d\n",
i_pVirConList->X,
i_pVirConList->Y, i_pVirConList->Z, i_pVirConList->TAG);
fflush(i_pFile);
}
}
void dumpVirConList(ocrVirtualConnector * i_pVirConList, FILE * i_pFile)
{
if (i_pVirConList) {
fprintf(i_pFile, " X : %ld Y : %ld Z : %ld TAG : %d\n",
i_pVirConList->X,
i_pVirConList->Y, i_pVirConList->Z, i_pVirConList->TAG);
if (i_pVirConList->NEXT)
dumpVirConList((ocrVirtualConnector *) i_pVirConList->NEXT,
i_pFile);
} else
puts("NULL");
fflush(i_pFile);
}
void dumpSegList(ocrWSegment * i_pSegment, FILE * i_pFile)
{
if (i_pSegment) {
fprintf(i_pFile, " PMIN : %ld PMAX : %ld OFFSET"
" : %ld LAYER : %ld INDEX : %ld\n",
i_pSegment->P_MIN * 5,
i_pSegment->P_MAX * 5,
i_pSegment->OFFSET * 5,
i_pSegment->LAYER, i_pSegment->SIGNAL_INDEX);
dumpSegList(i_pSegment->NEXT, i_pFile);
}
}
/**
* affiche la liste de connecteurs,
* ainsi que ses connecteurs virtuels
**/
void dumpConList(ocrConnector * i_pConList, FILE * i_pFile)
{
if (i_pConList) {
fprintf(i_pFile, " NAME : %s\n", i_pConList->NAME);
fprintf(i_pFile, " INSNAME: %s\n", i_pConList->INSNAME);
fprintf(i_pFile, " FACE : %d\n", i_pConList->FACE);
fprintf(i_pFile, " WIN : %d\n", i_pConList->WIN);
if (i_pConList->INTEXT == INTERNAL)
fprintf(i_pFile, " INT/EXT: INTERNAL\n");
else
fprintf(i_pFile, " INT/EXT: EXTERNAL\n");
if (i_pConList->CON) {
fprintf(i_pFile, " CON : \n");
fprintf(i_pFile, " X : %ld Y : %ld\n",
i_pConList->CON->X, i_pConList->CON->Y);
}
fflush(i_pFile);
if (i_pConList->VIR_CON_LIST) {
fprintf(i_pFile, " CONVIRT: \n");
dumpVirConList(i_pConList->VIR_CON_LIST, i_pFile);
}
if (i_pConList->NEXT)
dumpConList(i_pConList->NEXT, i_pFile);
}
}
void dumpSignalToFile(ocrSignal * i_pSignal, FILE * i_pFile)
{
fprintf(i_pFile, "NAME : %s\n", i_pSignal->NAME);
fprintf(i_pFile, " INDEX : %ld\n", i_pSignal->INDEX);
fprintf(i_pFile, " NB CON : %ld\n", i_pSignal->NB_CON);
fprintf(i_pFile, " PRIORITY: %d\n", i_pSignal->PRIORITY);
if (i_pSignal->INTEXT == INTERNAL)
fprintf(i_pFile, " INTEXT : INTERNAL\n");
else
fprintf(i_pFile, " INTEXT : EXTERNAL\n");
if (i_pSignal->CON_LIST)
dumpConList(i_pSignal->CON_LIST, i_pFile);
/*
if (i_pSignal->SEGMENT)
{
fprintf (i_pFile, " SEGMENTS :\n");
fflush (i_pFile);
dumpSegList (i_pSignal->SEGMENT, i_pFile);
}
if (i_pSignal->VIA)
{
fprintf (i_pFile, " VIAS :\n");
fflush (i_pFile);
dumpVirConList (i_pSignal->VIA, i_pFile);
}
*/
}
void dumpGlobalSignal(ocrRoutingDataBase * i_pDataBase, FILE * i_pFile)
{
ocrNaturalInt i;
display (LEVEL, VERBOSE, "o Number of signals : %ld\n", i_pDataBase->NB_GSIGNAL);
for (i = 0; i < i_pDataBase->NB_GSIGNAL; i++) {
fprintf(i_pFile, "NAME : %s\n", i_pDataBase->GSIGNAL[i]->NAME);
fprintf(i_pFile, " INDEX : %ld\n",
i_pDataBase->GSIGNAL[i]->INDEX);
fprintf(i_pFile, " NB CON : %ld\n",
i_pDataBase->GSIGNAL[i]->NB_CON);
fprintf(i_pFile, " PRIORITY: %d\n",
i_pDataBase->GSIGNAL[i]->PRIORITY);
if (i_pDataBase->GSIGNAL[i]->INTEXT == INTERNAL)
fprintf(i_pFile, " INTEXT : INTERNAL\n");
else
fprintf(i_pFile, " INTEXT : EXTERNAL\n");
if (i_pDataBase->GSIGNAL[i]->CON_LIST)
dumpConList(i_pDataBase->GSIGNAL[i]->CON_LIST, i_pFile);
if (i_pDataBase->GSIGNAL[i]->SEGMENT) {
fprintf(i_pFile, " SEGMENTS :\n");
fflush(i_pFile);
dumpSegList(i_pDataBase->GSIGNAL[i]->SEGMENT, i_pFile);
}
if (i_pDataBase->GSIGNAL[i]->VIA) {
fprintf(i_pFile, " VIAS :\n");
fflush(i_pFile);
dumpVirConList(i_pDataBase->GSIGNAL[i]->VIA, i_pFile);
}
}
}
/**
* affichage de la bd
**/
void dumpDataBase(ocrRoutingDataBase * i_pDataBase, FILE * i_pFile)
{
if (i_pDataBase) {
fprintf(i_pFile, "NAME : %s\n", i_pDataBase->NAME);
fprintf(i_pFile, "XAB1 : %ld\n", i_pDataBase->XAB1);
fprintf(i_pFile, "XAB2 : %ld\n", i_pDataBase->XAB2);
fprintf(i_pFile, "YAB1 : %ld\n", i_pDataBase->YAB1);
fprintf(i_pFile, "YAB2 : %ld\n", i_pDataBase->YAB2);
if (i_pDataBase->GSIGNAL)
dumpGlobalSignal(i_pDataBase, i_pFile);
}
fprintf(i_pFile, "dump complete !\n");
fflush(i_pFile);
}
/**
* création de la base de donnée
**/
ocrRoutingDataBase *createDataBase(phfig_list * i_pPhFig)
{
ocrRoutingDataBase *l_pDataBase;
l_pDataBase =
(ocrRoutingDataBase *) mbkalloc(sizeof(ocrRoutingDataBase));
l_pDataBase->NAME = namealloc(i_pPhFig->NAME);
l_pDataBase->XAB1 = i_pPhFig->XAB1;
l_pDataBase->XAB2 = i_pPhFig->XAB2;
l_pDataBase->YAB1 = i_pPhFig->YAB1;
l_pDataBase->YAB2 = i_pPhFig->YAB2;
l_pDataBase->NB_OF_LAYERS = 3;
l_pDataBase->NB_F = g_pOption->WINDOW;
l_pDataBase->GSIGNAL = NULL;
l_pDataBase->SIGNAL = NULL;
l_pDataBase->FSIGNAL = NULL;
l_pDataBase->NB_GSIGNAL = 0;
l_pDataBase->NB_SIGNAL = 0;
l_pDataBase->NB_FSIGNAL = NULL;
l_pDataBase->WINDOWS = NULL;
l_pDataBase->POINTS = NULL;
l_pDataBase->GOBSTACLE = NULL;
l_pDataBase->MFOBSTACLE = NULL;
l_pDataBase->FOBSTACLE = NULL;
l_pDataBase->HTABLE = NULL;
l_pDataBase->PARAM = NULL;
l_pDataBase->GRID = NULL;
l_pDataBase->RIPUP = NULL;
l_pDataBase->NB_IT = 0;
l_pDataBase->NB_UNROUTED = 0;
l_pDataBase->NB_ROUTED = 0;
return l_pDataBase;
}
void deleteDataBase(ocrRoutingDataBase * i_pDataBase)
{
if (i_pDataBase) {
if (i_pDataBase->WINDOWS) {
mbkfree(i_pDataBase->WINDOWS);
i_pDataBase->WINDOWS = NULL;
}
mbkfree(i_pDataBase);
}
}
/**
* création de la liste des signaux
**/
void
createGlobalSignalList(ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uNbSignaux)
{
i_pDataBase->GSIGNAL = (ocrSignal **)
mbkalloc(sizeof(ocrSignal) * i_uNbSignaux);
}
/*
* Gestion des signaux
*/
#define setSignalPriority(x,v) ((x)->PRIORITY = (v))
#define incSignalPriority(x) ((x)->PRIORITY ++)
/**
* création d'un signal
**/
ocrSignal *createSignal(losig_list * i_pLoSig)
{
ocrSignal *l_pSignal;
l_pSignal = (ocrSignal *) mbkalloc(sizeof(ocrSignal));
l_pSignal->NAME = namealloc(i_pLoSig->NAMECHAIN->DATA);
l_pSignal->INDEX = i_pLoSig->INDEX;
l_pSignal->NEXT = NULL;
l_pSignal->SEGMENT = NULL;
l_pSignal->VIA = NULL;
l_pSignal->GLOBAL = NULL;
l_pSignal->WIN = 0;
l_pSignal->TYPE = 0;
l_pSignal->ROUTED = 0;
l_pSignal->NB_CON = 0;
l_pSignal->PRIORITY = 0;
l_pSignal->INTEXT = i_pLoSig->TYPE;
l_pSignal->CON_LIST = NULL;
l_pSignal->NICHT_ZU_ROUTIEREN = 0;
return l_pSignal;
}
ocrSignal *dupSignal(ocrSignal * i_pSignal)
{
ocrSignal *l_pSignal;
l_pSignal = (ocrSignal *) mbkalloc(sizeof(ocrSignal));
l_pSignal->NAME = i_pSignal->NAME;
l_pSignal->INDEX = i_pSignal->INDEX;
l_pSignal->NEXT = NULL;
l_pSignal->SEGMENT = NULL;
l_pSignal->VIA = NULL;
l_pSignal->GLOBAL = NULL;
l_pSignal->WIN = i_pSignal->WIN;
l_pSignal->TYPE = 0;
l_pSignal->ROUTED = 0;
l_pSignal->NB_CON = 0;
l_pSignal->PRIORITY = i_pSignal->PRIORITY;
l_pSignal->INTEXT = i_pSignal->INTEXT;
l_pSignal->CON_LIST = NULL;
return l_pSignal;
}
/**
* ajoute le signal dans la bd
**/
void
addSignalGlobal(ocrRoutingDataBase * i_pDataBase, ocrSignal * i_pSignal)
{
(i_pDataBase->GSIGNAL)[i_pDataBase->NB_GSIGNAL] = i_pSignal;
i_pDataBase->NB_GSIGNAL++;
}
/**
* Création d'un connecteur
**/
ocrConnector *createConnector(char *i_sName,
char *i_sInsName,
ocrNaturalShort i_uType,
ocrNaturalShort i_uIntExt,
ocrNaturalShort i_uFace,
ocrNaturalInt i_uOrder,
ocrNaturalInt i_uNumFMF)
{
ocrConnector *l_pCon;
l_pCon = (ocrConnector *) mbkalloc(sizeof(ocrConnector));
l_pCon->NAME = namealloc(i_sName);
l_pCon->INSNAME = namealloc(i_sInsName);
l_pCon->TYPE = i_uType;
l_pCon->INTEXT = i_uIntExt;
l_pCon->FACE = i_uFace;
l_pCon->ORDER = i_uOrder;
l_pCon->WIN = i_uNumFMF;
l_pCon->VIR_CON_LIST = NULL;
l_pCon->CON = NULL;
/* XXX HCl */
l_pCon->NB_VC = 0;
l_pCon->critVC = NULL;
return l_pCon;
}
/**
* ajoute le connecteur au signal
**/
void addConnector(ocrSignal * i_pSignal, ocrConnector * i_pCon)
{
i_pCon->NEXT = i_pSignal->CON_LIST;
i_pSignal->CON_LIST = i_pCon;
i_pSignal->NB_CON++;
}
/**
* Ajoute le segment i_pSegment au signal i_pSignal
**/
void addSegmentSignalList(ocrSignal * i_pSignal, ocrWSegment * i_pSegment)
{
i_pSegment->NEXT = i_pSignal->SEGMENT;
i_pSignal->SEGMENT = i_pSegment;
// dumpSegList (i_pSignal->SEGMENT, stdout);
}
/**
* Supprime le segment de la liste associée au signal i_pSignal
**/
void
deleteSegmentSignalList(ocrSignal * i_pSignal, ocrWSegment * i_pSegment)
{
ocrWSegment *l_pSegList;
ocrWSegment *l_pSegListOld = NULL;
for (l_pSegList = i_pSignal->SEGMENT;
l_pSegList; l_pSegList = l_pSegList->NEXT) {
if (l_pSegList == i_pSegment) {
if (l_pSegListOld == NULL) {
i_pSignal->SEGMENT = l_pSegList->NEXT;
} else {
l_pSegListOld->NEXT = l_pSegList->NEXT;
}
}
l_pSegListOld = l_pSegList;
}
}
/*
* Gestion des connecteurs Virtuels
*/
ocrVirtualConnector *dupVirtualConnector(ocrVirtualConnector * i_pVirCon)
{
ocrVirtualConnector *l_pCon;
l_pCon = (ocrVirtualConnector *) mbkalloc(sizeof(ocrVirtualConnector));
l_pCon->X = i_pVirCon->X;
l_pCon->Y = i_pVirCon->Y;
l_pCon->Z = i_pVirCon->Z;
l_pCon->WIDTH = i_pVirCon->WIDTH;
l_pCon->ORIENT = i_pVirCon->ORIENT;
l_pCon->TAG = i_pVirCon->TAG;
l_pCon->WIN = i_pVirCon->WIN;
l_pCon->DIST = i_pVirCon->DIST;
l_pCon->NEXT = NULL;
return l_pCon;
}
/**
* création d'un connecteur virtuel
**/
ocrVirtualConnector *createVirtualConnector(ocrNaturalInt i_uX,
ocrNaturalInt i_uY,
ocrNaturalInt i_uZ,
ocrNaturalInt i_uWidth,
ocrNaturalShort i_uOrient)
{
ocrVirtualConnector *l_pCon;
l_pCon = (ocrVirtualConnector *) mbkalloc(sizeof(ocrVirtualConnector));
l_pCon->X = i_uX;
l_pCon->Y = i_uY;
l_pCon->Z = i_uZ;
l_pCon->WIDTH = i_uWidth;
l_pCon->ORIENT = i_uOrient;
l_pCon->TAG = 0;
l_pCon->WIN = 0;
l_pCon->DIST = 0;
l_pCon->NEXT = NULL;
return l_pCon;
}
/**
* ajoute un connceteur virtuel à une liste
**/
void
addVirtualConnector(ocrVirtualConnector ** i_pVirConList,
ocrVirtualConnector * i_pVirCon)
{
(ocrVirtualConnector *) i_pVirCon->NEXT = *i_pVirConList;
*i_pVirConList = i_pVirCon;
}
void deleteVirtualConnectorList(ocrVirtualConnector * i_pVirCon)
{
ocrVirtualConnector *vc1, *vc2;
vc1 = vc2 = i_pVirCon;
while (vc1) {
vc2 = vc1;
vc1 = vc1->NEXT;
mbkfree(vc2);
}
}

View File

@ -0,0 +1,77 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:27 $
$Log: ocrInitDataBase.c,v $
Revision 1.1 2002/03/15 14:37:27 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:25 hcl
First commit in the new tree.
Revision 1.4 2001/12/20 13:04:04 hcl
Cosmetique.
Revision 1.3 2001/12/14 15:58:40 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.2 2001/11/20 09:42:06 hcl
last but not least
Revision 1.1 2001/09/26 14:27:56 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrPath.h"
#include "display.h"
#include "ocrConnectorUtil.h"
#include "ocrSignalUtil.h"
#include "ocrInitDataBase.h"
static char *res_id =
"$Id: ocrInitDataBase.c,v 1.1 2002/03/15 14:37:27 hcl Exp $";
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
/**
* Initialisation de la base de donnée
**/
ocrRoutingDataBase *initDataBase(phfig_list * i_pPhFig,
lofig_list * i_pLoFig)
{
ocrRoutingDataBase *l_pDataBase;
// Création de la base de donnée
l_pDataBase = createDataBase(i_pPhFig);
// Création d'une vue duale de la connectique
lofigchain(i_pLoFig);
display(LEVEL, DEBUG, "%s\n", "o Dual connectique ...");
// paramtères physiques de la grille 5*5 viacost=2 Layer paires = HORZ
l_pDataBase->PARAM = setParameters(5, 5, 2, ocrHorizontal);
// Initialisation des signaux a router
initGlobalSignalList(l_pDataBase, i_pLoFig);
// Création des listes de connecteurs virtuels
initConnectorList(l_pDataBase, i_pPhFig, i_pLoFig);
// dumpDataBase (l_pDataBase, stdout);
return l_pDataBase;
}

View File

@ -0,0 +1,217 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:27 $
$Log: ocrSignalUtil.c,v $
Revision 1.1 2002/03/15 14:37:27 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:25 hcl
First commit in the new tree.
Revision 1.5 2001/12/20 13:04:04 hcl
Cosmetique.
Revision 1.4 2001/12/14 15:58:40 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.3 2001/12/03 14:31:24 hcl
Pour la route.
Revision 1.2 2001/11/20 09:42:06 hcl
last but not least
Revision 1.1 2001/09/26 14:27:56 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrPath.h"
#include "display.h"
#include "ocrSignalUtil.h"
#include "ocrConnectorUtil.h"
static char *res_id =
"$Id: ocrSignalUtil.c,v 1.1 2002/03/15 14:37:27 hcl Exp $";
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
/**
* lie tous les connecteur d'un signal
**/
void linkSignal(ocrRoutingDataBase * i_pDataBase, ocrSignal * i_pSignal)
{
ocrConnector *l_pCon;
for (l_pCon = i_pSignal->CON_LIST; l_pCon; l_pCon = l_pCon->NEXT) {
linkConnector(i_pDataBase, i_pSignal->INDEX, l_pCon);
}
}
/**
* détermine le nombre de signaux à router
**/
ocrNaturalInt getNumSignal(lofig_list * i_pLoFig)
{
losig_list *l_pLoSig;
ocrNaturalInt l_nNbSig = 0;
// détermine le nombre de signaux à router
for (l_pLoSig = i_pLoFig->LOSIG; l_pLoSig; l_pLoSig = l_pLoSig->NEXT)
l_nNbSig++;
return l_nNbSig;
}
/**
* Initialisation des signaux à router : tous sauf VDD et VSS
* création des signaux dans la bd
**/
void
initGlobalSignalList(ocrRoutingDataBase * i_pDataBase,
lofig_list * i_pLoFig)
{
losig_list *l_pLoSig;
createGlobalSignalList(i_pDataBase, getNumSignal(i_pLoFig));
for (l_pLoSig = i_pLoFig->LOSIG; l_pLoSig; l_pLoSig = l_pLoSig->NEXT) {
if ((!isvss(l_pLoSig->NAMECHAIN->DATA)) &&
(!isvdd(l_pLoSig->NAMECHAIN->DATA))) {
ocrSignal *l_pSignal;
l_pSignal = createSignal(l_pLoSig);
addSignalGlobal(i_pDataBase, l_pSignal);
}
}
}
/*
* FONCTIONS D'ORDONNANCEMENT DE SIGNAUX
*/
int funcCon(const void *a, const void *b)
{
//return (*(ocrSignal **) b)->NB_CON - (*(ocrSignal **) a)->NB_CON;
return (*(ocrSignal **) a)->NB_CON - (*(ocrSignal **) b)->NB_CON;
}
int funcRandom(const void *a, const void *b)
{
return (((double) random() / RAND_MAX) - 0.5) < 0;
}
int funcPriority(const void *a, const void *b)
{
if ((*(ocrSignal **) b)->PRIORITY == (*(ocrSignal **) a)->PRIORITY)
return 0;
else
return (*(ocrSignal **) b)->PRIORITY -
(*(ocrSignal **) a)->PRIORITY;
}
int funcPriorityRandom(const void *a, const void *b)
{
if ((*(ocrSignal **) b)->PRIORITY == (*(ocrSignal **) a)->PRIORITY)
return (((double) random() / RAND_MAX) - 0.5) < 0;
else
return (*(ocrSignal **) b)->PRIORITY -
(*(ocrSignal **) a)->PRIORITY;
}
int funcPriorityCon(const void *a, const void *b)
{
if ((*(ocrSignal **) b)->PRIORITY == (*(ocrSignal **) a)->PRIORITY)
return (*(ocrSignal **) b)->NB_CON - (*(ocrSignal **) a)->NB_CON;
//return (*(ocrSignal **) a)->NB_CON - (*(ocrSignal **) b)->NB_CON;
else
return (*(ocrSignal **) b)->PRIORITY -
(*(ocrSignal **) a)->PRIORITY;
}
/**
* Détermine si un signal possède tous sauf un de ses connecteurs
* de pris. (Urgent à router)
* recherche à partir du rang i_uRang.
*
* retourne le numéro du signal
**/
ocrNaturalInt
isCriticalSignal(ocrRoutingDataBase * i_pDataBase, ocrNaturalInt i_uRang)
{
ocrNaturalInt i;
ocrConnector *l_pCon;
for (i = i_uRang; i < i_pDataBase->NB_SIGNAL - 1; i++) {
if (i_pDataBase->SIGNAL[i]->ROUTED == 0)
for (l_pCon = i_pDataBase->SIGNAL[i]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT) {
if (l_pCon->INTEXT == INTERNAL)
if (isCriticalConnector(i_pDataBase->GRID, l_pCon))
return i;
}
}
return OCRNATURALINT_MAX;
}
void
orderingSignals(ocrSignal ** i_pSignal,
ocrNaturalInt i_uNbSig, ocrNaturalShort i_uType)
{
switch (i_uType) {
case ORDER_RANDOM:
{
display(LEVEL, VERBOSE, "%s\n", "o Ordering : Random ...");
qsort(i_pSignal, i_uNbSig, sizeof(ocrSignal *), funcRandom);
break;
}
case ORDER_CON:
{
display(LEVEL, VERBOSE, "%s\n", "o Ordering : Connectors ...");
qsort(i_pSignal, i_uNbSig, sizeof(ocrSignal *), funcCon);
break;
}
case ORDER_PRIORITY:
{
display(LEVEL, VERBOSE, "%s\n", "o Ordering : Priority ...");
qsort(i_pSignal, i_uNbSig, sizeof(ocrSignal *), funcPriority);
break;
}
case ORDER_PRIORITY_RANDOM:
{
display(LEVEL, VERBOSE, "%s\n",
"o Ordering : Priority Random ...");
qsort(i_pSignal, i_uNbSig, sizeof(ocrSignal *),
funcPriorityRandom);
break;
}
case ORDER_PRIORITY_CON:
{
display(LEVEL, VERBOSE, "%s\n",
"o Ordering : Priority, Connectors ...");
qsort(i_pSignal, i_uNbSig, sizeof(ocrSignal *),
funcPriorityCon);
break;
}
default:
{
display (LEVEL, ERROR, "orderingSignals in %s:%d\n", __FILE__, __LINE__);
exit(1);
}
}
}

View File

@ -0,0 +1,771 @@
/*
### -------------------------------------------------- ###
$Author: hcl $
$Date: 2002/03/15 14:37:27 $
$Log: ocrWindow.c,v $
Revision 1.1 2002/03/15 14:37:27 hcl
Ca roule.
Revision 1.1 2002/03/15 09:54:25 hcl
First commit in the new tree.
Revision 1.5 2001/12/20 13:04:04 hcl
Cosmetique.
Revision 1.4 2001/12/19 14:22:49 hcl
Moult petits changements.
Revision 1.3 2001/12/14 15:58:40 hcl
indent *.c, quelques bugs en moins, non-placement des connecteurs.
Revision 1.2 2001/11/20 09:42:06 hcl
last but not least
Revision 1.1 2001/09/26 14:27:56 hcl
premier commit....
### -------------------------------------------------- ###
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mut.h"
#include "mlo.h"
#include "mlu.h"
#include "mph.h"
#include "mpu.h"
#include "ocr.h"
#include "ocrUtil.h"
#include "ocrWRoutingDataBase.h"
#include "ocrWindow.h"
#include "ocrPath.h"
#include "display.h"
#include "ocrConnectorUtil.h"
static char *res_id =
"$Id: ocrWindow.c,v 1.1 2002/03/15 14:37:27 hcl Exp $";
extern ocrOption *g_pOption;
#define LEVEL (g_pOption->LEVEL)
#define MAX_HT 500
#define PITCH 5
#define SCALE_X 100
/**
* création d'une nouvelle fenetre
**/
ocrWindow *newWindow(ocrNaturalInt i_nNumWin)
{
ocrWindow *l_pWindow;
ocrNaturalInt i;
l_pWindow = (ocrWindow *) mbkalloc(sizeof(ocrWindow));
l_pWindow->XMIN = 0;
l_pWindow->XMAX = 0;
l_pWindow->YMIN = 0;
l_pWindow->YMAX = 0;
l_pWindow->NUM = i_nNumWin;
l_pWindow->NB_SIG = 0;
l_pWindow->NB_SIG_THROW = 0;
for (i = 0; i < 9; i++)
l_pWindow->NB_SIG_FACE[i] = 0;
return l_pWindow;
}
/**
* supprime une fenetre
**/
void deleteWindow(ocrWindow * i_pWindow)
{
if (i_pWindow)
mbkfree(i_pWindow);
}
/**
* renvoie 1 si le connecteru virtuel se trouve dans la fentre
**/
ocrNaturalInt
isVCInWindow(ocrVirtualConnector * i_pVirCon, ocrWindow * i_pWindow)
{
if ((i_pVirCon->X >= i_pWindow->XMIN) &&
(i_pVirCon->X < i_pWindow->XMAX) &&
(i_pVirCon->Y >= i_pWindow->YMIN)
&& (i_pVirCon->Y < i_pWindow->YMAX))
return 1;
return 0;
}
/**
* renvoie la fenetre du connecteur virtuel
**/
void
computeVCWindow(ocrRoutingDataBase * i_pDataBase,
ocrVirtualConnector * i_pVirCon)
{
ocrNaturalInt i;
for (i = 1; i <= i_pDataBase->NB_F; i++)
if (isVCInWindow(i_pVirCon, i_pDataBase->WINDOWS[i])) {
i_pVirCon->WIN = i;
return;
}
}
/**
* Attribue une fenete à n connecteur interne
* d'au plus deux fenetres differentes
**/
void computeCWindow(ocrConnector * i_pCon)
{
ocrNaturalShort l_uWin, l_uWin2 = 0;
ocrNaturalShort l_uOk = 1;
ocrVirtualConnector *l_pVirCon;
// fenetre du premier con vir
if (!i_pCon->VIR_CON_LIST) {
display (LEVEL, ERROR,
"o No virtual connector for connector: %s of instance : %s\n",
i_pCon->NAME, i_pCon->INSNAME);
exit(1);
}
l_uWin = i_pCon->VIR_CON_LIST->WIN;
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon; l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
if (l_pVirCon->WIN != l_uWin) {
l_uWin2 = l_pVirCon->WIN;
i_pCon->WIN = 0;
l_uOk = 0;
display(LEVEL, INFO, "Con cheval NAME %s INSNAME %s\n",
i_pCon->NAME, i_pCon->INSNAME);
}
}
if (l_uOk) {
// tous les connecteurs sont sur la meme verticale
// et dans la meme fenetre
i_pCon->WIN = l_uWin;
} else {
ocrNaturalShort l_uNb1 = 0;
ocrNaturalShort l_uNb2 = 0;
ocrNaturalShort l_uWinDel;
// recherche des connecteurs majoritaires
// les connecteurs sont dans les fenetres l_uWin et l_uWin2
// il n'y a pas d'autres fenetres car nous sommes sur des frontières
// de rangées
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
if (l_pVirCon->WIN == l_uWin)
l_uNb1++;
else
l_uNb2++;
}
// les connecteurs virtuels de la fenetre l_uWinDel sont
// a détruire.
if (l_uNb1 > l_uNb2) {
i_pCon->WIN = l_uWin;
l_uWinDel = l_uWin2;
} else {
i_pCon->WIN = l_uWin2;
l_uWinDel = l_uWin;
}
for (l_pVirCon = i_pCon->VIR_CON_LIST;
l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
if (l_pVirCon->WIN == l_uWinDel)
deleteConVirInConVirList(&i_pCon->VIR_CON_LIST, l_pVirCon);
}
}
}
/**
* création des listes de signaux
**/
void initSignalList(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt j;
i_pDataBase->FSIGNAL = (ocrSignal **)
mbkalloc((i_pDataBase->NB_F + 1) * sizeof(ocrSignal *));
for (j = 0; j <= i_pDataBase->NB_F; j++) {
i_pDataBase->FSIGNAL[j] = NULL;
}
}
/**
* insert un signal dans une fenetre
**/
void
insertSignalWindow(ocrRoutingDataBase * i_pDataBase, ocrSignal * i_pSignal)
{
// chainage du signal
i_pSignal->NEXT = i_pDataBase->FSIGNAL[i_pSignal->WIN];
i_pDataBase->FSIGNAL[i_pSignal->WIN] = i_pSignal;
// mise à jour du nb de signaux de la fenetre.
i_pDataBase->WINDOWS[i_pSignal->WIN]->NB_SIG++;
}
/**
* XYtoWin : donne le numéro de la Window à la position (x,y)
**/
void
XYtoWin(ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uX, ocrNaturalInt i_uY, ocrNaturalInt * o_pWin)
{
ocrNaturalInt l_uNbf = sqrt(i_pDataBase->NB_F);
*o_pWin = i_uY * l_uNbf + i_uX + 1;
}
/**
* WintoXY : donne la position (x,y) de la Window numéro Win
**/
void
WintoXY(ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt * o_pX, ocrNaturalInt * o_pY, ocrNaturalInt i_uWin)
{
ocrNaturalInt l_uNbf = sqrt(i_pDataBase->NB_F);
*o_pX = (i_uWin - 1) % l_uNbf;
*o_pY = (i_uWin - 1) / l_uNbf;
}
/**
* Renvoie le connecteur FACIAL associé au connecteur i_pCon
* face OPPOSÉE
* index IDENTIQUE
* window ADJACENTE dans la direction de la face
**/
ocrConnector *getAssociatedConnector(ocrRoutingDataBase *
i_pDataBase,
ocrNaturalInt i_uIndex,
ocrConnector * i_pCon)
{
ocrNaturalInt l_uFace = 0;
ocrNaturalInt l_uWin;
ocrNaturalInt l_uX, l_uY;
ocrConnector *l_pCon;
ocrConnector *l_pConRes = NULL;
ocrSignal *l_pSignal;
WintoXY(i_pDataBase, &l_uX, &l_uY, i_pCon->WIN);
// printf ("Win %d -> x=%ld y=%ld\n", i_pCon->WIN, l_uX, l_uY);
switch (i_pCon->FACE) {
case OCR_FACE_EAST:
l_uFace = OCR_FACE_WEST;
l_uX++;
break;
case OCR_FACE_WEST:
l_uFace = OCR_FACE_EAST;
l_uX--;
break;
case OCR_FACE_NORTH:
l_uFace = OCR_FACE_SOUTH;
l_uY++;
break;
case OCR_FACE_SOUTH:
l_uFace = OCR_FACE_NORTH;
l_uY--;
}
XYtoWin(i_pDataBase, l_uX, l_uY, &l_uWin);
if ((l_uWin <= 0) || (l_uWin > i_pDataBase->NB_F)) {
display(LEVEL, ERROR, "getAssociatedConnector limit\n");
exit(1);
}
for (l_pSignal = i_pDataBase->FSIGNAL[l_uWin];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
if (l_pSignal->INDEX == i_uIndex) {
for (l_pCon = l_pSignal->CON_LIST; l_pCon;
l_pCon = l_pCon->NEXT) {
if (IS_MARK_AS_FACE_CON(l_pCon)) {
if (l_uFace == l_pCon->FACE) // bonne face ?
{
l_pConRes = l_pCon;
}
}
}
}
}
if (!l_pConRes) {
display(LEVEL, ERROR, "l_pConRes NULL\n");
exit(1);
}
return l_pConRes;
}
/**
* lie le connecteur Facial i_pCon avec son connecteur associé
* de la window adjacente
**/
void
linkConnector(ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uIndex, ocrConnector * i_pCon)
{
ocrNaturalInt l_uNbf = sqrt(i_pDataBase->NB_F);
ocrConnector *l_pAssCon;
// if (i_pCon->FACE == OCR_TYPE_FACE)
if (IS_MARK_AS_FACE_CON(i_pCon)) {
l_pAssCon = getAssociatedConnector(i_pDataBase, i_uIndex, i_pCon);
// Est ce que le connecteur est déja lié = Fenetre déja routée ?
if (!IS_MARK_AS_LINKED(l_pAssCon))
// if (!l_pAssCon->CON)
{
// non, alors il faut le faire
MARK_AS_LINKED(l_pAssCon);
MARK_AS_LINKED(i_pCon);
// Modification du connecteur pour prendre les bonnes contraintes
l_pAssCon->VIR_CON_LIST = dupVirtualConnector(i_pCon->CON);
l_pAssCon->CON = l_pAssCon->VIR_CON_LIST;
switch (l_pAssCon->FACE) {
case OCR_FACE_EAST:
l_pAssCon->CON->X =
(i_pDataBase->XAB2 - i_pDataBase->XAB1) / 500 / l_uNbf;
break;
case OCR_FACE_WEST:
l_pAssCon->CON->X = 0;
break;
case OCR_FACE_NORTH:
l_pAssCon->CON->Y =
(i_pDataBase->YAB2 - i_pDataBase->YAB1) / 500 / l_uNbf;
break;
case OCR_FACE_SOUTH:
l_pAssCon->CON->Y = 0;
}
}
}
}
/**
* supprime le "lien" entre les deux connecteurs.
* si le signal n'est pas ROUTED alors on supprime la contrainte des 2 con
* si il est ROUTED alors on supprime la contrainte sur i_pCon seulement
**/
void
unLinkConnector(ocrRoutingDataBase * i_pDataBase, ocrConnector * i_pCon)
{
}
/**
* retourne 1 si le connecteur est dans une window
* en périphérie
**/
ocrNaturalInt
isABorderWindow(ocrRoutingDataBase * i_pDataBase, ocrNaturalInt i_uWin)
{
ocrNaturalInt l_uNbf = sqrt(i_pDataBase->NB_F);
ocrNaturalInt l_uX, l_uY;
WintoXY(i_pDataBase, &l_uX, &l_uY, i_uWin);
return ((l_uX == 0) || (l_uY == 0) ||
(l_uX == l_uNbf - 1) || (l_uY == l_uNbf - 1));
}
/*
* getFace
* donne les faces externes possibles de la Window
**/
void getFace(ocrRoutingDataBase * i_pDataBase, ocrConnector * i_pCon)
{
ocrNaturalInt l_uNbf = sqrt(i_pDataBase->NB_F);
ocrNaturalInt l_uX, l_uY;
if (i_pCon->WIN != 0) {
l_uX = (i_pCon->WIN - 1) % l_uNbf;
l_uY = (i_pCon->WIN - 1) / l_uNbf;
i_pCon->FACE = 0;
if (l_uX == 0)
i_pCon->FACE |= OCR_FACE_WEST;
if (l_uX == l_uNbf - 1)
i_pCon->FACE |= OCR_FACE_EAST;
if (l_uY == 0)
i_pCon->FACE |= OCR_FACE_SOUTH;
if (l_uY == l_uNbf - 1)
i_pCon->FACE |= OCR_FACE_NORTH;
}
}
/**
* XY fonctions
* transformation des coordonnées relatives des points dans les fenetres
* aux coordonnées réélles (et inv.)
**/
/**
* transforme les coordonnées relatives à la fenetre
* en coordonnées absolue
**/
void
XYYWindowToReal(ocrNaturalInt i_uWin,
ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt * o_uX,
ocrNaturalInt * o_uY1, ocrNaturalInt * o_uY2)
{
*o_uX += i_pDataBase->WINDOWS[i_uWin]->XMIN;
*o_uY1 += i_pDataBase->WINDOWS[i_uWin]->YMIN;
*o_uY2 += i_pDataBase->WINDOWS[i_uWin]->YMIN;
}
/**
* transforme les coordonnées relatives à la fenetre
* en coordonnées absolue
**/
void
XYWindowToReal(ocrNaturalInt i_uWin,
ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt * o_uX, ocrNaturalInt * o_uY)
{
*o_uX += i_pDataBase->WINDOWS[i_uWin]->XMIN;
*o_uY += i_pDataBase->WINDOWS[i_uWin]->YMIN;
}
/**
* transforme les coordonnées relatives à la fenetre
* en coordonnées absolue
**/
void
XXYWindowToReal(ocrNaturalInt i_uWin,
ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt * o_uX1,
ocrNaturalInt * o_uX2, ocrNaturalInt * o_uY)
{
*o_uX1 += i_pDataBase->WINDOWS[i_uWin]->XMIN;
*o_uX2 += i_pDataBase->WINDOWS[i_uWin]->XMIN;
*o_uY += i_pDataBase->WINDOWS[i_uWin]->YMIN;
}
/**
* transforme les coordonnées absolue en coordonnées
* relative à la fenetre
**/
void
XYRealToWindow(ocrNaturalInt i_uWin,
ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt * o_uX, ocrNaturalInt * o_uY)
{
*o_uX -= i_pDataBase->WINDOWS[i_uWin]->XMIN;
*o_uY -= i_pDataBase->WINDOWS[i_uWin]->YMIN;
}
/**
* transforme les coordonnées relatives à la fenetre
* en coordonnées absolue
**/
void translatingWindowsToReal(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt i;
ocrSignal *l_pSignal;
ocrConnector *l_pCon;
ocrVirtualConnector *l_pVirCon;
ocrWSegment *l_pSegment;
display(LEVEL, VERBOSE,
"o Translating Windows to Real : CON, VIA, SEGMENT ...\n");
for (i = 1; i <= i_pDataBase->NB_F; i++) {
for (l_pSignal = i_pDataBase->FSIGNAL[i];
l_pSignal; l_pSignal = l_pSignal->NEXT) {
// VIA
for (l_pVirCon = l_pSignal->VIA;
l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
XYWindowToReal(l_pSignal->WIN, i_pDataBase, &l_pVirCon->X,
&l_pVirCon->Y);
}
// SEGMENT
for (l_pSegment = l_pSignal->SEGMENT;
l_pSegment; l_pSegment = l_pSegment->NEXT) {
if (getWSegDirection(i_pDataBase->PARAM, l_pSegment)
== ocrHorizontal) {
XXYWindowToReal(l_pSignal->WIN,
i_pDataBase,
&l_pSegment->P_MIN,
&l_pSegment->P_MAX,
&l_pSegment->OFFSET);
} else {
XYYWindowToReal(l_pSignal->WIN,
i_pDataBase,
&l_pSegment->OFFSET,
&l_pSegment->P_MIN,
&l_pSegment->P_MAX);
}
}
// CON
for (l_pCon = l_pSignal->CON_LIST; l_pCon;
l_pCon = l_pCon->NEXT) {
for (l_pVirCon = l_pCon->VIR_CON_LIST; l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
XYWindowToReal(l_pSignal->WIN, i_pDataBase,
&l_pVirCon->X, &l_pVirCon->Y);
}
}
}
}
}
/**
* transforme les connecteurs virtuels en position absolue
**/
void translatingRealToWindows(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt i;
ocrConnector *l_pCon;
ocrVirtualConnector *l_pVirCon;
for (i = 0; i <= i_pDataBase->NB_GSIGNAL - 1; i++) {
for (l_pCon = i_pDataBase->GSIGNAL[i]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT) {
for (l_pVirCon = l_pCon->VIR_CON_LIST;
l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
XYRealToWindow(l_pCon->WIN, i_pDataBase, &l_pVirCon->X,
&l_pVirCon->Y);
}
}
}
}
/**
* initialisation des fenetres
**/
void initWindow(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt i, l_uFace, l_uRange;
ocrNaturalInt x, y;
i_pDataBase->WINDOWS =
(ocrWindow **) mbkalloc((i_pDataBase->NB_F + 1) *
sizeof(ocrWindow *));
// création des fenetres
for (i = 0; i <= i_pDataBase->NB_F; i++)
i_pDataBase->WINDOWS[i] = newWindow(i);
// affectation des coordonnées des fenetres pour respecter les rangées
// l_uRange = nb de rangées
// l_uFace = nb de fenetres par faces
l_uFace = sqrt(i_pDataBase->NB_F);
l_uRange = (i_pDataBase->YAB2 - i_pDataBase->YAB1) / 500 / 10;
display(LEVEL, VERBOSE, "o Layout has %ld rows\n", l_uRange);
for (y = 1; y <= l_uFace; y++) {
for (x = 1; x <= l_uFace; x++) {
i = (y - 1) * l_uFace + x;
i_pDataBase->WINDOWS[i]->XMIN =
(x - 1) * (i_pDataBase->XAB2 -
i_pDataBase->XAB1) / 500.0 / (l_uFace);
i_pDataBase->WINDOWS[i]->XMAX =
x * (i_pDataBase->XAB2 -
i_pDataBase->XAB1) / 500.0 / (l_uFace) - 0;
i_pDataBase->WINDOWS[i]->YMIN =
10 * (int) ((y - 1) *
((double) l_uRange / (double) l_uFace));
i_pDataBase->WINDOWS[i]->YMAX =
10 * (int) (y * ((double) l_uRange / (double) l_uFace)) -
0;
}
}
}
/**
* Attribue à chaque connecteur externe sa Window
**/
void computeExternalConnector(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt l_uWin;
ocrConnector *l_pCon, *l_pConExt, *l_pBetterCon;
ocrNaturalInt i, j, k;
// Recherche de la meilleure Window.
// Window en bordure qui contient un connecteur INTERNE
// ou une Window en bordure la plus proche possible d'une autre Window
for (k = 0; k <= i_pDataBase->NB_GSIGNAL - 1; k++) {
//printf (" o treating signal: %s\n", i_pDataBase->GSIGNAL[k]->NAME);
l_pConExt = NULL;
l_pBetterCon = NULL;
// Si le signal est EXTERNE
if (i_pDataBase->GSIGNAL[k]->INTEXT == EXTERNAL) {
for (l_pCon = i_pDataBase->GSIGNAL[k]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT)
// Si le connecteur est interne
if (l_pCon->INTEXT == INTERNAL) {
// Si la Window est en bordure
if (isABorderWindow(i_pDataBase, l_pCon->WIN))
l_pBetterCon = l_pCon;
} else
l_pConExt = l_pCon;
if (l_pBetterCon) {
l_pConExt->WIN = l_pBetterCon->WIN;
getFace(i_pDataBase, l_pConExt);
} else {
ocrNaturalInt l_uNbf = sqrt(i_pDataBase->NB_F);
ocrNaturalInt l_uDistMin = OCRNATURALINT_MAX;
ocrNaturalInt l_uDist;
//printf("signal %ld\n", i_pDataBase->GSIGNAL[k]->INDEX);
// parcours des Window en bordure pour déterminer
// la meilleure
for (i = 0; i <= l_uNbf; i++)
for (j = 0; j <= l_uNbf; j += l_uNbf) {
for (l_pCon = i_pDataBase->GSIGNAL[k]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT)
// Si le connecteur est interne
if (l_pCon->INTEXT == INTERNAL) {
ocrNaturalInt l_uX, l_uY;
WintoXY(i_pDataBase, &l_uX, &l_uY,
l_pCon->WIN);
l_uDist =
ABSDIFF(i, l_uX) + ABSDIFF(j, l_uY);
if (l_uDist < l_uDistMin) {
XYtoWin(i_pDataBase, i, j, &l_uWin);
l_uDistMin = l_uDist;
}
}
}
for (i = 0; i <= l_uNbf; i += l_uNbf)
for (j = 0; j <= l_uNbf; j++) {
for (l_pCon = i_pDataBase->GSIGNAL[k]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT)
// Si le connecteur est interne
if (l_pCon->INTEXT == INTERNAL) {
ocrNaturalInt l_uX, l_uY;
WintoXY(i_pDataBase, &l_uX, &l_uY,
l_pCon->WIN);
l_uDist =
ABSDIFF(i, l_uX) + ABSDIFF(j, l_uY);
if (l_uDist < l_uDistMin) {
XYtoWin(i_pDataBase, i, j, &l_uWin);
l_uDistMin = l_uDist;
}
}
}
l_pConExt->WIN = l_uWin;
getFace(i_pDataBase, l_pConExt);
}
}
}
}
/**
* Fenetrage
**/
void createWindow(ocrRoutingDataBase * i_pDataBase)
{
ocrNaturalInt i;
ocrNaturalInt l_uWindow;
ocrVirtualConnector *l_pVirCon;
ocrConnector *l_pCon;
initWindow(i_pDataBase);
// Calcul pour chaque connecteur INT sa fenetre
for (i = 0; i <= i_pDataBase->NB_GSIGNAL - 1; i++) {
if ((i_pDataBase->GSIGNAL[i]))
for (l_pCon = i_pDataBase->GSIGNAL[i]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT) {
//printf (" o treating signal %s\n", i_pDataBase->GSIGNAL[i]->NAME);
for (l_pVirCon = l_pCon->VIR_CON_LIST;
l_pVirCon;
l_pVirCon = (ocrVirtualConnector *) l_pVirCon->NEXT) {
computeVCWindow(i_pDataBase, l_pVirCon);
}
if ((l_pCon->INTEXT == INTERNAL)
&& (!isvdd(l_pCon->NAME))
&& (!isvss(l_pCon->NAME)))
computeCWindow(l_pCon);
}
}
// Calcul pour chaque connecteur EXT sa fenetre
computeExternalConnector(i_pDataBase);
// Calcul pour chaque signal sa fenetre
for (i = 0; i <= i_pDataBase->NB_GSIGNAL - 1; i++) {
l_uWindow = OCRNATURALINT_MAX;
for (l_pCon = i_pDataBase->GSIGNAL[i]->CON_LIST;
l_pCon; l_pCon = l_pCon->NEXT) {
// if (l_pCon->INTEXT == INTERNAL)
{
if (l_uWindow == OCRNATURALINT_MAX)
l_uWindow = l_pCon->WIN;
else {
if (l_uWindow != l_pCon->WIN)
l_uWindow = 0;
}
}
}
i_pDataBase->GSIGNAL[i]->WIN = l_uWindow;
}
// répartition des signaux locaux à une fenetre
initSignalList(i_pDataBase);
for (i = 0; i <= i_pDataBase->NB_GSIGNAL - 1; i++) {
insertSignalWindow(i_pDataBase, i_pDataBase->GSIGNAL[i]);
}
}
void
createWindowArray(ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uWinNum)
{
ocrNaturalInt n = 0;
ocrSignal *l_pSignal;
// création du tableau
i_pDataBase->SIGNAL = (ocrSignal **)
mbkalloc(i_pDataBase->WINDOWS[i_uWinNum]->NB_SIG *
sizeof(ocrSignal *));
// Mise à jour du tableau
i_pDataBase->NB_SIGNAL = i_pDataBase->WINDOWS[i_uWinNum]->NB_SIG;
for (l_pSignal = i_pDataBase->FSIGNAL[i_uWinNum];
l_pSignal; l_pSignal = l_pSignal->NEXT)
i_pDataBase->SIGNAL[n++] = l_pSignal;
}
void
deleteWindowArray(ocrRoutingDataBase * i_pDataBase,
ocrNaturalInt i_uWinNum)
{
mbkfree(i_pDataBase->SIGNAL);
i_pDataBase->SIGNAL = NULL;
}