Ca roule.
This commit is contained in:
parent
bd71a62dc6
commit
f891c4a8e6
|
@ -0,0 +1,3 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = src doc
|
|
@ -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
|
||||
])
|
|
@ -0,0 +1,4 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
man_MANS = ocr.1
|
||||
EXTRA_DIST = $(man_MANS)
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = seg util rout
|
||||
|
||||
EXTRA_DIST = include/*.h
|
|
@ -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 *~
|
|
@ -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);
|
||||
}
|
|
@ -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_ */
|
|
@ -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_*/
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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);
|
||||
|
||||
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
*/
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue