outil pour faire grossir les partilles de via

This commit is contained in:
Franck Wajsburt 2002-04-18 19:48:37 +00:00
parent b26da82338
commit d7c1096ac5
4 changed files with 599 additions and 0 deletions

View File

@ -0,0 +1,12 @@
## Process this file with automake to produce Makefile.in
bin_PROGRAMS = growstk
AM_CFLAGS = @ALLIANCE_CFLAGS@
growstk_LDADD = @ALLIANCE_LIBS@ \
-lMpu -lMcp -lMap -lMmg \
-lRtl -lRgs -lRcf -lRfm -lRpr -lRwi -lRut -lRds\
-lMph -lMut
growstk_SOURCES = hash.h hash.c growstk.c

View File

@ -0,0 +1,443 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <getopt.h>
#include "hash.h"
#include "mph.h"
#include "mpu.h"
#include "mut.h"
#include "rds.h"
#include "rfm.h"
#include "rpr.h"
#include "rwi.h"
#include "rut.h"
#include "rtl.h"
#define NEED_PATCH 0x08000000
#define NEED_PATCH_MASK 0x08000000
#define OBSTACLE_NORTH 0x80000000
#define OBSTACLE_SOUTH 0x40000000
#define OBSTACLE_EAST 0x20000000
#define OBSTACLE_WEST 0x10000000
#define OBSTACLE_MASK 0xF0000000
#define SetRdsNeedPatch(R) ((R)->FLAGS = ((R)->FLAGS | NEED_PATCH_MASK))
#define IsRdsNeedPatch(R) ((R)->FLAGS & NEED_PATCH_MASK)
#define SetRdsObstacle(R,O) ((R)->FLAGS = (R)->FLAGS | (O))
#define IsRdsObstacle(R) ((R)->FLAGS & OBSTACLE_MASK)
#define rds2mbklayer(L) (((L)==RDS_ALU2) ? ALU2 :\
((L)==RDS_ALU3) ? ALU3 :\
((L)==RDS_ALU4) ? ALU4 :\
((L)==RDS_ALU5) ? ALU5 :\
((L)==RDS_ALU6) ? ALU6 :0)
/* return 1 if r1 and r2 are in touch
*/
int RecInTouch (rdsrec_list * r1, rdsrec_list * r2)
{
if ( ( ((r2->X >= r1->X) && ((r2->X) <= (r1->X + r1->DX)))
|| ((r2->X <= r1->X) && ((r2->X + r2->DX) >= (r1->X)))
)
&& ( ((r2->Y >= r1->Y) && ((r2->Y) <= (r1->Y + r1->DY)))
|| ((r2->Y <= r1->Y) && ((r2->Y + r2->DY) >= (r1->Y)))
)
)
return 1;
return 0;
}
long verbose = 1;
void usage (char *av[])
{
printf ("Usage : %s [-h] [-v level] [-o OutFile] InFile\n\n", av[0]);
printf (" -h this help\n");
printf (" -v verbose mode (level is 1:2:3:4)\n");
printf (" -o define the output file (InFile by default)\n");
printf (" InFile define the input file\n");
printf ("\n uses only symbolic technology file !!!\n");
printf ("\n");
exit (1);
}
void getoption (int ac, char *av[], char **OutFile, char **InFile)
{
char option;
while ((option = getopt (ac, av, "hv:o:")) != EOF)
{
switch (option)
{
case 'v':
verbose = *optarg - '0';
if ((verbose < 0) || (verbose > 9))
usage (av);
break;
case 'o':
*OutFile = namealloc (optarg);
break;
default:
usage (av);
}
}
if (optind == ac - 1)
{
*InFile = namealloc (av[optind]);
}
else
usage (av);
}
#define NbLayerList 5
#define EquivNbLayerList 2
int main (int ac, char *av[])
{
char *InFile, *OutFile;
phfig_list *PhFig;
phseg_list *PhSeg;
phvia_list *PhVia;
rdsfig_list *RdsFig;
rdswindow *Window;
long WX, WY, Offset, Pitch, BorderX, BorderY;
rdswin_list *Win;
rdswinrec_list *WinRec;
rdsrec_list *NewRec = NULL;
rdsrec_list *ScanRec, *WinScanRec;
rdsrec_list *RecNorth, *RecSouth, *RecEast, *RecWest;
int Layer, WinLayer;
int LayerIdx, WinLayerIdx;
int MinLayerArea[NbLayerList] =
{ 2, // Alu2
2, // Alu3
2, // Alu4
2, // Alu5
2}; // Alu6
int LayerList[NbLayerList][EquivNbLayerList] =
{{RDS_LAYER_ALU2, RDS_LAYER_TALU2},
{RDS_LAYER_ALU3, RDS_LAYER_TALU3},
{RDS_LAYER_ALU4, RDS_LAYER_TALU4},
{RDS_LAYER_ALU5, RDS_LAYER_TALU5},
{RDS_LAYER_ALU6, RDS_LAYER_TALU6}};
int Index;
ht_t *dejavu = htinit (63179);
char buffer[1000];
/* read parameters & environment */
mbkenv ();
rdsenv ();
loadrdsparam ();
if (RDS_LAMBDA/RDS_UNIT != 1) usage (av);
Pitch = 5 * RDS_LAMBDA;
getoption (ac, av, &OutFile, &InFile);
if (verbose != 0)
alliancebanner ("GrowStk", VERSION, "grows the stacked vias", "2002", ALLIANCE_VERSION);
/* read files and buids mbk & rds structures */
PhFig = getphfig (InFile, 'A');
PhFig -> NAME = namealloc (OutFile);
RdsFig = addrdsfig (InFile, 0);
for (PhSeg = PhFig->PHSEG; PhSeg; PhSeg = PhSeg->NEXT)
segmbkrds (RdsFig, PhSeg, 0);
for (PhVia = PhFig->PHVIA; PhVia; PhVia = PhVia->NEXT)
viambkrds (RdsFig, PhVia, 0);
RecNorth = allocrdsrec(0);
RecSouth = allocrdsrec(0);
RecEast = allocrdsrec(0);
RecWest = allocrdsrec(0);
/* build windows */
Window = buildrdswindow (RdsFig);
for (LayerIdx = 0; LayerIdx < NbLayerList; LayerIdx++)
{
int first = 1;
Layer = RDS_DYNAMIC_LAYER[LayerList[LayerIdx][0]];
if (RdsFig->LAYERTAB)
{
for (ScanRec=RdsFig->LAYERTAB[Layer]; ScanRec; ScanRec = ScanRec->NEXT)
{
if (ScanRec == NULL) break;
if ((ScanRec->DX > RDS_LAMBDA * MinLayerArea[LayerIdx])
|| (ScanRec->DY > RDS_LAMBDA * MinLayerArea[LayerIdx]))
continue;
if (verbose > 3)
{
if (first) printf ("LAYER = %s\n", RDS_LAYER_NAME[Layer]);
printf ("X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f\n",
(float)ScanRec->X/RDS_UNIT, (float)ScanRec->Y/RDS_UNIT,
(float)ScanRec->DX/RDS_UNIT, (float)ScanRec->DY/RDS_UNIT);
first = 0;
}
/* there is a small square of metal */
/* scan all rectangles of the current window */
WX = ScanRec->X / Window->SIDE;
WY = ScanRec->Y / Window->SIDE;
if (verbose > 2) printf (" WINDOW (%ld,%ld)\n", WX, WY);
Offset = (WY) * Window->DX + (WX);
Win = Window->WINTAB + Offset;
{
int first = 1;
for (WinLayerIdx = 0; WinLayerIdx < EquivNbLayerList; WinLayerIdx++)
{
WinLayer = RDS_DYNAMIC_LAYER[LayerList[LayerIdx][WinLayerIdx]];
for (WinRec = Win->LAYERTAB[WinLayer]; WinRec != (rdswinrec_list *) NULL; WinRec = WinRec->NEXT)
{
for (Index = 0; Index < RWI_MAX_REC; Index++)
{
WinScanRec = WinRec->RECTAB[Index];
if (WinScanRec == NULL) break;
if ( (ScanRec->X == WinScanRec->X)
&& (ScanRec->Y == WinScanRec->Y)
&& (ScanRec->DX == WinScanRec->DX)
&& (ScanRec->DY == WinScanRec->DY)
)
continue;
if (RecInTouch (ScanRec, WinScanRec))
{
if (verbose > 3) printf (" abort\n");
goto in_touch;
}
if (verbose > 3)
{
if (first) printf (" NLAYER = %s\n", RDS_LAYER_NAME[WinLayer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f\n",
(float)WinScanRec->X/RDS_UNIT, (float)WinScanRec->Y/RDS_UNIT,
(float)WinScanRec->DX/RDS_UNIT, (float)WinScanRec->DY/RDS_UNIT);
first = 0;
}
}
}
}
}
if (verbose > 3) printf (" need patch\n");
SetRdsNeedPatch (ScanRec);
RecNorth->X = ScanRec->X; RecNorth->DX = ScanRec->DX; RecNorth->Y = ScanRec->Y; RecNorth->DY = ScanRec->DY + Pitch;
RecSouth->X = ScanRec->X; RecSouth->DX = ScanRec->DX; RecSouth->Y = ScanRec->Y - Pitch; RecSouth->DY = ScanRec->DY + Pitch;
RecEast->X = ScanRec->X - Pitch; RecEast->DX = ScanRec->DX + Pitch; RecEast->Y = ScanRec->Y; RecEast->DY = ScanRec->DY;
RecWest->X = ScanRec->X; RecWest->DX = ScanRec->DX + Pitch; RecWest->Y = ScanRec->Y; RecWest->DY = ScanRec->DY;
for (BorderX = -1; BorderX < 1; BorderX++)
{
if (BorderX+WX == -1) continue;
if (BorderX+WX == Window->DX +1) continue;
for (BorderY = -1; BorderY < 1; BorderY++)
{
if (BorderY+WY == -1) continue;
if (BorderY+WY == Window->DY +1) continue;
if (verbose > 2) printf (" NEIGHBOUR WINDOW (%ld,%ld)\n", WX+BorderX, WY+BorderY);
Offset = (WY+BorderY) * Window->DX + (WX+BorderX);
Win = Window->WINTAB + Offset;
if (Win->LAYERTAB>(void *)0x1000) // j'ai l'impression que les fenetres ne sont pas initialisées à 0.
{
for (WinLayerIdx = 0; WinLayerIdx < EquivNbLayerList; WinLayerIdx++)
{
int first = 1;
WinLayer = RDS_DYNAMIC_LAYER[LayerList[LayerIdx][WinLayerIdx]];
for (WinRec = Win->LAYERTAB[WinLayer]; WinRec != (rdswinrec_list *) NULL; WinRec = WinRec->NEXT)
{
for (Index = 0; Index < RWI_MAX_REC; Index++)
{
WinScanRec = WinRec->RECTAB[Index];
if (WinScanRec == NULL) break;
if ( (ScanRec->X == WinScanRec->X)
&& (ScanRec->Y == WinScanRec->Y)
&& (ScanRec->DX == WinScanRec->DX)
&& (ScanRec->DY == WinScanRec->DY)
)
continue;
if (RecInTouch (RecNorth, WinScanRec))
{
SetRdsObstacle(ScanRec,OBSTACLE_NORTH);
if (verbose > 3)
{
if (first) printf (" NLAYER = %s\n", RDS_LAYER_NAME[WinLayer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f is an obstacle north\n",
(float)WinScanRec->X/RDS_UNIT, (float)WinScanRec->Y/RDS_UNIT,
(float)WinScanRec->DX/RDS_UNIT, (float)WinScanRec->DY/RDS_UNIT);
first = 0;
}
}
if (RecInTouch (RecSouth, WinScanRec))
{
SetRdsObstacle(ScanRec,OBSTACLE_SOUTH);
if (verbose > 3)
{
if (first) printf (" NLAYER = %s\n", RDS_LAYER_NAME[WinLayer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f is an obstacle south\n",
(float)WinScanRec->X/RDS_UNIT, (float)WinScanRec->Y/RDS_UNIT,
(float)WinScanRec->DX/RDS_UNIT, (float)WinScanRec->DY/RDS_UNIT);
first = 0;
}
}
if (RecInTouch (RecWest, WinScanRec))
{
SetRdsObstacle(ScanRec,OBSTACLE_WEST);
if (verbose > 3)
{
if (first) printf (" NLAYER = %s\n", RDS_LAYER_NAME[WinLayer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f is an obstacle west\n",
(float)WinScanRec->X/RDS_UNIT, (float)WinScanRec->Y/RDS_UNIT,
(float)WinScanRec->DX/RDS_UNIT, (float)WinScanRec->DY/RDS_UNIT);
first = 0;
}
}
if (RecInTouch (RecEast, WinScanRec))
{
SetRdsObstacle(ScanRec,OBSTACLE_EAST);
if (verbose > 3)
{
if (first) printf (" NLAYER = %s\n", RDS_LAYER_NAME[WinLayer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f is an obstacle east\n",
(float)WinScanRec->X/RDS_UNIT, (float)WinScanRec->Y/RDS_UNIT,
(float)WinScanRec->DX/RDS_UNIT, (float)WinScanRec->DY/RDS_UNIT);
first = 0;
}
}
}
}
}
}
}
}
in_touch :
}
}
}
if (verbose > 1)
printf ("Segments that need patches :\n");
for (LayerIdx = 0; LayerIdx < NbLayerList; LayerIdx++)
{
int first = 1;
Layer = RDS_DYNAMIC_LAYER[LayerList[LayerIdx][0]];
for (ScanRec=RdsFig->LAYERTAB[Layer]; ScanRec; ScanRec = ScanRec->NEXT)
{
if (IsRdsNeedPatch(ScanRec))
{
rdsrec_list * rec;
sprintf (buffer, "%d %d %d %d %d",
ScanRec->X, ScanRec->Y, ScanRec->DX, ScanRec->DY, ScanRec->FLAGS);
if (!htget (dejavu, buffer))
{
htset (dejavu, buffer);
rec = allocrdsrec(0);
rec->NEXT = NewRec;
NewRec = rec;
NewRec->X = ScanRec->X;
NewRec->Y = ScanRec->Y;
NewRec->DX = ScanRec->DX;
NewRec->DY = ScanRec->DY;
NewRec->FLAGS = ScanRec->FLAGS;
NewRec->NAME = NULL;
NewRec->USER = NULL;
if (verbose > 1)
{
if (first) printf ("LAYER = %s\n", RDS_LAYER_NAME[Layer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f, OBS=%s%s%s%s\n",
(float)ScanRec->X/RDS_UNIT, (float)ScanRec->Y/RDS_UNIT,
(float)ScanRec->DX/RDS_UNIT, (float)ScanRec->DY/RDS_UNIT,
(IsRdsObstacle(ScanRec) & OBSTACLE_NORTH)?"NORTH ":"",
(IsRdsObstacle(ScanRec) & OBSTACLE_SOUTH)?"SOUTH ":"",
(IsRdsObstacle(ScanRec) & OBSTACLE_EAST)?"EAST ":"",
(IsRdsObstacle(ScanRec) & OBSTACLE_WEST)?"WEST ":""
);
first = 0;
}
if ((IsRdsObstacle(ScanRec) & OBSTACLE_NORTH) == 0)
{
NewRec->DY += Pitch;
}
else
if ((IsRdsObstacle(ScanRec) & OBSTACLE_EAST) == 0)
{
NewRec->DX += Pitch;
NewRec->X -= Pitch;
}
else
if ((IsRdsObstacle(ScanRec) & OBSTACLE_SOUTH) == 0)
{
NewRec->DY += Pitch;
NewRec->Y -= Pitch;
}
else
if ((IsRdsObstacle(ScanRec) & OBSTACLE_WEST) == 0)
{
NewRec->DX += Pitch;
}
else
{
if (first) printf ("LAYER = %s\n", RDS_LAYER_NAME[Layer]);
printf ("ERROR X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f CANNOT BE REPAIRED\n",
(float)ScanRec->X/RDS_UNIT, (float)ScanRec->Y/RDS_UNIT,
(float)ScanRec->DX/RDS_UNIT, (float)ScanRec->DY/RDS_UNIT);
first = 0;
}
}
else
{
if (verbose > 2)
{
printf ("DEJA VU : LAYER = %s ", RDS_LAYER_NAME[Layer]);
printf (" X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f, OBS=%s%s%s%s\n",
(float)ScanRec->X/RDS_UNIT, (float)ScanRec->Y/RDS_UNIT,
(float)ScanRec->DX/RDS_UNIT, (float)ScanRec->DY/RDS_UNIT,
(IsRdsObstacle(ScanRec) & OBSTACLE_NORTH)?"NORTH ":"",
(IsRdsObstacle(ScanRec) & OBSTACLE_SOUTH)?"SOUTH ":"",
(IsRdsObstacle(ScanRec) & OBSTACLE_EAST)?"EAST ":"",
(IsRdsObstacle(ScanRec) & OBSTACLE_WEST)?"WEST ":""
);
}
}
}
}
}
for (ScanRec=NewRec; ScanRec; ScanRec = ScanRec->NEXT)
{
char MbkLayer = rds2mbklayer(GetRdsLayer(ScanRec));
if (MbkLayer==0)
{
printf ("Internal error during the layer translation\n");
printf ("LAYER = %s X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f\n", RDS_LAYER_NAME[GetRdsLayer(ScanRec)],
(float)ScanRec->X/RDS_UNIT, (float)ScanRec->Y/RDS_UNIT,
(float)ScanRec->DX/RDS_UNIT, (float)ScanRec->DY/RDS_UNIT);
exit (1);
}
if (verbose > 1)
{
printf ("LAYER = %s X=%.2f, Y=%.2f, DX=%.2f, DY=%.2f\n", RDS_LAYER_NAME[GetRdsLayer(ScanRec)],
(float)ScanRec->X/RDS_UNIT, (float)ScanRec->Y/RDS_UNIT,
(float)ScanRec->DX/RDS_UNIT, (float)ScanRec->DY/RDS_UNIT);
}
if (ScanRec->DX < ScanRec->DY)
addphseg (PhFig, MbkLayer,
(SCALE_X * ScanRec->DX) / RDS_UNIT,
(SCALE_X * (ScanRec->X + ScanRec->DX / 2)) / RDS_UNIT ,
(SCALE_X * (ScanRec->Y + RDS_LAMBDA)) / RDS_UNIT ,
(SCALE_X * (ScanRec->X + ScanRec->DX / 2)) / RDS_UNIT ,
(SCALE_X * (ScanRec->Y + ScanRec->DY - RDS_LAMBDA)) / RDS_UNIT ,
NULL);
else
addphseg (PhFig, MbkLayer,
(SCALE_X * ScanRec->DY) / RDS_UNIT,
(SCALE_X * (ScanRec->X + RDS_LAMBDA)) / RDS_UNIT ,
(SCALE_X * (ScanRec->Y + ScanRec->DY / 2)) / RDS_UNIT ,
(SCALE_X * (ScanRec->X + ScanRec->DX - RDS_LAMBDA)) / RDS_UNIT ,
(SCALE_X * (ScanRec->Y + ScanRec->DY / 2)) / RDS_UNIT ,
NULL);
}
savephfig (PhFig);
return 0;
}

View File

@ -0,0 +1,107 @@
/*
* This file is part of the Alliance CAD System
* Copyright (C) Laboratoire LIP6 - Département ASIM
* Universite Pierre et Marie Curie
*
* Home page : http://www-asim.lip6.fr/alliance/
* E-mail support : mailto:alliance-support@asim.lip6.fr
*
* This progam is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Alliance VLSI CAD System is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the GNU C Library; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "hash.h"
static int primes[] = {
101, 223, 311, 419, 547, 659, 727, 877, 967,
1061, 2053, 3299, 4391, 5309, 6421, 7069, 8543, 9397,
10337, 20143, 32423, 43151, 52223, 63179, 0
};
void htremove (ht_t * htable)
{
int i;
for (i = 1; i < (int)htable[0]; i++)
freechain (htable[i]);
free (htable);
}
ht_t *htinit (int size)
{
int i;
ht_t *htable;
/* prend le premier nombre premier au dela de size */
for (i = 0; primes[i] && (size > primes[i]); i++);
if (primes[i] == 0)
{
fprintf (stderr, "Erreur : hash table trop grande (> %d)\n", primes[i - 1]);
exit (1);
}
size = primes[i];
if ((htable = calloc (size + 1, sizeof (chain_list *))) == NULL)
{
perror ("htinit");
exit (1);
}
htable[0] = (chain_list *) size; /* taille de la table dans premiere case */
return htable;
}
static int hash (ht_t * htable, char *key)
{
int alveole = 0;
int length = strlen (key);
int segment;
int l;
if ((key == NULL) || (length == 0))
{
fprintf (stderr, "Error : hash (NULL)\n");
exit (1);
}
for (l = 0; l < length; l += 2)
{
segment = 0xFFFF & ((key[l] << 8) | key[l + 1]);
alveole = alveole ^ ((segment << 1) | (segment >> 15));
}
alveole %= (int) htable[0]; /* htable[0] == la taille de la table */
return (alveole + 1); /* +1 car on ne doit rien mettre dans case 0 */
}
chain_list *htget (ht_t * htable, char *key)
{
int alveole = hash (htable, key);
chain_list *p;
for (p = htable[alveole]; p && strcmp (p->DATA, key); p = p->NEXT);
return p;
}
chain_list *htset (ht_t * htable, char *key)
{
int alveole = hash (htable, key);
chain_list *p;
for (p = htable[alveole]; p && strcmp (p->DATA, key); p = p->NEXT);
if (p)
return p;
htable[alveole] = addchain (htable[alveole], strdup (key));
return htable[alveole];
}

View File

@ -0,0 +1,37 @@
/*
* This file is part of the Alliance CAD System
* Copyright (C) Laboratoire LIP6 - Département ASIM
* Universite Pierre et Marie Curie
*
* Home page : http://www-asim.lip6.fr/alliance/
* E-mail support : mailto:alliance-support@asim.lip6.fr
*
* This progam is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Alliance VLSI CAD System is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the GNU C Library; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef HASH_H
#define HASH_H
#include <mut.h>
typedef chain_list *ht_t; /* def d'1 table de hachage table de htele_t */
extern ht_t *htinit (int size);
extern void htremove (ht_t * htable);
extern chain_list *htset (ht_t * htable, char *key);
extern chain_list *htget (ht_t * htable, char *key);
#endif