diff --git a/alliance/src/autostuff b/alliance/src/autostuff index 53083ebd..ab37ac02 100755 --- a/alliance/src/autostuff +++ b/alliance/src/autostuff @@ -73,7 +73,7 @@ dirs="$newdirs documentation" order="mbk \ aut rds elp abl bdd log btr vex ctl ctp abe abt \ abv fsm fks fvh ftl rtn rtd scl vpn vbh pat gcp \ - druc beh bhl bvl" + druc beh bhl bvl gscr" ordered_dirs="" for lib in $order; do if echo "$dirs" | grep $lib > /dev/null ; then diff --git a/alliance/src/gscr/Makefile.am b/alliance/src/gscr/Makefile.am new file mode 100644 index 00000000..9dd5545d --- /dev/null +++ b/alliance/src/gscr/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = src diff --git a/alliance/src/gscr/configure.in b/alliance/src/gscr/configure.in new file mode 100644 index 00000000..c81cabb6 --- /dev/null +++ b/alliance/src/gscr/configure.in @@ -0,0 +1,30 @@ + +AC_INIT(src/apr.h) + +APR_CUR=1 +APR_REV=3 +APR_REL=0 + +APR_VERSION=$APR_CUR.$APR_REV +APR_DLL_VERSION=${APR_CUR}:${APR_REV}:${APR_REL} + +AC_SUBST(APR_CUR) +AC_SUBST(APR_REV) +AC_SUBST(APR_REL) +AC_SUBST(APR_DLL_VERSION) + +AM_INIT_AUTOMAKE(apr, $APR_VERSION) +AC_PROG_INSTALL +AC_PROG_CC +AC_HEADER_STDC +AC_C_CONST +AC_TYPE_SIGNAL +AC_FUNC_VFORK +AM_PROG_LIBTOOL + +AM_ALLIANCE + +AC_OUTPUT([ +Makefile +src/Makefile +]) diff --git a/alliance/src/gscr/src/Makefile.am b/alliance/src/gscr/src/Makefile.am new file mode 100644 index 00000000..3d126406 --- /dev/null +++ b/alliance/src/gscr/src/Makefile.am @@ -0,0 +1,19 @@ +AM_CFLAGS = @ALLIANCE_CFLAGS@ \ + -I$(top_srcdir)/mbk/src \ + -DMAXLINE=500 -DMAXCOL=1000 -O4 + +lib_LTLIBRARIES = libApr.la +include_HEADERS = apr.h + +libApr_la_SOURCES = gscr_greedy.h gscr_StaticUtil.h scp_inits.h scp_modif.h scp_time.h \ + gscr_AllowFree.c gscr_GreedyRout.c gscr_SymbChanRout.c scp_main.c \ + scp_placer.c scp_types.h gscr_AllowFree.h gscr_GreedyRout.h \ + gscr_SymbChanRout.h scp_main.h scp_placer.h sx2sc.c gscr_DataBase.h \ + scp_channel.c scp_mbk2scp.c scp_scp2mbk.c gscr_DynamicUtil.c \ + gscr_main.h scp_channel.h scp_mbk2scp.h scp_scp2mbk.h gscr_DynamicUtil.h \ + gscr_StaticUtil.c scp_inits.c scp_modif.c scp_time.c + +#libApr_la_LDFLAGS = -version-info @APR_DLL_VERSION@ + +libApr_la_LIBADD = -lMut -lMph -lMlo + diff --git a/alliance/src/gscr/src/apr.h b/alliance/src/gscr/src/apr.h new file mode 100644 index 00000000..59f064cd --- /dev/null +++ b/alliance/src/gscr/src/apr.h @@ -0,0 +1,170 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Automatic Router and Placer library */ +/* File : @(#) */ +/* Contents : */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : El housseine REJOUAN Date : 06/10/1993 */ +/* Modified by : Date : ../../.... */ +/* Modified by : Date : ../../.... */ +/* Modified by : Date : ../../.... */ +/* */ +/******************************************************************************/ + +/*############################################################################*/ +/* Symbolic Channel Router */ +/*############################################################################*/ +# define BOOLEAN int +# define NONET ((long ) 0) +# define PITCH_X ((long )(/*6*/5 * SCALE_X)) +# define PITCH_Y ((long )(5 * SCALE_X)) +# define NORTHOFFSET ((long )((L3MODE?5:4) * SCALE_X)) +# define SOUTHOFFSET ((long )((L3MODE?0:4) * SCALE_X)) +# define WESTOFFSET (PITCH_X /* / 2 */) +# define EASTOFFSET (0 /* PITCH_X / 2 */) +# define LAYER1WIDTH ((long) 2 * SCALE_X) +# define LAYER2WIDTH ((long) 2 * SCALE_X) + +/******************************************************************************/ +typedef struct SCR_ConnectorList + { + struct SCR_ConnectorList *NextCon; + long ConName ;/* index signal */ + long Mark ;/* number of the column */ + }ConnectorList; + +typedef struct SCR_SegmentList + { + struct SCR_SegmentList *NextSeg; + char *SegName; + long X1Seg ; + long Y1Seg ; + long X2Seg ; + long Y2Seg ; + }SegmentList; + +typedef struct SCR_ViasList + { + struct SCR_ViasList *NextVia; + long XVia ; + long YVia ; + } ViasList; + +/******************************************************************************/ +extern BOOLEAN SymbolicChannelRouter(); + +/*############################################################################*/ +/* Symbolic Placer */ +/*############################################################################*/ + +typedef struct CaracCon + { + struct CaracCon *NEXT; + char *NAME; /* nom du connecteur a place */ + long USER; /* ordre du connecteur a place sur une */ + /* face donnee (concerne pour scr) */ + /* numero du slice dans lequel le */ + /* connecteur doit etre place (concerne */ + /* pour dpr) */ + } CaracConList; + +typedef struct PlaceCon + { + CaracConList *NORTH_CON; + CaracConList *SOUTH_CON; + CaracConList *WEST_CON; + CaracConList *EAST_CON; + long VER_FEED; /* pour scr, ce champs designe le nombre de transparences verticales */ + long HOR_FEED; /* pour scr, ce champs designe le nombre de transparences horizontales */ + } PlaceConList; + +/*---------------------------------------------------------\ + includes +\---------------------------------------------------------*/ +#include +#include +#include + +/*---------------------------------------------------------\ + typedefs +\---------------------------------------------------------*/ +typedef struct cell_struct +{ + struct cell *cell; + struct cell_struct *next; +} cells_of_net; +typedef struct +{ + long coeff; + cells_of_net *first; +} net_list; + +typedef struct net_struct +{ + net_list *net; + struct net_struct *next; +} nets_of_cell; +typedef struct cell +{ + struct cell *next; + struct cell *prev; + int width; + int x; + int y; + int row; + loins_list *ins; + void *first; +} cell_list; + +typedef struct +{ + cell_list *head; + cell_list *tail; + long length; +} row_elt; + +typedef struct +{ + row_elt *Rows; + long NbRows; + cell_list *Cells; + long NbCells; +} placement_fig; + +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +extern void sx2sc (); +extern placement_fig *Place(); +extern phfig_list *OpenVerticalChannel(); + +/*############################################################################*/ diff --git a/alliance/src/gscr/src/gscr_AllowFree.c b/alliance/src/gscr/src/gscr_AllowFree.c new file mode 100644 index 00000000..fe77a953 --- /dev/null +++ b/alliance/src/gscr/src/gscr_AllowFree.c @@ -0,0 +1,314 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* STANDARD CELLS ROUTER */ +/* FILE : SCR_AllowFree.c LAST MODIFICATION : JUL/8/1991 */ +/******************************************************************************/ + +# include "gscr_DataBase.h" +# include "apr.h" +# include +# include +# include + +/******************************************************************************/ +/* ALLOCATION D'UNE PISTE */ +/******************************************************************************/ +StaticPoint *SCR_AllowOneTrack(Width) + +long Width; + +{ + StaticPoint *LeadTrack = NULL; + StaticPoint *CurrentPoint = NULL; + StaticPoint *PrevCurrentPoint = NULL; + long Size = 0; + + LeadTrack = (StaticPoint *) mbkalloc (sizeof(StaticPoint)); + LeadTrack->NextPoint = NULL; + LeadTrack->RightPoint = NULL; + LeadTrack->PointName = ((long ) 0); + LeadTrack->Via = FALSE; + LeadTrack->Layer1 = NOP; + LeadTrack->Layer2 = NOP; + PrevCurrentPoint = LeadTrack; + for (Size = 1; Size < Width; Size++) { + CurrentPoint = (StaticPoint *) mbkalloc (sizeof(StaticPoint)); + PrevCurrentPoint->RightPoint = CurrentPoint; + PrevCurrentPoint = CurrentPoint; + CurrentPoint->NextPoint = NULL; + CurrentPoint->RightPoint = NULL; + CurrentPoint->PointName = ((long ) 0); + CurrentPoint->Via = FALSE; + CurrentPoint->Layer1 = NOP; + CurrentPoint->Layer2 = NOP; + } + return(LeadTrack); +} + +/******************************************************************************/ +/* ALLOCATION D'UN ENSEMBLE DE PISTES */ +/******************************************************************************/ +StaticPoint *SCR_AllowSetTrack(Density, Width) + +long Density; +long Width; + +{ + StaticPoint *LeadSetTrack = NULL; + StaticPoint *CurrentTrack = NULL; + StaticPoint *NewTrack = NULL; + StaticPoint *PrevCurrentTrack = NULL; + long Size = 0; + + LeadSetTrack = SCR_AllowOneTrack(Width); + PrevCurrentTrack = LeadSetTrack; + for (Size = 1; Size < Density; Size++) { + for (NewTrack = CurrentTrack = SCR_AllowOneTrack(Width); CurrentTrack; + CurrentTrack = CurrentTrack->RightPoint, + PrevCurrentTrack = PrevCurrentTrack->RightPoint) + PrevCurrentTrack->NextPoint = CurrentTrack; + PrevCurrentTrack = NewTrack; + } + return(LeadSetTrack); +} + +/******************************************************************************/ +/* ALLOCATION DE COLONNE SANS POINTs */ +/******************************************************************************/ +StaticColumn *SCR_AllowColumn(Width) + +long Width; + +{ + StaticColumn *LeadColumn = NULL; + StaticColumn *CurrentColumn = NULL; + StaticColumn *PrevCurrentColumn = NULL; + long Size = 0; + + LeadColumn = (StaticColumn *) mbkalloc (sizeof(StaticColumn)); + LeadColumn->NextCol = NULL; + LeadColumn->PrevCol = NULL; + LeadColumn->NorthCon = ((long ) 0); + LeadColumn->SouthCon = ((long ) 0); + LeadColumn->PointList = NULL; + PrevCurrentColumn = LeadColumn; + for (Size = 1; Size < Width ; Size++) { + CurrentColumn = (StaticColumn *) mbkalloc (sizeof(StaticColumn)); + PrevCurrentColumn->NextCol = CurrentColumn; + CurrentColumn->PrevCol = PrevCurrentColumn; + PrevCurrentColumn = CurrentColumn; + CurrentColumn->NextCol = NULL; + CurrentColumn->NorthCon = ((long ) 0); + CurrentColumn->SouthCon = ((long ) 0); + CurrentColumn->PointList = NULL; + } + return(LeadColumn); +} + +/******************************************************************************/ +/* ALLOCATION D'UN CANAL */ +/******************************************************************************/ +StaticColumn *SCR_AllowChannel(LeadStaticDataBase, Density, Width) + +StaticColumn *LeadStaticDataBase; +long Density; +long Width; + +{ + StaticColumn *CurrentColumn = NULL; + StaticPoint *CurrentSetTrack = NULL; + + CurrentSetTrack = SCR_AllowSetTrack(Density, Width); + for (CurrentColumn = LeadStaticDataBase; CurrentColumn; + CurrentColumn = CurrentColumn->NextCol, + CurrentSetTrack = CurrentSetTrack->RightPoint) + CurrentColumn->PointList = CurrentSetTrack; + return(LeadStaticDataBase); +} + +/*----------------------------------------------------------------------------*/ +/* Les fonctions d'allocation suivantes seront utlisees au cas ou */ +/* il faut ajouter une nouvelle colonne */ +/*----------------------------------------------------------------------------*/ +/******************************************************************************/ +/* ALLOCATION D'UNE LISTE DE POINTs */ +/******************************************************************************/ +StaticPoint *SCR_AllowStaticPoint(Density) + +long Density; + +{ + StaticPoint *LeadStaticPoint = NULL; + StaticPoint *CurrentPoint = NULL; + StaticPoint *PrevCurrentPoint = NULL; + long Size = 0; + + LeadStaticPoint = (StaticPoint *) mbkalloc (sizeof(StaticPoint)); + LeadStaticPoint->NextPoint = NULL; + LeadStaticPoint->RightPoint = NULL; + LeadStaticPoint->PointName = ((long ) 0); + LeadStaticPoint->Via = FALSE; + LeadStaticPoint->Layer1 = NOP; + LeadStaticPoint->Layer2 = NOP; + PrevCurrentPoint = LeadStaticPoint; + for (Size = 1; Size < Density; Size++) { + CurrentPoint = (StaticPoint *) mbkalloc (sizeof(StaticPoint)); + PrevCurrentPoint->NextPoint = CurrentPoint; + PrevCurrentPoint = CurrentPoint; + CurrentPoint->NextPoint = NULL; + CurrentPoint->RightPoint = NULL; + CurrentPoint->PointName = ((long ) 0); + CurrentPoint->Via = FALSE; + CurrentPoint->Layer1 = NOP; + CurrentPoint->Layer2 = NOP; + } + return(LeadStaticPoint); +} + +/******************************************************************************/ +/* ALLOCATION D'UNE COLONNE AVEC POINTs */ +/******************************************************************************/ +StaticColumn *SCR_AllowOneColumn(Density) + +long Density; +{ + StaticColumn *Column = NULL; + + Column = (StaticColumn *) mbkalloc (sizeof(StaticColumn)); + Column->NextCol = NULL; + Column->PrevCol = NULL; + Column->NorthCon = ((long ) 0); + Column->SouthCon = ((long ) 0); + Column->PointList = SCR_AllowStaticPoint(Density); + return(Column); +} + +/******************************************************************************/ +/* LIBERATION DE LA MEMOIRE */ +/******************************************************************************/ +void SCR_FreeDataBase(LeadDataBase) + +StaticColumn *LeadDataBase; + +{ + StaticColumn *CurrentColumn = NULL; + StaticColumn *AfterCurrentColumn = NULL; + StaticPoint *CurrentPoint = NULL; + StaticPoint *AfterCurrentPoint = NULL; + + CurrentColumn = LeadDataBase; + AfterCurrentColumn = LeadDataBase->NextCol; + while(CurrentColumn->NextCol) { + CurrentPoint = CurrentColumn->PointList; + AfterCurrentPoint = CurrentPoint->NextPoint; + while (CurrentPoint->NextPoint) { + mbkfree(((void * ) CurrentPoint)); + CurrentPoint = AfterCurrentPoint; + AfterCurrentPoint = CurrentPoint->NextPoint; + } + mbkfree(((void * ) CurrentPoint)); + mbkfree(((void * ) CurrentColumn)); + CurrentColumn = AfterCurrentColumn; + AfterCurrentColumn = CurrentColumn->NextCol; + } + mbkfree(((void * ) CurrentColumn)); +} + +/******************************************************************************/ +/* ALLOCATION MEMOIRE POUR LA LISTE DES SEGMENTs */ +/******************************************************************************/ +SegmentList *SCR_AllowSegmentList() + +{ + SegmentList *LeadSegmentList = NULL; + + LeadSegmentList = (SegmentList *) mbkalloc (sizeof(SegmentList)); + LeadSegmentList->NextSeg = NULL; + LeadSegmentList->SegName = '\0'; + LeadSegmentList->X1Seg = ((long ) 0); + LeadSegmentList->Y1Seg = ((long ) 0); + LeadSegmentList->X2Seg = ((long ) 0); + LeadSegmentList->Y2Seg = ((long ) 0); + return (LeadSegmentList); +} + +/******************************************************************************/ +/* ALLOCATION MEMOIRE POUR LA LISTE DES VIAs */ +/******************************************************************************/ +ViasList *SCR_AllowViasList() + +{ + ViasList *LeadViaList = NULL; + + LeadViaList = (ViasList *) mbkalloc (sizeof(ViasList)); + LeadViaList->NextVia = NULL; + LeadViaList->XVia = ((long ) 0); + LeadViaList->YVia = ((long ) 0); + return (LeadViaList); +} + +/******************************************************************************/ +/* FREE OF SEGMENT DATA BASE */ +/******************************************************************************/ +void SCR_FreeSegmentList(LeadSegList) + +SegmentList *LeadSegList; + +{ + SegmentList *CurrentSeg = NULL; + SegmentList *AfterCurrentSeg = NULL; + + CurrentSeg = LeadSegList; + AfterCurrentSeg = LeadSegList->NextSeg; + while (CurrentSeg->NextSeg) { + mbkfree(((void * ) CurrentSeg)); + CurrentSeg = AfterCurrentSeg; + AfterCurrentSeg = CurrentSeg->NextSeg; + } + mbkfree(((void * ) CurrentSeg)); +} + +/******************************************************************************/ +/* FREE OF VIA DATA BASE */ +/******************************************************************************/ +void SCR_FreeViasList(LeadViaList) + +ViasList *LeadViaList; + +{ + ViasList *CurrentVia = NULL; + ViasList *AfterCurrentVia = NULL; + + CurrentVia = LeadViaList; + AfterCurrentVia = LeadViaList->NextVia; + while(CurrentVia->NextVia) { + mbkfree(((void * ) CurrentVia)); + CurrentVia = AfterCurrentVia; + AfterCurrentVia = CurrentVia->NextVia; + } + mbkfree(((void *) CurrentVia)); +} + +/******************************************************************************/ diff --git a/alliance/src/gscr/src/gscr_AllowFree.h b/alliance/src/gscr/src/gscr_AllowFree.h new file mode 100644 index 00000000..fc7a30fd --- /dev/null +++ b/alliance/src/gscr/src/gscr_AllowFree.h @@ -0,0 +1,34 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +extern StaticPoint *SCR_AllowOneTrack(); +extern StaticPoint *SCR_AllowSetTrack(); +extern StaticColumn *SCR_AllowColumn(); +extern StaticColumn *SCR_AllowChannel(); +extern StaticPoint *SCR_AllowStaticPoint(); +extern StaticColumn *SCR_AllowOneColumn(); +extern void SCR_FreeDataBase(); +extern SegmentList *SCR_AllowSegmentList(); +extern ViasList *SCR_AllowViasList(); +extern void SCR_FreeSegmentList(); +extern void SCR_FreeViasList(); diff --git a/alliance/src/gscr/src/gscr_DataBase.h b/alliance/src/gscr/src/gscr_DataBase.h new file mode 100644 index 00000000..875ab3c5 --- /dev/null +++ b/alliance/src/gscr/src/gscr_DataBase.h @@ -0,0 +1,51 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +# define MAX(a,b) ((a>b) ? a:b) +# define BOOLEAN int +# define FALSE ((int ) 0) +# define TRUE ((int ) 1) +# define NOP ((char )'0') +# define HOR ((char )'H') +# define VER ((char )'V') + +typedef struct SCR_StaticPoint + { + struct SCR_StaticPoint *NextPoint ; + struct SCR_StaticPoint *RightPoint; + long PointName ; + BOOLEAN Via ; + char Layer1 ; + char Layer2 ; + }StaticPoint; + +typedef struct SCR_StaticColumn + { + struct SCR_StaticColumn *NextCol ; + struct SCR_StaticColumn *PrevCol ; + long NorthCon ; + long SouthCon ; + struct SCR_StaticPoint *PointList; + }StaticColumn; + + diff --git a/alliance/src/gscr/src/gscr_DynamicUtil.c b/alliance/src/gscr/src/gscr_DynamicUtil.c new file mode 100644 index 00000000..7568bc90 --- /dev/null +++ b/alliance/src/gscr/src/gscr_DynamicUtil.c @@ -0,0 +1,108 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* STANDARD CELLS ROUTER */ +/* FILE : DynamicUtility.c LAST MODIFICATION : JUL/16/1991 */ +/******************************************************************************/ + +# include +# include "gscr_DataBase.h" +# include "gscr_greedy.h" + +char car; +char string[10]; +int i=0; + +/******************************************************************************/ +/* LOAD DYNAMIC DATA BASE */ +/******************************************************************************/ +long U_ReadNumber(ptfich) + +FILE *ptfich; + +{ + long Number = 0; + i = 0; + car = getc(ptfich); + while ((car != ' ') && (car != ',') && (car != '}')) { + if (car != '\n') string[i++] = car; + car = getc(ptfich); + } + string[i] = '\0'; + Number = atol(string); + return (Number); +} +/******************************************************************************/ + +void U_GetDynamicDataBase(FichName, Density) + +char *FichName; +long Density; + +{ + long Line = 0; + FILE *ptfich; + + ptfich = fopen(FichName,"r"); + while ((car = getc(ptfich)) != '\n') string[i++] = car; + string[i] = '\0'; + for (; Line <= Density + 1; Line++) { + car = getc(ptfich); + PREVHNET(Line) = U_ReadNumber(ptfich); + HNET(Line) = U_ReadNumber(ptfich); + SPLIT(Line) = U_ReadNumber(ptfich); + SFRT(Line) = U_ReadNumber(ptfich); + VNET(Line) = U_ReadNumber(ptfich); + car = getc(ptfich); + } + fclose(ptfich); +} + +/******************************************************************************/ +/* PRINT COLUMN */ +/******************************************************************************/ +void U_PrintDynamicDataBase(Density) + +long Density; + +{ + long Column = 0; + long Line = 0; + printf(" P \n"); + printf(" R \n"); + printf(" E W \n"); + printf(" V S E C \n"); + printf(" H H P S I V O \n"); + printf(" N N L F G N M \n"); + printf(" E E I R H E B \n"); + printf(" T T T T T T I \n\n"); + + for (Line = 0; Line <= Density + 1; Line++) { + for (Column = 0; Column <= EndPattern; Column++) + printf("%2ld ", TabRout[Column][Line]); + printf("\n"); + } +} + +/******************************************************************************/ diff --git a/alliance/src/gscr/src/gscr_DynamicUtil.h b/alliance/src/gscr/src/gscr_DynamicUtil.h new file mode 100644 index 00000000..7e403eed --- /dev/null +++ b/alliance/src/gscr/src/gscr_DynamicUtil.h @@ -0,0 +1,26 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +extern long U_ReadNumber(); +extern void U_getDynamicDataBase(); +extern void U_PrintDynamicDataBase(); diff --git a/alliance/src/gscr/src/gscr_GreedyRout.c b/alliance/src/gscr/src/gscr_GreedyRout.c new file mode 100644 index 00000000..abda6b1c --- /dev/null +++ b/alliance/src/gscr/src/gscr_GreedyRout.c @@ -0,0 +1,1110 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* STANDARD CELLS ROUTER */ +/* FILE : SCR_GreedyRouter.c LAST MODIFICATION : JUL/11/1991 */ +/******************************************************************************/ + +# include +# include +# include +# include +# include "gscr_DataBase.h" +# include "gscr_greedy.h" +# include "gscr_SymbChanRout.h" +# include "gscr_DynamicUtil.h" + +long EndPattern = LEADPATTERN; +/******************************************************************************/ +/* SCR_SplitNet Modul of Initialisation */ +/******************************************************************************/ +void SCR_SplitNet(Density) + +long Density; + +{ + long Line = 0; + long Track = 0; + long Mark = 0; + long Counter = 0; + + for (Line = 1; Line <= Density; Line++) SPLIT(Line) = 0; + for (Line = 1; Line <= Density; Line++) + if ((HNET(Line) != 0) && (SPLIT(Line) == 0)) { + for (Track = Line, Counter = 0; Track <= Density; Track++) + if (HNET(Track) == HNET(Line)) Counter++; + for (Mark = Line; Mark <= Density; Mark++) + if (HNET(Mark) == HNET(Line)) + SPLIT(Mark) = Counter; + } +} + +/******************************************************************************/ +/* BELONG IN WINDOW */ +/******************************************************************************/ +BOOLEAN SCR_BelongInWindow(Element, LeadList, ControlCon) + +StaticColumn *LeadList; +long Element; +char ControlCon; + +{ + StaticColumn *CurrentColumn = NULL; + BOOLEAN Find = FALSE; + long ConName = 0; + long Counter = 0; + + for (CurrentColumn = LeadList; ((CurrentColumn) && (Counter <= SNC)); + Counter++, CurrentColumn = CurrentColumn->NextCol) { + if (ControlCon == 'N') ConName = CurrentColumn->NorthCon; + else ConName = CurrentColumn->SouthCon; + if (Element == ConName) { + Find = TRUE; + break; + } + } + return(Find); +} + +/******************************************************************************/ +/* TERMINAL, NON TERMINAL, STEADY, FALLING, RISING NET */ +/******************************************************************************/ +void SCR_SFRT_Net(Column, Density) + +StaticColumn *Column; +long Density; + +{ + StaticColumn *CurrentColumn = NULL; + long Line = 0; + BOOLEAN BelongNorth = FALSE; + BOOLEAN BelongSouth = FALSE; + BOOLEAN NonTerminalNet = FALSE; + + CurrentColumn = Column->NextCol; + for (Line = 1;Line <= Density; Line++) + if (HNET(Line) == 0) SFRT(Line) = TERMINAL; + else { + BelongNorth = SCR_BelongInWindow(HNET(Line), CurrentColumn, 'N'); + BelongSouth = SCR_BelongInWindow(HNET(Line), CurrentColumn, 'S'); + NonTerminalNet = (SCR_Belong(HNET(Line), CurrentColumn, NULL, 'N') || + SCR_Belong(HNET(Line), CurrentColumn, NULL, 'S')); + if (BelongNorth && BelongSouth) SFRT(Line) = STEADY; + else if ((!BelongNorth) && BelongSouth) SFRT(Line) = FALLING; + else if ((!BelongSouth) && BelongNorth) SFRT(Line) = RISING; + else if (NonTerminalNet) SFRT(Line) = NOTTERMINAL; + else SFRT(Line) = TERMINAL; + } +} + +/******************************************************************************/ +/* EVALUATION FUNCTION : WEIGHT */ +/******************************************************************************/ +void SCR_WeightTracks(Density) + +long Density; + +{ + long Line = 0; + long Weight = 0; + long Height = 0; + BOOLEAN Impaire = FALSE; + + Impaire = IMPAIRE(Density); + if (Impaire) Weight = Height = ((Density + 1) >> 1); + else { + Weight = (Density >> 1); + Height = (Density >> 1) + 1; + } + for (Line = 1; Line < Height ; Line++, Weight--) + WEIGHT(Line) = Weight; + if (!(Impaire)) Weight++; + for (; Line <= Density ; Line++, Weight++) + WEIGHT(Line) = Weight; +} + +/******************************************************************************/ +/* INSERT NEW LINE IN DYNAMIC DATA BASE */ +/******************************************************************************/ +void SCR_InsertNewLine(Position, Density) + +long Position; +long Density; + +{ + long Line = 0; + long Column = 0; + long NextLine = 0; + + for (Line = Density + 1; Line >= Position; Line--) { + NextLine = Line + 1; + for (Column = 0; Column <= EndPattern; Column++) + TabRout[Column][NextLine] = TabRout[Column][Line]; + } +} + +/******************************************************************************/ +/* UPDATE SFRT */ +/******************************************************************************/ +void SCR_UpDateSFRT(Column, Density) + +StaticColumn *Column; +long Density; + +{ + long MarkLine = 0; + long Line = 0; + long Track = 0; + + SCR_SplitNet(Density); + SCR_SFRT_Net(Column, Density); + SCR_WeightTracks(Density); + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(Density); +# endif + + for (Line = 1; Line <= Density; Line++) + if (SPLIT(Line) > 1) { + for (Track = Line + 1; ((Track <= Density) && (HNET(Track) != HNET(Line))); + Track++); + for (MarkLine = Line; ((MarkLine <= Track) && + (VNET(MarkLine) == (HNET(Line)))); MarkLine++); + if (SFRT(Line) == RISING) { + if (MarkLine > Track) { + SFRT(Track) = TERMINAL; + SPLIT(Track) = ((long ) 1); + if (SPLIT(Line) > 1) { + for (Track = Line + 1; ((Track <= Density) && + (HNET(Track) != HNET(Line))); Track++); + SPLIT(Track) = SPLIT(Line) - 2; + } + } + else SPLIT(Track) = --SPLIT(Line); + } + else + if (SFRT(Line) == FALLING) { + if (MarkLine > Track) { + SFRT(Line) = TERMINAL; + SPLIT(Track) = --SPLIT(Line); + SPLIT(Line) = ((long ) 1); + } + else SPLIT(Track) = --SPLIT(Line); + } + else + if (SFRT(Line) == TERMINAL) { + if (MarkLine <= Track) { + if (Track == Density + 1) Track--; + SFRT(Line) = SFRT(Track) = NOTTERMINAL; + for (MarkLine = Track; ((MarkLine <= Density) && + (VNET(MarkLine) == (HNET(Line)))); MarkLine++) + if (HNET(MarkLine) == HNET(Line)) SPLIT(MarkLine) = ((long ) 1); + } + else SPLIT(Track) = --SPLIT(Line); + } + else + if ((SFRT(Line) == STEADY) || (SFRT(Line) == NOTTERMINAL)) { + if (MarkLine > Track) + if (WEIGHT(Line) > WEIGHT(Track)) { + SFRT(Line) = TERMINAL; + SPLIT(Track) = --SPLIT(Line); + } + else { + SFRT(Track) = TERMINAL; + SPLIT(Track) = ((long ) 1); + } + else SPLIT(Track) = --SPLIT(Line); + } + } + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(Density); +# endif +} + +/******************************************************************************/ +/* UPDATE STATIC DATA BASE */ +/******************************************************************************/ +void SCR_UpDateDataBase(Column, Density) + +StaticColumn *Column; +long Density; + +{ + StaticPoint *CurrentPoint = NULL; + long Line = 0; + + + SCR_UpDateSFRT(Column, Density); + CurrentPoint = Column->PointList; + if (SCR_TOP != 0) { + CurrentPoint->PointName = SCR_TOP; + CurrentPoint->Via = FALSE; + CurrentPoint->Layer1 = NOP; + CurrentPoint->Layer2 = DOWN; + } + +# ifdef SCR_DEBUG + fprintf(stdout,"NorthCon = %ld \n",SCR_TOP); + fprintf(stdout,"Via = %d \t Layer1 = %c \t Layer2 = %c \t Name = %ld \n", + CurrentPoint->Via, CurrentPoint->Layer1, CurrentPoint->Layer2, + CurrentPoint->PointName); +# endif + + for (CurrentPoint = CurrentPoint->NextPoint, Line = 1; ((CurrentPoint) && + (Line <= Density)); CurrentPoint = CurrentPoint->NextPoint, Line++) { + CurrentPoint->PointName = HNET(Line); + if (HNET(Line) == 0) { + if ((PREVHNET(Line) == VNET(Line)) && (PREVHNET(Line) != 0)) { + CurrentPoint->Layer1 = LEFT; + CurrentPoint->Layer2 = NOP; + CurrentPoint->Via = TRUE; + } + } + else { + + /*-------------------------------------------------------*/ + /* TRAITEMENT DES LAYER1 */ + /*-------------------------------------------------------*/ + if (SFRT(Line) != TERMINAL) + if (HNET(Line) == PREVHNET(Line)) CurrentPoint->Layer1 = NOP; + else CurrentPoint->Layer1 = RIGHT; + else + if ((HNET(Line) == PREVHNET(Line)) || (VNET(Line) == PREVHNET(Line))) + CurrentPoint->Layer1 = LEFT; + /*-------------------------------------------------------*/ + /* TRAITEMENT DES VIAS */ + /*-------------------------------------------------------*/ + if (HNET(Line) == VNET(Line)) + if (SFRT(Line) == TERMINAL) + if (HNET(Line) == PREVHNET(Line)) CurrentPoint->Via = TRUE; + else CurrentPoint->Via = FALSE; + else CurrentPoint->Via = TRUE; + else + if (SFRT(Line) == TERMINAL) + if (VNET(Line) == PREVHNET(Line)) CurrentPoint->Via = TRUE; + /*-------------------------------------------------------*/ + /* TRAITEMENT DES LAYER2 */ + /*-------------------------------------------------------*/ + if (VNET(Line) != 0) + if (VNET(Line) == SCR_TOP) + if (VNET(Line) != VNET(Line + 1)) CurrentPoint->Layer2 = UP; + else CurrentPoint->Layer2 = NOP; + else /* # SCR_TOP */ + if (VNET(Line) == SCR_BOTTOM(Density + 1)) + if (VNET(Line) != VNET(Line - 1)) CurrentPoint->Layer2 = DOWN; + else CurrentPoint->Layer2 = NOP; + else /* # SCR_BOTTOM */ + if (VNET(Line) != VNET(Line - 1)) CurrentPoint->Layer2 = DOWN; + else + if (VNET(Line) != VNET(Line + 1)) CurrentPoint->Layer2 = UP; + else CurrentPoint->Layer2 = NOP; + } +# ifdef SCR_DEBUG + fprintf(stdout,"Via = %d \t Layer1 = %c \t Layer2 = %c \t Name = %ld \n", + CurrentPoint->Via, CurrentPoint->Layer1, CurrentPoint->Layer2, + CurrentPoint->PointName); +# endif + + } + if (SCR_BOTTOM(Density + 1) != 0) { + CurrentPoint->PointName = SCR_BOTTOM(Density + 1); + CurrentPoint->Via = FALSE; + CurrentPoint->Layer1 = NOP; + CurrentPoint->Layer2 = UP; + } + +# ifdef SCR_DEBUG + fprintf(stdout,"Via = %d \t Layer1 = %c \t Layer2 = %c \t Name = %ld \n", + CurrentPoint->Via, CurrentPoint->Layer1, CurrentPoint->Layer2, + CurrentPoint->PointName); + fprintf(stdout,"SouthCon = %ld \n",SCR_BOTTOM(Density + 1)); +# endif + +} + +/******************************************************************************/ +/* SCR_InitCombi Modul of Initialisation */ +/******************************************************************************/ +void SCR_InitCombi(Density) + +long Density; + +{ + long Column = LEADPATTERN; + long MarkLine = 1; + + for (MarkLine = 1; MarkLine <= (Density + 1) ; MarkLine++) + for (Column = LEADPATTERN; Column <= EndPattern; Column++) + COMBI(Column,MarkLine) = 0; + EndPattern = LEADPATTERN; +} + +/******************************************************************************/ +/* SCR_InitTabRout Modul of Initialisation */ +/******************************************************************************/ +void SCR_InitTabRout() +{ +long I=0; +long J=0; + +for (J = 0; J < MAXLINE; J++) { + for (I = 0; I < MAXCOL; I++) { + TabRout[I][J] = 0; + } +} +} + +/******************************************************************************/ +/* Step 1 : Make Feasible Top and Bottom Connetions : */ +/* for each pin connection existing at the column being processed, */ +/* connect it to an empty track or to a track occupied by the same net, */ +/* whichever uses the least vertical wire. If the channel is fully */ +/* occupied, bringing a new net is deferred until step 5. If two nets, */ +/* one from the bottom and one from the top, create a confilct due to */ +/* overlap,bring the one that uses the least wire, deferrin the other */ +/* until step 5. If there are no empty tracks, a vertical straight- */ +/* through connection is permissible. */ +/******************************************************************************/ +void Step1(Column, Density) + +StaticColumn *Column; +long Density; + +{ + long Track = 0; + long Line = 0; + long MarkLine = 0; + + for (Line = 0; Line <= (Density + 1); Line++) + VNET(Line) = ((long) 0); + + if (SCR_TOP == SCR_BOTTOM(Density + 1)) { + if (SCR_TOP != 0) { + for (Line = 1; ((HNET(Line) != 0) && (HNET(Line) != SCR_TOP) && + (Line <= Density)); Line++); + if (Line > Density) /* pas piste libre ni meme noeud */ + if (!(SCR_Belong(SCR_TOP, Column->NextCol, NULL, 'N') || + SCR_Belong(SCR_TOP, Column->NextCol, NULL, 'S'))) { /* noeud terminal */ + for (Line = 0; Line <= (Density + 1); Line++) + VNET(Line) = SCR_TOP; + TOPNOTROUT = FALSE; + BOTNOTROUT = FALSE; + } + else { /* on attend l'etape 5 */ + TOPNOTROUT = TRUE; + BOTNOTROUT = FALSE; + } + else { /* existance piste libre ou meme noeud */ + HNET(Line) = SCR_TOP; + for (Track = 0; Track <= Line; Track++) + VNET(Track) = SCR_TOP; + TOPNOTROUT = FALSE; + for (Line = Density; ((HNET(Line) != 0) && + (HNET(Line) != SCR_BOTTOM(Density + 1)) && (Line >= 1)); Line--); + HNET(Line) = SCR_BOTTOM(Density + 1); + for (Track = (Density + 1); Track >= Line; Track--) + VNET(Track) = SCR_BOTTOM(Density + 1); + BOTNOTROUT = FALSE; + } + } + else { /* Top = Bottom = 0 */ + TOPNOTROUT = FALSE; + BOTNOTROUT = FALSE; + } + } + else { /* Top != Bottom */ + if (SCR_TOP != 0) { + for (Line = 1; ((HNET(Line) != 0) && (HNET(Line) != SCR_TOP) && + (Line <= Density)); Line++); + if (Line > Density) TOPNOTROUT = TRUE; + else { + HNET(Line) = SCR_TOP; + for (Track = 0; Track <= Line; Track++) + VNET(Track) = SCR_TOP; + TOPNOTROUT = FALSE; + } + } + else TOPNOTROUT = FALSE; + + if (SCR_BOTTOM(Density + 1) != 0) { + for (MarkLine = Density; ((VNET(MarkLine) == 0) && (MarkLine >= 1)); + MarkLine--); + for (Line = Density; ((HNET(Line) != 0) && + (HNET(Line) != SCR_BOTTOM(Density + 1)) && (Line >= 1) + && (Line > MarkLine)); Line--); + if ((Line == 0) || (Line == MarkLine)) BOTNOTROUT = TRUE; + else { + HNET(Line) = SCR_BOTTOM(Density + 1); + for (Track = (Density + 1); Track >= Line; Track--) + VNET(Track) = SCR_BOTTOM(Density + 1); + BOTNOTROUT = FALSE; + } + } + else BOTNOTROUT = FALSE; + } +} + +/******************************************************************************/ +/* Step 2 : Free up As Many Tracks As Possible By Collapsing Split Nets */ +/* Collapse as many split nets as possible. This an important step in */ +/* the algorithm since it makes avaible to nets arriving at the */ +/* channel to the right. A collapsing segment is a piece of vertical */ +/* wire that connects two adjacent tracks occupied by the same net. */ +/* A pattern consists of a set of collapsing segments where the */ +/* segments for different nets do not overlap and no segment overlaps */ +/* the routing placed in step 1. Each collapsing segment has a weight */ +/* of either 1 or 2, depending on whether or not the net continues to */ +/* the right beyond the current column. The weight represents the */ +/* number of tracks freed due to collapse. The "winning" pattern is */ +/* found by a combinatrial search that maximizes the weighted sum. */ +/* If there is a tie, the pattern that leaves the outermost uncollapsed */ +/* split net as far as possible from the channel edge is chosen. The */ +/* idea is to keep the free area as close to the edges as possible. */ +/* If necessary, the second outermost net is considered, and so on. */ +/* If there are still remaining ties, use the pattern that maximizes */ +/* the amount of vertical wire. The idea is to minimize the adverse */ +/* effects on the future pattern due to large collapsing segments. */ +/* The lists of tracks occupied by a net are updateto reflect the */ +/* track merging for the pattern selected. If the collapsed track */ +/* continues to the right, it will do so along the track that is closest */ +/* to the target edge (the side of the channel where the next terminal */ +/* connection). */ +/******************************************************************************/ +void Step2(Column, Density) + +StaticColumn *Column; +long Density; + +{ + long MarkColumn = 0; + long MarkLine = 0; + long Track = 0; + long Line = 0; + long SplitNet = 0; + long NotLayer2 = 0; + BOOLEAN NotFind = TRUE; + long Weight = 0; + long MaxiWeight = 0; + long LeadLayer2 = 0; + long EndLayer2 = 0; + long WeightTerminal = 0; + + if ((SCR_TOP == SCR_BOTTOM(Density + 1)) && (SCR_TOP != 0)) { + for (Track = 1;Track <= Density; Track++) + VNET(Track) = SCR_TOP; + return; + } + else { /* Top != Bottom, Fusion noeuds multiple */ + + SCR_SplitNet(Density); + SCR_SFRT_Net(Column, Density); + SCR_WeightTracks(Density); + SCR_InitCombi(Density); + + for (Line = 1; Line <= Density; Line++) + if (SPLIT(Line) > 1) { + for (SplitNet = SPLIT(Line); SplitNet > 1; SplitNet--) { + for (Track = Line + 1; Track <= Density; Track++) { + if (HNET(Line) == HNET(Track)) + if (SPLIT(Line) == SPLIT(Track)) break; + } + SPLIT(Track) = SPLIT(Line) - 1; + for (NotLayer2 = Line; ((NotLayer2 <= Track) && ((VNET(NotLayer2) == 0) + || (VNET(NotLayer2) == HNET(Line)))); + NotLayer2++); + if (NotLayer2 > Track) /* pas de Layer2 */ + if ((Track - Line) >= MINJOG_LENGTH) { + NotFind = TRUE; + for (MarkColumn = LEADPATTERN; MarkColumn <= EndPattern; MarkColumn++) + if (COMBI(MarkColumn,Line) == 0) { + NotFind = FALSE; + for (MarkLine = Line; MarkLine <= Track; MarkLine++) + COMBI(MarkColumn,MarkLine) = HNET(Line); + } + if (NotFind) { + for (MarkLine = Line; MarkLine <= Track; MarkLine++) + COMBI(MarkColumn,MarkLine) = HNET(Line); + EndPattern = MarkColumn; + } + } + } + --SPLIT(Line); + } + } + + for (MarkColumn = LEADPATTERN; MarkColumn <= EndPattern; + MarkColumn++, Weight = 0) { + for (Track = 1; Track <= Density; Track++) + if (COMBI(MarkColumn, Track) != 0) { + LeadLayer2 = Track; + for (Line = Track + 1; + (COMBI(MarkColumn, Line) == COMBI(MarkColumn, LeadLayer2)); Line++); + Track = EndLayer2 = --Line; + if (SFRT(Track) == TERMINAL) + WeightTerminal = MAX(WEIGHT(Track),WEIGHT(Line)); + else WeightTerminal = 0; + Weight = Weight + (EndLayer2 - LeadLayer2) + WeightTerminal; + } + COMBI(MarkColumn, (Density + 1)) = Weight; + } + + for (MarkColumn = LEADPATTERN; MarkColumn <= (EndPattern + 1); MarkColumn += 2) + MaxiWeight = MAX(MaxiWeight,MAX(COMBI(MarkColumn,(Density + 1)), + COMBI((MarkColumn + 1),(Density + 1)))); + for (MarkColumn = LEADPATTERN; + (MaxiWeight != COMBI(MarkColumn, (Density + 1))); MarkColumn++); + for (Track = 1; Track <= Density; Track++) + if (COMBI(MarkColumn, Track) != 0) { + LeadLayer2 = Track; + for (Track = Track + 1; + ((COMBI(MarkColumn, Track) == COMBI(MarkColumn, LeadLayer2)) && + (Track <= Density)); Track++); + EndLayer2 = Track - 1; + for (Line = LeadLayer2; Line <= EndLayer2; Line++) + VNET(Line) = COMBI(MarkColumn, EndLayer2); + if (PREVHNET(LeadLayer2) == 0) HNET(LeadLayer2) = 0; + else if (PREVHNET(EndLayer2) == 0) HNET(EndLayer2) = 0; + Track--; + } +} + + +/******************************************************************************/ +/* Step 3 : Add Doglegs To Reduce The Range of Split Nets */ +/* Add jogs to reduce the range of split nets. For each uncollapsed */ +/* split net, additional jogs are added so that the track in the highest */ +/* level goes as far down as possible and the one at the lowest level */ +/* goes as far up as possible if such jogs are permissible. No jogs can */ +/* be shorter than the minimum jog length discussed earlier. */ +/******************************************************************************/ +void Step3(Column, Density) + +StaticColumn *Column ; +long Density; + +{ +long Line = 0; +long Length = 0; +long Counter = 0; +long MarkLine = 0; +long MarkLine1 = 0; +long Track = 0; +long ColumnPattern = LEADPATTERN; + +/*****************************************************************************/ +/* Step3: 3.0 Search Nets to Reduce the Range (Top to Bottom) */ +/*****************************************************************************/ +SCR_SplitNet(Density); +SCR_SFRT_Net(Column,Density); +SCR_InitCombi(Density); + +for (Line = 1; Line <= Density ; Line++) { + if (SPLIT(Line) > 1) { + if ((SFRT(Line) == FALLING) || (SFRT(Line) == STEADY)) { + for (Track = Line + 1; ((HNET(Track) != HNET(Line)) && + (Track <= Density));Track++) ; + if ((Track <= Density ) && ((Track-Line) >= JOG_LENGTH(Density))) { + for (MarkLine = Line + 1; ((VNET(MarkLine) ==0) && + (MarkLine <= Track));MarkLine++) ; + if ((MarkLine-Line) >= JOG_LENGTH(Density)) { + for (MarkLine1 = MarkLine; ((HNET(MarkLine1) != 0) && + (MarkLine1 >= Line)); MarkLine1--); + if ((MarkLine1-Line) >= JOG_LENGTH(Density)) { + Length=0; + for (ColumnPattern = LEADPATTERN, MarkLine = Line; + MarkLine<= MarkLine1 ;MarkLine++) { + COMBI(ColumnPattern,MarkLine)=HNET(Line); + Length++; + } + COMBI(ColumnPattern,Density+1)=Length; + if (ColumnPattern <= MAXCOL ) ColumnPattern++; + else { + fprintf(stdout,"MAXCOL insuffisant !!\n"); + exit(0); + } + EndPattern= ColumnPattern; + } + } + } + } +/*****************************************************************************/ +/* Step3: 3.1 Search Nets to reduce the Range (Bottom to Top) */ +/*****************************************************************************/ + if (SFRT(Line) == RISING) { + for (Track = Line - 1; ((HNET(Track) != HNET(Line)) && + (Track >= 1));Track--); + if ((Track >= 1 ) && ((Line-Track) >= JOG_LENGTH(Density))) { + for (MarkLine = Line - 1; ((VNET(MarkLine) ==0) && + (MarkLine >= Track));MarkLine--) ; + if ((Line-MarkLine) >= JOG_LENGTH(Density)) { + for (MarkLine1 = MarkLine; ((HNET(MarkLine1) != 0) && + (MarkLine1 <= Line)); MarkLine1++) ; + if ((Line-MarkLine1) >= JOG_LENGTH(Density)) { + Length=0; + for (MarkLine = MarkLine1; MarkLine<= Line ;MarkLine++) { + COMBI(ColumnPattern,MarkLine)=HNET(Line); + Length++; + } + COMBI(ColumnPattern,Density+1)=Length; + if (ColumnPattern <= MAXCOL ) ColumnPattern++; + else { + fprintf(stdout,"MAXCOL insuffisant !!\n"); + exit(0); + } + EndPattern= ColumnPattern; + } + } + } + } + } + } +/**********************************************************************/ +/* Step3: 3.2 Select Patterns */ +/**********************************************************************/ + + if ( COMBI(LEADPATTERN,Density+1)> 0) { + for (ColumnPattern = LEADPATTERN, Track = 1, Length = 0; + (ColumnPattern <= EndPattern); ColumnPattern++) { + for (Counter=Track; Counter <= Density; Counter++) { + if (COMBI(ColumnPattern, Counter) != 0) { + COMBI((EndPattern+1), Counter) = COMBI(ColumnPattern, Counter); + Length++; + Track = Counter; + } + } + } + COMBI((EndPattern+1),(Density+1)) = Length; + + for (ColumnPattern = EndPattern, Track=Density, Length=0; + ColumnPattern >= LEADPATTERN; ColumnPattern--) { + for (Counter=Track; Counter >0; Counter--) { + if (COMBI(ColumnPattern, Counter) != 0) { + COMBI((EndPattern+2), Counter) = COMBI(ColumnPattern, Counter); + Length++; + Track = Counter; + } + } + } + COMBI((EndPattern+2),(Density+1)) = Length; + + if (COMBI((EndPattern+1),(Density+1)) > COMBI((EndPattern+2),(Density+1))) + ColumnPattern=EndPattern+1; + else ColumnPattern=EndPattern+2; + if (COMBI(ColumnPattern, 1) != 0) { + VNET(1) = COMBI(ColumnPattern, 1); + HNET(1) = VNET(1) ; + } + if (COMBI(ColumnPattern, Density) != 0) { + VNET(Density) = COMBI(ColumnPattern, Density); + HNET(Density) = VNET(Density) ; + } + for(Track=2;Track= JOG_LENGTH(Density)) { + for (Column = LEADPATTERN; Column <= EndPattern; Column++) + if (COMBI(Column,MarkLine) == 0) { + NotFind = FALSE; + for (Line = MarkLine; Line <= Track; Line++) + COMBI(Column,Line) = HNET(MarkLine); + } + if (NotFind) { + for (Line = MarkLine; Line <= Track; Line++) + COMBI(Column,Line) = HNET(MarkLine); + EndPattern = Column; + } + } + } + } + else { + if (SFRT(MarkLine) == RISING) { + for (Track = MarkLine - 1; ((VNET(Track) == 0) && (Track >= 1)); Track-- ) + if (HNET(Track) == 0) { + NotFind = TRUE; + if ((MarkLine - Track) >= JOG_LENGTH(Density)) { + for (Column = LEADPATTERN; Column <= EndPattern; Column++) + if (COMBI(Column,MarkLine) == 0) { + for (Line = Track;((COMBI(Column,Line) == 0) && (Line <= MarkLine)); + Line++); + if (Line > MarkLine) { + NotFind = FALSE; + for (Line = Track; Line <= MarkLine; Line++) + COMBI(Column,Line) = HNET(MarkLine); + } + } + if (NotFind) { + for (Line = Track; Line <= MarkLine; Line++) + COMBI(Column,Line) = HNET(MarkLine); + EndPattern = Column; + } + } + } + } + } +/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*//* CHOICE PATTERN *//*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ + for (Column = LEADPATTERN; Column <= EndPattern; Column++, Weight = 0) { + for (Track = 1; Track <= Density; Track++) + if (COMBI(Column, Track) != 0) { + LeadLayer2 = Track; + for (Track = Track + 1; + (COMBI(Column, Track) == COMBI(Column, LeadLayer2)); Track++); + EndLayer2 = Track - 1; + Weight = Weight + (EndLayer2 - LeadLayer2); + } + COMBI(Column, (Density + 1)) = Weight; + } + + for (Column = LEADPATTERN; Column <= (EndPattern + 1); Column += 2) + MaxiWeight = MAX(MaxiWeight,MAX(COMBI(Column,(Density + 1)), + COMBI((Column + 1),(Density + 1)))); + for (Column = LEADPATTERN; (MaxiWeight != COMBI(Column, (Density + 1))); + Column++); + + for (Track = 1; Track <= Density; Track++) + if (COMBI(Column, Track) != 0) { + LeadLayer2 = Track; + for (Track = Track + 1;((Track <= Density) && + (COMBI(Column, Track) == COMBI(Column, LeadLayer2))); Track++); + EndLayer2 = --Track; + + if (SFRT(LeadLayer2) == FALLING) { + HNET(EndLayer2) = COMBI(Column, EndLayer2); + if (SCR_TOP == COMBI(Column, LeadLayer2)) + HNET(LeadLayer2) = 0; + } + if (SFRT(EndLayer2) == RISING) { + HNET(LeadLayer2) = COMBI(Column, LeadLayer2); + if (SCR_BOTTOM(Density + 1) == COMBI(Column, LeadLayer2)) + HNET(EndLayer2) = 0; + } + for (MarkLine = LeadLayer2; MarkLine <= EndLayer2; MarkLine++) + VNET(MarkLine) = COMBI(Column, EndLayer2); + } +} + +/******************************************************************************/ +/* Step 5 : Widen Channel If Needed To Make Previously Infeasible Top or */ +/* Bottom Connecions */ +/* If the nets in the current column could not be routed in step 1, */ +/* add new tracks and bring them to these tracks. Such new tracks */ +/* must be placed as near the center of the channel as possible if */ +/* they do no conflict with existing wiring. */ +/******************************************************************************/ +void Step5(LeadDataBase, Density, Width) + +StaticColumn *LeadDataBase; +long *Density; +long Width; + +{ + long Position = 0; + long Line = 0; + + if (((*Density) + 2) >= MAXLINE) { + fprintf(stdout,"\n IMPOSSIBLE DE CONTINUER PAR MANQUE DE LIGNE \n \n"); + fprintf(stdout," AUGMENTER MAXLINE DANS MAKEFILE !!! \n"); + exit(0); + } + else { + if (TOPNOTROUT) { + for (Position = 1; ((VNET(Position) == 0) && + (Position <= ((long ) ((*Density) >> 1)))); Position++); + SCR_InsertNewTrack(LeadDataBase, Position, Width); + SCR_InsertNewLine(Position, *Density); + (*Density)++; + PREVHNET(Position) = ((long ) 0); + HNET(Position) = SCR_TOP; + for (Line = 0; Line <= Position; Line++) + VNET(Line) = SCR_TOP; + TOPNOTROUT = FALSE; + } + if (BOTNOTROUT) { + for (Position = (*Density); ((VNET(Position) == 0) && + (Position >= ((long ) ((*Density) >> 1)))); Position--); + Position++; + SCR_InsertNewTrack(LeadDataBase, Position, Width); + SCR_InsertNewLine(Position, *Density); + (*Density)++; + PREVHNET(Position) = ((long ) 0); + HNET(Position) = SCR_BOTTOM(*Density + 1); + for (Line = Position; Line <= (*Density + 1); Line++) + VNET(Line) = SCR_BOTTOM(*Density + 1); + BOTNOTROUT = FALSE; + } + } +} +/******************************************************************************/ +/* Step 6 : Extend To Next Column */ +/* For each unsplit net that ended in the current column, delete the */ +/* list of tracks occupied by the net. extend all tracks occupied by */ +/* unfinished nets and split nets to the next column. */ +/******************************************************************************/ +void Step6(Density) + +long Density; + +{ + long Line = 0; + + for (Line = 1; Line <= Density; Line++) + if (SFRT(Line) == TERMINAL) { + PREVHNET(Line) = 0; + HNET(Line) = 0; + } + else PREVHNET(Line) = HNET(Line); + VNET(Line) = 0; +} + +/******************************************************************************/ +/* ENDING NOT COLLAPSING SPLIT NETS */ +/******************************************************************************/ +void SCR_EndingNotCollapsingNets( + EndRealChannel, LeadEastColumn, + Density, ChannelWidth + ) + +StaticColumn *EndRealChannel; +StaticColumn *LeadEastColumn; +long Density; +long *ChannelWidth; + +{ + long ColumnNumber = 0; + long MarkColumn = 0; + long MarkLine = 0; + long Line = 0; + long Track = 0; + BOOLEAN NotFind = TRUE; + BOOLEAN InsertMode = FALSE; + + SCR_SplitNet(Density); + SCR_InitCombi(Density); + +# ifdef SCR_DEBUG + fprintf(stdout,"In SCR_EndingNotCollapsingNets \n"); + U_PrintDynamicDataBase(Density); +# endif + + for (Line = 1; Line <= Density; Line++) + if (SPLIT(Line) > 1) { + InsertMode = TRUE; + break; + } + if (InsertMode) { + for (Line = 1; Line <= Density; Line++) + if ((HNET(Line) != 0) && (SPLIT(Line) > 1)) { + SCR_TOP = ((long ) 0); + SCR_BOTTOM(Density + 1) = ((long ) 0); + NotFind = TRUE; + for (Track = Line + 1; ((SPLIT(Line) > 1) && (Track <= Density)); Track++) + if (HNET(Track) == HNET(Line)) { + SPLIT(Track) = ((long ) 1); + SPLIT(Line)--; + } + for (MarkColumn = LEADPATTERN; MarkColumn <= EndPattern; MarkColumn++) + if (COMBI(MarkColumn,Line) == 0) { + NotFind = FALSE; + for (MarkLine = Line; MarkLine < Track; MarkLine++) + COMBI(MarkColumn,MarkLine) = HNET(Line); + break; + } + if (NotFind) { + for (MarkLine = Line; MarkLine < Track; MarkLine++) + COMBI(MarkColumn,MarkLine) = HNET(Line); + EndPattern = MarkColumn; + } + } + +# ifdef SCR_DEBUG + fprintf(stdout,"In SCR_EndingNotCollapsingNets \n"); + U_PrintDynamicDataBase(Density); +# endif + + ColumnNumber = (EndPattern - LEADPATTERN) + 1; + SCR_InsertNewColumn(EndRealChannel, LeadEastColumn, Density, ColumnNumber); + *ChannelWidth += ColumnNumber; + for (MarkColumn = LEADPATTERN; MarkColumn <= EndPattern; MarkColumn++) { + for (Line = 0; Line <= (Density + 1); Line++) + VNET(Line) = ((long) 0); + for (Line = 1; Line <= Density; Line++) + VNET(Line) = COMBI(MarkColumn,Line); + SCR_UpDateDataBase(EndRealChannel->NextCol, Density); + +# ifdef SCR_DEBUG + fprintf(stdout,"In SCR_EndingNotCollapsingNets befor Step6\n"); + U_PrintDynamicDataBase(Density); +# endif + + Step6(Density); + + EndRealChannel = EndRealChannel->NextCol; + +# ifdef SCR_DEBUG + fprintf(stdout,"In SCR_EndingNotCollapsingNets \n"); + fprintf(stdout,"In SCR_EndingNotCollapsingNets after Step6\n"); + U_PrintDynamicDataBase(Density); +# endif + } + } +} + +/******************************************************************************/ +/* GREEDY ROUTER ALGORITHM */ +/******************************************************************************/ +void SCR_GreedyRouter( + LeadStaticDataBase, EndRealChannel, + LeadEastColumn, Density, Width, ChannelWidth + ) + +StaticColumn *LeadStaticDataBase; +StaticColumn *EndRealChannel; +StaticColumn *LeadEastColumn; +long *Density; +long Width; +long *ChannelWidth; + +{ + StaticColumn *CurrentColumn = NULL; + + SCR_InitTabRout(); + + for(CurrentColumn = LeadStaticDataBase; CurrentColumn; + CurrentColumn = CurrentColumn->NextCol) { + if (CurrentColumn == LeadEastColumn) { + SCR_EndingNotCollapsingNets( + EndRealChannel, LeadEastColumn, + *Density, ChannelWidth + ); + } + SCR_TOP = CurrentColumn->NorthCon; + SCR_BOTTOM(*Density + 1) = CurrentColumn->SouthCon; + +# ifdef SCR_DEBUG + fprintf(stdout,"Befor Routing Column \n"); + U_PrintDynamicDataBase(*Density); + fprintf(stdout,"In Step1 \n"); +# endif + + Step1(CurrentColumn, *Density); + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(*Density); + fprintf(stdout,"In Step2 \n"); +# endif + + Step2(CurrentColumn, *Density); + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(*Density); +/* +fprintf(stdout,"In Step3 \n"); +*/ +# endif +/* + Step3(CurrentColumn, *Density); +*/ + +# ifdef SCR_DEBUG + /* +U_PrintDynamicDataBase(*Density); +*/ + fprintf(stdout,"In Step4 \n"); +# endif + + Step4(CurrentColumn, *Density); + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(*Density); + fprintf(stdout,"In Step5 \n"); +# endif + + Step5(LeadStaticDataBase, Density, Width); + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(*Density); +# endif + + SCR_UpDateDataBase(CurrentColumn, *Density); + +# ifdef SCR_DEBUG + fprintf(stdout,"In Step6 \n"); +# endif + + Step6(*Density); + +# ifdef SCR_DEBUG + U_PrintDynamicDataBase(*Density); +# endif + } + SCR_EndingNotCollapsingNets(EndRealChannel, LeadEastColumn, + *Density, ChannelWidth); +} + +/******************************************************************************/ diff --git a/alliance/src/gscr/src/gscr_GreedyRout.h b/alliance/src/gscr/src/gscr_GreedyRout.h new file mode 100644 index 00000000..aa471a81 --- /dev/null +++ b/alliance/src/gscr/src/gscr_GreedyRout.h @@ -0,0 +1,38 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +extern BOOLEAN SCR_BelongInWindow(); +extern void SCR_InitSplit(); +extern void SCR_SplitNet(); +extern void SCR_SFRT_Net(); +extern void SCR_WeightTracks(); +extern void SCR_InsertNewLine(); +extern void SCR_UpDateDataBase(); +extern void Step1(); +extern void Step2(); +extern void Step3(); +extern void Step4(); +extern void Step5(); +extern void Step6(); +extern void SCR_EndingNotCollapsingNets(); +extern void SCR_GreedyRouter(); diff --git a/alliance/src/gscr/src/gscr_StaticUtil.c b/alliance/src/gscr/src/gscr_StaticUtil.c new file mode 100644 index 00000000..f9e634c8 --- /dev/null +++ b/alliance/src/gscr/src/gscr_StaticUtil.c @@ -0,0 +1,543 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Symbolic Channel Router */ +/* File : @(#) */ +/* Contents : */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : El housseine REJOUAN Date : ../../.... */ +/* Modified by : El housseine REJOUAN Date : 29/07/1992 */ +/* Modified by : Date : ../../.... */ +/* Modified by : Date : ../../.... */ +/* */ +/******************************************************************************/ +# include +# include +# include +# include +# include +# include "apr.h" +# include "gscr_main.h" +# include "gscr_DataBase.h" + +int L3MODE; + +/***********************************************************************/ +/* CHARGEMENT DES LISTES NORTH, SOUTH, WEST ET EAST */ +/***********************************************************************/ +ConnectorList *U_GetConList(ptfich) + +FILE *ptfich; + +{ + ConnectorList *LeadConList = NULL; + ConnectorList *CurrentList = NULL; + ConnectorList *PrevCurrentList = NULL; + long Mark = 1; + char car; + char string[10]; + int i=0; + + + if ((car = getc(ptfich)) == '{') + if ((car = getc(ptfich)) != '}') { + while ((car != ' ') && (car != ',') && (car != '}')) { + if (car != '\n') string[i++] = car; + car = getc(ptfich); + } + string[i] = '\0'; + LeadConList = (ConnectorList *) mbkalloc (sizeof(ConnectorList)); + PrevCurrentList = LeadConList; + LeadConList->NextCon = NULL; + LeadConList->ConName = atol(string); + LeadConList->Mark = Mark; + Mark++; + + while (car != '}') { + i = 0; + car = getc(ptfich); + while ((car != ' ') && (car != ',') && (car != '}')) { + if (car != '\n') string[i++] = car; + car = getc(ptfich); + } + string[i] = '\0'; + CurrentList = (ConnectorList *) mbkalloc (sizeof(ConnectorList)); + PrevCurrentList->NextCon = CurrentList; + PrevCurrentList = CurrentList; + CurrentList->NextCon = NULL; + CurrentList->ConName = atol(string); + CurrentList->Mark = Mark; + Mark++; + } + } + else LeadConList = NULL; + car = getc(ptfich); + return (LeadConList); +} +/******************************************************************************/ +/* Function : U_GetChannel() */ +/******************************************************************************/ +void U_GetChannel(FichName, LeadNorthList, LeadSouthList, + LeadWestList, LeadEastList) + +char *FichName; +ConnectorList **LeadNorthList; +ConnectorList **LeadSouthList; +ConnectorList **LeadWestList; +ConnectorList **LeadEastList; + +{ + FILE *ptfich; + + if ((ptfich = fopen(FichName,"r")) == NULL) { + fprintf(stdout,"fichier inexistant \n"); + exit(0); + } + else { + *LeadNorthList = U_GetConList(ptfich); + *LeadSouthList = U_GetConList(ptfich); + *LeadWestList = U_GetConList(ptfich); + *LeadEastList = U_GetConList(ptfich); + fclose(ptfich); + } +} +/******************************************************************************/ +/* VISUALISATION DE LA LISTE DES CONNECTEURS */ +/******************************************************************************/ +void U_PrintList(LeadConList) + +ConnectorList *LeadConList; + +{ + ConnectorList *CurrentConList; + CurrentConList = LeadConList; + + if (LeadConList) + while (CurrentConList) { + fprintf(stderr, "ConName= %ld \t Mark= %ld \n", CurrentConList->ConName, + CurrentConList->Mark); + CurrentConList = CurrentConList->NextCon; + } +} + +/******************************************************************************/ +/* VISUALISATION DE LA LISTE DES COLONNES */ +/******************************************************************************/ +void U_PrintColumn(LeadColumn) + +StaticColumn *LeadColumn; +{ + StaticColumn *CurrentColumn = NULL; + + CurrentColumn = LeadColumn; + while (CurrentColumn) { + fprintf(stderr, "NorthCon = %ld \t SouthCon = %ld \n",CurrentColumn->NorthCon, + CurrentColumn->SouthCon); + CurrentColumn = CurrentColumn->NextCol; + } +} + +/******************************************************************************/ +/* LARGEUR DU CANAL */ +/******************************************************************************/ +long U_ChannelWidth(LeadNorth, LeadSouth) + +StaticColumn *LeadNorth; +StaticColumn *LeadSouth; + +{ + StaticColumn *CurrentColumn = NULL; + long NorthWidth = 0; + long SouthWidth = 0; + + for (CurrentColumn = LeadNorth; CurrentColumn; + CurrentColumn = CurrentColumn->NextCol, NorthWidth++); + for (CurrentColumn = LeadSouth; CurrentColumn; + CurrentColumn = CurrentColumn->NextCol, SouthWidth++); + return(MAX(NorthWidth, SouthWidth)); +} + +/******************************************************************************/ +/* VISUALISATION DE LA BASE DE DONNEE STATIQUE */ +/******************************************************************************/ +void U_PrintStaticDataBase(LeadColumn) + +StaticColumn *LeadColumn; + +{ + StaticColumn *CurrentColumn = NULL; + StaticPoint *CurrentPoint = NULL; + + for (CurrentColumn = LeadColumn;CurrentColumn; + CurrentColumn = CurrentColumn->NextCol) { + fprintf(stderr, "NorthCon = %ld \t SouthCon = %ld \n",CurrentColumn->NorthCon, + CurrentColumn->SouthCon); + for (CurrentPoint = CurrentColumn->PointList; CurrentPoint; + CurrentPoint = CurrentPoint->NextPoint) + fprintf(stderr, "Via = %d \t Layer1 = %c \t Layer2 = %c \t Name = %ld \n", + CurrentPoint->Via, CurrentPoint->Layer1, CurrentPoint->Layer2, + CurrentPoint->PointName); + } +} +/******************************************************************************/ +/* VISUALISATION DE LA LISTE DES SEGMENTS */ +/******************************************************************************/ +void U_PrintSegmentList(LeadList) + +SegmentList *LeadList; + +{ + SegmentList *CurrentList = NULL; + + for (CurrentList = LeadList; CurrentList; CurrentList = CurrentList->NextSeg) { + fprintf(stderr,"Name = %s \t X1Seg = %3ld \t Y1Seg = %3ld \t ", + CurrentList->SegName, CurrentList->X1Seg, CurrentList->Y1Seg); + fprintf(stderr,"X2Seg= %3ld \t Y2Seg= %3ld \n", + CurrentList->X2Seg, CurrentList->Y2Seg); + } + +} + +/******************************************************************************/ +/* VISUALISATION DE LA LISTE DES SEGMENTS */ +/******************************************************************************/ +void U_PrintViasList(LeadList) + +ViasList *LeadList; + +{ + ViasList *CurrentList = NULL; + + for (CurrentList = LeadList; CurrentList; CurrentList = CurrentList->NextVia) + fprintf(stderr,"XVia = %ld \t YVia = %ld \t \n", + CurrentList->XVia, CurrentList->YVia); +} + +/******************************************************************************/ +/* Function : */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +void gscr2mbk(FigName,LeadHorSeg,LeadVerSeg,LeadVia, + LeadNorthCon,LeadSouthCon,LeadWestCon, + LeadEastCon,ChannelWidth,ChannelHeight) +char *FigName; +SegmentList *LeadHorSeg; +SegmentList *LeadVerSeg; +ViasList *LeadVia; +ConnectorList *LeadNorthCon; +ConnectorList *LeadSouthCon; +ConnectorList *LeadWestCon; +ConnectorList *LeadEastCon; +long ChannelWidth; +long ChannelHeight; + +{ + phfig_list *ptFigure = NULL; + SegmentList *CurrentSeg = NULL; + ViasList *CurrentVia = NULL; + ConnectorList *CurrentCon = NULL; + long X1Symbolic = 0; + long X2Symbolic = 0; + long Y1Symbolic = 0; + long Y2Symbolic = 0; + long X1Segment = 0; + long X2Segment = 0; + long Y1Segment = 0; + long Y2Segment = 0; + long Xab1 = 0; + long Xab2 = 0; + long Yab1 = 0; + long Yab2 = 0; + long ConName = 0; + char Buffer[10]; + + ptFigure = addphfig(FigName); + Xab1 = Yab1 = ptFigure->XAB1 = ptFigure->YAB1 = 0; + Xab2 = ptFigure->XAB2 = + ((ChannelWidth - 1) * PITCH_X) + WESTOFFSET + EASTOFFSET; + Yab2 = ptFigure->YAB2 = + ((ChannelHeight - 1) * PITCH_Y) + SOUTHOFFSET + NORTHOFFSET; + +/******************************************************************************/ +/* SAVING HORIZONTAL SEGMENT */ +/******************************************************************************/ + for (CurrentSeg = LeadHorSeg; CurrentSeg; CurrentSeg = CurrentSeg->NextSeg) { + if ((X1Symbolic = CurrentSeg->X1Seg) == 0) + X1Segment = Xab1; + else + X1Segment = ((X1Symbolic - 1) * PITCH_X) + WESTOFFSET; + if ((X2Symbolic = CurrentSeg->X2Seg) == (ChannelWidth + 1)) + X2Segment = Xab2; + else + X2Segment = ((X2Symbolic - 1) * PITCH_X) + WESTOFFSET; + Y1Segment = Y2Segment = (((CurrentSeg->Y1Seg - 1) * PITCH_Y) + SOUTHOFFSET); + addphseg(ptFigure, ((char )ALU1), LAYER1WIDTH, X1Segment, Y1Segment, + X2Segment , Y2Segment, CurrentSeg->SegName); + } + +/******************************************************************************/ +/* SAVING VERTICAL SEGMENT */ +/******************************************************************************/ + for (CurrentSeg = LeadVerSeg; CurrentSeg; CurrentSeg = CurrentSeg->NextSeg) { + if ((Y1Symbolic = CurrentSeg->Y1Seg) == 0) + Y1Segment = Yab1; + else + Y1Segment = ((Y1Symbolic - 1) * PITCH_Y) + SOUTHOFFSET; + if ((Y2Symbolic = CurrentSeg->Y2Seg) == ChannelHeight + 1) + Y2Segment = Yab2; + else + Y2Segment = ((Y2Symbolic - 1) * PITCH_Y) + SOUTHOFFSET; + X1Segment = X2Segment = ((CurrentSeg->X1Seg - 1) * PITCH_X) + WESTOFFSET; + addphseg(ptFigure, ((char )ALU2), LAYER2WIDTH, X1Segment, Y1Segment, + X2Segment, Y2Segment, CurrentSeg->SegName); + } + +/******************************************************************************/ +/* SAVING VIA */ +/******************************************************************************/ + for (CurrentVia = LeadVia; CurrentVia; CurrentVia = CurrentVia->NextVia) { + addphvia(ptFigure, ((char ) CONT_VIA), + ((CurrentVia->XVia - 1) * PITCH_X) + WESTOFFSET, + ((CurrentVia->YVia - 1) * PITCH_Y) + SOUTHOFFSET,0,0,NULL); + } + +/******************************************************************************/ +/* SAVING CONNECTOR */ +/******************************************************************************/ + for (CurrentCon = LeadNorthCon; CurrentCon; CurrentCon = CurrentCon->NextCon) { + if ((ConName = CurrentCon->ConName) != NONET) { + sprintf(Buffer,"%ld",ConName); + addphcon(ptFigure, NORTH, Buffer, + ((CurrentCon->Mark - 1) * PITCH_X) + WESTOFFSET, + Yab2, ((char ) ALU2), LAYER2WIDTH); + } + } + for (CurrentCon = LeadSouthCon; CurrentCon; CurrentCon = CurrentCon->NextCon) { + if ((ConName = CurrentCon->ConName) != NONET) { + sprintf(Buffer,"%ld",ConName); + addphcon(ptFigure, SOUTH, Buffer, + ((CurrentCon->Mark - 1) * PITCH_X) + WESTOFFSET, + Yab1, ((char ) ALU2), LAYER2WIDTH); + } + } + for (CurrentCon = LeadWestCon; CurrentCon; CurrentCon = CurrentCon->NextCon) { + sprintf(Buffer,"%ld",CurrentCon->ConName); + addphcon(ptFigure, WEST, Buffer, Xab1, + ((CurrentCon->Mark - 1) * PITCH_Y) + SOUTHOFFSET, + ((char ) ALU1), LAYER1WIDTH); + } + for (CurrentCon = LeadEastCon; CurrentCon; CurrentCon = CurrentCon->NextCon) { + sprintf(Buffer,"%ld",CurrentCon->ConName); + addphcon(ptFigure, EAST, Buffer, Xab2, + ((CurrentCon->Mark - 1) * PITCH_Y) + SOUTHOFFSET, + ((char ) ALU1), LAYER1WIDTH); + } +/******************************************************************************/ +/* SAVING FIGURE */ +/******************************************************************************/ + savephfig(ptFigure); +} + +/******************************************************************************/ +/* SAUVEGARDE DU RESULTAT DE ROUTAGE */ +/******************************************************************************/ +void U_SaveChannel( + FigName, LeadH_Segment, LeadV_Segment, + LeadVia, Width, Height, + LeadWestList, LeadEastList + ) + +char *FigName; +SegmentList *LeadH_Segment; +SegmentList *LeadV_Segment; +ViasList *LeadVia; +long Width; +long Height; +ConnectorList *LeadWestList; +ConnectorList *LeadEastList; + +{ + phfig_list *ptfig = NULL; + SegmentList *CurrentSegment = NULL; + SegmentList *CurrentSeg = NULL; + ViasList *CurrentVia = NULL; + long Layer1Length = 0; + long Layer2Length = 0; + long ViasNumber = 0; + long X1Symbolic = 0; + long X2Symbolic = 0; + long Y1Symbolic = 0; + long Y2Symbolic = 0; + long X1Segment = 0; + long X2Segment = 0; + long Y1Segment = 0; + long Y2Segment = 0; + long Xab1 = 0; + long Xab2 = 0; + long Yab1 = 0; + long Yab2 = 0; + + ptfig = addphfig(FigName); + +fprintf(stdout,"Width = %ld \n",Width); +fprintf(stdout,"Height = %ld \n",Height); + + Xab1 = Yab1 = ptfig->XAB1 = ptfig->YAB1 = ((long ) 0); +/* + ptfig->XAB2 = ((Width + 1) * PITCH_X); + ptfig->YAB2 = ((Height + 1 ) * PITCH_Y); +*/ + + Xab2 = ptfig->XAB2 = ((Width - 1) * PITCH_X) + WESTOFFSET + EASTOFFSET; + Yab2 = ptfig->YAB2 = ((Height - 1) * PITCH_Y) + SOUTHOFFSET + NORTHOFFSET; + +fprintf(stderr,"XAB1 = %ld \n",ptfig->XAB1); +fprintf(stderr,"XAB2 = %ld \n",ptfig->XAB2); +fprintf(stderr,"YAB1 = %ld \n",ptfig->YAB1); +fprintf(stderr,"YAB2 = %ld \n",ptfig->YAB2); + +fflush(stderr); + +/******************************************************************************/ +/* SAVING HORIZONTAL SEGMENT */ +/******************************************************************************/ + for (CurrentSeg = LeadH_Segment; CurrentSeg; CurrentSeg = CurrentSeg->NextSeg) { + if ((X1Symbolic = CurrentSeg->X1Seg) == 0) + X1Segment = Xab1; + else + X1Segment = ((X1Symbolic - 1) * PITCH_X) + WESTOFFSET; + if ((X2Symbolic = CurrentSeg->X2Seg) == (Width + 1)) + X2Segment = Xab2; + else + X2Segment = ((X2Symbolic - 1) * PITCH_X) + WESTOFFSET; + Y1Segment = Y2Segment = (((CurrentSeg->Y1Seg - 1) * PITCH_Y) + SOUTHOFFSET), + addphseg(ptfig, ((char )ALU1), LAYER1WIDTH, X1Segment, + Y1Segment, X2Segment , Y2Segment, CurrentSeg->SegName); + } + +/******************************************************************************/ + +/* + for (CurrentSegment = LeadH_Segment; CurrentSegment; + CurrentSegment = CurrentSegment->NextSeg) { + addphseg(ptfig, ((char ) ALU1), LAYER1WIDTH, + ((CurrentSegment->X1Seg) * PITCH_X), + ((CurrentSegment->Y1Seg) * PITCH_Y), + ((CurrentSegment->X2Seg) * PITCH_X), + ((CurrentSegment->Y2Seg) * PITCH_Y), + CurrentSegment->SegName); + Layer1Length = Layer1Length + (CurrentSegment->X2Seg - CurrentSegment->X1Seg); + } + Layer1Length = Layer1Length * PITCH_X; +*/ + + for (CurrentSegment = LeadV_Segment; CurrentSegment; + CurrentSegment = CurrentSegment->NextSeg) { + addphseg(ptfig, ((char ) ALU2), LAYER2WIDTH, + ((CurrentSegment->X1Seg) * PITCH_X), + ((CurrentSegment->Y1Seg) * PITCH_Y), + ((CurrentSegment->X2Seg) * PITCH_X), + ((CurrentSegment->Y2Seg) * PITCH_Y), + CurrentSegment->SegName); + Layer2Length = Layer2Length + (CurrentSegment->Y2Seg - CurrentSegment->Y1Seg); + } + Layer2Length = Layer2Length * PITCH_Y; + + for (CurrentVia = LeadVia; CurrentVia; CurrentVia = CurrentVia->NextVia) { + addphvia(ptfig, ((char ) CONT_VIA), + ((CurrentVia->XVia) * PITCH_X), + ((CurrentVia->YVia) * PITCH_Y),0,0,NULL); + ViasNumber = ViasNumber + 1; + } + + for (CurrentSegment = LeadV_Segment; CurrentSegment; + CurrentSegment = CurrentSegment->NextSeg) { + if (CurrentSegment->Y1Seg == 0) + addphcon(ptfig, SOUTH, CurrentSegment->SegName, + ((CurrentSegment->X1Seg) * PITCH_X), + ((CurrentSegment->Y1Seg) * PITCH_Y), + ((char ) ALU2), (LAYER2WIDTH)); + if (CurrentSegment->Y2Seg == (Height + 1)) + addphcon(ptfig, NORTH, CurrentSegment->SegName, + ((CurrentSegment->X2Seg) * PITCH_X), + ((CurrentSegment->Y2Seg) * PITCH_Y), + ((char ) ALU2), (LAYER2WIDTH)); + } + + if (LeadWestList && LeadEastList) { + for (CurrentSegment = LeadH_Segment; CurrentSegment; + CurrentSegment = CurrentSegment->NextSeg) { + if (CurrentSegment->X1Seg == 0) + addphcon(ptfig, WEST, CurrentSegment->SegName, + ((CurrentSegment->X1Seg) * PITCH_X), + ((CurrentSegment->Y1Seg) * PITCH_Y), + ((char ) ALU1), (LAYER1WIDTH)); + if (CurrentSegment->X2Seg == (Width - 1)) + addphcon(ptfig, EAST, CurrentSegment->SegName, + ((CurrentSegment->X2Seg) * PITCH_X), + ((CurrentSegment->Y2Seg) * PITCH_Y), + ((char ) ALU1), (LAYER1WIDTH)); + } + } + else + if (LeadWestList) { + for (CurrentSegment = LeadH_Segment; CurrentSegment; + CurrentSegment = CurrentSegment->NextSeg) + if (CurrentSegment->X1Seg == 0) + addphcon(ptfig, WEST, CurrentSegment->SegName, + ((CurrentSegment->X1Seg) * PITCH_X), + ((CurrentSegment->Y1Seg) * PITCH_Y), + ((char ) ALU1), (LAYER1WIDTH)); + } + else + if (LeadEastList) { + for (CurrentSegment = LeadH_Segment; CurrentSegment; + CurrentSegment = CurrentSegment->NextSeg) + if (CurrentSegment->X2Seg == (Width - 1)) + addphcon(ptfig, EAST, CurrentSegment->SegName, + ((CurrentSegment->X2Seg) * PITCH_X), + ((CurrentSegment->Y2Seg) * PITCH_Y), + ((char ) ALU1), (LAYER1WIDTH)); + } + +fprintf(stdout,"Layer1 Length = %ld \n",Layer1Length); +fprintf(stdout,"Layer2 Length = %ld \n",Layer2Length); +fprintf(stdout,"ViasNumber = %ld \n",ViasNumber); + savephfig(ptfig); +} +/******************************************************************************/ diff --git a/alliance/src/gscr/src/gscr_StaticUtil.h b/alliance/src/gscr/src/gscr_StaticUtil.h new file mode 100644 index 00000000..657bdedb --- /dev/null +++ b/alliance/src/gscr/src/gscr_StaticUtil.h @@ -0,0 +1,32 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +extern ConnectorList *U_GetConList(); +extern void U_Get_NSWE_List(); +extern void U_PrintList(); +extern void U_PrintColumn(); +extern void U_PrintStaticDataBase(); +extern void U_PrintSegmentList(); +extern void U_PrintViasList(); +extern void U_SaveChannel(); +extern void gscr2mbk(); diff --git a/alliance/src/gscr/src/gscr_SymbChanRout.c b/alliance/src/gscr/src/gscr_SymbChanRout.c new file mode 100644 index 00000000..56fee859 --- /dev/null +++ b/alliance/src/gscr/src/gscr_SymbChanRout.c @@ -0,0 +1,813 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* STANDARD CELLS ROUTER */ +/* FILE : SymbChanRout.c LAST MODIFICATIOIN : JUL/25/1991 AT 9:23 */ +/******************************************************************************/ + + +# include +# include +# include +# include +# include +# include "gscr_DataBase.h" +# include "apr.h" +# include "gscr_main.h" +# include "gscr_AllowFree.h" +# include "gscr_StaticUtil.h" +# include "gscr_GreedyRout.h" + +StaticColumn *Lead_NS_Column = NULL; +StaticColumn *End_NS_Column = NULL; +StaticColumn *LeadEastColumn = NULL; + +/******************************************************************************/ +/* */ +/******************************************************************************/ +void EliminateOnlyCon(LeadList1,LeadList2,LeadList3,LeadList4) + +ConnectorList **LeadList1; +ConnectorList **LeadList2; +ConnectorList **LeadList3; +ConnectorList **LeadList4; + +{ + ConnectorList *ptList = NULL; + ConnectorList *ptList1 = NULL; + ConnectorList *ptList2 = NULL; + ConnectorList *ptList3 = NULL; + ConnectorList *ptList4 = NULL; + ConnectorList *PrevList1 = NULL; + ConnectorList *ptEliminate = NULL; + long ConName = 0; + + ptList1 = PrevList1 = *LeadList1; + while (ptList1) { + ConName = ptList1->ConName; + for (ptList = *LeadList1; ptList; ptList = ptList->NextCon) + if ((ptList != ptList1) && (ConName == ptList->ConName)) break; + + if (ptList == NULL) + for (ptList2 = *LeadList2; ptList2; ptList2 = ptList2->NextCon) + if (ConName == ptList2->ConName) break; + + if ((ptList == NULL) && (ptList2 == NULL)) + for (ptList3 = *LeadList3; ptList3; ptList3 = ptList3->NextCon) + if (ConName == ptList3->ConName) break; + + if ((ptList == NULL) && (ptList2 == NULL) && (ptList3 == NULL)) + for (ptList4 = *LeadList4; ptList4; ptList4 = ptList4->NextCon) + if (ConName == ptList4->ConName) break; + + if ((ptList == NULL) && (ptList2 == NULL) && + (ptList3 == NULL) && (ptList4 == NULL)) { + ptEliminate = ptList1; + ptList1 = ptList1->NextCon; + if (ptList1 == (*LeadList1)->NextCon) *LeadList1 = ptList1; + else if (ptList1 == NULL) PrevList1->NextCon = NULL; + else PrevList1->NextCon = ptList1; + mbkfree((void *) ptEliminate); + } + else { + PrevList1 = ptList1; + ptList1 = ptList1->NextCon; + } + } +} + +/******************************************************************************/ +/* cette fonction elimine les connecteurs redondant dans la liste */ +/* EAST et dans la liste WEST. */ +/******************************************************************************/ +void SCR_Eliminate(LeadConList) + +ConnectorList **LeadConList; + +{ + ConnectorList *EliminateCon = NULL; + ConnectorList *CurrentCon = NULL; + ConnectorList *CurrentConList = NULL; + ConnectorList *BeforCurrentConList = NULL; + + if (*LeadConList) + for(CurrentCon = *LeadConList; CurrentCon; + CurrentCon = CurrentCon->NextCon) { + BeforCurrentConList = CurrentCon; + CurrentConList = CurrentCon->NextCon; + while(CurrentConList) + if(CurrentCon->ConName == CurrentConList->ConName) { + EliminateCon = CurrentConList; + if (CurrentConList->NextCon) { + CurrentConList = CurrentConList->NextCon; + BeforCurrentConList->NextCon = CurrentConList; + } + else { + CurrentConList = NULL; + BeforCurrentConList->NextCon = NULL; + } + mbkfree(((void *) EliminateCon)); + } + else { + CurrentConList = CurrentConList->NextCon; + BeforCurrentConList = BeforCurrentConList->NextCon; + } + } +} + +/******************************************************************************/ +/* CALCUL DE LA NOUVELLE LARGEUR DU CANAL */ +/******************************************************************************/ +long SCR_NewChannelWidth(LeadWest, LeadEast, Width) + +ConnectorList *LeadWest; +ConnectorList *LeadEast; +long Width; + +{ + ConnectorList *CurrentList = NULL; + + for (CurrentList = LeadWest; CurrentList; Width++, + CurrentList = CurrentList->NextCon); + for (CurrentList = LeadEast; CurrentList; Width++, + CurrentList = CurrentList->NextCon); + return(Width); +} + +/******************************************************************************/ +/* Creation de la base de donnee du routeur canal symbolique */ +/******************************************************************************/ + +StaticColumn *SCR_LoadStaticColumn(LeadColumn, LeadNorth,LeadSouth, + LeadWest, LeadEast, Width) + +StaticColumn *LeadColumn; +ConnectorList *LeadNorth; +ConnectorList *LeadSouth; +ConnectorList *LeadWest; +ConnectorList *LeadEast; +long Width; + +{ + StaticColumn *CurrentColumn = NULL; + ConnectorList *CurrentList = NULL; + ConnectorList *CurrentNorthList = NULL; + ConnectorList *CurrentSouthList = NULL; + long Indice = 0; + + + + CurrentColumn = LeadColumn; + + /* Transfert de la liste WEST - si elle n'est pas vide - vers la liste des */ + /* colonnes */ + + if (LeadWest) + for (CurrentList = LeadWest; CurrentList; + CurrentList = CurrentList->NextCon, CurrentColumn = CurrentColumn->NextCol) { + CurrentColumn->NorthCon = CurrentList->ConName; + CurrentColumn->SouthCon = 0; + } + + /* Transfert de la liste NORTH et SOUTH vers la liste des colonnes */ + + + for (Lead_NS_Column = CurrentColumn, CurrentNorthList = LeadNorth, + CurrentSouthList = LeadSouth, Indice = 1; Indice <= Width; + CurrentColumn = CurrentColumn->NextCol, Indice++) { + if (CurrentNorthList) + if (CurrentNorthList->Mark == Indice) { + CurrentColumn->NorthCon = CurrentNorthList->ConName; + CurrentNorthList = CurrentNorthList->NextCon; + } + else CurrentColumn->NorthCon = 0; + else CurrentColumn->NorthCon = 0; + + if (CurrentSouthList) + if (CurrentSouthList->Mark == Indice) { + CurrentColumn->SouthCon = CurrentSouthList->ConName; + CurrentSouthList = CurrentSouthList->NextCon; + } + else CurrentColumn->SouthCon = 0; + else CurrentColumn->SouthCon = 0; + + End_NS_Column = CurrentColumn; + } + + /* Transfert de la liste EAST - si elle n'est pas vide - vers la liste des */ + /* colonnes en creant au fur et a mesure les colonnes necessaires */ + + if (LeadEast) + for (CurrentList = LeadEast, LeadEastColumn = CurrentColumn; CurrentList; + CurrentList = CurrentList->NextCon, CurrentColumn = CurrentColumn->NextCol) { + CurrentColumn->NorthCon = CurrentList->ConName; + CurrentColumn->SouthCon = 0; + } + + return(LeadColumn); +} + +/******************************************************************************/ +/* BELONG */ +/******************************************************************************/ +BOOLEAN SCR_Belong(Element, LeadList, EndList, ControlCon) + +StaticColumn *LeadList; +StaticColumn *EndList; +long Element; +char ControlCon; + +{ + StaticColumn *CurrentColumn = NULL; + BOOLEAN Find = FALSE; + long ConName = 0; + + CurrentColumn = LeadList; + while (CurrentColumn != EndList) { + if (ControlCon == 'N') ConName = CurrentColumn->NorthCon; + else ConName = CurrentColumn->SouthCon; + if (Element == ConName) { + Find = TRUE; + break; + } + CurrentColumn = CurrentColumn->NextCol; + } + return(Find); +} + +/******************************************************************************/ +/* CALCUL DE LA DENSITE DU CANAL */ +/******************************************************************************/ +long SCR_ChannelDensity(LeadStaticColumn, Height) + +StaticColumn *LeadStaticColumn; +long *Height; + +{ + StaticColumn *CurrentColumn = NULL; + StaticColumn *BeforCurrentColumn = NULL; + StaticColumn *AfterCurrentColumn = NULL; + long BeforCurrentNorthCon = 0; + long BeforCurrentSouthCon = 0; + long LocalDensity = 0; + long Density = 0; + + for (CurrentColumn = Lead_NS_Column; CurrentColumn != LeadEastColumn; + CurrentColumn = CurrentColumn->NextCol) { + AfterCurrentColumn = CurrentColumn->NextCol; + for (BeforCurrentColumn = LeadStaticColumn; + BeforCurrentColumn != AfterCurrentColumn; + BeforCurrentColumn = BeforCurrentColumn->NextCol) { + BeforCurrentNorthCon = BeforCurrentColumn->NorthCon; + BeforCurrentSouthCon = BeforCurrentColumn->SouthCon; + if (BeforCurrentNorthCon != BeforCurrentSouthCon) { + if (BeforCurrentNorthCon != 0) + if (!(SCR_Belong(BeforCurrentNorthCon, LeadStaticColumn, + BeforCurrentColumn, 'N') || + SCR_Belong(BeforCurrentNorthCon, LeadStaticColumn, + BeforCurrentColumn, 'S'))) + if (SCR_Belong(BeforCurrentNorthCon, CurrentColumn, + ((StaticColumn *) NULL), 'N') || + SCR_Belong(BeforCurrentNorthCon, CurrentColumn, + ((StaticColumn *) NULL), 'S')) + LocalDensity++; + if (BeforCurrentSouthCon != 0) + if (!(SCR_Belong(BeforCurrentSouthCon, LeadStaticColumn, + BeforCurrentColumn, 'N') || + SCR_Belong(BeforCurrentSouthCon, LeadStaticColumn, + BeforCurrentColumn, 'S'))) + if (SCR_Belong(BeforCurrentSouthCon, CurrentColumn, + ((StaticColumn *) NULL), 'N') || + SCR_Belong(BeforCurrentSouthCon, CurrentColumn, + ((StaticColumn *) NULL), 'S')) + LocalDensity++; + } + else if (CurrentColumn != BeforCurrentColumn) { + if (BeforCurrentNorthCon != 0) + if (!(SCR_Belong(BeforCurrentNorthCon, LeadStaticColumn, + BeforCurrentColumn, 'N') || + SCR_Belong(BeforCurrentNorthCon, LeadStaticColumn, + BeforCurrentColumn, 'S'))) + if (SCR_Belong(BeforCurrentNorthCon, CurrentColumn, + ((StaticColumn *) NULL), 'N') || + SCR_Belong(BeforCurrentNorthCon, CurrentColumn, + ((StaticColumn *) NULL), 'S')) + LocalDensity++; + } + else + if (BeforCurrentNorthCon != 0) + if (!(SCR_Belong(BeforCurrentNorthCon, LeadStaticColumn, + BeforCurrentColumn, 'N') || + SCR_Belong(BeforCurrentNorthCon, LeadStaticColumn, + BeforCurrentColumn, 'S'))) + if (SCR_Belong(BeforCurrentNorthCon, CurrentColumn->NextCol, + ((StaticColumn *) NULL), 'N') || + SCR_Belong(BeforCurrentNorthCon, CurrentColumn->NextCol, + ((StaticColumn *) NULL), 'S')) + LocalDensity++; + + } + Density = MAX(Density, LocalDensity); + LocalDensity = 0; + } + return((*Height = MAX(Density, *Height))); +} + +/******************************************************************************/ +/* INSERER UNE NOUVELLE COLONNE */ +/******************************************************************************/ +void SCR_InsertNewColumn(EndRealChannel, LeadEastColumn, Density, NumberColumn) + +StaticColumn *EndRealChannel; +StaticColumn *LeadEastColumn; +long Density; +long NumberColumn; + +{ + StaticColumn *NewSetColumn = NULL; + StaticColumn *LeadNewChannel = NULL; + StaticColumn *EndNewChannel = NULL; + StaticColumn *CurrentColumn = NULL; + StaticPoint *LeadNewPoint = NULL; + StaticPoint *EndNewPoint = NULL; + StaticPoint *OldPoint = NULL; + StaticPoint *EastPoint = NULL; + + NewSetColumn = SCR_AllowColumn(NumberColumn); + LeadNewChannel = SCR_AllowChannel(NewSetColumn, (Density + 2), NumberColumn); + for (CurrentColumn = LeadNewChannel; CurrentColumn; + CurrentColumn = CurrentColumn->NextCol) + EndNewChannel = CurrentColumn; + if (LeadEastColumn) { + EndNewChannel->NextCol = LeadEastColumn; + LeadEastColumn->PrevCol = EndNewChannel; + EndRealChannel->NextCol = LeadNewChannel; + LeadNewChannel->PrevCol = EndRealChannel; + for (OldPoint = EndRealChannel->PointList, + EastPoint = LeadEastColumn->PointList, + LeadNewPoint = LeadNewChannel->PointList, + EndNewPoint = EndNewChannel->PointList; OldPoint; + OldPoint = OldPoint->NextPoint, + EastPoint = EastPoint->NextPoint, + LeadNewPoint = LeadNewPoint->NextPoint, + EndNewPoint = EndNewPoint->NextPoint ) { + EndNewPoint->RightPoint = EastPoint; + OldPoint->RightPoint = LeadNewPoint; + } + } + else { + EndRealChannel->NextCol = LeadNewChannel; + LeadNewChannel->PrevCol = EndRealChannel; + for (OldPoint = EndRealChannel->PointList, + LeadNewPoint = LeadNewChannel->PointList; OldPoint; + OldPoint = OldPoint->NextPoint, + LeadNewPoint = LeadNewPoint->NextPoint ) + OldPoint->RightPoint = LeadNewPoint; + } +} + +/******************************************************************************/ +/* INSERER UNE NOUVELLE PISTE */ +/******************************************************************************/ +void SCR_InsertNewTrack(LeadDataBase, Position, Width) + +StaticColumn *LeadDataBase; +long Position; +long Width; + +{ + StaticPoint *CurrentPoint = NULL; + StaticPoint *NextCurrentPoint = NULL; + StaticPoint *NewTrack = NULL; + long Counter = 1; + + for (CurrentPoint = LeadDataBase->PointList; Counter < Position; Counter++, + CurrentPoint = CurrentPoint->NextPoint); + NewTrack = SCR_AllowOneTrack(Width); + for (NextCurrentPoint = CurrentPoint->NextPoint; CurrentPoint; + CurrentPoint = CurrentPoint->RightPoint, + NextCurrentPoint = NextCurrentPoint->RightPoint, + NewTrack = NewTrack->RightPoint) { + NewTrack->NextPoint = NextCurrentPoint; + CurrentPoint->NextPoint = NewTrack; + } +} + +/******************************************************************************/ +/* POST TREATMENT OF THE WEST CONNECTORS */ +/******************************************************************************/ +StaticColumn *SCR_WestPostAnalysis(Lead_NS_Column, LeadWestCon, Density) + +StaticColumn *Lead_NS_Column; +ConnectorList *LeadWestCon; +long Density; + +{ + StaticColumn *CurrentColumn = NULL; + StaticColumn *EndWestColumn = NULL; + StaticPoint *CurrentPoint = NULL; + StaticPoint *PointList = NULL; + ConnectorList *CurrentList = NULL; + long TrackCounter = 0; + long Counter; + + EndWestColumn = Lead_NS_Column->PrevCol; + EndWestColumn->PointList->Via = FALSE; + EndWestColumn->PointList->Layer1 = NOP; + EndWestColumn->PointList->Layer2 = NOP; + for (CurrentColumn = EndWestColumn; CurrentColumn; + CurrentColumn = CurrentColumn->PrevCol) { + for (TrackCounter = Density, + CurrentPoint = CurrentColumn->PointList->NextPoint; + ((CurrentPoint) && (CurrentPoint->Layer1 != RIGHT)); + CurrentPoint = CurrentPoint->NextPoint, TrackCounter--); + for (Counter = Density, PointList = EndWestColumn->PointList->NextPoint; + Counter > TrackCounter; PointList = PointList->NextPoint, Counter--); + PointList->Via = FALSE; + PointList->Layer1 = RIGHT; + PointList->Layer2 = NOP; + for (CurrentList = LeadWestCon; + CurrentList->ConName != CurrentPoint->PointName; + CurrentList = CurrentList->NextCon); + CurrentList->Mark = TrackCounter; + } + return (EndWestColumn); +} + +/******************************************************************************/ +/* POST TREATMENT OF THE EAST CONNECTORS */ +/******************************************************************************/ +StaticColumn *SCR_EastPostAnalysis(LeadEastColumn, LeadEastCon, Density) + +StaticColumn *LeadEastColumn; +ConnectorList *LeadEastCon; +long Density; + +{ + StaticColumn *CurrentColumn = NULL; + StaticPoint *CurrentPoint = NULL; + StaticPoint *CurrentEastPoint = NULL; + StaticPoint *EastPoint = NULL; + ConnectorList *CurrentList = NULL; + long TrackCounter = 0; + BOOLEAN NetNotTreated = TRUE; + BOOLEAN FirstColumn = TRUE; + + LeadEastColumn->PointList->Via = FALSE; + LeadEastColumn->PointList->Layer1 = NOP; + LeadEastColumn->PointList->Layer2 = NOP; + + for (CurrentColumn = LeadEastColumn; CurrentColumn; + CurrentColumn = CurrentColumn->NextCol) { + + for (TrackCounter = Density, + CurrentPoint = CurrentColumn->PointList->NextPoint, + CurrentEastPoint = LeadEastColumn->PointList->NextPoint; CurrentPoint; + CurrentEastPoint = CurrentEastPoint->NextPoint, + CurrentPoint = CurrentPoint->NextPoint, TrackCounter--) { + if (CurrentPoint->Layer1 == LEFT) { + NetNotTreated = TRUE; + if (FirstColumn) { + for (CurrentList = LeadEastCon; + CurrentList->ConName != CurrentPoint->PointName; + CurrentList = CurrentList->NextCon); + CurrentList->Mark = TrackCounter; + } + else { + for (EastPoint = LeadEastColumn->PointList->NextPoint; EastPoint; + EastPoint = EastPoint->NextPoint) + if (EastPoint->PointName == CurrentPoint->PointName) { + NetNotTreated = FALSE; + break; + } + if (NetNotTreated) { + CurrentEastPoint->PointName = CurrentPoint->PointName; + CurrentEastPoint->Layer1 = LEFT; + for (CurrentList = LeadEastCon; + CurrentList->ConName != CurrentPoint->PointName; + CurrentList = CurrentList->NextCon); + CurrentList->Mark = TrackCounter; + } + } + } + else + if (CurrentEastPoint->Layer1 != LEFT) { + CurrentEastPoint->PointName = ((long ) 0); + CurrentEastPoint->Layer1 = NOP; + } + CurrentEastPoint->Via = FALSE; + CurrentEastPoint->Layer2 = NOP; + } + FirstColumn = FALSE; + } + return (LeadEastColumn); +} + +/******************************************************************************/ +/* SAUVEGARDE DU RESULTAT DE ROUTAGE */ +/******************************************************************************/ +void SCR_SaveResult( + LeadDataBase, EndDataBase, LeadH_Segment, + LeadV_Segment, LeadVia, Density, LeadWestCon + ) + +StaticColumn *LeadDataBase; +StaticColumn *EndDataBase; +SegmentList **LeadH_Segment; +SegmentList **LeadV_Segment; +ViasList **LeadVia; +long Density; +ConnectorList *LeadWestCon; + +{ + StaticColumn *CurrentColumnList = NULL; + StaticPoint *CurrentPoint = NULL; + StaticPoint *RightCurrentPoint = NULL; + StaticPoint *NextCurrentPoint = NULL; + SegmentList *CurrentH_Segment = NULL; + SegmentList *CurrentV_Segment = NULL; + ViasList *CurrentVia = NULL; + SegmentList *BeforCurrentH_Seg = NULL; + SegmentList *BeforCurrentV_Seg = NULL; + ViasList *BeforCurrentVia = NULL; + long CounterTrack = 0; + long Counter = 0; + long CounterColumn = 0; + BOOLEAN FirstVia = TRUE; + BOOLEAN FirstH_Segment = TRUE; + BOOLEAN FirstV_Segment = TRUE; + char NodeName[15]; + char Buffer[10]; + + if (LeadWestCon) CounterColumn = 0; + else CounterColumn = 1; + for (CurrentColumnList = LeadDataBase; (CurrentColumnList != EndDataBase); + CurrentColumnList = CurrentColumnList->NextCol, CounterColumn++) + for (CurrentPoint = CurrentColumnList->PointList, + CounterTrack = (Density + 1); CurrentPoint; + CurrentPoint = CurrentPoint->NextPoint, CounterTrack--) { + + sprintf(Buffer,"%ld",CurrentPoint->PointName); + strcpy(NodeName,"Seg_"); + strcat(NodeName,Buffer); + + if (CurrentPoint->Via) { + if (FirstVia) { + *LeadVia = BeforCurrentVia = SCR_AllowViasList(); + BeforCurrentVia->XVia = CounterColumn; + BeforCurrentVia->YVia = CounterTrack; + FirstVia = FALSE; + } + else { + CurrentVia = SCR_AllowViasList(); + BeforCurrentVia->NextVia = CurrentVia; + CurrentVia->XVia = CounterColumn; + CurrentVia->YVia = CounterTrack; + BeforCurrentVia = CurrentVia; + } + } + + if (CurrentPoint->Layer1 == RIGHT) { + if (FirstH_Segment) { + *LeadH_Segment = BeforCurrentH_Seg = SCR_AllowSegmentList(); + BeforCurrentH_Seg->SegName = namealloc(NodeName); + BeforCurrentH_Seg->X1Seg = CounterColumn; + BeforCurrentH_Seg->Y1Seg = BeforCurrentH_Seg->Y2Seg = CounterTrack; + for (Counter = CounterColumn, RightCurrentPoint = CurrentPoint->RightPoint; + ((RightCurrentPoint) && (RightCurrentPoint->Layer1 != LEFT)); + RightCurrentPoint = RightCurrentPoint->RightPoint, Counter++); + BeforCurrentH_Seg->X2Seg = ++Counter; + FirstH_Segment = FALSE; + } + else { + CurrentH_Segment = SCR_AllowSegmentList(); + BeforCurrentH_Seg->NextSeg = CurrentH_Segment; + CurrentH_Segment->SegName = namealloc(NodeName); + CurrentH_Segment->X1Seg = CounterColumn; + CurrentH_Segment->Y1Seg = CurrentH_Segment->Y2Seg = CounterTrack; + for (Counter = CounterColumn, RightCurrentPoint = CurrentPoint->RightPoint; + ((RightCurrentPoint) && (RightCurrentPoint->Layer1 != LEFT)); + RightCurrentPoint = RightCurrentPoint->RightPoint, Counter++); + CurrentH_Segment->X2Seg = ++Counter; + BeforCurrentH_Seg = CurrentH_Segment; + } + } + + if (CurrentPoint->Layer2 == DOWN) { + if (FirstV_Segment) { + *LeadV_Segment = BeforCurrentV_Seg = SCR_AllowSegmentList(); + BeforCurrentV_Seg->SegName = namealloc(NodeName); + BeforCurrentV_Seg->X1Seg = BeforCurrentV_Seg->X2Seg = CounterColumn; + BeforCurrentV_Seg->Y2Seg = CounterTrack; + for (Counter = CounterTrack, NextCurrentPoint = CurrentPoint->NextPoint; + ((NextCurrentPoint) && (NextCurrentPoint->Layer2 != UP)); + NextCurrentPoint = NextCurrentPoint->NextPoint, Counter--); + BeforCurrentV_Seg->Y1Seg = --Counter; + FirstV_Segment = FALSE; + } + else { + CurrentV_Segment = SCR_AllowSegmentList(); + BeforCurrentV_Seg->NextSeg = CurrentV_Segment; + CurrentV_Segment->SegName = namealloc(NodeName); + CurrentV_Segment->X1Seg = CurrentV_Segment->X2Seg = CounterColumn; + CurrentV_Segment->Y2Seg = CounterTrack; + for (Counter = CounterTrack, NextCurrentPoint = CurrentPoint->NextPoint; + ((NextCurrentPoint) && (NextCurrentPoint->Layer2 != UP)); + NextCurrentPoint = NextCurrentPoint->NextPoint, Counter--); + CurrentV_Segment->Y1Seg = --Counter; + BeforCurrentV_Seg = CurrentV_Segment; + } + } + } +} + +/******************************************************************************/ +/* SYMBOLIC CHANNEL ROUTER */ +/******************************************************************************/ +BOOLEAN SymbolicChannelRouter( + LeadNorthCon, LeadSouthCon, + LeadWestCon, LeadEastCon, + ChannelWidth, ChannelHeight, + LeadH_Segment, LeadV_Segment, LeadVia + ) + +ConnectorList **LeadNorthCon; +ConnectorList **LeadSouthCon; +ConnectorList **LeadWestCon; +ConnectorList **LeadEastCon; +long *ChannelWidth; +long *ChannelHeight; +SegmentList **LeadH_Segment; +SegmentList **LeadV_Segment; +ViasList **LeadVia; + +{ + long OldChannelWidth = 0; + long NewChannelWidth = 0; + long ChannelDensity = 0; + StaticColumn *LeadStaticColumn = NULL; + StaticColumn *LeadColumnList = NULL; + StaticColumn *LeadStaticDataBase = NULL; + StaticColumn *LeadRealChannel = NULL; + StaticColumn *EndRealChannel = NULL; + BOOLEAN Change = FALSE; + + Lead_NS_Column = NULL; + End_NS_Column = NULL; + LeadEastColumn = NULL; + OldChannelWidth = *ChannelWidth; + +# ifdef SCR_DEBUG + fprintf(stderr,"Befor elimination : \n"); + fprintf(stderr,"Northlist : \n"); + U_PrintList(*LeadNorthCon); + fprintf(stderr,"Southlist : \n"); + U_PrintList(*LeadSouthCon); + fprintf(stderr,"Westlist : \n"); + U_PrintList(*LeadWestCon); + fprintf(stderr,"Eastlist : \n"); + U_PrintList(*LeadEastCon); +# endif + +# ifdef SCR_DEBUG + fprintf(stderr,"Eliminate a Multiply Connector on West Edge if necessary \n"); +# endif + + if (LeadWestCon) SCR_Eliminate(LeadWestCon); + +# ifdef SCR_DEBUG + fprintf(stderr,"Eliminate a Multiply Connector on East Edge if necessary \n"); +# endif + + if (LeadEastCon) SCR_Eliminate(LeadEastCon); + + EliminateOnlyCon(LeadNorthCon,LeadSouthCon,LeadWestCon,LeadEastCon); + EliminateOnlyCon(LeadSouthCon,LeadNorthCon,LeadWestCon,LeadEastCon); + if (LeadWestCon) EliminateOnlyCon(LeadWestCon,LeadNorthCon,LeadSouthCon,LeadEastCon); + if (LeadEastCon) EliminateOnlyCon(LeadEastCon,LeadNorthCon,LeadSouthCon,LeadWestCon); + +# ifdef SCR_DEBUG + fprintf(stderr,"After elimination : \n"); + fprintf(stderr,"Northlist : \n"); + U_PrintList(*LeadNorthCon); + fprintf(stderr,"Southlist : \n"); + U_PrintList(*LeadSouthCon); + fprintf(stderr,"Westlist : \n"); + U_PrintList(*LeadWestCon); + fprintf(stderr,"Eastlist : \n"); + U_PrintList(*LeadEastCon); +# endif + +# ifdef SCR_DEBUG + fprintf(stderr,"Computing a New Channel Width \n"); +# endif + + NewChannelWidth = SCR_NewChannelWidth(*LeadWestCon,*LeadEastCon,*ChannelWidth); + +# ifdef SCR_DEBUG + fprintf(stderr,"Allow Static Column \n"); +# endif + + LeadStaticColumn = SCR_AllowColumn(NewChannelWidth); + +# ifdef SCR_DEBUG + fprintf(stderr,"Loading Static Data Base \n"); +# endif + + LeadColumnList = SCR_LoadStaticColumn(LeadStaticColumn, + *LeadNorthCon,*LeadSouthCon, + *LeadWestCon,*LeadEastCon, + OldChannelWidth); + +# ifdef SCR_DEBUG + fprintf(stderr,"Column Static Data Base \n"); + U_PrintColumn(LeadColumnList); + fprintf(stderr,"Computing Channel Density \n"); +# endif + + ChannelDensity = SCR_ChannelDensity(LeadColumnList, ChannelHeight); + +# ifdef SCR_DEBUG + fprintf(stderr,"Channel Density = %ld \n", ChannelDensity); + fprintf(stderr,"Allow Memory of a Channel \n"); +# endif + + LeadStaticDataBase = SCR_AllowChannel( LeadColumnList, ChannelDensity + 2, + NewChannelWidth); + + LeadRealChannel = LeadStaticDataBase; + +# ifdef SCR_DEBUG + fprintf(stderr,"U_PrintStaticDataBase Befor Routing\n"); + U_PrintStaticDataBase(LeadStaticDataBase); + fprintf(stderr,"Greedy Router \n"); +# endif + + *ChannelWidth = OldChannelWidth; + SCR_GreedyRouter( LeadStaticDataBase, End_NS_Column, LeadEastColumn, + &ChannelDensity, NewChannelWidth, ChannelWidth); + + *ChannelHeight = ChannelDensity; + + if (OldChannelWidth != *ChannelWidth) Change = TRUE; + +# ifdef SCR_DEBUG + fprintf(stderr,"ChannelDensity = %ld \n", ChannelDensity); + fprintf(stderr,"U_PrintStaticDataBase \n"); + U_PrintStaticDataBase(LeadStaticDataBase); +# endif + + if (*LeadWestCon) { + LeadRealChannel = SCR_WestPostAnalysis( Lead_NS_Column,*LeadWestCon, + ChannelDensity); + } + + if (*LeadEastCon) { + EndRealChannel = SCR_EastPostAnalysis( LeadEastColumn,*LeadEastCon, + ChannelDensity ); + } + +# ifdef SCR_DEBUG + fprintf(stderr,"U_PrintStaticDataBase \n"); + U_PrintStaticDataBase(LeadRealChannel); + fprintf(stderr,"Saving a Channel Router Result \n"); +# endif + + SCR_SaveResult(LeadRealChannel, EndRealChannel, LeadH_Segment, + LeadV_Segment, LeadVia, ChannelDensity,*LeadWestCon); + +# ifdef SCR_DEBUG + fprintf(stderr,"Print Horizontal Segment : \n"); + U_PrintSegmentList(*LeadH_Segment); + fprintf(stderr,"Print Vertical Segment : \n"); + U_PrintSegmentList(*LeadV_Segment); + fprintf(stderr,"Print Via List : \n"); + U_PrintViasList(*LeadVia); + fprintf(stderr,"Free of Memory \n"); +# endif + + SCR_FreeDataBase(LeadStaticDataBase); + + return (Change); +} diff --git a/alliance/src/gscr/src/gscr_SymbChanRout.h b/alliance/src/gscr/src/gscr_SymbChanRout.h new file mode 100644 index 00000000..7d37d2f1 --- /dev/null +++ b/alliance/src/gscr/src/gscr_SymbChanRout.h @@ -0,0 +1,34 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +extern void SCR_Eliminate(); +extern long SCR_NewChannelWidth(); +extern StaticColumn *SCR_LoadStaticColumn(); +extern BOOLEAN SCR_Belong(); +extern long SCR_ChannelDensity(); +extern void SCR_InsertNewColumn(); +extern void SCR_InsertNewTrack(); +extern void SCR_GreedyRouter(); +extern StaticColumn *SCR_WestEastPostAnalysis(); +extern void SCR_SaveResult(); +extern BOOLEAN SymbolicChannelRouter(); diff --git a/alliance/src/gscr/src/gscr_greedy.h b/alliance/src/gscr/src/gscr_greedy.h new file mode 100644 index 00000000..8c037fe7 --- /dev/null +++ b/alliance/src/gscr/src/gscr_greedy.h @@ -0,0 +1,48 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +# define IMPAIRE(a) (((a) & 1) ? TRUE : FALSE) +# define JOG_LENGTH(a) ((long ) (IMPAIRE(a) ? ((a+1) >> 2) : ((a) >> 2))) +# define MINJOG_LENGTH ((long ) 1) +# define LEADPATTERN 6 +extern long EndPattern; +long TabRout[MAXCOL][MAXLINE]; + +BOOLEAN TOPNOTROUT, BOTNOTROUT; + +#define PREVHNET(I) TabRout[0][I] +#define HNET(I) TabRout[1][I] +#define SPLIT(I) TabRout[2][I] +#define SFRT(I) TabRout[3][I] +#define WEIGHT(I) TabRout[4][I] +#define VNET(I) TabRout[5][I] +#define COMBI(I,J) TabRout[I][J] +#define SCR_TOP TabRout[1][0] +#define SCR_BOTTOM(I) TabRout[1][I] + +#define SNC ((long ) 1000) +#define TERMINAL ((long ) 0) +#define NOTTERMINAL ((long ) 1) +#define STEADY ((long ) 2) +#define FALLING ((long ) 3) +#define RISING ((long ) 4) diff --git a/alliance/src/gscr/src/gscr_main.c b/alliance/src/gscr/src/gscr_main.c new file mode 100644 index 00000000..94d80697 --- /dev/null +++ b/alliance/src/gscr/src/gscr_main.c @@ -0,0 +1,102 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* Cette fonction est provisoire, elle fait just appel a la fonction routeur */ +/******************************************************************************/ + +# include +# include "apr.h" +# include "gscr_DataBase.h" +# include "gscr_StaticUtil.h" +# include "gscr_SymbChanRout.h" + +main(argc,argv) + +int argc; +char *argv[]; + +{ + ConnectorList *LeadNorthList = NULL; + ConnectorList *LeadSouthList = NULL; + ConnectorList *LeadWestList = NULL; + ConnectorList *LeadEastList = NULL; + SegmentList *LeadH_Segment = NULL; + SegmentList *LeadV_Segment = NULL; + ViasList *LeadViaList = NULL; + long ChannelWidth = 0; + long ChannelHeight = 0; + BOOLEAN Change = FALSE; + + mbkenv(); + if (argc == 1) fprintf(stdout,"Erreur manque du nom de fichier \n"); + else { + U_GetChannel(argv[1], &LeadNorthList, &LeadSouthList, + &LeadWestList, &LeadEastList); + +# ifdef SCR_DEBUG + fprintf(stdout,"Northlist : \n"); + U_PrintList(LeadNorthList); + fprintf(stdout,"Southlist : \n"); + U_PrintList(LeadSouthList); + fprintf(stdout,"Westlist : \n"); + U_PrintList(LeadWestList); + fprintf(stdout,"Eastlist : \n"); + U_PrintList(LeadEastList); +# endif + + ChannelWidth = U_ChannelWidth(LeadNorthList, LeadSouthList); + +# ifdef SCR_DEBUG + fprintf(stdout,"ChannelWidth = %ld \n",ChannelWidth); +# endif + + Change = SymbolicChannelRouter(LeadNorthList,LeadSouthList, LeadWestList, + LeadEastList, &ChannelWidth, &ChannelHeight, + &LeadH_Segment, &LeadV_Segment, &LeadViaList); + + gscr2mbk(argv[2],LeadH_Segment,LeadV_Segment,LeadViaList, + LeadNorthList,LeadSouthList,LeadWestList, + LeadEastList,ChannelWidth,ChannelHeight); + + if (LeadH_Segment) SCR_FreeSegmentList(LeadH_Segment); + if (LeadV_Segment) SCR_FreeSegmentList(LeadV_Segment); + if (LeadViaList) SCR_FreeViasList(LeadViaList); + +# ifdef SCR_DEBUG + fprintf(stdout,"ChannelWidth = %ld \n",ChannelWidth); + fprintf(stdout,"ChannelHeight = %ld \n",ChannelHeight); + fprintf(stdout,"NorthList : \n"); + U_PrintList(LeadNorthList); + fprintf(stdout,"SouthList : \n"); + U_PrintList(LeadSouthList); + fprintf(stdout,"Westlist : \n"); + U_PrintList(LeadWestList); + fprintf(stdout,"Eastlist : \n"); + U_PrintList(LeadEastList); +# endif + + } +} + + diff --git a/alliance/src/gscr/src/gscr_main.h b/alliance/src/gscr/src/gscr_main.h new file mode 100644 index 00000000..48e0237f --- /dev/null +++ b/alliance/src/gscr/src/gscr_main.h @@ -0,0 +1,27 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +extern ConnectorList *LeadNorthList; +extern ConnectorList *LeadSouthList; +extern ConnectorList *LeadWestList; +extern ConnectorList *LeadEastList; diff --git a/alliance/src/gscr/src/scp_channel.c b/alliance/src/gscr/src/scp_channel.c new file mode 100644 index 00000000..deba2bb5 --- /dev/null +++ b/alliance/src/gscr/src/scp_channel.c @@ -0,0 +1,178 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_channel.c */ +/* Contents : main of placer */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 21/07/1993 */ +/* */ +/******************************************************************************/ + +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include "scp_channel.h" +extern int SXMODE; +# define PITCH_X ((long )((SXMODE ? 5:6) * SCALE_X)) +/*---------------------------------------------------------\ + Les definitions de type +\---------------------------------------------------------*/ +typedef struct cells +{ + struct cells *NEXT; + phins_list *INS; +} cells_list; +#define min(x,y) ((xPHINS == NULL) + return (NULL); + if (Abscisse % PITCH_X || + Epsilon % PITCH_X || + Largeur % PITCH_X) + { + fprintf (stderr, "X(%d), Width(%d), Epsilon(%d) MUST be PITCHED\n", Abscisse, Largeur, Epsilon); + exit (1); + } + Abscisse += Figure->XAB1; + Oy = Figure->YAB1; + Fig = getphfig(Figure->PHINS->FIGNAME,'A'); + sx2sc (Fig); + Height = Fig->YAB2 - Fig->YAB1; + if (Epsilon + Abscisse > Figure->XAB2 || + Epsilon - Abscisse <= Figure->XAB1) + Epsilon = 0; + + /* on commence par calculer le nombre de lignes qu'occupe la figure */ + NbCells = 0; + NbRow = 0; + for (Ins = Figure->PHINS; Ins; Ins=Ins->NEXT) + { + NbCells++; + Row = (Ins->YINS - Oy) / Height; + if (Row > NbRow) + NbRow = Row; + } + NbRow++; /* la ligne 0 existe : 0 a 3 donne 4 lignes */ + + /* on remplit la structure rows */ + Rows = (cells_list **) mbkalloc (sizeof (cells_list *) * NbRow); + memset (Rows, 0, sizeof (cells_list *) * NbRow); + List = (cells_list **) mbkalloc (sizeof (cells_list *) * NbRow); + CellTab = (cells_list *) mbkalloc (sizeof (cells_list) * NbCells); + memset (CellTab, 0, sizeof (cells_list) * NbCells); + iCell = 0; + for (Ins = Figure->PHINS; Ins; Ins=Ins->NEXT, iCell++) + { + Row = (Ins->YINS - Oy) / Height; + X = Ins->XINS; + Cell = &CellTab[iCell]; + Cell->INS = Ins; + Fig = getphfig (Ins->FIGNAME,'A'); + sx2sc (Fig); + Previous = (cells_list *)&Rows[Row]; + for (Current = Rows[Row]; Current && X > Current->INS->XINS; Previous = Current, Current = Current->NEXT); + Cell->NEXT = Current; + Previous->NEXT = Cell; + } + + /* on recherche l'abscisse optimale */ + XOpen = Abscisse - Epsilon; + MinCost = 1<<30; + for (X = XOpen; X <= Abscisse + Epsilon; X+=PITCH_X) + { + long Left, Right, Cost; + + Left = 1<<30; + Right = 0; + Cost = 0; + for (i=0; iINS->XINS < X; Previous = Cell, Cell = Cell->NEXT); + if (Previous) + { + if (Previous->INS->XINS < Left) + Left = Previous->INS->XINS; + if (Previous->INS->XINS > Right) + Right = Previous->INS->XINS; + } + if (Right - Left > Cost) + Cost = Right - Left; + } + if (MinCost > Cost && + abs(XOpen-Abscisse) >= abs(X-Abscisse)) + { + MinCost = Cost; + XOpen = X; + } + } + + X = MinCost + Largeur; + if (X%PITCH_X) + X += PITCH_X - X % PITCH_X; + for (i=0; iINS->XINS < XOpen; Previous = Cell, Cell = Cell->NEXT); + for (Cell = Previous; Cell; Cell = Cell->NEXT) + Cell->INS->XINS += X; + } + Figure->XAB2 += X; + mbkfree (CellTab); + mbkfree (Rows); + mbkfree (List); +} /* fin de OpenVerticalChannel */ diff --git a/alliance/src/gscr/src/scp_channel.h b/alliance/src/gscr/src/scp_channel.h new file mode 100644 index 00000000..530358f1 --- /dev/null +++ b/alliance/src/gscr/src/scp_channel.h @@ -0,0 +1,54 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_channel.h */ +/* Contents : prototypes du parser */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/08/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_CHANNEL +#define SCP_CHANNEL +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include +#include +#include + +/*---------------------------------------------------------\ + Prototypes +\---------------------------------------------------------*/ +extern phfig_list *OpenVerticalChannel (); + +#endif /* SCP_CHANNEL */ diff --git a/alliance/src/gscr/src/scp_inits.c b/alliance/src/gscr/src/scp_inits.c new file mode 100644 index 00000000..6beca3c1 --- /dev/null +++ b/alliance/src/gscr/src/scp_inits.c @@ -0,0 +1,346 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_inits.c */ +/* Contents : fonctions d'initialisation */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Pierre Fedrichkine Date : 02/07/1993 */ +/* Modified by : Xavier Picat Date : 08/07/1993 */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include +#include +#include "scp_types.h" +#include "scp_main.h" +#include "scp_mbk2scp.h" +#include "scp_inits.h" + +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +static void InsereConnecteur (); + +/*---------------------------------------------------------\ + Les variables globales +\---------------------------------------------------------*/ +long NombreLignes; +long LargeurIdeale; +long Norme; + +/*---------------------------------------------------------\ + initialisation +\---------------------------------------------------------*/ +void initialisation(WeightRow,nbrow,WHratio) +int WeightRow; +int nbrow; +int WHratio; +{ + long NombreLignesIdeal, NormeLignesIdeal; + long NormeBandes, NormeCellules; + + /* on considere que pour une bande de hauteur n, la hauteur du canal + * de routage est egale a 2.5*n d'ou le /3.5 -> 99/23/9 WHratio + */ + if (WHratio==0) WHratio=100; + NombreLignesIdeal = (int)(sqrt((float)LargeurTotale/(3 * (float)Hauteur * WHratio/100))); + NormeLignesIdeal = (int)(sqrt((float)NombreCellules)/2); + if (NombreLignesIdeal == 0) + NombreLignesIdeal++; + if (NormeLignesIdeal == 0) + NormeLignesIdeal++; + NombreLignes = (nbrow == 0) ? NombreLignesIdeal : nbrow; + + LargeurIdeale = LargeurTotale / NombreLignes; + fprintf(stderr,"Original width : %ld\n", LargeurIdeale); + NormeBandes = 1; + if (NombreLignes < (NormeLignesIdeal >> 1)) + NormeBandes = -((NombreLignes << 3) / NormeLignesIdeal) + 5; + else if (NombreLignes > (NormeLignesIdeal << 1)) + NormeBandes = ((NombreLignes << 1) / NormeLignesIdeal) - 3; + + NormeCellules = FLOAT_TO_LONG; + if (NombreCellules > 100) + { + NormeCellules *= NombreCellules; + NormeCellules /= 350; + NormeCellules += 0.71 * FLOAT_TO_LONG; + } + Norme = NormeCellules * NormeBandes * WeightRow; + + Rows = (row_elt *) mbkalloc (sizeof (row_elt) * NombreLignes); + memset (Rows, 0, sizeof (row_elt) * NombreLignes); +} /* fin de initialisation */ + +/*---------------------------------------------------------\ + generation_configuration_initiale + + fonction realisant le placement initial aleatoire +\---------------------------------------------------------*/ +void generation_configuration_initiale(ptlofig, Connectors, WeightCon, WeightY) +lofig_list *ptlofig; +PlaceConList *Connectors; +long WeightCon; +long WeightY; +{ + CaracConList *Con; + int nLigne; + int iCell; /* indice de cellule */ + int iRow; /* indice de collonne */ + int iCol; /* indice de colonne */ + long iPos; /* indice de position */ + int up = 1; + int NombreCellulesParRangee; + int *tab_row; /* table d'occupation des rangees (nb cellules) */ + int **tab_row_col; /* position des cellules */ + + /*********************** initialisations ******************************/ + tab_row_col = (int **) mbkalloc (sizeof (int *) * NombreLignes); + for (iRow =0; iRow < NombreLignes; iRow++) + { + tab_row_col[iRow] = mbkalloc (sizeof (int) * NombreCellules); + memset (tab_row_col[iRow], NONE, sizeof (int) * NombreCellules); + } + tab_row = (int *) mbkalloc (sizeof (int) * NombreLignes); + memset (tab_row, 0, sizeof (int) * NombreLignes); + + /*********************** initialisations ******************************/ + NombreCellulesParRangee = NombreCellules / NombreLignes; /* nb de cells par rangee (div entiere) */ + + /************ repartition des cellules dans les rangees ***************/ + for (iCell = 0;iCell < NombreCellules;iCell++) + { + do + { + nLigne = rand()%NombreLignes; + } while(tab_row[nLigne] > NombreCellulesParRangee); + tab_row[nLigne]++; + Cells[iCell].row = nLigne; + Cells[iCell].y = nLigne << WeightY; + } + + /************* repartition des cellules par colonnes *****************/ + for (iCell = 0; iCell < NombreCellules; iCell++) + { + nLigne = Cells[iCell].row; + iCol = rand()%tab_row[nLigne]; + while(tab_row_col[nLigne][iCol] != NONE) + if (up) + if(iCol == tab_row[nLigne]-1) + iCol =0; + else + iCol++; + else + if(iCol == 0) + iCol = tab_row[nLigne]-1; + else + iCol--; + tab_row_col[nLigne][iCol] = iCell; + up = 1 - up; + } + + /******** affectation du placement dans la structure Cells ************/ + for (iRow=0; iRow < NombreLignes; iRow++) + { + cell_list *Cell, *PrevCell; + + iCell = tab_row_col[iRow][0]; + Cell = &Cells[iCell]; + iPos = Cell->width; + + Rows[iRow].head = Cell; + Cell->prev = NULL; + Cell->x = Cell->width >> 0 /* 99/9/21 1 */; + + for (iCol=1; iCol < tab_row[iRow]; iCol++) + { + PrevCell = Cell; + + iCell = tab_row_col[iRow][iCol]; + Cell = &Cells[iCell]; + Cell->x = iPos + (Cell->width >> 0 /* 99/9/21 1 */); + iPos += Cell->width; + + Cell->prev = PrevCell; + PrevCell->next = Cell; + } + Rows[iRow].tail = Cell; + Cell->next = NULL; + Rows[iRow].length = iPos; + } + + /* insertion des connecteurs */ + if (Connectors) + { + cell_list *Cell; + + iCell = NombreCellules; + for (Con = Connectors->NORTH_CON; Con; Con = Con->NEXT) + { + Cell = &Cells[iCell]; + InsereConnecteur (Cell, NombreLignes - 1); + /* Cell->x = 0; */ + Cell->y = (NombreLignes << WeightY) + WeightCon; + iCell++; + } + for (Con = Connectors->SOUTH_CON; Con; Con = Con->NEXT) + { + Cell = &Cells[iCell]; + InsereConnecteur (Cell, 0); + /* Cell->x = 0; */ + Cell->y = - WeightCon; + iCell++; + } + for (Con = Connectors->WEST_CON; Con; Con = Con->NEXT) + { + Cell = &Cells[iCell]; + InsereConnecteur (Cell, Con->USER); + Cell->x = -WeightCon; + Cell->y = Con->USER << WeightY; + iCell++; + } + for (Con = Connectors->EAST_CON; Con; Con = Con->NEXT) + { + Cell = &Cells[iCell]; + InsereConnecteur (Cell, Con->USER); + Cell->x = LargeurIdeale+WeightCon; + Cell->y = Con->USER << WeightY; + iCell++; + } + } + + for (iRow =0; iRow < NombreLignes; iRow++) + mbkfree (tab_row_col[iRow]); + mbkfree (tab_row_col); + mbkfree (tab_row); +} /* fin de generation_configuration_initiale */ + +/*---------------------------------------------------------\ + InsereConnecteur +\---------------------------------------------------------*/ +static void InsereConnecteur (Cell,nLigne) +cell_list *Cell; +int nLigne; +{ + if (nLigne >= NombreLignes) + { + fprintf (stderr, "There are only %d rows and a connector is placed in row %d\n", NombreLignes, nLigne); + exit (1); + } + Cell->row = nLigne; + Rows[nLigne].head->prev = Cell; + Cell->next = Rows[nLigne].head; + Cell->prev = NULL; + Rows[nLigne].head = Cell; +} /* fin de InsereConnecteur */ + + + + +/* Cette version genere un placement environ deux fois meilleur que le placement + * aleatoire genere ci-dessus. Il pourrait etre interessant de l'utiliser pour + * un nombre d'iterations a 0, ou en diminuant le taux d'acceptation initial, car + * le resultat obtenu est identique. + * ATTENTION, elle n'utilise pas le meme format de donnee que celui implemente +void generation_configuration_initiale(ptlofig, Connectors, ConWeight) +lofig_list *ptlofig; +PlaceConList *Connectors; +long ConWeight; +{ + int iCell,j; + int NonPlacee; + cell_list *Cell; + + for (iCell=0; iCellnext == NULL || + ((Rows[j].length+Cell->width < LargeurIdeale) && SignalCommun (Cell,Rows[j].tail))) + { + InsereCellule (Cell,j); + NonPlacee = FALSE; + } + j++; + } while (jwidth; + DepassementMin = Rows[0].length+Largeur-LargeurIdeale; + Ligne = 0; + for (j=1; jfirst; sig1; sig1 = sig1->next) + for (sig2 = Cell2->first; sig2; sig2 = sig2->next) + if (sig1->net == sig2->net) + return (1); + return (0); +} + +static void InsereCellule (Cell,Ligne) +cell_list *Cell; +int Ligne; +{ + Cell->pos = Cell->width>>1; + if (Rows[Ligne].head->next) + Cell->pos += Rows[Ligne].tail->pos + (Rows[Ligne].tail->width>>1); + Rows[Ligne].length += Cell->width; + Cell->row = Ligne; + + Cell->next = (cell_list *)&Rows[Ligne].null; + Cell->prev = Rows[Ligne].tail; + Rows[Ligne].tail->next = Cell; + Rows[Ligne].tail = Cell; +} + */ diff --git a/alliance/src/gscr/src/scp_inits.h b/alliance/src/gscr/src/scp_inits.h new file mode 100644 index 00000000..53d70d71 --- /dev/null +++ b/alliance/src/gscr/src/scp_inits.h @@ -0,0 +1,56 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_inits.h */ +/* Contents : prototypes des fonctions d'initialisation */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_INITS_H +#define SCP_INITS_H + +/*---------------------------------------------------------\ + Les variables globales +\---------------------------------------------------------*/ +extern long LargeurIdeale; +extern long NombreLignes; +extern long Norme; + +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +extern void initialisation (); +extern void generation_configuration_initiale (); + +#endif /* SCP_INITS_H */ diff --git a/alliance/src/gscr/src/scp_main.c b/alliance/src/gscr/src/scp_main.c new file mode 100644 index 00000000..291420f8 --- /dev/null +++ b/alliance/src/gscr/src/scp_main.c @@ -0,0 +1,218 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_main.c */ +/* Contents : main of placer */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Pierre Fedrichkine Date : 02/07/1993 */ +/* Modified by : Xavier Picat Date : 08/07/1993 */ +/* */ +/******************************************************************************/ + +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "scp_types.h" +#include "scp_modif.h" +#include "scp_main.h" +#include "scp_inits.h" +#include "scp_mbk2scp.h" +#include "scp_scp2mbk.h" +#include "scp_time.h" + +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +extern float CalculCoutTotal (); +extern long Accepte (); + +/*---------------------------------------------------------\ + Les variables globales +\---------------------------------------------------------*/ +long PoidsX, PoidsY; +cell_list *Cells; +net_list *Nets; +row_elt *Rows; +placement_fig Placement; + +/*---------------------------------------------------------\ + Les variables locales +\---------------------------------------------------------*/ +static long CoutMoyen = 141900; + +/*---------------------------------------------------------\ + Place +\---------------------------------------------------------*/ + +int SXMODE=0; +int SCR_RATIO=100; /* carre */ + +placement_fig *Place (LogicalFigur,NombreModifications,NbRow,WeightX,WeightY,WeightRows,WeightCon,Connectors,WHratio) +lofig_list *LogicalFigur; +unsigned long NombreModifications; +unsigned long NbRow; +unsigned long WeightX; +unsigned long WeightY; +unsigned long WeightRows; +long WeightCon; +int WHratio; +PlaceConList *Connectors; +{ + float CoutInitial; /* il faut le laisser en flottant car le cout initial est >> 2 000 000 000 */ + int Iteration; + int Acceptees, Totales; + long DeltaCout; + nets_of_cell *pt_cn1; + nets_of_cell *pt_cn2; + cells_of_net *pt_cl1; + cells_of_net *pt_cl2; + int iNet, iCell; + + set_time (); + srand(getpid()); + PoidsX = WeightX; + PoidsY = WeightY; + printf("Loading SCP data base ...\n"); + chargement_figure(LogicalFigur,Connectors); + initialisation(WeightRows,NbRow,WHratio); + printf("Generating initial placement ... \n"); + generation_configuration_initiale(LogicalFigur, Connectors, WeightCon, WeightY); + CoutInitial = CalculCoutTotal(); + printf ("%d cells %d nets in %d rows\n", NombreCellules, NombreSignaux, NombreLignes); + Placement.Rows = Rows; + Placement.NbRows = NombreLignes; + Placement.Cells = Cells; + Placement.NbCells = NombreCellules; + if (NombreCellules > NombreModifications) + NombreModifications = 10*NombreCellules; + + printf("Placement in process of treatment : "); + Iteration = 85; + while (Iteration) + { + printf ("%3d%%\b\b\b\b",100-20*Iteration/17); + fflush (stdout); + Acceptees = 0; + Totales = 0; + while (Acceptees < NombreModifications && Totales < NombreModifications*3) + { + DeltaCout = modification_configuration (); + if (DeltaCout <= 0 || Accepte (DeltaCout)) + { + memorisation_nouvelle_configuration(); + Acceptees++; + } + Totales++; + } + if (CoutMoyen < 10240) + { + CoutMoyen *= 9; + CoutMoyen /= 10; + } + else if (CoutMoyen < 51200) + { + CoutMoyen <<= 2; + CoutMoyen /= 5; + } + else + { + CoutMoyen *= 49; + CoutMoyen /= 50; + } + Iteration--; + } + printf ("100%%\n%d%% saved in %4.1f s\n", (int)(100*(CoutInitial-CalculCoutTotal())/CoutInitial), get_time ()); + fflush (stdout); + + /* liberation des structures associees au signaux */ + for (iCell = 0;iCell < NombreCellules;iCell++) + if (pt_cn1=Cells[iCell].first) + { + for(pt_cn2=pt_cn1->next;pt_cn2;pt_cn1=pt_cn2,pt_cn2=pt_cn2->next) + mbkfree(pt_cn1); + Cells[iCell].first = NULL; + } + for (iNet = 0;iNet < NombreSignaux;iNet++) + if (pt_cl1=Nets[iNet].first) + for(pt_cl2=pt_cl1->next;pt_cl2;pt_cl1=pt_cl2,pt_cl2=pt_cl2->next) + mbkfree(pt_cl1); + mbkfree (Nets); + return (&Placement); +} + +/*---------------------------------------------------------\ + Accepte +\---------------------------------------------------------*/ +long Accepte (DeltaCout) +long DeltaCout; +{ + long Proba; + + Proba = CoutMoyen-(DeltaCout<<10); + if (Proba <0) + return (0); + else + return (CoutMoyen*(rand() % 100) < 100*Proba); +} + +/*---------------------------------------------------------\ + CalculCoutTotal +\---------------------------------------------------------*/ +float CalculCoutTotal () +{ + cells_of_net *cell1, *cell2; + long CoutNoeud; + float CoutTotal; + int Signal; + + CoutTotal = 0; + /*** parcours et calcul du cout total du a la longueur des nets *******/ + for (Signal = 0; Signal < NombreSignaux; Signal++) + { + CoutNoeud = 0; + for (cell1 = Nets[Signal].first; cell1; cell1 = cell1->next) + for (cell2 = cell1->next; cell2; cell2 = cell2->next) + CoutNoeud += (abs(cell1->cell->x - cell2->cell->x)<cell->y - cell2->cell->y); + CoutTotal += CoutNoeud * Nets[Signal].coeff; + } + return (CoutTotal); +} + diff --git a/alliance/src/gscr/src/scp_main.h b/alliance/src/gscr/src/scp_main.h new file mode 100644 index 00000000..fc42401a --- /dev/null +++ b/alliance/src/gscr/src/scp_main.h @@ -0,0 +1,61 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_main.h */ +/* Contents : prototypes du placeur */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_MAIN_H +#define SCP_MAIN_H +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include "scp_types.h" + +/*---------------------------------------------------------\ + Les variables globales +\---------------------------------------------------------*/ +extern long PoidsX; +extern long PoidsY; +extern cell_list *Cells; +extern net_list *Nets; +extern row_elt *Rows; + +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +extern placement_fig *Place (); + +#endif /* SCP_MAIN_H */ diff --git a/alliance/src/gscr/src/scp_mbk2scp.c b/alliance/src/gscr/src/scp_mbk2scp.c new file mode 100644 index 00000000..5f6ea966 --- /dev/null +++ b/alliance/src/gscr/src/scp_mbk2scp.c @@ -0,0 +1,266 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_mbk2scp.c */ +/* Contents : function wich loads the netlist in the internal data */ +/* structure through MBK data base */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Pierre Fedrichkine Date : 02/07/1993 */ +/* Modified by : Xavier Picat Date : 09/08/1993 */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include +#include "scp_types.h" +#include "scp_inits.h" +#include "scp_main.h" +#include "scp_mbk2scp.h" + +/*---------------------------------------------------------\ + Prototypes +\---------------------------------------------------------*/ +static void add_net_cell (); +static void add_cell_net (); +static long man2dp (); +static long get_index (); + +/*---------------------------------------------------------\ + Les variables globales +\---------------------------------------------------------*/ +long NombreCellules; +long NombreSignaux; +long LargeurTotale; +long Hauteur; + +/*---------------------------------------------------------\ + chargement_figure +\---------------------------------------------------------*/ +void chargement_figure(ptlofig,Connectors) +lofig_list *ptlofig; +PlaceConList *Connectors; +{ + phfig_list *ptphfig; + locon_list *ptlocon; + loins_list *ptloins; + losig_list *ptlosig; + int NetMax,iNet; + int NombreConnecteurs; + int *inter_net; + CaracConList *Con; + net_list *Net; + cell_list *Cell; + + /**************** comptage du nombre de cellules *************************/ + NombreCellules = 0; + for (ptloins=ptlofig->LOINS; ptloins; ptloins=ptloins->NEXT) + NombreCellules++; + NombreConnecteurs = 0; + if (Connectors) + { + for (Con = Connectors->NORTH_CON; Con; Con = Con->NEXT) + NombreConnecteurs++; + for (Con = Connectors->SOUTH_CON; Con; Con = Con->NEXT) + NombreConnecteurs++; + for (Con = Connectors->WEST_CON; Con; Con = Con->NEXT) + NombreConnecteurs++; + for (Con = Connectors->EAST_CON; Con; Con = Con->NEXT) + NombreConnecteurs++; + } + Cells = (cell_list *) mbkalloc (sizeof (cell_list) * (NombreCellules + NombreConnecteurs)); + memset (Cells, 0, sizeof (cell_list) * (NombreCellules + NombreConnecteurs)); + + /**************** comptage du nombre de signaux *************************/ + NombreSignaux = 0; + NetMax = 0; + for (ptlosig=ptlofig->LOSIG; ptlosig; ptlosig=ptlosig->NEXT) + { + NombreSignaux++; + if (ptlosig->INDEX>NetMax) + NetMax = ptlosig->INDEX; + } + NetMax++; /* les signaux partent de 0 */ + Nets = (net_list *) mbkalloc (sizeof (net_list) * NombreSignaux); + memset (Nets, 0, sizeof (net_list) * NombreSignaux); + inter_net = (int *) mbkalloc (sizeof (int) * NetMax); + iNet = 0; + for (ptlosig=ptlofig->LOSIG; ptlosig; ptlosig=ptlosig->NEXT) + { + inter_net[ptlosig->INDEX] = iNet; + iNet++; + } + + /******************** lecture des instances (cellules) ********************/ + LargeurTotale = 0; + Cell = &Cells[0]; + for (ptloins=ptlofig->LOINS; ptloins; ptloins=ptloins->NEXT) + { + Cell->ins = ptloins; + ptphfig = getphfig(ptloins->FIGNAME,'A'); + sx2sc (ptphfig); + Cell->width = (ptphfig->XAB2 - ptphfig->XAB1) / SCALE_X; + LargeurTotale += Cell->width; + for(ptlocon=ptloins->LOCON; ptlocon; ptlocon=ptlocon->NEXT) + { + char *NomConnecteur; + + NomConnecteur = namealloc(ptlocon->NAME); + if (!(isvdd(NomConnecteur) || isvss(NomConnecteur))) + { + Net = &Nets[inter_net[ptlocon->SIG->INDEX]]; + add_net_cell(Cell,Net); + add_cell_net(Net,Cell); + } + } + Cell++; + } + if (Connectors) + { + int i; + + for (i = 0; i < 4; i++) + for (Con = ((CaracConList **)Connectors)[i]; Con; Con = Con->NEXT) + { + Net = &Nets[inter_net[get_index(ptlofig->LOSIG, namealloc(Con->NAME))]]; + add_net_cell(Cell,Net); + add_cell_net(Net,Cell); + Cell++; + } + } + for (iNet=0; iNetYAB2 - ptphfig->YAB1) / SCALE_X; + + /******************** lecture des connecteurs *********************/ + mbkfree (inter_net); +} /* fin de chargement_figure */ + +/*---------------------------------------------------------\ + get_index +\---------------------------------------------------------*/ +static long get_index (ptlosig, ConName) +losig_list *ptlosig; +char *ConName; +{ + chain_list *NameList; + + while (ptlosig) + { + NameList = ptlosig->NAMECHAIN; + while (NameList) + { + if (ConName == NameList->DATA) + return (ptlosig->INDEX); + NameList = NameList->NEXT; + } + ptlosig = ptlosig->NEXT; + } + fprintf (stderr, "\nThere is no signal named %s\n", ConName); + exit (1); +} /* fin de get_index */ + +/*---------------------------------------------------------\ + add_net_cell +\---------------------------------------------------------*/ +static void add_net_cell(Cell,Net) +cell_list *Cell; +net_list *Net; +{ + nets_of_cell *NetOfCell; + + NetOfCell = (nets_of_cell *) mbkalloc (sizeof (nets_of_cell)); + NetOfCell->net = Net; + NetOfCell->next = Cell->first; + Cell->first = NetOfCell; +} /* fin de add_net_cell */ + +/*---------------------------------------------------------\ + add_cell_net +\---------------------------------------------------------*/ +static void add_cell_net(Net,Cell) +net_list *Net; +cell_list *Cell; +{ + cells_of_net *CellOfNet; + + CellOfNet = (cells_of_net *) mbkalloc (sizeof (cells_of_net)); + CellOfNet->cell = Cell; + CellOfNet->next = Net->first; + Net->coeff++; + Net->first = CellOfNet; +} /* fin de add_cell_net */ + +/*---------------------------------------------------------\ + man2dp +\---------------------------------------------------------*/ +static long man2dp(card) +int card; +{ + switch(card) + { + case 0 : + case 1 : + /* fprintf (stderr, "Warning : a signal isn't connected to any cell\n"); */ + return(0); + break; + + case 2 : return(FLOAT_TO_LONG * 1); + break; + + case 3 : return(FLOAT_TO_LONG * 0.5); + break; + + case 4 : return(FLOAT_TO_LONG * 0.333); + break; + + case 5 : return(FLOAT_TO_LONG * 0.222); + break; + + case 6 : return(FLOAT_TO_LONG * 0.15); + break; + + case 7 : return(FLOAT_TO_LONG * 0.11); + break; + + case 8 : return(FLOAT_TO_LONG * 0.087); + break; + + case 9 : return(FLOAT_TO_LONG * 0.0689); + break; + + case 10 : return(FLOAT_TO_LONG * 0.0563); + break; + + default : return(FLOAT_TO_LONG * 6.0 / (card*(card+1.0))); + } +} /* fin de man2dp */ diff --git a/alliance/src/gscr/src/scp_mbk2scp.h b/alliance/src/gscr/src/scp_mbk2scp.h new file mode 100644 index 00000000..c76a4980 --- /dev/null +++ b/alliance/src/gscr/src/scp_mbk2scp.h @@ -0,0 +1,56 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_mbk2scp.h */ +/* Contents : prototypes du parser */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/08/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_MBK2SCP +#define SCP_MBK2SCP + +/*---------------------------------------------------------\ + Les variables globales +\---------------------------------------------------------*/ +extern long NombreCellules; +extern long NombreSignaux; +extern long LargeurTotale; +extern long Hauteur; + +/*---------------------------------------------------------\ + Prototypes +\---------------------------------------------------------*/ +extern void chargement_figure(); + +#endif /* SCP_MBK2SCP */ diff --git a/alliance/src/gscr/src/scp_modif.c b/alliance/src/gscr/src/scp_modif.c new file mode 100644 index 00000000..23dc00ec --- /dev/null +++ b/alliance/src/gscr/src/scp_modif.c @@ -0,0 +1,241 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_modif.c */ +/* Contents : fonctions de modification de la configuration */ +/* et du calcul du cout associe */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Pierre Fedrichkine Date : 02/07/1993 */ +/* Modified by : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include +#include +#include +#include "scp_types.h" +#include "scp_modif.h" +#include "scp_inits.h" +#include "scp_main.h" +#include "scp_mbk2scp.h" + +/*---------------------------------------------------------\ + Les variables locales +\---------------------------------------------------------*/ +static cell_list *Cell1, *Cell2; /* Cellules selectionnees pour la modification */ +static long DeltaWidth; /* Difference de largeur entre Cell2 et Cell1 */ + +/*---------------------------------------------------------\ + memorisation_nouvelle_configuration +\---------------------------------------------------------*/ +void memorisation_nouvelle_configuration () +{ + cell_list *Cell; + int Pos; + + /****** mise a jour des dernieres cellules ********/ + if (Cell1->next == NULL) + Rows[Cell1->row].tail = Cell2; + if (Cell2->next == NULL) + Rows[Cell2->row].tail = Cell1; + + /****** mise a jour des premieres cellules *******/ + if (Cell1->prev == NULL) + Rows[Cell1->row].head = Cell2; + if (Cell2->prev == NULL) + Rows[Cell2->row].head = Cell1; + + /********* mise a jour des longueurs des rangeesRows[].length ********/ + Rows[Cell1->row].length += DeltaWidth; + Rows[Cell2->row].length -= DeltaWidth; + + /*************** mise a jour des positions de cellules ****************/ + /* ne marche pas si les 2 cellules sont sur la meme rangee */ + /* si 2 suit 1, 2 sera decale de deltawidth .. */ + for(Cell = Cell1->next; Cell; Cell = Cell->next) + Cell->x += DeltaWidth; + + for(Cell = Cell2->next; Cell; Cell = Cell->next) + Cell->x -= DeltaWidth; + + Pos = Cell2->x - (DeltaWidth >> 0 /* 99/9/21 1 */); + Cell2->x = Cell1->x + (DeltaWidth >> 0 /* 99/9/21 1 */); + Cell1->x = Pos; + + if (Cell1->next == Cell2) + { + if (Cell1->prev) + Cell1->prev->next = Cell2; + if (Cell2->next) + Cell2->next->prev = Cell1; + Cell1->next = Cell2->next; + Cell2->next = Cell1; + Cell2->prev = Cell1->prev; + Cell1->prev = Cell2; + } + else + { + int Row; + int Y; + cell_list *Cell; + + if (Cell1->next) + Cell1->next->prev = Cell2; + if (Cell1->prev) + Cell1->prev->next = Cell2; + if (Cell2->next) + Cell2->next->prev = Cell1; + if (Cell2->prev) + Cell2->prev->next = Cell1; + + Row = Cell1->row; + Cell1->row = Cell2->row; + Cell2->row = Row; + + Y = Cell1->y; + Cell1->y = Cell2->y; + Cell2->y = Y; + + Cell = Cell1->next; + Cell1->next = Cell2->next; + Cell2->next = Cell; + + Cell = Cell1->prev; + Cell1->prev = Cell2->prev; + Cell2->prev = Cell; + } +} /* fin de memorisation_nouvelle_configuration */ + +/*---------------------------------------------------------\ + modification_configuration + +Effectue une modification elementaire de la configuration +et renvoie une approximation du cout qu'elle occasionnerait +\---------------------------------------------------------*/ +long modification_configuration () +{ + long DeltaCoutSignal, DeltaCout, DeltaCoutBandes; + long NewX, NewY; + long OldX, OldY; + long XCellule, YCellule; + nets_of_cell *signal; + cells_of_net *cell; + cell_list *Cellule; + + /* Recherche de deux cellules a echanger */ + Cell1 = &Cells[rand() % NombreCellules]; + /* sur les tests effectues, on obtient JAMAIS (sur des millions d'appels) + * deux fois la meme cellule, il est donc inutile de passer par un entier + * qui contiendrait le numero de la cellule, plutot que de calculer directement + * l'adresse de la cellule + */ + do + { + Cell2 = &Cells[rand() % NombreCellules]; + } while (Cell2 == Cell1) ; + if (Cell2->next == Cell1) + { + Cellule = Cell1; + Cell1 = Cell2; + Cell2 = Cellule; + } + DeltaWidth = Cell2->width - Cell1->width; + + /* calcul du cout occasionne par la premiere cellule */ + DeltaCout = 0; + NewX = Cell2->x + ((Cell1->width - Cell2->width) >> 0 /* 99/9/21 1 */); + NewY = Cell2->y; /* bande de finale de la cellule */ + OldX = Cell1->x; /* position initiale cellule */ + OldY = Cell1->y; /* bande initiale de la cellule */ + for (signal=Cell1->first; signal; signal=signal->next) + { + DeltaCoutSignal = 0; + for(cell=signal->net->first; cell; cell=cell->next) + { + Cellule = cell->cell; + if ((Cellule != Cell1) && (Cellule != Cell2)) + { + XCellule = Cellule->x; + YCellule = Cellule->y; + if (Cellule->width) + DeltaCoutSignal += ((abs(NewX - XCellule) - abs(OldX - XCellule)) << PoidsX) + + abs(NewY - YCellule) - abs(OldY - YCellule); + else if (XCellule) + /* c'est un connecteur EST/OUEST */ + DeltaCoutSignal += ((abs(NewX - XCellule) - abs(OldX - XCellule)) << PoidsX) + + ((abs(NewY - YCellule) - abs(OldY - YCellule)) << 1); + else + /* c'est un connecteur NORD/SUD */ + DeltaCoutSignal += ((abs(NewY - YCellule) - abs(OldY - YCellule)) << 1); + } + } /* fin du parcours des cellules signalees a ce signal */ + DeltaCout += DeltaCoutSignal * signal->net->coeff; + } /* fin du parcours des signaux attaches a cette cellule */ + DeltaCoutBandes = abs(Rows[Cell1->row].length + DeltaWidth - LargeurIdeale) + - abs(Rows[Cell1->row].length - LargeurIdeale); + + /* calcul du cout occasionne par la premiere cellule */ + NewX = Cell1->x + ((Cell2->width - Cell1->width) >> 0 /* 99/9/21 1 */); + NewY = Cell1->y; /* bande de finale de la cellule */ + OldX = Cell2->x; /* position initiale cellule */ + OldY = Cell2->y; /* bande initiale de la cellule */ + for (signal=Cell2->first; signal; signal=signal->next) + { + DeltaCoutSignal = 0; + for(cell=signal->net->first; cell; cell=cell->next) + { + Cellule = cell->cell; + if ((Cellule != Cell1) && (Cellule != Cell2)) + { + XCellule = Cellule->x; + YCellule = Cellule->y; + if (Cellule->width) + DeltaCoutSignal += ((abs(NewX - XCellule) - abs(OldX - XCellule)) << PoidsX) + + abs(NewY - YCellule) - abs(OldY - YCellule); + else if (XCellule) + /* c'est un connecteur EST/OUEST */ + DeltaCoutSignal += ((abs(NewX - XCellule) - abs(OldX - XCellule)) << PoidsX) + + ((abs(NewY - YCellule) - abs(OldY - YCellule)) << 1); + else + /* c'est un connecteur NORD/SUD */ + DeltaCoutSignal += ((abs(NewY - YCellule) - abs(OldY - YCellule)) << 1); + } + } /* fin du parcours des cellules signalees a ce signal */ + DeltaCout += DeltaCoutSignal * signal->net->coeff; + } /* fin du parcours des signaux attaches a cette cellule */ + DeltaCoutBandes += 2* (abs(Rows[Cell2->row].length - DeltaWidth - LargeurIdeale) + - abs(Rows[Cell2->row].length - LargeurIdeale)); + + return (DeltaCout/Norme + DeltaCoutBandes); +} /* fin de calcul_difference_cout */ diff --git a/alliance/src/gscr/src/scp_modif.h b/alliance/src/gscr/src/scp_modif.h new file mode 100644 index 00000000..ac45ebce --- /dev/null +++ b/alliance/src/gscr/src/scp_modif.h @@ -0,0 +1,48 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_modif.h */ +/* Contents : prototypes des fonctions de modification de la configuration*/ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_MODIF_H +#define SCP_MODIF_H +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +extern void memorisation_nouvelle_configuration (); +extern long modification_configuration (); + +#endif /* SCP_MODIF_H */ diff --git a/alliance/src/gscr/src/scp_placer.c b/alliance/src/gscr/src/scp_placer.c new file mode 100644 index 00000000..fea2771d --- /dev/null +++ b/alliance/src/gscr/src/scp_placer.c @@ -0,0 +1,159 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_Placer.c */ +/* Contents : */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Date : .......... */ +/* Modified by : Xavier Picat Date : 08/07/1993 */ +/* */ +/******************************************************************************/ + +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include "scp_placer.h" +#include "scp_scp2mbk.h" + +/******************************************************************************/ +/* Function : ScrUsage() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : none */ +/* Output parameters : none */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +void ScrUsage(Execut) +char *Execut; + +{ + fprintf(stdout,"Syntax error on command line\n"); + fprintf(stdout,"usage : %s [options...]\n",Execut); + fprintf(stdout,"where valid options are :\n"); + fprintf(stdout," : netlist file and placed layout (same name)\n"); + fprintf(stdout," [-i IterationNumber] : This action is used to improve the quality of the placement\n"); + fprintf(stdout," [-s SliceNumber] : This option allows the designer to set the number of slices\n"); + exit(1); +} + +/******************************************************************************/ +/* Function : GetOptions() */ +/* */ +/* Description : getting all used options on commad line */ +/* */ +/* Input parameters : argument count and argument value */ +/* Input global Variables : none */ +/* Output parameters : option list pointer */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +OptionList *GetOptions(ArgCount,ArgValue) +int ArgCount; +char *ArgValue[]; + +{ + OptionList *ptOption = (OptionList *) mbkalloc (sizeof(OptionList)); + int ArgNumber = 0; + char car; + + ptOption->ChannelName = NULL; + ptOption->FileName = NULL; + ptOption->Placer = 0; + ptOption->Router = 0; + ptOption->SupplyRecall = 1; + ptOption->Row = 0; + ptOption->Iteration = 0; + + for (ArgNumber = 2; ArgNumber < ArgCount; ArgNumber++) { + char *ArgV = ArgValue[ArgNumber]; + if (*ArgV == '-') { + switch (*++ArgV) { + + case 's' : if ((car = *++ArgV) == '\0') + ptOption->Row = atoi(ArgValue[++ArgNumber]); + else ScrUsage(ArgValue[0]); + continue; + + case 'i' : if (*++ArgV == '\0') + ptOption->Iteration = atoi(ArgValue[++ArgNumber]); + else ScrUsage(ArgValue[0]); + continue; + + default : ScrUsage(ArgValue[0]); + } + } + } + return(ptOption); +} + +/******************************************************************************/ +/* Function : main() */ +/******************************************************************************/ +int main(argc,argv) + +int argc; +char *argv[]; + +{ + phfig_list *ptphfig = NULL; + lofig_list *ptlofig = NULL; + OptionList *ptOption = NULL; + + mbkenv(); + + ptOption = GetOptions(argc,argv); + + fprintf(stdout,"Loading logical view : %s\n",argv[1]); + ptlofig = getlofig(argv[1],'A'); + rflattenlofig(ptlofig,'Y','Y'); + + if (ptlofig->LOTRS) { + fprintf(stdout,"scp_error : Check that the catalogue file existes and that it contains all the models instanciated in the figure.\n"); + exit(1); + } + + fprintf(stdout,"Placing logical view : %s\n",argv[1]); + ptphfig = Placer2Scr( ptlofig->NAME, Place( ptlofig, ptOption->Iteration, ptOption->Row, 0, 7, 5, 5, NULL)); + + savephfig(ptphfig); + + return(0); +} diff --git a/alliance/src/gscr/src/scp_placer.h b/alliance/src/gscr/src/scp_placer.h new file mode 100644 index 00000000..49d4164d --- /dev/null +++ b/alliance/src/gscr/src/scp_placer.h @@ -0,0 +1,53 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_placer.h */ +/* Contents : prototypes du placeur */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ + +#define BOOLEAN int +typedef struct Option + { + char *ChannelName; + char *FileName; + BOOLEAN Placer; + BOOLEAN Router; + int SupplyRecall; + int Row; + int Iteration; + }OptionList; + + diff --git a/alliance/src/gscr/src/scp_scp2mbk.c b/alliance/src/gscr/src/scp_scp2mbk.c new file mode 100644 index 00000000..82ae7247 --- /dev/null +++ b/alliance/src/gscr/src/scp_scp2mbk.c @@ -0,0 +1,116 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_scp2mbk.c */ +/* Contents : function sauvegarde_figure wich save the final placement */ +/* through MBK data base */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Pierre Fedrichkine Date : 02/07/1993 */ +/* Modified by : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include "apr.h" + +/*---------------------------------------------------------\ + Placer2Scr + + ecriture du placement dans mbk physique +\---------------------------------------------------------*/ +phfig_list *Placer2Scr(Nom,FigurePlacee) +char *Nom; +placement_fig *FigurePlacee; + +{ + phfig_list *ptphfig; + int iCell, iRow; + int Width; + int Height; + row_elt *Row; + cell_list *Cell; + long step, percent, i; + long NombreLignes, NombreCellules, Hauteur; + + printf ("Saving placement "); + /****************** recuperation de la hauteur d'UNE cellule ********************/ + Row = FigurePlacee->Rows; + ptphfig = getphfig (Row[0].head->ins->FIGNAME,'P'); + sx2sc(ptphfig); + Hauteur = (ptphfig->YAB2 - ptphfig->YAB1) / SCALE_X; + + /****************** chargement du pointeur figure ********************/ + ptphfig = addphfig(Nom); + NombreCellules = FigurePlacee->NbCells; + NombreLignes = FigurePlacee->NbRows; + + /**************** calcul de la taille de la figure ********************/ + Width = 0; + for (iRow=0;iRowWidth) + Width=Row[iRow].length; + Height = NombreLignes*Hauteur; + ptphfig->XAB1 = 0; + ptphfig->YAB1 = 0; + ptphfig->XAB2 = Width*SCALE_X; + ptphfig->YAB2 = Height*SCALE_X; + + step = NombreCellules/100; + percent = 0; + i = step - 1; + /********************* placement des cellules *************************/ + Cell = FigurePlacee->Cells; + for (iCell=0;iCell < NombreCellules;iCell++) + { + i++; + if (i == step) + { + i = 0; + printf ("%3d%%\b\b\b\b", percent); + fflush (stdout); + percent++; + } + addphins (ptphfig, + Cell->ins->FIGNAME, + Cell->ins->INSNAME, + NOSYM, + (Cell->x-(Cell->width>>0 /* 99/9/21 1 */))*SCALE_X, + Cell->row*Hauteur*SCALE_X + ); + Cell++; + } + printf ("100%\n"); + mbkfree (FigurePlacee->Rows); + mbkfree (FigurePlacee->Cells); + return(ptphfig); +} /* fin de Placer2Scr */ diff --git a/alliance/src/gscr/src/scp_scp2mbk.h b/alliance/src/gscr/src/scp_scp2mbk.h new file mode 100644 index 00000000..e26a231c --- /dev/null +++ b/alliance/src/gscr/src/scp_scp2mbk.h @@ -0,0 +1,52 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_scp2mbk.h */ +/* Contents : prototypes du driver */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_SCP2MBK_H +#define SCP_SCP2MBK_H +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include "scp_main.h" + +/*---------------------------------------------------------\ + Les prototypes +\---------------------------------------------------------*/ +extern phfig_list *Placer2Scr (); + +#endif /* SCP_SCP2MBK_H */ diff --git a/alliance/src/gscr/src/scp_time.c b/alliance/src/gscr/src/scp_time.c new file mode 100644 index 00000000..3be05824 --- /dev/null +++ b/alliance/src/gscr/src/scp_time.c @@ -0,0 +1,69 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_time.c */ +/* Contents : timing gunctions */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 02/07/1993 */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include +#include "scp_time.h" + +#define HZ 50 +/*---------------------------------------------------------\ + Les variables locales +\---------------------------------------------------------*/ +static struct tms start_time; + +/*---------------------------------------------------------\ + set_time +\---------------------------------------------------------*/ +void set_time () +{ + times (&start_time); +} /* fin de set_time */ + +/*---------------------------------------------------------\ + get_time +\---------------------------------------------------------*/ +float get_time () +{ + struct tms end_time; + + times (&end_time); + return ((float) (end_time.tms_utime - start_time.tms_utime)/(float) HZ + + (float) (end_time.tms_stime - start_time.tms_stime)/(float) HZ); +} /* fin de get_time */ diff --git a/alliance/src/gscr/src/scp_time.h b/alliance/src/gscr/src/scp_time.h new file mode 100644 index 00000000..169e1906 --- /dev/null +++ b/alliance/src/gscr/src/scp_time.h @@ -0,0 +1,49 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Placer */ +/* File : scp_time.h */ +/* Contents : prototypes of the timing functions */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Xavier Picat Date : 09/07/1993 */ +/* */ +/******************************************************************************/ + +#ifndef SCP_TIME_H +#define SCP_TIME_H + +/*---------------------------------------------------------\ + Prototypes +\---------------------------------------------------------*/ +extern void set_time (); +extern float get_time (); + +#endif /* SCP_TIME_H */ diff --git a/alliance/src/gscr/src/scp_types.h b/alliance/src/gscr/src/scp_types.h new file mode 100644 index 00000000..5612f4f0 --- /dev/null +++ b/alliance/src/gscr/src/scp_types.h @@ -0,0 +1,73 @@ +/* + * 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 library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : Standard Cell Router */ +/* File : @(#) */ +/* Contents : */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : Date : ../../.... */ +/* Modified by : El housseine REJOUAN Date : 26/02/1993 */ +/* Modified by : Xavier Picat Date : 09/07/1993 */ +/* Modified by : Date : ../../.... */ +/* */ +/******************************************************************************/ + +#ifndef SCP_TYPES_H +#define SCP_TYPES_H +/*---------------------------------------------------------\ + Les includes +\---------------------------------------------------------*/ +#include +#include +#include +#include + +/*---------------------------------------------------------\ + Les constantes +\---------------------------------------------------------*/ +#define NONE -1 +/* cette valeur de 10 000 est suffisante pour des circuits <10000 cellules, mais peut etre + * trop importante pour des circuits plus gros, en effet, lors du calcul de cout dans modif + * les calculs se font en long et apparemment avec 100 000, le cout depasse parfois les + * 2<<30 maximaux que peu contenir un long et donc tous les calculs sont fausses. + * apparemment le fait de designer CoutTotal comme un float ne ralenti pas les calculs, se + * serait peut etre la solution : CoutTotal += (float)((long)CoutSignal*(long)Net.coeff); + * CoutSignal et coeff etant des longs. le fait de caster en long, evite que le C convertisse + * tout en flottant (ce qu'il doit faire normalement je crois), on n'a donc plus qu'une + * conversion et une addition en flottant (on gagne une multiplication en flottant). + * il est moins probable qu'UN signal occasionne une valeur > 2<<30, mais si c le cas, alors + * il faudrait tout mettre en flottant. + */ +#define FLOAT_TO_LONG 10000 + +#define max(a,b) ((a)<(b) ? (b):(a)) + +#endif /* SCP_TYPES_H */ diff --git a/alliance/src/gscr/src/sx2sc.c b/alliance/src/gscr/src/sx2sc.c new file mode 100644 index 00000000..5ee09793 --- /dev/null +++ b/alliance/src/gscr/src/sx2sc.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include "apr.h" + +extern int SXMODE; + +void sx2sc (phfig_list * phfig) +{ + phref_list *phref; + int used[100]; + int t; + + if (SXMODE == 0) return; + + if (phfig->USER) return; /* deja traite */ + + phfig->USER = 1; + /* + * initialisation du tableau des transparences + */ + for (t=0; t <= (phfig->XAB2)/PITCH_X; t++) + { + used[t] = 0; + } + used[t] = -1; + + for (phref = phfig->PHREF; phref; phref = phref->NEXT) + { + if (phref->NAME && strstr (phref->NAME, "_25")) + { + char ConnName[32]; + strcpy (ConnName, phref->NAME); + *(strchr (ConnName, '_')) = '\0'; + addphcon (phfig, NORTH, ConnName, + phref->XREF, phref->YREF, ALU2, 2*SCALE_X); + addphcon (phfig, SOUTH, ConnName, + phref->XREF, phref->YREF, ALU2, 2*SCALE_X); + } + used[(phref->XREF)/PITCH_X] = 1; + } + + for (t=1; used[t] != -1; t++) + { + if (!used[t]) + { + char transname[32]; + sprintf (transname, "T%d", t); + addphseg (phfig, TALU2, 2*SCALE_X, + t*PITCH_X, phfig->YAB1, t*PITCH_X, phfig->YAB2, + transname); + } + } +} diff --git a/alliance/src/rds/src/rfmacces.c b/alliance/src/rds/src/rfmacces.c index 74879af6..c80d2d3b 100644 --- a/alliance/src/rds/src/rfmacces.c +++ b/alliance/src/rds/src/rfmacces.c @@ -478,8 +478,7 @@ rdsrec_list *viambkrds( Figure, Via, Lynx ) ( ( USE == RDS_USE_DRC ) && ( ! Lynx ) ) ) { if ( SIDE_STEP == 0 ) break; - if ( WSX < SIDE+(SIDE>>1) ) break; - if ( WSY < SIDE+(SIDE>>1) ) break; + if ( ( WSX < SIDE+(SIDE>>1) ) && ( WSY < SIDE+(SIDE>>1) ) ) break; X1R = Xvia + OVERLAP - ( ( WSX + DWR ) >> 1 ); Y1R = Yvia + OVERLAP - ( ( WSY + DWR ) >> 1 ); @@ -494,11 +493,13 @@ rdsrec_list *viambkrds( Figure, Via, Lynx ) Y1R = RfmRoundLow ( Y1R ); Y2R = RfmRoundHigh( Y2R ); +#if 0 if ( X1R >= 0 ) X1R = ( (X1R + SIDE_STEP - 1) / SIDE_STEP ) * SIDE_STEP; else X1R = ( X1R / SIDE_STEP ) * SIDE_STEP; if ( Y1R >= 0 ) Y1R = ( (Y1R + SIDE_STEP - 1) / SIDE_STEP ) * SIDE_STEP; else Y1R = ( Y1R / SIDE_STEP ) * SIDE_STEP; +#endif BX1R = X1R; diff --git a/alliance/src/ring/src/lireplace.c b/alliance/src/ring/src/lireplace.c index 296bb037..e51b2e73 100644 --- a/alliance/src/ring/src/lireplace.c +++ b/alliance/src/ring/src/lireplace.c @@ -201,7 +201,7 @@ void lecture_fic(char *nomfic, lofig_list *circuit_lo, if (!existe_signal_circuit(liste, circuit_lo, lecoeur)) ringerreur(ERR_NONCONWIDTHPARAM, nom_con, NULL); - if (larg_con < SCALE_X) + if (larg_con < WVIA_ALU2) ringerreur(ERR_WIDTHPARAM, (void * )nom_con, (void * ) & larg_con); liste = liste->NEXT; diff --git a/alliance/src/scr/Makefile.am b/alliance/src/scr/Makefile.am new file mode 100644 index 00000000..9dd5545d --- /dev/null +++ b/alliance/src/scr/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = src diff --git a/alliance/src/scr/configure.in b/alliance/src/scr/configure.in new file mode 100644 index 00000000..dbec53d4 --- /dev/null +++ b/alliance/src/scr/configure.in @@ -0,0 +1,37 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/ScrSesame.cpp) + +SCR_MAJOR_VERSION=5 +SCR_MINOR_VERSION=4 +SCR_VERSION=$SCR_MAJOR_VERSION.$SCR_MINOR_VERSION + +AC_SUBST(SCR_MAJOR_VERSION) +AC_SUBST(SCR_MINOR_VERSION) +AC_SUBST(SCR_VERSION) + +# For automake. +VERSION=$SCR_VERSION +PACKAGE=scr + +dnl Initialize automake stuff +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + +dnl Checks for programs. +AC_PROG_CC +AM_PROG_LIBTOOL +AC_PROG_MAKE_SET +AM_WITH_REGEX +AM_PROG_LEX +AC_PROG_YACC + +AC_CHECK_LIB(m, pow) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +AM_ALLIANCE + +AC_OUTPUT([ +Makefile +src/Makefile +]) diff --git a/alliance/src/scr/src/GlobalRouter.c b/alliance/src/scr/src/GlobalRouter.c new file mode 100644 index 00000000..350f1800 --- /dev/null +++ b/alliance/src/scr/src/GlobalRouter.c @@ -0,0 +1,719 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : GlobalRouter.c */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : El housseine REJOUAN le : 25/07/1992 */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +# include +# include +# include +# include +# include "SCR_Type.h" +# include "LoadDataBase.h" +# include "ViewDataBase.h" +# include "ScrDataBase.h" +# include "main.h" + +/******************************************************************************/ +/* Function : EliminateMultipleConnection() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +Figure *EliminateMultipleConnection(ptFig) +Figure *ptFig; + +{ + Line *PathLine = NULL; + Line *CentralChannel = NULL; + Channel *ptChannel = NULL; + Signal *ptSignal = NULL; + ConnectorList *ptNorthCon = NULL; + ConnectorList *ptSouthCon = NULL; + ConnectorList *ptWestCon = NULL; + ConnectorList *ptEastCon = NULL; + ConnectorList *ptDeleteCon = NULL; + ConnectorList *ptConList = NULL; + ConnectorList *PrevConList = NULL; + ConnectorList *CurrentCon = NULL; + ConnectorList *ptSaveCon = NULL; + long CounterCon = 0; + long IndexSignal = 0; + long IndexCentralChannel = 0; + long GravityCentre = 0; + long AddMarkCon = 0; + long MinLength = 0; + long NewLength = 0; + BOOLEAN NetInChannel = FALSE; + +/******************************************************************************/ + for (ptSignal = ptFig->SIG; ptSignal; ptSignal = ptSignal->NEXT) { + if (!(isvdd(ptSignal->NAME) || isvss(ptSignal->NAME))) { + ptSignal->MAXCON = 0; + IndexSignal = ptSignal->INDEX; + for (PathLine = ptFig->LINE; PathLine; PathLine = PathLine->NEXT) { + if (PathLine->TYPE == PATH) { + ptChannel = PathLine->CHANNEL; + CounterCon = 0; + for (ptNorthCon = ptChannel->NORTH_LIST; ptNorthCon; + ptNorthCon = ptNorthCon->NextCon) + if (IndexSignal == ptNorthCon->ConName) CounterCon++; + for (ptSouthCon = ptChannel->SOUTH_LIST; ptSouthCon; + ptSouthCon = ptSouthCon->NextCon) + if (IndexSignal == ptSouthCon->ConName) CounterCon++; + for (ptWestCon = ptChannel->WEST_LIST; ptWestCon; + ptWestCon = ptWestCon->NextCon) + if (IndexSignal == ptWestCon->ConName) CounterCon++; + for (ptEastCon = ptChannel->EAST_LIST; ptEastCon; + ptEastCon = ptEastCon->NextCon) + if (IndexSignal == ptEastCon->ConName) CounterCon++; + if (CounterCon > ptSignal->MAXCON) { + CentralChannel = PathLine; + ptSignal->MAXCON = CounterCon; + } + } + } + ptSignal->MAXCON = CentralChannel->INDEX; + } + } +/******************************************************************************/ + for (ptSignal = ptFig->SIG; ptSignal; ptSignal = ptSignal->NEXT) { +if ((NameVdd != ptSignal->NAME) && (NameVss != ptSignal->NAME)) { + IndexSignal = ptSignal->INDEX; + IndexCentralChannel = ptSignal->MAXCON; + for (PathLine = ptFig->LINE; PathLine; PathLine = PathLine->NEXT) { +if (PathLine->TYPE == PATH) { + if (PathLine->INDEX != IndexCentralChannel) { + ptChannel = PathLine->CHANNEL; + CounterCon = AddMarkCon = GravityCentre = 0; + NetInChannel = FALSE; + for (ptNorthCon = ptChannel->NORTH_LIST; ptNorthCon; + ptNorthCon = ptNorthCon->NextCon) + if (IndexSignal == ptNorthCon->ConName) { + NetInChannel = TRUE; + CounterCon++; + AddMarkCon += ptNorthCon->Mark; + } + for (ptSouthCon = ptChannel->SOUTH_LIST; ptSouthCon; + ptSouthCon = ptSouthCon->NextCon) + if (IndexSignal == ptSouthCon->ConName) { + NetInChannel = TRUE; + CounterCon++; + AddMarkCon += ptSouthCon->Mark; + } + for (ptWestCon = ptChannel->WEST_LIST; ptWestCon; + ptWestCon = ptWestCon->NextCon) + if (IndexSignal == ptWestCon->ConName) { + NetInChannel = TRUE; + CounterCon++; + AddMarkCon += ptWestCon->Mark; + } + for (ptEastCon = ptChannel->EAST_LIST; ptEastCon; + ptEastCon = ptEastCon->NextCon) + if (IndexSignal == ptEastCon->ConName) { + NetInChannel = TRUE; + CounterCon++; + AddMarkCon += ptChannel->WIDTH; + } +if (NetInChannel) { + if (PathLine->INDEX < IndexCentralChannel) + ptConList = ptChannel->NORTH_LIST; + else + if (PathLine->INDEX > IndexCentralChannel) + ptConList = ptChannel->SOUTH_LIST; + GravityCentre = ((long ) ((AddMarkCon / CounterCon) + 0.5)); + MinLength = ptChannel->WIDTH; + ptSaveCon = NULL; + for (CurrentCon = ptConList; CurrentCon; CurrentCon = CurrentCon->NextCon) { + if (CurrentCon->ConName == IndexSignal) { + NewLength = LABS(GravityCentre,CurrentCon->Mark); + if (NewLength <= MinLength) { + MinLength = NewLength; + ptSaveCon = CurrentCon; + } + } + } + PrevConList = NULL; + while (ptConList) { + if ((ptConList->ConName == IndexSignal) && (ptConList != ptSaveCon)) { + ptDeleteCon = ptConList; + ptConList = ptConList->NextCon; + if (PrevConList) { + PrevConList->NextCon = ptConList; + } + else { + if (PathLine->INDEX < IndexCentralChannel) + ptChannel->NORTH_LIST = ptConList; + else + if (PathLine->INDEX > IndexCentralChannel) + ptChannel->SOUTH_LIST = ptConList; + } + mbkfree((void *) ptDeleteCon); + } + else { + PrevConList = ptConList; + ptConList = ptConList->NextCon; + } + } +} + } +} + } +} + } + return(ptFig); +} + +/******************************************************************************/ +/* Function : AutoAllowInsert() */ +/******************************************************************************/ +Segment *AutoAllowInsert(ptfig,ptLine,Xinf,Xsup,NewphIns,ptXInsert,Counter) +Figure *ptfig; +Line *ptLine; +long Xinf; +long Xsup; +phfig_list *NewphIns; +XSupplyRecallList *ptXInsert; +long Counter; + +{ + XSupplyRecallList *ptXBreakList = NULL; + long Xinsert = 0; + long XInsertSouth = 0; + long Xmoy = 0; + Line *CurrentLine = NULL; + Instance *CurrentInst = NULL; + Instance *PrevInst = NULL; + Instance *ptNewIns = NULL; + long Xinst = 0; + long XWinst = 0; + long NewWidth = 0; + long phNewHeight = 0; + Connector *CurrentCon = NULL; + Segment *CurrentSeg = NULL; + Segment *ptNewAllow = NULL; + Segment *ptSaveAllow = NULL; + chain_list *ConList = NULL; + + Xmoy = ((Xsup + Xinf) / 2); + NewWidth = NewphIns->XAB2 - NewphIns->XAB1; + phNewHeight = NewphIns->YAB2 - NewphIns->YAB1; + for (CurrentLine = ptfig->LINE; CurrentLine; CurrentLine = CurrentLine->NEXT) { + if (CurrentLine->TYPE == CELL) { + for (PrevInst = NULL, CurrentInst = CurrentLine->INS; CurrentInst; + CurrentInst = CurrentInst->NEXT) { + if ((Xmoy >= (Xinst = CurrentInst->X)) && + (Xmoy <= (XWinst = Xinst + CurrentInst->WIDTH))) break; + PrevInst = CurrentInst; + } + Xinsert = INF(Xmoy,Xinst,XWinst); + if (CurrentLine == (ptfig->LINE->NEXT->NEXT)) XInsertSouth = Xinsert; + if (Xinsert == XWinst) { + PrevInst = CurrentInst; + CurrentInst = CurrentInst->NEXT; + } + ptNewIns = CreateInstance(nameindex(CurrentLine->NAME,Counter), + NewphIns->NAME,Xinsert,CurrentLine->Y, + NewWidth,phNewHeight,NOSYM); + if (PrevInst) { + ptNewIns->NEXT = CurrentInst; + PrevInst->NEXT = ptNewIns; + } + else { + ptNewIns->NEXT = CurrentInst; + CurrentLine->INS = ptNewIns; + } + + CurrentLine->WIDTH += NewWidth; + ptNewAllow = InsertAllowInIns(ptNewIns,NewphIns->XAB1,NewphIns->XAB2, + NewphIns->YAB1,NewphIns->YAB2,NewphIns); + if (CurrentLine == ptLine) + ptSaveAllow = ptNewAllow; + CurrentLine->ALLOW = addchain(CurrentLine->ALLOW,(char *)ptNewAllow); + for (CurrentSeg = CurrentLine->ALLOWUSED; CurrentSeg; + CurrentSeg = CurrentSeg->NEXT) + if (CurrentSeg->X1 >= Xinsert) { + CurrentSeg->X1 += NewWidth; + CurrentSeg->X2 += NewWidth; + } +/* Mise a jour des connecteurs des lignes */ + for (ConList = CurrentLine->CON; ConList; ConList = ConList->NEXT){ + CurrentCon = ((Connector *)ConList->DATA); + if ((!CurrentCon->INST) && (CurrentCon->X >= Xinsert)) + CurrentCon->X += NewWidth; + } +/* Mise a jour des connecteurs internes et des segment des instances */ + for (; CurrentInst; CurrentInst = CurrentInst->NEXT) { + CurrentInst->X += NewWidth; + for (CurrentCon = CurrentInst->CON; CurrentCon; + CurrentCon = CurrentCon->NEXT) + CurrentCon->X += NewWidth; + for (CurrentSeg = CurrentInst->ALLOW; CurrentSeg; + CurrentSeg = CurrentSeg->NEXT) { + CurrentSeg->X1 += NewWidth; + CurrentSeg->X2 += NewWidth; + } + } + } + else + CurrentLine->WIDTH += NewWidth; + } +/* Mise a jour des connecteurs externes */ + for (CurrentCon = ptfig->CON; CurrentCon; CurrentCon = CurrentCon->NEXT) { + if (CurrentCon->ORIENT == EAST) + CurrentCon->X += NewWidth; + else + if ((CurrentCon->ORIENT == NORTH) && (CurrentCon->X >= Xinsert)) + CurrentCon->X += NewWidth; + else + if ((CurrentCon->ORIENT == SOUTH) && (CurrentCon->X >= XInsertSouth)) + CurrentCon->X += NewWidth; + } + /* MISE A JOUR DES POSITIONS D'OUVERTURES DES ALIM. */ + for (ptXBreakList = ptXInsert; ptXBreakList; ptXBreakList = ptXBreakList->NEXT) { + if (ptXBreakList->X >= Xinsert) ptXBreakList->X += NewWidth; + } + /* MISE A JOUR DES POSITIONS D'OUVERTURES DES ALIM. */ + + return(ptSaveAllow); +} + +/******************************************************************************/ +/* Function : MakeConList() */ +/******************************************************************************/ +ConnectorList *MakeConList(LeadConList,IndexSig,IndexCol) + +ConnectorList *LeadConList; +long IndexSig; +long IndexCol; + +{ + ConnectorList *ptNewCon = NULL; + ConnectorList *CurrentCon = NULL; + ConnectorList *PrevCon = NULL; + + ptNewCon = (ConnectorList *) mbkalloc (sizeof(ConnectorList)); + ptNewCon->NextCon = NULL; + ptNewCon->ConName = IndexSig; + ptNewCon->Mark = IndexCol; + + if (LeadConList == NULL) LeadConList = ptNewCon; + else { + PrevCon = CurrentCon = LeadConList; + while (CurrentCon) { + if (CurrentCon->Mark > IndexCol) { + ptNewCon->NextCon = CurrentCon; + if (CurrentCon == LeadConList) LeadConList = ptNewCon; + else PrevCon->NextCon = ptNewCon; + break; + } + PrevCon = CurrentCon; + CurrentCon = CurrentCon->NextCon; + } + if (CurrentCon == NULL) PrevCon->NextCon = ptNewCon; + } + + return(LeadConList); +} + +/******************************************************************************/ +/* Function : CreateChannel() */ +/******************************************************************************/ +Channel *CreateChannel( LeadNorth,LeadSouth,LeadWest,LeadEast, + Width,Heigth) + +ConnectorList *LeadNorth; +ConnectorList *LeadSouth; +ConnectorList *LeadWest; +ConnectorList *LeadEast; +long Width; +long Heigth; + +{ + Channel *ptNewChannel = NULL; + + ptNewChannel = (Channel *) mbkalloc (sizeof(Channel)); + ptNewChannel->NORTH_LIST = LeadNorth; + ptNewChannel->SOUTH_LIST = LeadSouth; + ptNewChannel->WEST_LIST = LeadWest; + ptNewChannel->EAST_LIST = LeadEast; + ptNewChannel->H_SEGMENT = NULL; + ptNewChannel->V_SEGMENT = NULL; + ptNewChannel->VIA = NULL; + ptNewChannel->WIDTH = Width; + ptNewChannel->HEIGTH = Heigth; + + return (ptNewChannel); +} + +/******************************************************************************/ +/* Function : FillChannel() */ +/******************************************************************************/ +void FillChannel(ptfig) + +Figure *ptfig; + +{ + Line *PathLine = NULL; + Line *NorthLine = NULL; + Line *SouthLine = NULL; + Connector *CurrentCon = NULL; + chain_list *ConList = NULL; + ConnectorList *ptNorthList = NULL; + ConnectorList *ptSouthList = NULL; + ConnectorList *ptEastList = NULL; + ConnectorList *ptWestList = NULL; + + for (SouthLine = ptfig->LINE; SouthLine->NEXT; + SouthLine = SouthLine->NEXT->NEXT) { + + ptNorthList = NULL; + ptSouthList = NULL; + ptEastList = NULL; + ptWestList = NULL; + + PathLine = SouthLine->NEXT; + NorthLine = PathLine->NEXT; + for (ConList = PathLine->CON; ConList; ConList = ConList->NEXT) { + CurrentCon = ((Connector *) ConList->DATA); + if (CurrentCon->ORIENT == WEST) + ptWestList = MakeConList(ptWestList,CurrentCon->SIG->INDEX,0); + else if (CurrentCon->ORIENT == EAST) + ptEastList = MakeConList(ptEastList,CurrentCon->SIG->INDEX,0); + } + if (SouthLine->TYPE == DOWN) { + for (ConList = SouthLine->CON; ConList; ConList = ConList->NEXT) { + CurrentCon = ((Connector *) ConList->DATA); + ptSouthList = MakeConList(ptSouthList,CurrentCon->SIG->INDEX, + ((CurrentCon->X - WESTOFFSET) / PITCH_X) + 1); + } + } + else { + for (ConList = SouthLine->CON; ConList; ConList = ConList->NEXT) { + CurrentCon = ((Connector *) ConList->DATA); + if (CurrentCon->ORIENT == NORTH) + ptSouthList = MakeConList(ptSouthList,CurrentCon->SIG->INDEX, + ((CurrentCon->X - WESTOFFSET) / PITCH_X) + 1); + } + } + if (NorthLine->TYPE == UP) { + for (ConList = NorthLine->CON; ConList; ConList = ConList->NEXT) { + CurrentCon = ((Connector *) ConList->DATA); + ptNorthList = MakeConList(ptNorthList,CurrentCon->SIG->INDEX, + ((CurrentCon->X - WESTOFFSET) / PITCH_X) + 1); + } + } + else { + for (ConList = NorthLine->CON; ConList; ConList = ConList->NEXT) { + CurrentCon = ((Connector *) ConList->DATA); + if (CurrentCon->ORIENT == SOUTH) + ptNorthList = MakeConList(ptNorthList,CurrentCon->SIG->INDEX, + ((CurrentCon->X - WESTOFFSET) / PITCH_X) + 1); + } + } + + PathLine->CHANNEL = CreateChannel(ptNorthList,ptSouthList,ptWestList, + ptEastList, + ((PathLine->WIDTH) / PITCH_X), + ((PathLine->HEIGTH) / PITCH_Y)); + } +} + +/******************************************************************************/ +/* fonction MaxConInColumn() */ +/******************************************************************************/ +long MaxConInColumn(ptSig) + +Signal *ptSig; + +{ + chain_list *ConList1 = NULL; + chain_list *ConList2 = NULL; + Connector *CurrentCon = NULL; + Connector *NextCon = NULL; + long MaxConInCol = 0 ; + long ConInColumn = 0 ; + + for (ConList1 = ptSig->CON; ConList1; ConList1 = ConList1->NEXT) { + CurrentCon = ((Connector *) ConList1->DATA); + ConInColumn = 1; + for (ConList2 = ConList1->NEXT; ConList2; ConList2 = ConList2->NEXT) { + NextCon = ((Connector *) ConList2->DATA); + if (NextCon->X == CurrentCon->X) ConInColumn++; + } + if (MaxConInCol < ConInColumn) MaxConInCol = ConInColumn; + } + return (MaxConInCol); +} + +/******************************************************************************/ +/* fonction SortSignal() */ +/******************************************************************************/ +Signal *SortSignal(ptLeadSig) + +Signal *ptLeadSig; + +{ + Signal *CurrentSig = NULL; + Signal *ptNextSig = NULL; + Signal *ptPrevSig = NULL; + BOOLEAN EndingSort = FALSE; + long SecondSig = 0; + + + for (CurrentSig = ptLeadSig; CurrentSig; CurrentSig = CurrentSig->NEXT) + CurrentSig->MAXCON = MaxConInColumn(CurrentSig); + + while (!EndingSort) { + EndingSort = TRUE; + SecondSig = 0; + for (ptPrevSig = CurrentSig = ptLeadSig; CurrentSig->NEXT; + CurrentSig = CurrentSig->NEXT) { + ptNextSig = CurrentSig->NEXT; + if (SecondSig < 2) SecondSig++; + else ptPrevSig = ptPrevSig->NEXT; + if (CurrentSig->MAXCON < ptNextSig->MAXCON) { + EndingSort = FALSE; + + if (CurrentSig == ptLeadSig) { + if (ptNextSig->NEXT == NULL) { + ptLeadSig = ptNextSig; + ptNextSig->NEXT = CurrentSig; + CurrentSig->NEXT = NULL; + break; + } + else { + ptLeadSig = ptNextSig; + CurrentSig->NEXT = ptNextSig->NEXT; + ptNextSig->NEXT = CurrentSig; + } + } + else { + if (ptNextSig->NEXT == NULL) { + ptPrevSig->NEXT = ptNextSig; + ptNextSig->NEXT = CurrentSig; + CurrentSig->NEXT = NULL; + break; + } + else { + CurrentSig->NEXT = ptNextSig->NEXT; + ptNextSig->NEXT = CurrentSig; + ptPrevSig->NEXT = ptNextSig; + CurrentSig = ptNextSig; + } + } + } + } + } + return (ptLeadSig); +} + +/******************************************************************************/ +/* Function : SpreadSignal() */ +/******************************************************************************/ +void SpreadSignal(ptScrRoot,NewphIns,ptXInsert) +Figure *ptScrRoot; +phfig_list *NewphIns; +XSupplyRecallList *ptXInsert; + +{ + Signal *CurrentSig = NULL; + Signal *ptSignal = NULL; + Connector *ptCon = NULL; + Connector *ptNewCon = NULL; + Segment *ptAllow = NULL; + Segment *ptSaveAllow = NULL; + Segment *ptNewAllow = NULL; + Line *FirstLine = NULL; + Line *LastLine = NULL; + Line *CellLine = NULL; + Line *PrevLine = NULL; + Line *ptSaveLine = NULL; + Line *ptLine = NULL; + chain_list *LineList = NULL; + chain_list *SigList = NULL; + chain_list *ConList = NULL; + chain_list *AllowList = NULL; + chain_list *PrevAllow = NULL; + char *SigName = NULL; + long MinLength = 0; + long NewLength = 0; + long Xinf = 0; + long Xsup = 0; + long Counter = 0; + + for (CurrentSig = ptScrRoot->SIG; CurrentSig; CurrentSig = CurrentSig->NEXT) { + SigName = namealloc(CurrentSig->NAME); + if (!(isvdd(SigName) || isvss(SigName))) { + FirstLine = LastLine = ((Line *) (CurrentSig->LINE)->DATA); + for (LineList = CurrentSig->LINE; LineList; LineList = LineList->NEXT) { + ptLine = ((Line *) LineList->DATA); + if(ptLine->INDEX < FirstLine->INDEX) FirstLine = ptLine; + else if (ptLine->INDEX > LastLine->INDEX) LastLine = ptLine; + } + if ((FirstLine != LastLine) && (FirstLine->NEXT != LastLine)) { + for (ptSaveLine = PrevLine = FirstLine, CellLine = PrevLine->NEXT; + (CellLine != LastLine); ptSaveLine = PrevLine, + PrevLine = CellLine, CellLine = CellLine->NEXT) { + if (CellLine->TYPE == CELL) { + for (SigList = CellLine->SIG; SigList; SigList = SigList->NEXT) + if (CurrentSig->INDEX == ((Signal *) SigList->DATA)->INDEX) break; + if (SigList == NULL) { /* signal n'appartient pas a la ligne */ + if (CellLine->ALLOW) { + for (SigList = PrevLine->SIG; SigList; SigList = SigList->NEXT) { + ptSignal = ((Signal *) SigList->DATA); + if (CurrentSig->INDEX == ptSignal->INDEX) break; + } + if (SigList == NULL) { + for (SigList = ptSaveLine->SIG; SigList; SigList = SigList->NEXT) { + ptSignal = ((Signal *) SigList->DATA); + if (CurrentSig->INDEX == ptSignal->INDEX) break; + } + } + for (ConList = ptSignal->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ( ((ptCon->LINE->INDEX == PrevLine->INDEX) && + (ptCon->ORIENT == NORTH)) + ||((ptCon->LINE->INDEX == ptSaveLine->INDEX) && + (ptCon->ORIENT == NORTH)) ) + break; + } + MinLength = CellLine->WIDTH; + ptSaveAllow = NULL; + for (AllowList = CellLine->ALLOW; AllowList; + AllowList = AllowList->NEXT) { + ptAllow = ((Segment *) AllowList->DATA); + NewLength = LABS(ptAllow->X1,ptCon->X); + if (MinLength > NewLength) { + MinLength = NewLength; + ptSaveAllow = ptAllow; + } + } + } + else { + Xinf = CellLine->WIDTH; + Xsup = CellLine->X; + for (ConList = CurrentSig->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *)ConList->DATA); + if (Xinf > ptCon->X) Xinf = ptCon->X; + if (Xsup < ptCon->X) Xsup = ptCon->X; + } + ptSaveAllow = AutoAllowInsert(ptScrRoot,CellLine,Xinf,Xsup, + NewphIns,ptXInsert,++Counter); + } + /* Insert ALLOW in Line at ALLOWUSED */ + if (ptSaveAllow) { + ptNewAllow = CreateSegment(namealloc(CurrentSig->NAME),ptSaveAllow->X1, + ptSaveAllow->Y1,ptSaveAllow->X2, + ptSaveAllow->Y2,LAYER2WIDTH,VER,ALU2); + if (CellLine->ALLOWUSED == NULL) CellLine->ALLOWUSED = ptNewAllow; + else { + for (ptAllow = CellLine->ALLOWUSED; ptAllow->NEXT; + ptAllow = ptAllow->NEXT); + ptAllow->NEXT = ptNewAllow; + } + /* delete ALLOW from Line */ + PrevAllow = AllowList = CellLine->ALLOW; + while (AllowList) { + if (ptSaveAllow == ((Segment *) AllowList->DATA)) { + if (AllowList == CellLine->ALLOW) CellLine->ALLOW = AllowList->NEXT; + else if (AllowList->NEXT) PrevAllow->NEXT = AllowList->NEXT; + else PrevAllow->NEXT = NULL; + /* FREE(AllowList) */ + break; + } + PrevAllow = AllowList; + AllowList = AllowList->NEXT; + } + + CellLine->SIG = addchain(CellLine->SIG,CurrentSig); + CurrentSig->LINE = addchain(CurrentSig->LINE,CellLine); + ptNewCon = CreateCon(CurrentSig->NAME,'I',UNKNOWN,NORTH, + ptSaveAllow->X1,ptSaveAllow->Y2, + LAYER2WIDTH,ALU2,CellLine,NULL); + ptNewCon->SIG = CurrentSig; + ptNewCon->LINE = CellLine; + CellLine->CON = addchain(CellLine->CON,ptNewCon); + CurrentSig->CON = addchain(CurrentSig->CON,ptNewCon); + ptNewCon = CreateCon(CurrentSig->NAME,'I',UNKNOWN,SOUTH, + ptSaveAllow->X1,ptSaveAllow->Y1, + LAYER2WIDTH,ALU2,CellLine,NULL); + ptNewCon->SIG = CurrentSig; + ptNewCon->LINE = CellLine; + CellLine->CON = addchain(CellLine->CON,ptNewCon); + CurrentSig->CON = addchain(CurrentSig->CON,ptNewCon); + } + else { + fprintf(stderr,"scr_error : in Spread Signal !!! \n"); + exit(1); + } + } + } + } + } + } + } +} + +/******************************************************************************/ +/* fonction GlobalRoute() */ +/******************************************************************************/ +void GlobalRoute(ptfig,NewphIns,ptXInsert) +Figure *ptfig; +phfig_list *NewphIns; +XSupplyRecallList *ptXInsert; + +{ + + ptfig->SIG = SortSignal(ptfig->SIG); + SpreadSignal(ptfig,NewphIns,ptXInsert); + FillChannel(ptfig); + +# ifdef SCR_DEBUG + fprintf(stderr,"Eliminate the multiple connections ...\n"); +# endif + + ptfig = EliminateMultipleConnection(ptfig); + +} +/******************************************************************************/ diff --git a/alliance/src/scr/src/GlobalRouter.h b/alliance/src/scr/src/GlobalRouter.h new file mode 100644 index 00000000..cc4e0aec --- /dev/null +++ b/alliance/src/scr/src/GlobalRouter.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : GlobalRouter.h */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 11/07/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +extern long MaxConInColumn(); +extern Signal *SortSignal(); +extern void GlobalRoute(); diff --git a/alliance/src/scr/src/LoadDataBase.c b/alliance/src/scr/src/LoadDataBase.c new file mode 100644 index 00000000..0825da21 --- /dev/null +++ b/alliance/src/scr/src/LoadDataBase.c @@ -0,0 +1,1390 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : LoadDataBase.c */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 11/07/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +# include +# include +# include +# include +# include "SCR_Type.h" +# include "ViewDataBase.h" +# include "main.h" + +/******************************************************************************/ +/* Fonction orient : Calcul de l'orientation reelle d'une reference */ +/* de type quelconque parmis NORTH/SOUTH/EAST/WEST en tenant compte */ +/* de la transformation de l'instance. */ +/******************************************************************************/ +char Orientation(ORIENT,TRANSF) + +char ORIENT; +char TRANSF; + +{ + if (ORIENT == NORTH) + switch(TRANSF) { + case NOSYM : return (NORTH); + case SYM_X : return (NORTH); + case SYM_Y : return (SOUTH); + case SYMXY : return (SOUTH); + case ROT_P : return (WEST); + case SY_RP : return (EAST); + case ROT_M : return (EAST); + case SY_RM : return (WEST); + } + if (ORIENT == SOUTH) + switch(TRANSF) { + case NOSYM : return (SOUTH); + case SYM_X : return (SOUTH); + case SYM_Y : return (NORTH); + case SYMXY : return (NORTH); + case ROT_P : return (EAST); + case SY_RP : return (WEST); + case ROT_M : return (WEST); + case SY_RM : return (EAST); + } + if (ORIENT == EAST) + switch(TRANSF) { + case NOSYM : return (EAST); + case SYM_X : return (WEST); + case SYM_Y : return (EAST); + case SYMXY : return (WEST); + case ROT_P : return (NORTH); + case SY_RP : return (NORTH); + case ROT_M : return (SOUTH); + case SY_RM : return (SOUTH); + } + if (ORIENT == WEST) + switch(TRANSF) { + case NOSYM : return (WEST); + case SYM_X : return (EAST); + case SYM_Y : return (WEST); + case SYMXY : return (EAST); + case ROT_P : return (SOUTH); + case SY_RP : return (SOUTH); + case ROT_M : return (NORTH); + case SY_RM : return (NORTH); + } +} + +/******************************************************************************/ +/* Fonction Delta_X : Calcul de la largeur de l'instance en tenant */ +/* compte de sa transformation. */ +/******************************************************************************/ +long Delta_X(Xab1,Yab1,Xab2,Yab2,X,Y,TRANSF) + +long Xab1,Yab1,Xab2,Yab2,X,Y; +char TRANSF; + +{ + switch(TRANSF) { + case NOSYM : return(X - Xab1); + case SYM_X : return(-X + Xab2); + case SYM_Y : return(X - Xab1); + case SYMXY : return(Xab2 - Xab1 - Y + Yab1); + case ROT_P : return(Yab2 - Y); + case ROT_M : return(Y - Yab1); + case SY_RM : return(Yab2 - Y); + case SY_RP : return(Y - Yab1); + } +} + +/******************************************************************************/ +/* Fonction Delta_Y : Calcul de la hauteur de l'instance en tenant */ +/* compte de sa transformation. */ +/******************************************************************************/ +long Delta_Y(Xab1,Yab1,Xab2,Yab2,X,Y,TRANSF) + +long Xab1,Yab1,Xab2,Yab2,X,Y; +char TRANSF; + +{ + switch(TRANSF) { + case NOSYM : return(Y - Yab1); + case SYM_X : return(Y - Yab1); + case SYM_Y : return(Yab2 - Y); + case SYMXY : return(Yab2 - Y); + case ROT_P : return(X - Xab1); + case ROT_M : return(Xab2 - X); + case SY_RM : return(Xab2 - X); + case SY_RP : return(X - Xab1); + } +} + +/******************************************************************************/ +/* Fonction Deltab_Y : Calcul de la hauteur de l'instance en tenant */ +/* compte de sa transformation. */ +/******************************************************************************/ +long Deltab_Y(Xab1,Yab1,Xab2,Yab2,TRANSF) + +long Xab1,Yab1,Xab2,Yab2; +char TRANSF; + +{ + switch(TRANSF) { + case NOSYM : + case SYM_X : + case SYM_Y : + case SYMXY : return(Yab2 - Yab1); + case ROT_P : + case ROT_M : + case SY_RM : + case SY_RP : return(Xab2 - Xab1); + } +} + +/******************************************************************************/ +/* Fonction Deltab_X : Calcul de la largeur de l'instance en tenant */ +/* compte de sa transformation. */ +/******************************************************************************/ +long Deltab_X(Xab1,Yab1,Xab2,Yab2,TRANSF) + +long Xab1,Yab1,Xab2,Yab2; +char TRANSF; + +{ + switch(TRANSF) { + case NOSYM : + case SYM_X : + case SYM_Y : + case SYMXY : return(Xab2 - Xab1); + case ROT_P : + case ROT_M : + case SY_RM : + case SY_RP : return(Yab2 - Yab1); + } +} + +/******************************************************************************/ +/* fonction CreateInstance() */ +/******************************************************************************/ +Instance *CreateInstance(InsName,FigName,X,Y,Width,Heigth,Transf) + +char *InsName; +char *FigName; +long X; +long Y; +long Width; +long Heigth; +char Transf; + +{ + Instance *ptNewIns = NULL; + + ptNewIns = (Instance *) mbkalloc (sizeof(Instance)); + ptNewIns->NEXT = NULL; + ptNewIns->NAME = InsName; + ptNewIns->FIGNAME = FigName; + ptNewIns->X = X; + ptNewIns->Y = Y; + ptNewIns->WIDTH = Width; + ptNewIns->HEIGTH = Heigth; + ptNewIns->TRANSF = Transf; + ptNewIns->CON = NULL; + ptNewIns->ALLOW = NULL; + + return (ptNewIns); +} + +/******************************************************************************/ +/* fonction InsertInstance() */ +/******************************************************************************/ +Instance *InsertInstance(ptLine,InsName,FigName,X,Y,Width,Heigth,Transf) + +Line *ptLine; +char *InsName; +char *FigName; +long X; +long Y; +long Width; +long Heigth; +char Transf; + +{ + + Instance *CurrentIns = NULL; + Instance *PrevIns = NULL; + Instance *ptNewIns = NULL; + long XIns = 0; + long WidthIns = 0; + + for (CurrentIns = ptLine->INS; CurrentIns; CurrentIns = CurrentIns->NEXT) { + XIns = CurrentIns->X; + WidthIns = CurrentIns->WIDTH; + if ((XIns == X) || + ((XIns < (X + Width)) && (X + Width) < (XIns + WidthIns)) || + ((XIns < X) && (X < (XIns + WidthIns)))) { + fprintf(stderr,"scr_error :Overlaping of cells %s \n",CurrentIns->NAME); + exit(1); + } + else if (X < XIns) break; + else PrevIns = CurrentIns; + } + ptNewIns = CreateInstance(InsName,FigName,X,Y,Width,Heigth,Transf); + if (!CurrentIns && !PrevIns) ptLine->INS = ptNewIns; + else if (!CurrentIns && PrevIns) PrevIns->NEXT = ptNewIns; + else if (CurrentIns && !PrevIns) { + ptNewIns->NEXT = CurrentIns; + ptLine->INS = ptNewIns; + } + else { + ptNewIns->NEXT = CurrentIns; + PrevIns->NEXT = ptNewIns; + } + return(ptNewIns); +} +/******************************************************************************/ +/* fonction CreateLine() */ +/******************************************************************************/ +Line *CreateLine(Type,X1,Y1,X2,Y2) + +char Type; +long X1,Y1,X2,Y2; + +{ + Line *ptNewLine; + + ptNewLine = (Line *) mbkalloc (sizeof(Line)); + ptNewLine->NEXT = NULL; + ptNewLine->NAME = NULL; + ptNewLine->TYPE = Type; + ptNewLine->X = X1; + ptNewLine->Y = Y1; + ptNewLine->WIDTH = X2-X1; + ptNewLine->HEIGTH = Y2-Y1; + ptNewLine->INDEX = 0; + ptNewLine->INS = NULL; + ptNewLine->SIG = NULL; + ptNewLine->CON = NULL; + ptNewLine->ALLOWUSED = NULL; + ptNewLine->ALLOW = NULL; + ptNewLine->CHANNEL = NULL; + + return(ptNewLine); +} + +/******************************************************************************/ +/* fonction CreateSegment () */ +/******************************************************************************/ +Segment *CreateSegment(Name,X1,Y1,X2,Y2,Width,Type,Layer) + +char *Name; +long X1; +long Y1; +long X2; +long Y2; +long Width; +char Type; +char Layer; + +{ + Segment *ptNewSeg = NULL; + + ptNewSeg = (Segment *) mbkalloc (sizeof(Segment)); + ptNewSeg->NEXT = NULL ; + ptNewSeg->NAME = Name ; + ptNewSeg->X1 = X1 ; + ptNewSeg->X2 = X2 ; + ptNewSeg->Y1 = Y1 ; + ptNewSeg->Y2 = Y2 ; + ptNewSeg->WIDTH = Width ; + ptNewSeg->TYPE = Type ; + ptNewSeg->LAYER = Layer ; + + return (ptNewSeg); +} +/******************************************************************************/ +/* fonction InsertAllowInIns() */ +/******************************************************************************/ +Segment * +InsertAllowInIns (ptCell, Xab1, Xab2, Yab1, Yab2, ptphInsfig) + + Instance *ptCell; + long Xab1; + long Xab2; + long Yab1; + long Yab2; + phfig_list *ptphInsfig; + +{ + Segment *ptNewAllow = NULL; + phseg_list *ptphSeg = NULL; + phseg_list *ptphSeg_dejavu = NULL; + long X1 = 0; + long X2 = 0; + long Y1 = 0; + long Y2 = 0; + + if (ptCell->ALLOW) + printf ("[SCR] Allow builded twice for %s \n", ptCell->NAME); + + for (ptphSeg = ptphInsfig->PHSEG; ptphSeg; ptphSeg = ptphSeg->NEXT) + { + if (ptphSeg->LAYER == TALU2) + { + xyflat (&X1, &Y1, ptphSeg->X1, ptphSeg->Y1, ptCell->X, ptCell->Y, + Xab1, Yab1, Xab2, Yab2, ptCell->TRANSF); + + /* fw : elimination des segments ALLOW empiles */ + for (ptphSeg_dejavu = ptCell->ALLOW; + ptphSeg_dejavu && (X1 != ptphSeg_dejavu->X1); + ptphSeg_dejavu = ptphSeg_dejavu->NEXT); + + if (!ptphSeg_dejavu) + { + xyflat (&X2, &Y2, ptphSeg->X2, ptphSeg->Y2, ptCell->X, ptCell->Y, + Xab1, Yab1, Xab2, Yab2, ptCell->TRANSF); + ptNewAllow = CreateSegment (ptphSeg->NAME, X1, (Y1 - ptCell->Y), X2, + (Y2 - ptCell->Y), ptphSeg->WIDTH, + ptphSeg->TYPE, ptphSeg->LAYER); + ptNewAllow->NEXT = ptCell->ALLOW; + ptCell->ALLOW = ptNewAllow; + } + } + } + return (ptCell->ALLOW); +} +/* forbidden 99/2/28 +Segment *InsertAllowInIns(ptCell,Xab1,Xab2,Yab1,Yab2,ptphInsfig) + +Instance *ptCell; +long Xab1; +long Xab2; +long Yab1; +long Yab2; +phfig_list *ptphInsfig; + +{ + Segment *CurrentAllow = NULL; + Segment *PrevAllow = NULL; + Segment *ptNewAllow = NULL; + phseg_list *ptphSeg = NULL; + long X1 = 0; + long X2 = 0; + long Y1 = 0; + long Y2 = 0; + + for (ptphSeg = ptphInsfig->PHSEG; ptphSeg; ptphSeg = ptphSeg->NEXT) { + if(ptphSeg->LAYER == TALU2) { + xyflat(&X1,&Y1,ptphSeg->X1,ptphSeg->Y1,ptCell->X,ptCell->Y, + Xab1,Yab1,Xab2,Yab2,ptCell->TRANSF); + xyflat(&X2,&Y2,ptphSeg->X2,ptphSeg->Y2,ptCell->X,ptCell->Y, + Xab1,Yab1,Xab2,Yab2,ptCell->TRANSF); + for (PrevAllow = NULL, CurrentAllow = ptCell->ALLOW; CurrentAllow; + CurrentAllow = CurrentAllow->NEXT) { + if (X1 > CurrentAllow->X1) break; + PrevAllow = CurrentAllow; + } + ptNewAllow = CreateSegment(ptphSeg->NAME,X1,(Y1 - ptCell->Y),X2, + (Y2 - ptCell->Y),ptphSeg->WIDTH, + ptphSeg->TYPE,ptphSeg->LAYER); + if ((CurrentAllow == NULL) && (PrevAllow == NULL)) + ptCell->ALLOW = ptNewAllow; + else if ((CurrentAllow == NULL) && PrevAllow) + PrevAllow->NEXT = ptNewAllow; + else if (CurrentAllow && (PrevAllow == NULL)) { + ptNewAllow->NEXT = CurrentAllow; + ptCell->ALLOW = ptNewAllow; + } + else { + ptNewAllow->NEXT = CurrentAllow; + PrevAllow->NEXT = ptNewAllow; + } + } + } + return(ptNewAllow); +} +*/ + +/******************************************************************************/ +/* Fonction CreateCon() */ +/******************************************************************************/ +Connector *CreateCon( Name,Type,Direction,Orient,X,Y,Width, + Layer,ptLine,ptIns) + +char *Name; +char Type; +char Direction; +char Orient; +long X; +long Y; +long Width; +char Layer; +Line *ptLine; +Instance *ptIns; + +{ + Connector *ptNewCon = NULL; + ptNewCon=(Connector *) mbkalloc (sizeof(Connector)); + ptNewCon->NEXT = NULL; + ptNewCon->NAME = Name; + ptNewCon->TYPE = Type; + ptNewCon->DIRECTION = Direction; + ptNewCon->ORIENT = Orient; + ptNewCon->X = X; + ptNewCon->Y = Y; + ptNewCon->WIDTH = Width; + ptNewCon->LAYER = Layer; + ptNewCon->ORDER = 0; /* indique l'ordre du connecteur sur une face */ + ptNewCon->SIG = NULL; + ptNewCon->LINE = ptLine; + ptNewCon->INST = ptIns; + + return(ptNewCon); +} + +/******************************************************************************/ +/* Fonction InsertConInIns() */ +/******************************************************************************/ +Connector *InsertConInIns( + Name,Type,Direction,Orient,X,Y, + Width,Layer,ptLine,ptIns + ) + +char *Name; +char Type; +char Direction; +char Orient; +long X; +long Y; +long Width; +char Layer; +Line *ptLine; +Instance *ptIns; + +{ + Connector *ptScrCon = NULL; + + ptScrCon = CreateCon(Name,Type,Direction,Orient,X,(Y - ptIns->Y), + Width,Layer,ptLine,ptIns); + if (ptIns->CON == NULL) ptIns->CON = ptScrCon; + else { + ptScrCon->NEXT = ptIns->CON; + ptIns->CON = ptScrCon; + } + return(ptScrCon); +} + +/******************************************************************************/ +/* Fonction InsertConInFig() */ +/******************************************************************************/ +Connector *InsertConInFig( ptfig,Name,Type,Direction,Orient,X,Y, + Width,Layer,ptLine) + +Figure *ptfig; +char *Name; +char Type; +char Direction; +char Orient; +long X; +long Y; +long Width; +char Layer; +Line *ptLine; + +{ + Connector *ptNewScrCon = NULL; + Connector *ptScrCon = NULL; + + ptNewScrCon = CreateCon(Name,Type,Direction,Orient,X,Y,Width,Layer,ptLine,NULL); + if (ptfig->CON == NULL) ptfig->CON = ptNewScrCon; + else { + for(ptScrCon = ptfig->CON; ptScrCon->NEXT; ptScrCon = ptScrCon->NEXT); + ptScrCon->NEXT = ptNewScrCon; + } + return(ptNewScrCon); +} + +/******************************************************************************/ +/* Fonction CreateSignal() */ +/******************************************************************************/ +Signal *CreateSignal(Name,Index,Type) + +char *Name; +long Index; +char Type; + +{ + Signal *ptNewSig=NULL; + + ptNewSig=(Signal *) mbkalloc (sizeof(Signal)); + ptNewSig->NEXT = NULL; + ptNewSig->NAME = Name; + ptNewSig->INDEX = Index; + ptNewSig->TYPE = Type; + ptNewSig->CON = NULL; + ptNewSig->LINE = NULL; + ptNewSig->MAXCON = 0; + + return(ptNewSig); +} + +/******************************************************************************/ +/* fonction InsertSignal() */ +/******************************************************************************/ +Signal *InsertSignal(ptRoot,Name,Index,Type,ptCon,ptLine) + +Figure *ptRoot; +char *Name; +long Index; +long Type; +Connector *ptCon; +Line *ptLine; + +{ + Signal *ptNewSig = NULL; + + if (ptRoot->SIG == NULL) { + ptRoot->SIG = ptNewSig = CreateSignal(Name,Index,Type); + ptNewSig->CON = addchain(ptNewSig->CON,((char *) ptCon)); + ptNewSig->LINE = addchain(ptNewSig->LINE,((char *) ptLine)); + } + else { + ptNewSig = CreateSignal(Name,Index,Type); + ptNewSig->NEXT = ptRoot->SIG; + ptRoot->SIG = ptNewSig; + ptNewSig->CON = addchain(ptNewSig->CON,((char *) ptCon)); + ptNewSig->LINE = addchain(ptNewSig->LINE,((char *) ptLine)); + } + return (ptNewSig); +} + +/******************************************************************************/ +/* Function : ScrOrganizeXCon() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : none */ +/* Output parameters : none */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +void ScrOrganizeXCon(LeadScrCon,Orient) + +Connector *LeadScrCon; +char Orient; + +{ + Connector *ptScrphcon = NULL; + Connector *NextptScrphcon = NULL; + long ConOrder = -1; + long NextConOrder = -1; + long XCon = 0; + long XNextCon = 0; + long XAuxCon = 0; + +/* +fprintf(stderr,"##### AVANT TRIE #####\n"); +for (ptScrphcon = LeadScrCon; ptScrphcon; ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == Orient) && (ptScrphcon->ORDER != -1)) + fprintf (stderr,"NAME : %s , ORIENT : %c , X : %ld , Y : %ld , ORDER : %ld\n",ptScrphcon->NAME,ptScrphcon->ORIENT,ptScrphcon->X,ptScrphcon->Y,ptScrphcon->ORDER); +} +*/ + + for(ptScrphcon = LeadScrCon; ptScrphcon; ptScrphcon = ptScrphcon->NEXT) { + ConOrder = ptScrphcon->ORDER; + if ((ptScrphcon->ORIENT == Orient) && (ConOrder != -1)) { + for(NextptScrphcon = ptScrphcon->NEXT; NextptScrphcon; NextptScrphcon = NextptScrphcon->NEXT) { + NextConOrder = NextptScrphcon->ORDER; + if ((NextptScrphcon->ORIENT == Orient) && (NextConOrder != -1)) { + if (ConOrder < NextConOrder) { + if ((XCon = ptScrphcon->X) > (XNextCon = NextptScrphcon->X)) { + XAuxCon = XCon; + ptScrphcon->X = XNextCon; + NextptScrphcon->X = XAuxCon; + } + } + } + } + } + } + +/* +fprintf(stderr,"##### APRES TRIE #####\n"); +for (ptScrphcon = LeadScrCon; ptScrphcon; ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == Orient) && (ptScrphcon->ORDER != -1)) + fprintf (stderr,"NAME : %s , ORIENT : %c , X : %ld , Y : %ld , ORDER : %ld\n",ptScrphcon->NAME,ptScrphcon->ORIENT,ptScrphcon->X,ptScrphcon->Y,ptScrphcon->ORDER); +} +*/ + +} + +/******************************************************************************/ +/* Function : MakeFatherCon() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : none */ +/* Output parameters : none */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +void MakeFatherCon(ptfig,ptphfig,ptlofig,Leadphcon) + +Figure *ptfig; +phfig_list *ptphfig; +lofig_list *ptlofig; +PlaceConList *Leadphcon; + +{ + CaracConList *ptphCon = NULL; + locon_list *ptloCon = NULL; + losig_list *ptMbkSig = NULL; + Line *ptLine = NULL; + Line *FirstCellLine = NULL; + Line *LastCellLine = NULL; + Line *ptSaveLine = NULL; + Line *DownLine = NULL; + Line *UpLine = NULL; + chain_list *LineList = NULL; + chain_list *ConList = NULL; + Connector *ptNewCon = NULL; + Connector *ptCon = NULL; + Connector *ptScrphcon = NULL; + Signal *ptSigFig = NULL; + long XConSave = 0; + long FirstIndex = 0; + long LastIndex = 0; + long IndexLine = 0; + long RightXCon = 0; + long LeftXCon = 0; + long XConFig = 0; + long YConFig = 0; + long Order = 0; + long Counter = 0; + long ConWidth = 0; + char TypeLine; + char ConLayer; + char Orient; + char *LoNameCon; + char *PhNameCon; + BOOLEAN NotFindInRight = TRUE; + BOOLEAN NotFindInLeft = TRUE; + BOOLEAN NotStopLeft = TRUE; + BOOLEAN NotStopRight = TRUE; + + /* reperer la 1ere et la derniere ligne */ + DownLine = ptfig->LINE; + FirstCellLine = DownLine->NEXT->NEXT; + FirstIndex = FirstCellLine->INDEX; + for (LastCellLine = FirstCellLine; LastCellLine->NEXT->NEXT->NEXT; + LastCellLine = LastCellLine->NEXT->NEXT); + UpLine = LastCellLine->NEXT->NEXT; + LastIndex = LastCellLine->INDEX; + + /* on place les connecteurs de la figure mere qui n'ont pas de contraintes + physiques */ + for(ptloCon = ptlofig->LOCON; ptloCon; ptloCon = ptloCon->NEXT) { + LoNameCon = namealloc(ptloCon->NAME); + if (!(isvdd(LoNameCon) || isvss(LoNameCon))) { + if (Leadphcon) { + for(ptphCon = Leadphcon->NORTH_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + if (LoNameCon == PhNameCon) break; + } + + if (ptphCon == NULL) + for(ptphCon = Leadphcon->SOUTH_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + if (LoNameCon == PhNameCon) break; + } + + if (ptphCon == NULL) + for(ptphCon = Leadphcon->WEST_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + if (LoNameCon == PhNameCon) break; + } + + if (ptphCon == NULL) + for(ptphCon = Leadphcon->EAST_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + if (LoNameCon == PhNameCon) break; + } + } + + if (ptphCon == NULL) { /* n'appartient pas aux connecteurs preplaces */ + /* on le place */ + for (ptSigFig = ptfig->SIG; (ptSigFig && + (ptSigFig->INDEX != ptloCon->SIG->INDEX)); + ptSigFig = ptSigFig->NEXT); + if (ptSigFig) { + ptSaveLine = NULL; + for (LineList = ptSigFig->LINE; LineList; LineList = LineList->NEXT) { + ptLine = ((Line *) LineList->DATA); + IndexLine = ptLine->INDEX; + TypeLine = ptLine->TYPE; + if (TypeLine == CELL) { + ptSaveLine = ptLine; + if (IndexLine == FirstIndex) { + for (ConList = ptLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ((ptCon->ORIENT == SOUTH) && (ptCon->SIG->INDEX == ptSigFig->INDEX)) + break; + } + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,ptCon->ORIENT,ptCon->X, + ptphfig->YAB1,LAYER2WIDTH,ALU2,DownLine); + ptNewCon->ORDER = -1; + ptNewCon->SIG = ptSigFig; + DownLine->CON = addchain(DownLine->CON,((Connector *) ptNewCon)); + DownLine->SIG = addchain(DownLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) DownLine)); + break; + } + else if (IndexLine == LastIndex) { + for (ConList = ptLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ((ptCon->ORIENT == NORTH) && + (ptCon->SIG->INDEX == ptSigFig->INDEX)) break; + } + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,ptCon->ORIENT, + ptCon->X,ptphfig->YAB2,LAYER2WIDTH, + ALU2,UpLine); + ptNewCon->ORDER = -1; + ptNewCon->SIG = ptSigFig; + UpLine->CON = addchain(UpLine->CON,((Connector *) ptNewCon)); + UpLine->SIG = addchain(UpLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) UpLine)); + break; + } + } + } + if (LineList == NULL) { + for (ptLine = ptfig->LINE->NEXT; (ptLine->NEXT != ptSaveLine); + ptLine = ptLine->NEXT->NEXT); + for (ConList = ptSaveLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if (ptCon->SIG->INDEX == ptSigFig->INDEX) break; + } + if ((ptCon->X - ptphfig->XAB1) >= (ptphfig->XAB2 - ptCon->X)) { + Orient = EAST; + XConFig = ptphfig->XAB2; + } + else { + Orient = WEST; + XConFig = ptphfig->XAB1; + } + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,Orient, + XConFig,ptLine->Y,LAYER1WIDTH,ALU1,ptLine); + ptNewCon->ORDER = -1; + ptNewCon->SIG = ptSigFig; + ptLine->CON = addchain(ptLine->CON, ((Connector *) ptNewCon)); + ptLine->SIG = addchain(ptLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) ptLine)); + } + } + else { + fprintf(stderr,"scr_warning : the connector : %s is not connected to any signal !\n", ptloCon->NAME); + } + } + } +/* + else if (isvdd(LoNameCon)) NameVdd = LoNameCon; + else if (isvss(LoNameCon)) NameVss = LoNameCon; +*/ + } + +/******************************************************************************/ +/* traitement des connecteurs pre-places */ +/******************************************************************************/ + if (Leadphcon != NULL) { +/******************************************************************************/ +/* Traitement des connecteurs sur la face SOUTH */ +/******************************************************************************/ + for(ptphCon = Leadphcon->SOUTH_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + Orient = SOUTH; + Order = ptphCon->USER; + if (!(isvdd(PhNameCon) || isvss(PhNameCon))) { + NotFindInRight = TRUE; + NotFindInLeft = TRUE; + NotStopRight = TRUE; + NotStopLeft = TRUE; + for(ptloCon = ptlofig->LOCON; ptloCon; ptloCon = ptloCon->NEXT) { + LoNameCon = namealloc(ptloCon->NAME); + if (LoNameCon == PhNameCon) break; + } + if (ptloCon == NULL) { + fprintf(stderr,"scr_error : the connector : %s does not exist in the netlist !\n", ptphCon->NAME); + exit(1); + } + for (ptSigFig = ptfig->SIG; (ptSigFig && (ptSigFig->INDEX != ptloCon->SIG->INDEX)); ptSigFig = ptSigFig->NEXT); + if (ptSigFig == NULL) { + ptMbkSig = ptloCon->SIG; + ptSigFig = CreateSignal(getsigname(ptMbkSig),ptMbkSig->INDEX,ptMbkSig->TYPE); + ptSigFig->NEXT = ptfig->SIG; + ptfig->SIG = ptSigFig; + } + YConFig = ptphfig->YAB1; + for (ConList = FirstCellLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ((ptCon->ORIENT == SOUTH) && (ptCon->SIG->INDEX == ptSigFig->INDEX)) + break; + } + if (ConList != NULL) XConSave = ptCon->X; + else { + for (LineList = ptSigFig->LINE; LineList; LineList = LineList->NEXT) { + ptLine = ((Line *) LineList->DATA); + if (ptLine->TYPE == CELL) { + for (ConList = ptLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ((ptCon->ORIENT == SOUTH) && (ptCon->SIG->INDEX == ptSigFig->INDEX)) { + RightXCon = LeftXCon = XConSave = ptCon->X; + LineList == NULL; + break; + } + } + } + } + } + for(ptScrphcon = ptfig->CON; ptScrphcon; ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == SOUTH) && (ptScrphcon->X == XConSave)) + break; + } + if (ptScrphcon == NULL) { + XConFig = XConSave; + } + else { + while (NotFindInRight && NotFindInLeft) { + if (!((NotStopRight) && (NotStopLeft))) { + fprintf(stderr,"Impossible configuration : the number of connectors to be placed on south side is greater than the existing number of pitchs. \n"); + exit(1); + } + if (NotStopRight) RightXCon += PITCH_X; + if (NotStopLeft) LeftXCon -= PITCH_X; + if (RightXCon >= ptphfig->XAB2) { + NotStopRight = FALSE; + } + if (LeftXCon <= ptphfig->XAB1) { + NotStopLeft = FALSE; + } + for(ptScrphcon = ptfig->CON; (NotStopRight && NotFindInLeft && ptScrphcon); ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == SOUTH) && (ptScrphcon->X == RightXCon)) + break; + } + if (NotStopRight && NotFindInLeft && (ptScrphcon == NULL)) { + XConFig = RightXCon; + NotFindInRight = FALSE; + } + for(ptScrphcon = ptfig->CON; (NotStopLeft && NotFindInRight && ptScrphcon); ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == SOUTH) && (ptScrphcon->X == LeftXCon)) + break; + } + if (NotStopLeft && NotFindInRight && (ptScrphcon == NULL)) { + XConFig = LeftXCon; + NotFindInLeft = FALSE; + } + } + } + ptLine = DownLine; + ConWidth = LAYER2WIDTH; + ConLayer = ALU2; + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,Orient, + XConFig,YConFig,ConWidth,ConLayer,ptLine); + ptNewCon->ORDER = Order; + ptNewCon->SIG = ptSigFig; + ptLine->CON = addchain(ptLine->CON, ((Connector *) ptNewCon)); + ptLine->SIG = addchain(ptLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) ptLine)); + } + } + ScrOrganizeXCon(ptfig->CON,Orient); +/******************************************************************************/ +/* Traitement des connecteurs sur la face NORTH */ +/******************************************************************************/ + for(ptphCon = Leadphcon->NORTH_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + Orient = NORTH; + Order = ptphCon->USER; + + if (!(isvdd(PhNameCon) || isvss(PhNameCon))) { + NotFindInRight = TRUE; + NotFindInLeft = TRUE; + NotStopRight = TRUE; + NotStopLeft = TRUE; + for(ptloCon = ptlofig->LOCON; ptloCon; ptloCon = ptloCon->NEXT) { + LoNameCon = namealloc(ptloCon->NAME); + if (LoNameCon == PhNameCon) break; + } + if (ptloCon == NULL) { + fprintf(stderr,"scr_error : the connector : %s does not exist in the netlist !\n", ptphCon->NAME); + exit(1); + } + for (ptSigFig = ptfig->SIG; (ptSigFig && (ptSigFig->INDEX != ptloCon->SIG->INDEX)); ptSigFig = ptSigFig->NEXT); + if (ptSigFig == NULL) { + ptMbkSig = ptloCon->SIG; + ptSigFig = CreateSignal(getsigname(ptMbkSig),ptMbkSig->INDEX,ptMbkSig->TYPE); + ptSigFig->NEXT = ptfig->SIG; + ptfig->SIG = ptSigFig; + } + YConFig = ptphfig->YAB2; + for (ConList = FirstCellLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ((ptCon->ORIENT == NORTH) && (ptCon->SIG->INDEX == ptSigFig->INDEX)) + break; + } + if (ConList != NULL) XConSave = ptCon->X; + else { + for (LineList = ptSigFig->LINE; LineList; LineList = LineList->NEXT) { + ptLine = ((Line *) LineList->DATA); + if (ptLine->TYPE == CELL) { + for (ConList = ptLine->CON; ConList; ConList = ConList->NEXT) { + ptCon = ((Connector *) ConList->DATA); + if ((ptCon->ORIENT == NORTH) && (ptCon->SIG->INDEX == ptSigFig->INDEX)) { + RightXCon = LeftXCon = XConSave = ptCon->X; + LineList == NULL; + break; + } + } + } + } + } + for(ptScrphcon = ptfig->CON; ptScrphcon; ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == NORTH) && (ptScrphcon->X == XConSave)) + break; + } + if (ptScrphcon == NULL) { + XConFig = XConSave; + } + else { + while (NotFindInRight && NotFindInLeft) { + if (!((NotStopRight) && (NotStopLeft))) { + fprintf(stderr,"Impossible configuration : the number of connectors to be placed on north side is greater than the existing number of pitchs.\n"); + exit(1); + } + if (NotStopRight) RightXCon += PITCH_X; + if (NotStopLeft) LeftXCon -= PITCH_X; + if (RightXCon >= ptphfig->XAB2) { + NotStopRight = FALSE; + } + if (LeftXCon <= ptphfig->XAB1) { + NotStopLeft = FALSE; + } + for(ptScrphcon = ptfig->CON; (NotStopRight && NotFindInLeft && ptScrphcon); ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == NORTH) && (ptScrphcon->X == RightXCon)) + break; + } + if (NotStopRight && NotFindInLeft && (ptScrphcon == NULL)) { + XConFig = RightXCon; + NotFindInRight = FALSE; + } + for(ptScrphcon = ptfig->CON; (NotStopLeft && NotFindInRight && ptScrphcon); ptScrphcon = ptScrphcon->NEXT) { + if ((ptScrphcon->ORIENT == NORTH) && (ptScrphcon->X == LeftXCon)) + break; + } + if (NotStopLeft && NotFindInRight && (ptScrphcon == NULL)) { + XConFig = LeftXCon; + NotFindInLeft = FALSE; + } + } + } + ptLine = UpLine; + ConWidth = LAYER2WIDTH; + ConLayer = ALU2; + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,Orient, + XConFig,YConFig,ConWidth,ConLayer,ptLine); + ptNewCon->ORDER = Order; + ptNewCon->SIG = ptSigFig; + ptLine->CON = addchain(ptLine->CON, ((Connector *) ptNewCon)); + ptLine->SIG = addchain(ptLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) ptLine)); + } + } + ScrOrganizeXCon(ptfig->CON,Orient); +/******************************************************************************/ +/* Traitement des connecteurs sur la face WEST */ +/******************************************************************************/ + for(ptphCon = Leadphcon->WEST_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + Orient = WEST; + Order = ptphCon->USER; + if (!(isvdd(PhNameCon) || isvss(PhNameCon))) { + for(ptloCon = ptlofig->LOCON; ptloCon; ptloCon = ptloCon->NEXT) { + LoNameCon = namealloc(ptloCon->NAME); + if (LoNameCon == PhNameCon) break; + } + if (ptloCon == NULL) { + fprintf(stderr,"scr_error : the connector : %s does not exist in the netlist !\n", ptphCon->NAME); + exit(1); + } + for (ptSigFig = ptfig->SIG; (ptSigFig && (ptSigFig->INDEX != ptloCon->SIG->INDEX)); + ptSigFig = ptSigFig->NEXT); + if (ptSigFig == NULL) { + ptMbkSig = ptloCon->SIG; + ptSigFig = CreateSignal(getsigname(ptMbkSig),ptMbkSig->INDEX,ptMbkSig->TYPE); + ptSigFig->NEXT = ptfig->SIG; + ptfig->SIG = ptSigFig; + } + for (LineList = ptSigFig->LINE; LineList; LineList = LineList->NEXT) { + ptLine = ((Line *) (LineList->DATA)); + if (ptLine->TYPE == CELL) { + ptSaveLine = ptLine; + break; + } + } + for (ptLine = ptfig->LINE->NEXT; (ptLine->NEXT != ptSaveLine); ptLine = ptLine->NEXT->NEXT); + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,Orient, + ptphfig->XAB1,ptLine->Y,LAYER1WIDTH,ALU1,ptLine); + ptNewCon->ORDER = Order; + ptNewCon->SIG = ptSigFig; + ptLine->CON = addchain(ptLine->CON, ((Connector *) ptNewCon)); + ptLine->SIG = addchain(ptLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) ptLine)); + } + } +/******************************************************************************/ +/* Traitement des connecteurs sur la face EAST */ +/******************************************************************************/ + for(ptphCon = Leadphcon->EAST_CON; ptphCon; ptphCon = ptphCon->NEXT) { + PhNameCon = namealloc(ptphCon->NAME); + Orient = EAST; + Order = ptphCon->USER; + if (!(isvdd(PhNameCon) || isvss(PhNameCon))) { + for(ptloCon = ptlofig->LOCON; ptloCon; ptloCon = ptloCon->NEXT) { + LoNameCon = namealloc(ptloCon->NAME); + if (LoNameCon == PhNameCon) break; + } + if (ptloCon == NULL) { + fprintf(stderr,"scr_error : the connector : %s does not exist in the netlist !\n", ptphCon->NAME); + exit(1); + } + for (ptSigFig = ptfig->SIG; (ptSigFig && (ptSigFig->INDEX != ptloCon->SIG->INDEX)); + ptSigFig = ptSigFig->NEXT); + if (ptSigFig == NULL) { + ptMbkSig = ptloCon->SIG; + ptSigFig = CreateSignal(getsigname(ptMbkSig),ptMbkSig->INDEX,ptMbkSig->TYPE); + ptSigFig->NEXT = ptfig->SIG; + ptfig->SIG = ptSigFig; + } + for (LineList = ptSigFig->LINE; LineList; LineList = LineList->NEXT) { + ptLine = ((Line *) (LineList->DATA)); + if (ptLine->TYPE == CELL) { + ptSaveLine = ptLine; + break; + } + } + for (ptLine = ptfig->LINE->NEXT; (ptLine->NEXT != ptSaveLine); ptLine = ptLine->NEXT->NEXT); + ptNewCon = InsertConInFig(ptfig,ptloCon->NAME,ptloCon->TYPE, + ptloCon->DIRECTION,Orient, + ptphfig->XAB2,ptLine->Y,LAYER1WIDTH,ALU1,ptLine); + ptNewCon->ORDER = Order; + ptNewCon->SIG = ptSigFig; + ptLine->CON = addchain(ptLine->CON, ((Connector *) ptNewCon)); + ptLine->SIG = addchain(ptLine->SIG,((Signal *) ptSigFig)); + ptSigFig->CON = addchain(ptSigFig->CON,((Connector *) ptNewCon)); + ptSigFig->LINE = addchain(ptSigFig->LINE,((Line *) ptLine)); + } + } + } +} + + +/******************************************************************************/ +/* fonction FillFigure() */ +/******************************************************************************/ +void FillFigure(ptRoot,ptphfig,ptlofig,HeadphconList) + +Figure *ptRoot; +phfig_list *ptphfig; +lofig_list *ptlofig; +PlaceConList *HeadphconList; + +{ + phins_list *ptphIns = NULL; + phfig_list *ptphInsfig = NULL; + loins_list *ptloIns = NULL; + Line *ptLine = NULL; + Instance *CurrentIns = NULL; + Connector *ptScrCon = NULL; + phcon_list *ptphCon = NULL; + locon_list *ptloCon = NULL; + Signal *ptScrSig = NULL; + Signal *ptRootSig = NULL; + chain_list *LineList = NULL; + chain_list *SigList = NULL; + losig_list *ptSig = NULL; + Segment *ptScrAllow = NULL; + long Xab1 = 0; + long Xab2 = 0; + long Yab1 = 0; + long Yab2 = 0; + long XlInsFig = 0; + long XrInsFig = 0; + long YuInsFig = 0; + long YdInsFig = 0; + long YuLineFig = 0; + long YdLineFig = 0; + long XConLine = 0; + long YConLine = 0; + char Transf; + char *phName; + char Orient; + + for (ptphIns = ptphfig->PHINS ; ptphIns; ptphIns = ptphIns->NEXT) { + ptphInsfig = getphfig(ptphIns->FIGNAME,'A'); + sx2sc (ptphInsfig); + Xab1 = ptphInsfig->XAB1; + Yab1 = ptphInsfig->YAB1; + Xab2 = ptphInsfig->XAB2; + Yab2 = ptphInsfig->YAB2; + Transf = ptphIns->TRANSF; + XlInsFig = ptphIns->XINS; + YdInsFig = ptphIns->YINS; + XrInsFig = XlInsFig + Deltab_X(Xab1, Yab1, Xab2, Yab2, Transf); + YuInsFig = YdInsFig + Deltab_Y(Xab1, Yab1, Xab2, Yab2, Transf); + + + for (ptLine = ptRoot->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == CELL) { + YdLineFig = ptLine->Y; + YuLineFig = YdLineFig + ptLine->HEIGTH; + if ((YdLineFig == YdInsFig) && (YuLineFig == YuInsFig)) break; + } + } + CurrentIns = InsertInstance(ptLine,ptphIns->INSNAME,ptphIns->FIGNAME, + XlInsFig,ptLine->Y,(XrInsFig - XlInsFig), + (YuInsFig - YdInsFig),Transf); + ptScrAllow = InsertAllowInIns(CurrentIns,Xab1,Xab2,Yab1,Yab2,ptphInsfig); + while (ptScrAllow) { + ptLine->ALLOW = addchain(ptLine->ALLOW,((char *) ptScrAllow)); + ptScrAllow = ptScrAllow->NEXT; + } + + if (!(incatalogfeed(ptphIns->FIGNAME))) { + ptloIns = getloins(ptlofig,ptphIns->INSNAME); + for(ptphCon = ptphInsfig->PHCON ; ptphCon; ptphCon = ptphCon->NEXT) { + for(ptloCon = ptloIns->LOCON ; + (ptloCon && (ptloCon->NAME != ptphCon->NAME)); + ptloCon = ptloCon->NEXT); + if (ptloCon) { + ptScrCon = NULL; + ptScrSig = NULL; + xyflat(&XConLine,&YConLine,ptphCon->XCON,ptphCon->YCON, + XlInsFig,YdInsFig,Xab1,Yab1,Xab2,Yab2,Transf); + Orient = Orientation(ptphCon->ORIENT,Transf); + phName = namealloc (ptphCon->NAME); + if ((phName == NameVss) || (phName == NameVdd)) + phName = ScrNameIndex(phName,ptLine->INDEX); + ptScrCon = InsertConInIns(phName,ptloCon->TYPE,ptloCon->DIRECTION,Orient, + XConLine,YConLine,ptphCon->WIDTH, ptphCon->LAYER, + ptLine,CurrentIns + ); + ptLine->CON = addchain(ptLine->CON,((char *) ptScrCon)); + ptSig = ptloCon->SIG; + for(ptRootSig = ptRoot->SIG ; (ptRootSig && + (ptRootSig->INDEX != ptSig->INDEX)); ptRootSig = ptRootSig->NEXT); + if (ptRootSig == NULL) { + ptScrSig = InsertSignal(ptRoot,getsigname(ptSig),ptSig->INDEX,ptSig->TYPE, + ptScrCon,ptLine); + ptScrCon->SIG = ptScrSig; + ptLine->SIG = addchain(ptLine->SIG,((char *) ptScrSig)); + } + else { + ptScrCon->SIG = ptRootSig; + ptRootSig->CON = addchain(ptRootSig->CON,((char *) ptScrCon)); + for (LineList = ptRootSig->LINE; LineList; LineList = LineList->NEXT) + if (ptLine->INDEX == ((Line *) LineList->DATA)->INDEX) break; + if (LineList == NULL) + ptRootSig->LINE = addchain(ptRootSig->LINE,((char *) ptLine)); + for (SigList = ptLine->SIG; SigList; SigList = SigList->NEXT) + if (ptSig->INDEX == ((Signal *) SigList->DATA)->INDEX) break; + if (SigList == NULL) + ptLine->SIG = addchain(ptLine->SIG,((char *) ptRootSig)); + } + + } + } + } + } + MakeFatherCon(ptRoot,ptphfig,ptlofig,HeadphconList); + +} + +/******************************************************************************/ +/* Fonction : MakeLine() */ +/* Creation des differentes lignes et verification */ +/* de la topologie du circuit. */ +/******************************************************************************/ +Line *MakeLine(ptphfig) + +phfig_list *ptphfig; + +{ + Line *ptLeadLine = NULL; + Line *ptBeforLine = NULL; + Line *ptAfterLine = NULL; + Line *ptNewLine = NULL; + Line *ptLine = NULL; + phins_list *ptIns = NULL; + phfig_list *ptphInsfig = NULL; + BOOLEAN LineExist = FALSE; + long Xab2 = 0,Xab1 = 0,Yab2 = 0,Yab1 = 0; + long Y1Line = 0,Y2Line = 0; + long Y1Ins = 0,Y2Ins = 0; + long LineIndex = 0; + + Xab1 = ptphfig->XAB1; + Xab2 = ptphfig->XAB2; + Yab1 = ptphfig->YAB1; + Yab2 = ptphfig->YAB2; + + /* building UP line */ + ptLeadLine = CreateLine(UP,Xab1,Yab2,Xab2,Yab2); + + /* building CELLs lines */ + for (ptIns = ptphfig->PHINS ; ptIns; ptIns = ptIns->NEXT) { + ptphInsfig = getphfig(ptIns->FIGNAME,'A'); + sx2sc (ptphInsfig); + Y1Ins = ptIns->YINS; + Y2Ins = ptIns->YINS + Deltab_Y(ptphInsfig->XAB1,ptphInsfig->YAB1, + ptphInsfig->XAB2,ptphInsfig->YAB2, + ptIns->TRANSF); + + ptBeforLine = ptAfterLine = NULL; + LineExist = FALSE; + for (ptLine = ptLeadLine; ptLine; ptLine = ptLine->NEXT) { + Y1Line = ptLine->Y; + Y2Line = Y1Line + ptLine->HEIGTH; + if (((Y2Line < Y2Ins) && (Y2Line > Y1Ins)) || + ((Y1Line < Y2Ins) && (Y1Line > Y1Ins)) || + ((Y2Line < Y2Ins) && (Y1Line > Y1Ins)) || + ((Y2Line > Y2Ins) && (Y1Line == Y1Ins)) || + ((Y2Line >= Y2Ins) && (Y1Line < Y1Ins)) || + ((Y2Line <= Y2Ins) && (Y1Line > Y1Ins) && (Y1Line < Y2Ins)) || + ((Y2Line < Y2Ins) && (Y1Line == Y1Ins))) { + fprintf(stderr,"scr_error,Bad placed instance : %s, or the abutment box is not defined in the genlib file.\n",ptIns->INSNAME); + exit(1); + } + else if ((Y2Line == Y2Ins) && (Y1Line == Y1Ins)) { + LineExist = TRUE; + break; + } + else if (Y2Line <= Y1Ins) { + ptBeforLine = ptLine; + } + else if (Y1Line >= Y2Ins) { + ptAfterLine = ptLine; + break; + } + } + if ((!LineExist) && ptBeforLine && ptAfterLine) { + ptNewLine = CreateLine(CELL,Xab1,Y1Ins,Xab2,Y2Ins); + ptNewLine->NEXT = ptAfterLine; + ptBeforLine->NEXT = ptNewLine; + } + else if ((!LineExist) && ptBeforLine) { + ptNewLine = CreateLine(CELL,Xab1,Y1Ins,Xab2,Y2Ins); + ptBeforLine->NEXT = ptNewLine; + } + else if ((!LineExist) && ptAfterLine) { + ptNewLine = CreateLine(CELL,Xab1,Y1Ins,Xab2,Y2Ins); + ptNewLine->NEXT = ptAfterLine; + ptLeadLine = ptNewLine; + } + } + + + + /* building DOWN line */ + ptNewLine = CreateLine(DOWN,Xab1,Yab1,Xab2,Yab1); + ptNewLine->NEXT = ptLeadLine; + ptLeadLine = ptNewLine; + + + /* building PATH lines */ + for (ptBeforLine = ptLeadLine, ptAfterLine = ptLeadLine->NEXT ; ptAfterLine; + ptBeforLine = ptAfterLine, ptAfterLine = ptAfterLine->NEXT) { + ptNewLine = CreateLine(PATH,Xab1,(ptBeforLine->Y + ptBeforLine->HEIGTH), + Xab2,ptAfterLine->Y); + ptNewLine->NEXT = ptAfterLine; + ptBeforLine->NEXT = ptNewLine; + } + + /* indexing lines */ + for (ptLine = ptLeadLine ; ptLine; ptLine = ptLine->NEXT) { + ptLine->INDEX = ++LineIndex; + if (ptLine->TYPE == PATH) + ptLine->NAME = ScrNameIndex("SCR_P",LineIndex); + else if (ptLine->TYPE == CELL) + ptLine->NAME = ScrNameIndex("SCR_C",LineIndex); + else if (ptLine->TYPE == UP) + ptLine->NAME = ScrNameIndex("SCR_U",LineIndex); + else if (ptLine->TYPE == DOWN) + ptLine->NAME = ScrNameIndex("SCR_D",LineIndex); + + } + return(ptLeadLine); +} + +/******************************************************************************/ +/* fonction LoadScrFig() */ +/******************************************************************************/ +Figure *LoadScrFig(ptphfig, ptlofig,ptphcon) + +phfig_list *ptphfig; +lofig_list *ptlofig; +PlaceConList *ptphcon; + +{ + Figure *ptroot = NULL; + + ptroot = (Figure *) mbkalloc (sizeof(Figure)); + ptroot->LINE = MakeLine(ptphfig); + ptroot->SIG = NULL; + ptroot->CON = NULL; + ptroot->ALLOW = NULL; + + FillFigure(ptroot,ptphfig,ptlofig,ptphcon); + return (ptroot); +} + diff --git a/alliance/src/scr/src/LoadDataBase.h b/alliance/src/scr/src/LoadDataBase.h new file mode 100644 index 00000000..54bf598a --- /dev/null +++ b/alliance/src/scr/src/LoadDataBase.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : LoadDataBase.h */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 11/07/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +extern char Orient(); +extern long Delta_X(); +extern long Delta_Y(); +extern long Deltab_X(); +extern long Deltab_Y(); +extern Connector *CreateCon(); +extern Connector *InsertConInIns(); +extern Instance *CreateInstance(); +extern Instance *InsertInstance(); +extern Line *CreateLine(); +extern Line *MakeLine(); +extern Segment *CreateSegment(); +extern Segment *InsertAllowInIns(); +extern void FillFigure(); +extern Figure *LoadScrFig(); diff --git a/alliance/src/scr/src/Makefile.am b/alliance/src/scr/src/Makefile.am new file mode 100644 index 00000000..9749c8d5 --- /dev/null +++ b/alliance/src/scr/src/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in + +AM_YFLAGS = -d + +#CFLAGS = -g -pg -O2 +CFLAGS = -g -O2 +#CFLAGS = -O2 +AM_CFLAGS = @ALLIANCE_CFLAGS@ \ + -I$(top_srcdir)/mbk/src + +bin_PROGRAMS = scr + +scr_LDADD = -L$(libdir) @ALLIANCE_LIBS@ \ + -L$(top_builddir)/mbk/src/.libs \ + -lApr -lMpu -lMlu -lMlo -lMph -lMut + +scr_SOURCES = GlobalRouter.c LoadDataBase.c main.c ScrSesame.c ViewDataBase.c \ + scr_grammar.y scr_lexer.l diff --git a/alliance/src/scr/src/SCR_Type.h b/alliance/src/scr/src/SCR_Type.h new file mode 100644 index 00000000..efb3deb5 --- /dev/null +++ b/alliance/src/scr/src/SCR_Type.h @@ -0,0 +1,159 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : SCR_Type.h */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ + +extern char *ScrNameIndex(); +extern int SXMODE; + +# define TRICE ((char *) "_") +# define SIGNAME ((char *) "Sig_") +# define NOTNET ((long 0) 0) + +# define IMPAIRE(a) (((a) & 1) ? TRUE : FALSE) +# define MAX(a,b) ((a>b) ? a:b) +# define MIN(a,b) ((a y) ? (x - y) : (y - x)) +# define PATH 'P' +# define CELL 'C' +# define DOWN 'D' +# define UP 'U' +# define BOOLEAN int +# define FALSE ((int ) 0) +# define TRUE ((int ) 1) +# define VDDOFFSET ((long ) (SXMODE ? 3:2) * SCALE_X) +# define VSSOFFSET ((long ) (SXMODE ? 3:2) * SCALE_X) +# define VDDWIDTH ((long ) (SXMODE ? 6:8) * SCALE_X) +# define VSSWIDTH ((long ) (SXMODE ? 6:8) * SCALE_X) +# define RIGHTSUPPLY (PITCH_X / (SXMODE ? 1:2)) +# define LEFTSUPPLY (PITCH_X / (SXMODE ? 1:2)) +# define MIDDLESUPPLY ((long ) 3 * SCALE_X) +# define CELLAB ((long ) 50 * SCALE_X) + +typedef struct SCR_Figure + { + struct SCR_Line *LINE; + struct SCR_Signal *SIG; + struct SCR_Connector *CON; + struct SCR_Segment *ALLOW; + } Figure; + +typedef struct SCR_Line + { + struct SCR_Line *NEXT; + char *NAME; + char TYPE; + long X,Y; + long WIDTH; + long HEIGTH; + long INDEX; + struct SCR_Instance *INS; + struct chain *SIG; + struct chain *CON; + struct SCR_Segment *ALLOWUSED; + struct chain *ALLOW; + struct SCR_Channel *CHANNEL; + } Line; + +typedef struct SCR_Signal + { + struct SCR_Signal *NEXT; + char *NAME; + long INDEX; + char TYPE; + struct chain *CON; + struct chain *LINE; + long MAXCON; + } Signal; + +typedef struct SCR_Instance + { + struct SCR_Instance *NEXT; + char *NAME; + char *FIGNAME; + long X,Y; + long WIDTH; + long HEIGTH; + char TRANSF; + struct SCR_Connector *CON; + struct SCR_Segment *ALLOW; + } Instance; + +typedef struct SCR_Connector + { + struct SCR_Connector *NEXT; + char *NAME; + char TYPE; + char DIRECTION; + char ORIENT; + long X,Y; + long WIDTH; + long ORDER; /* tenir compte de l'ordre des con. physiques */ + char LAYER; + struct SCR_Signal *SIG; + struct SCR_Line *LINE; + struct SCR_Instance *INST; + } Connector; + +typedef struct SCR_Segment + { + struct SCR_Segment *NEXT; + char *NAME; + long X1,Y1,X2,Y2; + long WIDTH; + char TYPE; + char LAYER; + } Segment; + + +typedef struct SCR_Channel + { + struct SCR_ConnectorList *NORTH_LIST; + struct SCR_ConnectorList *SOUTH_LIST; + struct SCR_ConnectorList *WEST_LIST; + struct SCR_ConnectorList *EAST_LIST; + struct SCR_SegmentList *H_SEGMENT; + struct SCR_SegmentList *V_SEGMENT; + struct SCR_ViasList *VIA; + long WIDTH; + long HEIGTH; + } Channel ; + diff --git a/alliance/src/scr/src/ScrDataBase.h b/alliance/src/scr/src/ScrDataBase.h new file mode 100644 index 00000000..7e79748d --- /dev/null +++ b/alliance/src/scr/src/ScrDataBase.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : ScrDataBase.h */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ + +# define BOOLEAN int +# define FALSE ((int ) 0) +# define TRUE ((int ) 1) + +# define HOR ((char )'H') +# define VER ((char )'V') diff --git a/alliance/src/scr/src/ScrSesame.c b/alliance/src/scr/src/ScrSesame.c new file mode 100644 index 00000000..63755633 --- /dev/null +++ b/alliance/src/scr/src/ScrSesame.c @@ -0,0 +1,188 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : ScrSesame.c */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ + +# include +# include +# include + +# define XNEG 1 +# define YNEG 2 + +extern int SXMODE; + +/******************************************************************************/ +/* Function : UpDateNegatifCoordinate() */ +/******************************************************************************/ +void UpDateNegatifCoordinate(ptphfig,XYflag) +phfig_list *ptphfig; +int XYflag; + +{ + phcon_list *CurrentphCon = NULL; + phins_list *CurrentphIns = NULL; + + if (XYflag == XNEG) { + for (CurrentphCon = ptphfig->PHCON; CurrentphCon; CurrentphCon = CurrentphCon->NEXT) { + CurrentphCon->XCON += (ptphfig->XAB1 * (-1)); + } + for (CurrentphIns = ptphfig->PHINS; CurrentphIns; CurrentphIns = CurrentphIns->NEXT) { + CurrentphIns->XINS += (ptphfig->XAB1 * (-1)); + } + } + else { + if (XYflag == YNEG) { + for (CurrentphCon = ptphfig->PHCON; CurrentphCon; CurrentphCon = CurrentphCon->NEXT) { + CurrentphCon->YCON += (ptphfig->YAB1 * (-1)); + } + for (CurrentphIns = ptphfig->PHINS; CurrentphIns; CurrentphIns = CurrentphIns->NEXT) { + CurrentphIns->YINS += (ptphfig->YAB1 * (-1)); + } + } + } + +} + +/******************************************************************************/ +/* Function : InsCompare() */ +/******************************************************************************/ +void InsCompare(ptphIns,ptloIns) + +phins_list *ptphIns; +loins_list *ptloIns; + +{ + phins_list *CurrentphIns = NULL; + phins_list *ptCurrentph = NULL; + loins_list *CurrentloIns = NULL; + loins_list *ptCurrentlo = NULL; + char *InsName; + + for (CurrentloIns = ptloIns; CurrentloIns; CurrentloIns = CurrentloIns->NEXT) { + InsName = CurrentloIns->INSNAME; + for (ptCurrentlo = ptloIns; ptCurrentlo; ptCurrentlo = ptCurrentlo->NEXT) + if ((ptCurrentlo != CurrentloIns) && (InsName == ptCurrentlo->INSNAME)) { + fprintf(stderr,"scr_error : Logic instance : %s is redeclared !!\n", InsName); + exit(1); + } + } + + for (CurrentphIns = ptphIns; CurrentphIns; CurrentphIns = CurrentphIns->NEXT) { + InsName = CurrentphIns->INSNAME; + for (ptCurrentph = ptphIns; ptCurrentph; ptCurrentph = ptCurrentph->NEXT) + if ((ptCurrentph != CurrentphIns) && (InsName == ptCurrentph->INSNAME)) { + fprintf(stderr,"scr_error : Physical instance : %s is redeclared !!\n", InsName); + exit(1); + } + } + + for (CurrentphIns = ptphIns; CurrentphIns; CurrentphIns = CurrentphIns->NEXT) { + /*if (!(incatalogfeed(CurrentphIns->FIGNAME))) {*/ + if (strcmp(CurrentphIns->FIGNAME,(SXMODE ? "rowend_x0":"tie_y"))) { +// if (strcmp(CurrentphIns->FIGNAME,(SXMODE ? "tie_x0":"tie_y"))) { + for (CurrentloIns = ptloIns; CurrentloIns; CurrentloIns = CurrentloIns->NEXT) + if (CurrentloIns->INSNAME == CurrentphIns->INSNAME) break; + if (CurrentloIns == NULL) { + fprintf(stderr,"scr_error : Physical instance : %s does not exist in logic net-list !! \n", CurrentphIns->INSNAME); + exit(1); + } + } + } + + for (CurrentloIns = ptloIns; CurrentloIns; CurrentloIns = CurrentloIns->NEXT) { + for (CurrentphIns = ptphIns; CurrentphIns; CurrentphIns = CurrentphIns->NEXT) + if (CurrentloIns->INSNAME == CurrentphIns->INSNAME) break; + if (CurrentphIns == NULL) { + fprintf(stderr,"scr_error : Logic instance : %s does not exist in physical net-list !! \n", CurrentloIns->INSNAME); + exit(1); + } + } +} + +/******************************************************************************/ +/* Function : ConCompare() */ +/******************************************************************************/ +void ConCompare(ptphCon,ptloCon) + +phcon_list *ptphCon; +locon_list *ptloCon; + +{ + phcon_list *CurrentphCon = NULL; + locon_list *CurrentloCon = NULL; + + for (CurrentphCon = ptphCon; CurrentphCon; CurrentphCon = CurrentphCon->NEXT) { + for (CurrentloCon = ptloCon; CurrentloCon; CurrentloCon = CurrentloCon->NEXT) + if (CurrentphCon->NAME == CurrentloCon->NAME) break; + if (CurrentloCon == NULL) { + fprintf(stderr,"scr_error : Physical connector : %s does not exist in logic connector list\n", CurrentphCon->NAME); + exit(1); + } + } +} + +/******************************************************************************/ +/* Function : Sesame() */ +/******************************************************************************/ +void Sesame(ptphfig,ptlofig) + +phfig_list *ptphfig; +lofig_list *ptlofig; + +{ + if (ptphfig->PHSEG || ptphfig->PHVIA) { + fprintf(stderr,"scr_error : Segments and Vias list must be NULL !!\n"); + exit(1); + } + if (ptphfig->XAB1 < 0) { + UpDateNegatifCoordinate(ptphfig,XNEG); + ptphfig->XAB2 += (ptphfig->XAB1 * (-1)); + ptphfig->XAB1 += (ptphfig->XAB1 * (-1)); + } + if (ptphfig->YAB1 < 0) { + UpDateNegatifCoordinate(ptphfig,YNEG); + ptphfig->YAB2 += (ptphfig->YAB1 * (-1)); + ptphfig->YAB1 += (ptphfig->YAB1 * (-1)); + } + InsCompare(ptphfig->PHINS,ptlofig->LOINS); + ConCompare(ptphfig->PHCON,ptlofig->LOCON); +} + diff --git a/alliance/src/scr/src/ViewDataBase.c b/alliance/src/scr/src/ViewDataBase.c new file mode 100644 index 00000000..c299e942 --- /dev/null +++ b/alliance/src/scr/src/ViewDataBase.c @@ -0,0 +1,295 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : ViewDataBase.c */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +# include +# include +# include +# include +# include "SCR_Type.h" + +/******************************************************************************/ +/* function DecodLayer() / +/******************************************************************************/ +char *DecodLayer(index) +char index; +{ + switch (index) { + case NWELL : + return "nwell"; + case PWELL : + return "pwell"; + case NTIE : + return "ntie"; + case PTIE : + return "ptie"; + case NDIF : + return "ndif"; + case PDIF : + return "pdif"; + case NTRANS : + return "ntrans"; + case PTRANS : + return "ptrans"; + case POLY : + return "poly"; + case ALU1 : + return "metal1"; + case ALU2 : + return "metal2"; + case ALU3 : + return "metal3"; + case TPOLY : + return "allowP"; + case TALU1 : + return "allowM1"; + case TALU2 : + return "allowM2"; + case TALU3 : + return "allowM3"; + } + return NULL; /* makes lint silent */ +} + +/******************************************************************************/ +/* Function : ViewConList() */ +/******************************************************************************/ +void ViewConList(ptLeadList) + +ConnectorList *ptLeadList; + +{ + ConnectorList *CurrentCon = NULL; + + for (CurrentCon = ptLeadList; CurrentCon; CurrentCon = CurrentCon->NextCon) + fprintf(stdout,"|____(NAME,INDEX) : ( %ld , %ld ) \n", + CurrentCon->ConName,CurrentCon->Mark); +} + +/******************************************************************************/ +/* Function : ViewScrChannel() */ +/******************************************************************************/ +void ViewScrChannel(ptfig) + +Figure *ptfig; + +{ + Line *ptLine = NULL; + Channel *ptChannel = NULL; + + for(ptLine = ptfig->LINE->NEXT; ptLine->NEXT->NEXT; + ptLine = ptLine->NEXT->NEXT) { + ptChannel = ptLine->CHANNEL; + if (ptChannel) { + fprintf(stdout,"|__ChannelName : %s \n",ptLine->NAME); + fprintf(stdout,"|__________|__NorthConList : \n"); + ViewConList(ptChannel->NORTH_LIST); + fprintf(stdout,"|__________|__SouthConList : \n"); + ViewConList(ptChannel->SOUTH_LIST); + fprintf(stdout,"|__________|__WestConList : \n"); + ViewConList(ptChannel->WEST_LIST); + fprintf(stdout,"|__________|__EastConList : \n"); + ViewConList(ptChannel->EAST_LIST); + } + } +} + +/******************************************************************************/ +/* fonction ViewScrSegment() */ +/******************************************************************************/ +void ViewScrSegment(ptSeg) + +Segment *ptSeg; + +{ + Segment *CurrentSeg; + + for (CurrentSeg = ptSeg ; CurrentSeg; CurrentSeg = CurrentSeg->NEXT) { + printf("|__SEG.NAME________________: %s \n",CurrentSeg->NAME); + printf("| |__SEG.(X1,Y1) : (%ld , %ld ) \n",CurrentSeg->X1,CurrentSeg->Y1); + printf("| |__SEG.(X2,Y2) : (%ld , %ld ) \n",CurrentSeg->X2,CurrentSeg->Y2); + printf("| |__SEG.(WIDTH) : %ld \n",CurrentSeg->WIDTH); + printf("| |__SEG.(TYPE) : ( %c ) \n",CurrentSeg->TYPE); + printf("| |__SEG.(LAYER) : ( %s ) \n",DecodLayer(CurrentSeg->LAYER)); + } +} + +/******************************************************************************/ +/* fonction ViewScrCon() */ +/******************************************************************************/ +void ViewScrCon(ptCon) + +Connector *ptCon; + +{ + Connector *CurrentCon = NULL; + + for ( CurrentCon = ptCon ; CurrentCon; CurrentCon = CurrentCon->NEXT ) { + printf("|__CON.NAME____________________: %s \n",CurrentCon->NAME); + printf("| |__CON.(TYPE) : ( %c )\n",CurrentCon->TYPE); + printf("| |__CON.(DIRECT) : ( %c )\n",CurrentCon->DIRECTION); + printf("| |__CON.(ORIENT) : ( %c )\n",CurrentCon->ORIENT); + printf("| |__CON.(X,Y) : ( %ld, %ld )\n",CurrentCon->X,CurrentCon->Y); + printf("| |__CON.(WIDTH) : ( %ld )\n",CurrentCon->WIDTH); + printf("| |__CON.(LAYER) : ( %s )\n",DecodLayer(CurrentCon->LAYER)); + printf("| |__CON.(SIG_INDEX) : ( %ld )\n",CurrentCon->SIG->INDEX); + printf("| |__CON.(LINE_INDEX): ( %ld )\n",CurrentCon->LINE->INDEX); + if (CurrentCon->INST != NULL) + printf("| |__CON.(LINE_INST) : ( %s )\n",CurrentCon->INST->NAME); + } +} + +/******************************************************************************/ +/* fonction ViewScrInstance() */ +/******************************************************************************/ +void ViewScrInstance(ptLeadIns) + +Instance *ptLeadIns; + +{ + Instance *ptIns = NULL; + + for ( ptIns = ptLeadIns ; ptIns; ptIns = ptIns->NEXT ) { + printf("| |__INS.INSNAME__________: %s \n",ptIns->NAME ); + printf("| | |__INS.FIGNAME : %s \n", ptIns->FIGNAME ); + printf("| | |__INS.(X,WIDTH) : ( %ld , %ld ) \n",ptIns->X,ptIns->WIDTH); + printf("| | |__INS.(Y,HEIGTH): ( %ld , %ld ) \n",ptIns->Y,ptIns->HEIGTH); + printf("| | |__INS.TRANSF : ( %c ) \n",ptIns->TRANSF ); + printf("| | |__Connecteurs de l'instance : \n"); + ViewScrCon(ptIns->CON); + printf("| | |__Transparences de la cellule : \n"); + if (ptIns->ALLOW == NULL) + fprintf(stdout,"Pas de TRANSPARENCES dans cette cellule.\n"); + else ViewScrSegment(ptIns->ALLOW); + } +} + +/******************************************************************************/ +/* fonction ViewScrSignal() */ +/******************************************************************************/ +void ViewScrSignal(ptLeadSig) + +Signal *ptLeadSig; + +{ + Signal *ptSig = NULL; + chain_list *ConList = NULL; + chain_list *LineList = NULL; + + for (ptSig = ptLeadSig; ptSig; ptSig = ptSig->NEXT ) { + printf("|____SIG.NAME__________________: %s \n",ptSig->NAME); + printf("| |__SIG.(INDEX,TYPE) : ( %ld , %c ) \n",ptSig->INDEX,ptSig->TYPE); + printf("| |__Connecteurs du signal : \n"); + for (ConList = ptSig->CON; ConList; ConList = ConList->NEXT ) + printf("| |__SIG.(CON_X) : ( %ld ) \n", + ((Connector *) ConList->DATA)->X); + printf("| |__Lignes du signal : \n"); + for (LineList = ptSig->LINE; LineList; LineList = LineList->NEXT ) + printf("| |__SIG.(INDEX_LINE) : ( %ld ) \n", + ((Line *) LineList->DATA)->INDEX); + printf("| |__SIG.(MAXCON) : ( %ld ) \n",ptSig->MAXCON); + } +} + +/******************************************************************************/ +/* fonction ViewScrLine() */ +/******************************************************************************/ +void ViewScrLine(ptLeadLine) + +Line *ptLeadLine; + +{ + Line *ptLine = NULL; + chain_list *SigList = NULL; + chain_list *ConList = NULL; + chain_list *AllowList = NULL; + Segment *ptAllow = NULL; + + for (ptLine = ptLeadLine; ptLine; ptLine = ptLine->NEXT) { + printf("|_LIN.Name____________________: %s \n", ptLine->NAME); + printf("| |__LIN.(TYPE,INDEX) :( %c, %ld )\n", ptLine->TYPE, ptLine->INDEX); + printf("| |__LIN.(X,WIDTH) :( %ld, %ld )\n", ptLine->X , ptLine->WIDTH); + printf("| |__LIN.(Y,HEIGTH) :( %ld, %ld )\n", ptLine->Y, ptLine->HEIGTH); + if (ptLine->TYPE == 'C') { + printf("|_________Cellules de la ligne : \n"); + ViewScrInstance(ptLine->INS); + } + printf("| |__signaux de la ligne : \n"); + for (SigList = ptLine->SIG; SigList; SigList = SigList->NEXT) + printf("| |__LIN.(SIG_INDEX) : ( %ld )\n", + ((Signal *) SigList->DATA)->INDEX); + printf("| |__connecteurs de la ligne : \n"); + for (ConList = ptLine->CON; ConList; ConList = ConList->NEXT) + printf("| |__LIN.(CON_NAME) : ( %s )\n", + ((Connector *) ConList->DATA)->NAME); + printf("| |__transprences utilisees de la ligne : \n"); + for (ptAllow = ptLine->ALLOWUSED; ptAllow; ptAllow = ptAllow->NEXT) { + printf("| |__LIN.(ALLOWUSED_X1_Y1) : ( %ld , %ld )\n", + ptAllow->X1,ptAllow->Y1); + printf("| |__LIN.(ALLOWUSED_X2_Y2) : ( %ld , %ld )\n", + ptAllow->X2,ptAllow->Y2); + } + printf("| |__transprences de la ligne : \n"); + for (AllowList = ptLine->ALLOW; AllowList; AllowList = AllowList->NEXT) { + printf("| |__LIN.(ALLOW_X1_Y1) : ( %ld , %ld )\n", + ((Segment *) AllowList->DATA)->X1,((Segment *) AllowList->DATA)->Y1); + printf("| |__LIN.(ALLOW_X2_Y2) : ( %ld , %ld )\n", + ((Segment *) AllowList->DATA)->X2,((Segment *) AllowList->DATA)->Y2); + } + } +} + +/******************************************************************************/ +/* fonction ViewScrFigure() */ +/******************************************************************************/ +void ViewScrFigure(ptRoot) + +Figure *ptRoot; + +{ + fprintf(stdout,"Les LIGNES de la figure : \n\n"); + ViewScrLine(ptRoot->LINE); + fprintf(stdout,"Les SIGNAUX de la figure : \n\n"); + ViewScrSignal(ptRoot->SIG); + fprintf(stdout,"Les CONNECTEURS de la figure : \n\n"); + ViewScrCon(ptRoot->CON); + fprintf(stdout,"Les TRANSPARENCES de la figure : \n\n"); + ViewScrSegment(ptRoot->ALLOW); +} diff --git a/alliance/src/scr/src/ViewDataBase.h b/alliance/src/scr/src/ViewDataBase.h new file mode 100644 index 00000000..05e544b2 --- /dev/null +++ b/alliance/src/scr/src/ViewDataBase.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDAD CELLS ROUTER */ +/* Fichier : ViewDataBase.h */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +extern char *DecodLayer(); +extern void ViewScrSegment(); +extern void ViewScrCon(); +extern void ViewScrInstance(); +extern void ViewScrSignal(); +extern void ViewScrLine(); +extern void ViewScrFigure(); diff --git a/alliance/src/scr/src/main.c b/alliance/src/scr/src/main.c new file mode 100644 index 00000000..568e8e5b --- /dev/null +++ b/alliance/src/scr/src/main.c @@ -0,0 +1,1740 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* Chaine de CAO & VLSI Alliance */ +/* */ +/* Produit : STANDARD CELLS ROUTER */ +/* Fichier : main.c */ +/* */ +/* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */ +/* Tous droits reserves */ +/* Support : e-mail cao-vlsi@masi.ibp.fr */ +/* */ +/* Auteur(s) : El housseine REJOUAN le : 26/10/1991 */ +/* */ +/* Modifie par : El housseine REJOUAN le : 04/08/1992 */ +/* Modifie par : El housseine REJOUAN le : 04/06/1993 */ +/* Modifie par : le : ../../.... */ +/* */ +/******************************************************************************/ +#define NOL3DEBUG +#ifdef L3DEBUG +#define LOGld(t,v) fprintf(stderr,"%30s%30s : %ld\n",t,#v,v) +#define LOGs(t,v) fprintf(stderr,"%30s%30s : %s\n",t,#v,v) +#define LOGf(t,v) fprintf(stderr,"%30s%30s : %f\n",t,#v,v) +#else +#define LOGld(t,v) +#define LOGs(t,v) +#define LOGf(t,v) +#endif + +# include +# include +# include +# include +# include +# include "SCR_Type.h" +# include "main.h" +# include "LoadDataBase.h" +# include "ViewDataBase.h" + +PlaceConList *LeadPlaceConList = NULL; +extern int L3MODE; +extern int SXMODE; +extern int SCR_RATIO; + +/******************************************************************************/ +/* Function : ScrUsage() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : none */ +/* Output parameters : none */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +void ScrUsage(Execut) +char *Execut; + +{ + fprintf(stderr,"scr_error : Syntax error on command line\n"); + fprintf(stderr,"usage : %s [options...] \n",Execut); + fprintf(stderr,"where valid options are :\n"); + fprintf(stderr," : netlist file and placed layout (same name)\n"); + fprintf(stderr," [-c ChannelName] : if the option ChannelName is used\n"); + fprintf(stderr," then the result will be hierarchical\n"); + fprintf(stderr," otherwise the result will be flattened\n"); + fprintf(stderr," [-o OutputFileName] : renames the output file name to FileName\n"); + fprintf(stderr," [-p] : This option invokes the placement process\n"); + fprintf(stderr," [-r] : This option invokes the routing process\n"); + fprintf(stderr," [-i IterationNumber] : This action is used to improve the quality of the placement\n"); + fprintf(stderr," [-l SliceNumber] : This option allows the designer to set the number of rows\n"); + fprintf(stderr," [-a SupplyNumber] : This option allows the designer to set the number of power supply\n"); + fprintf(stderr,"for more informations use man scr\n"); + exit(1); +} + +/******************************************************************************/ +/* Function : GetOptions() */ +/* */ +/* Description : getting all used options on commad line */ +/* */ +/* Input parameters : argument count and argument value */ +/* Input global Variables : none */ +/* Output parameters : option list pointer */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +OptionList *GetOptions(ArgCount,ArgValue) +int ArgCount; +char *ArgValue[]; + +{ + OptionList *ptOption = (OptionList *) mbkalloc (sizeof(OptionList)); + int ArgNumber = 0; + + ptOption->ChannelName = NULL; + ptOption->InputFileName = NULL; + ptOption->OutputFileName = NULL; + ptOption->Placer = FALSE; + ptOption->Router = FALSE; + ptOption->SupplyRecall = 1; + ptOption->Row = 0; + ptOption->Iteration = 0; + + L3MODE = (getenv ("SCR_L3MODE")) ? 1 : 0; + SXMODE = (getenv ("SCR_SCLIB")) ? 0 : 1; + if (L3MODE) SXMODE=1; + if (getenv ("SCR_RATIO")) + SCR_RATIO = atol(getenv ("SCR_RATIO")); + else + SCR_RATIO = L3MODE?70:100; + for (ArgNumber = 1; ArgNumber < ArgCount; ArgNumber++) { + int AuxArgNumber = ArgNumber; + char *ArgV = ArgValue[ArgNumber]; + if (*ArgV == '-') { + switch (*++ArgV) { + + case 'c' : if (ArgValue[++AuxArgNumber] == NULL) + ScrUsage(ArgValue[0]); + else + ptOption->ChannelName = ArgValue[++ArgNumber]; + continue; + case 'o' : if (ArgValue[++AuxArgNumber] == NULL) + ScrUsage(ArgValue[0]); + else + ptOption->OutputFileName = ArgValue[++ArgNumber]; + continue; + case 'p' : if (*++ArgV == '\0') ptOption->Placer = TRUE; + else ScrUsage(ArgValue[0]); + continue; + + case 'r' : if (*++ArgV == '\0') ptOption->Router = TRUE; + else ScrUsage(ArgValue[0]); + continue; + + case 'l' : if ((*++ArgV) == '\0') + if (ArgValue[++AuxArgNumber] == NULL) + ScrUsage(ArgValue[0]); + else + ptOption->Row = atoi(ArgValue[++ArgNumber]); + else ScrUsage(ArgValue[0]); + continue; + + case 'a' : if ((*++ArgV) == '\0') + if (ArgValue[++AuxArgNumber] == NULL) + ScrUsage(ArgValue[0]); + else + ptOption->SupplyRecall = atoi(ArgValue[++ArgNumber]); + else ScrUsage(ArgValue[0]); + continue; + + case 'i' : if (*++ArgV == '\0') + if (ArgValue[++AuxArgNumber] == NULL) + ScrUsage(ArgValue[0]); + else + ptOption->Iteration = atoi(ArgValue[++ArgNumber]); + else ScrUsage(ArgValue[0]); + continue; + + default : ScrUsage(ArgValue[0]); + } + } + else ptOption->InputFileName = ArgV; + } + return(ptOption); +} + +/******************************************************************************* +* function ScrNameIndex() * +* return a string that is the concatenation of the name argument, the mbk * +* separator, and an index * +*******************************************************************************/ +char *ScrNameIndex(name, index) +char *name; +long index; +{ +char str[100]; + + (void)sprintf(str,"%s%ld", name, index); + return namealloc(str); +} + +/******************************************************************************/ +/* Function : PreparVerticalChannel() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +XSupplyRecallList *PreparVerticalChannel(ptScrFig, ptMbkTie, Number, Counter) +Figure *ptScrFig; +phfig_list *ptMbkTie; +int Number; +long *Counter; + +{ + long Interval = (long ) (((ptScrFig->LINE->WIDTH) / (Number + 1)) + + 0.5); + long XBreak = ptScrFig->LINE->X; + Line *ptLine = NULL; + Instance *CurrentInst = NULL; + Instance *PrevInst = NULL; + Instance *ptNewInst = NULL; + long XMin = 0; + long XMax = 0; + long NewXMin = 0; + long WidthShift = 0; + long TieNumber = 0; + long TieNumberSave = 0; + long XInsert = 0; + long XInsertSouth = 0; + Connector *CurrentCon = NULL; + chain_list *ConList = NULL; + XSupplyRecallList *CurrentX = NULL; + XSupplyRecallList *ptXSave = NULL; + XSupplyRecallList *ptXNewSave = NULL; + Segment *CurrentSeg = NULL; + Segment *ptNewAllow = NULL; + long TieWidth = (ptMbkTie->XAB2 - ptMbkTie->XAB1); + long TieHeight = (ptMbkTie->YAB2 - ptMbkTie->YAB1); + + while (Number > 0) { + XBreak += (Interval + WidthShift); + XMin = XBreak; + XMax = ptScrFig->LINE->X; + + /* CALCUL DE LA LARGEUR DE DECALAGE */ + for (ptLine = ptScrFig->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == CELL) { + for (PrevInst = NULL, CurrentInst = ptLine->INS; + (CurrentInst && ((NewXMin = CurrentInst->X) < XBreak)); + PrevInst = CurrentInst, CurrentInst = CurrentInst->NEXT); + if ((XBreak - PrevInst->X) <= (NewXMin - XBreak)) + NewXMin = PrevInst->X; + if (NewXMin < XMin) XMin = NewXMin; + if (NewXMin > XMax) XMax = NewXMin; + } + } + WidthShift = (XMax - XMin); + if ((WidthShift % TieWidth) >= (TieWidth / (2 * SCALE_X))) { + TieNumber = (WidthShift / TieWidth) + 1; + } + else { + TieNumber = (WidthShift / TieWidth); + } + WidthShift = TieNumber * TieWidth; + TieNumberSave = TieNumber; + +/* SAUVEGARDE DES POSITIONS DES LIGNES DE COUPE */ + ptXNewSave = (XSupplyRecallList *) mbkalloc (sizeof(XSupplyRecallList)); + ptXNewSave->NEXT = NULL; + ptXNewSave->X = XMax; + if (ptXSave == NULL) ptXSave = ptXNewSave; + else { + for (CurrentX = ptXSave; CurrentX->NEXT; CurrentX = CurrentX->NEXT); + CurrentX->NEXT = ptXNewSave; + } + for (ptLine = ptScrFig->LINE; ptLine; ptLine = ptLine->NEXT) { + ptLine->WIDTH += WidthShift; + if (ptLine->TYPE == CELL) { + for (PrevInst = NULL, CurrentInst = ptLine->INS; + (CurrentInst && (CurrentInst->X < XBreak)); + PrevInst = CurrentInst, CurrentInst = CurrentInst->NEXT); + if ((XBreak - PrevInst->X) <= (CurrentInst->X - XBreak)) + CurrentInst = PrevInst; + XInsert = CurrentInst->X; + if (ptLine == (ptScrFig->LINE->NEXT->NEXT)) XInsertSouth = XInsert; + if (CurrentInst != ptLine->INS) { + for (PrevInst = ptLine->INS; PrevInst->NEXT != CurrentInst; + PrevInst = PrevInst->NEXT); + } + else PrevInst = NULL; + TieNumber = TieNumberSave; + while (TieNumber > 0) { + ptNewInst = CreateInstance(ScrNameIndex("feed",(*Counter)++), + ptMbkTie->NAME,XInsert,ptLine->Y, + TieWidth,TieHeight,NOSYM); + if (PrevInst) { + ptNewInst->NEXT = CurrentInst; + PrevInst->NEXT = ptNewInst; + } + else { + ptNewInst->NEXT = CurrentInst; + ptLine->INS = ptNewInst; + } + + ptNewAllow = InsertAllowInIns(ptNewInst,ptMbkTie->XAB1,ptMbkTie->XAB2, + ptMbkTie->YAB1,ptMbkTie->YAB2,ptMbkTie); + ptLine->ALLOW = addchain(ptLine->ALLOW,(char *)ptNewAllow); + PrevInst = ptNewInst; + XInsert += TieWidth; + TieNumber--; + } + for (CurrentSeg = ptLine->ALLOWUSED; CurrentSeg; + CurrentSeg = CurrentSeg->NEXT) + if (CurrentSeg->X1 >= XInsert) { + CurrentSeg->X1 += WidthShift; + CurrentSeg->X2 += WidthShift; + } + /*MISE A JOUR DES CONNECTEURS DES LIGNES */ + for (ConList = ptLine->CON; ConList; ConList = ConList->NEXT){ + CurrentCon = ((Connector *)ConList->DATA); + if ((!CurrentCon->INST) && (CurrentCon->X >= XInsert)) + CurrentCon->X += WidthShift; + } + /*MISE A JOUR DES CONNECTEURS INTERNES ET DES SEGMENT DES INSTANCES */ + for (; CurrentInst; CurrentInst = CurrentInst->NEXT) { + CurrentInst->X += WidthShift; + for (CurrentCon = CurrentInst->CON; CurrentCon; + CurrentCon = CurrentCon->NEXT) + CurrentCon->X += WidthShift; + for (CurrentSeg = CurrentInst->ALLOW; CurrentSeg; + CurrentSeg = CurrentSeg->NEXT) { + CurrentSeg->X1 += WidthShift; + CurrentSeg->X2 += WidthShift; + } + } + } + } +/* MISE A JOUR DES CONNECTEURS EXTERNES */ + XInsert -= WidthShift; + for(CurrentCon = ptScrFig->CON; CurrentCon; CurrentCon = CurrentCon->NEXT) { + if (CurrentCon->ORIENT == EAST) + CurrentCon->X += WidthShift; + else + if ((CurrentCon->ORIENT == NORTH) && (CurrentCon->X >= XInsert)) + CurrentCon->X += WidthShift; + else + if ((CurrentCon->ORIENT == SOUTH) && (CurrentCon->X >= XInsertSouth)) + CurrentCon->X += WidthShift; + } + Number--; + } + return(ptXSave); +} + +/******************************************************************************/ +/* Function : MakeVerticalChannel() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +void MakeVerticalChannel(ptFigure, ptXInsert, ChannelWidth) +Figure *ptFigure; +XSupplyRecallList *ptXInsert; +long ChannelWidth; + +{ + XSupplyRecallList *ptXBreak = NULL; + XSupplyRecallList *ptXBreakList = NULL; + Line *ptLine = NULL; + Instance *ptInst = NULL; + Instance *PrevInst = NULL; + Connector *ptCon = NULL; + Segment *ptSeg = NULL; + SegmentList *ptSegList = NULL; + ViasList *ptViaList = NULL; + long WidthShiftSymb = ChannelWidth / PITCH_X; + long XOpen = 0; + long XOpenSymb = 0; + + for (ptXBreak = ptXInsert; ptXBreak; ptXBreak = ptXBreak->NEXT) { + XOpen = ptXBreak->X; + XOpenSymb = (XOpen / PITCH_X) + 1; + for (ptLine = ptFigure->LINE; ptLine; ptLine = ptLine->NEXT) { + ptLine->WIDTH += ChannelWidth; + if (ptLine->TYPE == CELL) { + for (PrevInst = NULL, ptInst = ptLine->INS; + (ptInst && (ptInst->X < XOpen)); + PrevInst = ptInst, ptInst = ptInst->NEXT); + for (; ptInst; ptInst = ptInst->NEXT) { + ptInst->X += ChannelWidth; + for (ptCon = ptInst->CON; ptCon; ptCon = ptCon->NEXT) + ptCon->X += ChannelWidth; + for (ptSeg = ptInst->ALLOW; ptSeg; ptSeg = ptSeg->NEXT) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + } + else { + if (ptLine->TYPE == PATH) { + ptLine->CHANNEL->WIDTH += WidthShiftSymb; + for (ptSegList = ptLine->CHANNEL->H_SEGMENT; ptSegList; + ptSegList = ptSegList->NextSeg) { + if (ptSegList->X1Seg >= XOpenSymb) ptSegList->X1Seg += WidthShiftSymb; + if (ptSegList->X2Seg >= XOpenSymb) ptSegList->X2Seg += WidthShiftSymb; + } + for (ptSegList = ptLine->CHANNEL->V_SEGMENT; ptSegList; + ptSegList = ptSegList->NextSeg) { + if (ptSegList->X1Seg >= XOpenSymb) { + ptSegList->X1Seg += WidthShiftSymb; + ptSegList->X2Seg += WidthShiftSymb; + } + } + for (ptViaList = ptLine->CHANNEL->VIA; ptViaList; + ptViaList = ptViaList->NextVia) { + if (ptViaList->XVia >= XOpenSymb) { + ptViaList->XVia += WidthShiftSymb; + } + } + } + } + } + + /* MISE A JOUR DES TRANSPARENCES VERTICALES */ + for (ptSeg = ptFigure->ALLOW; ptSeg; ptSeg = ptSeg->NEXT) { + if (ptSeg->X1 >= XOpen) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + + /* MISE A JOUR DES CONNECTEURS EXTERNES */ + for (ptCon = ptFigure->CON; ptCon; ptCon = ptCon->NEXT) { + if (ptCon->ORIENT == EAST) ptCon->X += ChannelWidth; + else if ((ptCon->ORIENT == NORTH) && (ptCon->X >= XOpen)) + ptCon->X += ChannelWidth; + else if ((ptCon->ORIENT == SOUTH) && (ptCon->X >= XOpen)) + ptCon->X += ChannelWidth; + } + + /* MISE A JOUR DES SEGMENTS DE LA FIGURE MERE */ + for (ptLine = ptFigure->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == CELL) { + for (ptSeg = ptLine->ALLOWUSED; ptSeg; ptSeg = ptSeg->NEXT) { + if (ptSeg->X1 >= XOpen) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + } + } + for (ptXBreakList = ptXBreak->NEXT; ptXBreakList; + ptXBreakList = ptXBreakList->NEXT) { + ptXBreakList->X += ChannelWidth; + } + } +} + +/******************************************************************************/ +/* Function : CompleteLine() */ +/******************************************************************************/ +void CompleteLine(ptFig,NewphIns,Counter) +Figure *ptFig; +phfig_list *NewphIns; +long *Counter; + +{ + Line *CurrentLine = NULL; + Instance *CurrentInst = NULL; + Instance *NextInst = NULL; + Instance *PrevInst = NULL; + long NewInstWidth = 0; + long NewInstHeight = 0; + Segment *ptNewAllow = NULL; + long Xab1Figure = ptFig->LINE->X; + long Xab2Figure = ptFig->LINE->WIDTH + Xab1Figure; + + NewInstWidth = ((NewphIns->XAB2) - (NewphIns->XAB1)); + NewInstHeight = ((NewphIns->YAB2) - (NewphIns->YAB1)); + for (CurrentLine = ptFig->LINE; CurrentLine; CurrentLine = CurrentLine->NEXT) { + if (CurrentLine->TYPE == CELL) { + CurrentInst = CurrentLine->INS; + if (Xab1Figure + NewInstWidth <= CurrentInst->X) { + CurrentInst = CreateInstance(ScrNameIndex("row",(*Counter)++), + NewphIns->NAME,Xab1Figure,CurrentLine->Y, + NewInstWidth,NewInstHeight,NOSYM); + CurrentInst->NEXT = CurrentLine->INS; + CurrentLine->INS = CurrentInst; + ptNewAllow = InsertAllowInIns(CurrentInst,NewphIns->XAB1,NewphIns->XAB2, + NewphIns->YAB1,NewphIns->YAB2,NewphIns); + CurrentLine->ALLOW = addchain(CurrentLine->ALLOW,(char *)ptNewAllow); + } + while (CurrentInst->NEXT) { + if ((CurrentInst->X + CurrentInst->WIDTH) + NewInstWidth <= + (NextInst = CurrentInst->NEXT)->X) { + PrevInst = CurrentInst; + CurrentInst = CreateInstance(ScrNameIndex("row",(*Counter)++), + NewphIns->NAME, + CurrentInst->X + CurrentInst->WIDTH, + CurrentLine->Y, + NewInstWidth,NewInstHeight,NOSYM); + CurrentInst->NEXT = NextInst; + PrevInst->NEXT = CurrentInst; + ptNewAllow = InsertAllowInIns(CurrentInst,NewphIns->XAB1,NewphIns->XAB2, + NewphIns->YAB1,NewphIns->YAB2,NewphIns); + CurrentLine->ALLOW = addchain(CurrentLine->ALLOW,(char *)ptNewAllow); + } + else CurrentInst = CurrentInst->NEXT; + } + while ((CurrentInst->X + CurrentInst->WIDTH) + NewInstWidth <= Xab2Figure) { + CurrentInst->NEXT = CreateInstance(ScrNameIndex("row",(*Counter)++), + NewphIns->NAME, + CurrentInst->X + CurrentInst->WIDTH, + CurrentLine->Y,NewInstWidth, + NewInstHeight,NOSYM); + CurrentInst = CurrentInst->NEXT; + ptNewAllow = InsertAllowInIns(CurrentInst,NewphIns->XAB1,NewphIns->XAB2, + NewphIns->YAB1,NewphIns->YAB2,NewphIns); + CurrentLine->ALLOW = addchain(CurrentLine->ALLOW,(char *)ptNewAllow); + } + } + } +} + +/******************************************************************************/ +/* Function : UpDateWidthLine() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +void UpDateWidthLine(ptFig,NewphIns,Counter) +Figure *ptFig; +phfig_list *NewphIns; +long *Counter; + +{ + Line *CurrentLine = NULL; + Instance *CurrentInst = NULL; + Segment *ptNewAllow = NULL; + SegmentList *ptSegment = NULL; + Channel *ptChannel = NULL; + Connector *ptScrCon = NULL; + long NewWidth = 0; + long LineWidth = 0; + long NewInstWidth = 0; + long NewInstHeight = 0; + long NextXInst = 0; + long Xab1 = 0; + + NewInstWidth = ((NewphIns->XAB2) - (NewphIns->XAB1)); + NewInstHeight = ((NewphIns->YAB2) - (NewphIns->YAB1)); + + for (CurrentLine = ptFig->LINE; CurrentLine; CurrentLine = CurrentLine->NEXT) { + if (CurrentLine->TYPE == PATH) { + NewWidth = MAX(NewWidth,CurrentLine->WIDTH); + } + } + NewWidth += (Xab1 = (CurrentLine = ptFig->LINE)->X); + for (; CurrentLine; CurrentLine = CurrentLine->NEXT) { + if ((LineWidth = CurrentLine->WIDTH) != NewWidth) { + CurrentLine->WIDTH = NewWidth - Xab1; + if (CurrentLine->TYPE == CELL) { + for (CurrentInst = CurrentLine->INS;CurrentInst->NEXT; + CurrentInst = CurrentInst->NEXT); + while ((NextXInst = CurrentInst->X + CurrentInst->WIDTH) != NewWidth) { + CurrentInst->NEXT = CreateInstance(ScrNameIndex("feed",(*Counter)++), + NewphIns->NAME,NextXInst, + CurrentLine->Y,NewInstWidth, + NewInstHeight,NOSYM); + CurrentInst = CurrentInst->NEXT; + ptNewAllow = InsertAllowInIns(CurrentInst,NewphIns->XAB1,NewphIns->XAB2, + NewphIns->YAB1,NewphIns->YAB2,NewphIns); + CurrentLine->ALLOW = addchain(CurrentLine->ALLOW,(char *)ptNewAllow); + } + } + else { + if (CurrentLine->TYPE == PATH) { + ptChannel = CurrentLine->CHANNEL; +/* + ptChannel->WIDTH = NewWidth / PITCH_X; +*/ + for (ptSegment = ptChannel->H_SEGMENT; ptSegment; + ptSegment = ptSegment->NextSeg) { + if (ptSegment->X2Seg == (ptChannel->WIDTH + 1)) { + ptSegment->X2Seg += ((NewWidth - LineWidth + Xab1) / PITCH_X); + } + } + } + } + } + } + for (ptScrCon = ptFig->CON; ptScrCon; ptScrCon = ptScrCon->NEXT) + if (ptScrCon->ORIENT == EAST) ptScrCon->X = NewWidth; + +} +/******************************************************************************/ +/* Function : Scr_GetSigName() 4 juin 1993 */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +char *ScrGetSigName(ptSig, SigIndex) +Signal *ptSig; +long SigIndex; + +{ + for (;ptSig; ptSig = ptSig->NEXT) { + if (ptSig->INDEX == SigIndex) { + return(ptSig->NAME); + } + if (ptSig == NULL) return NULL; + } +} +/******************************************************************************/ +/* Placer2Scr */ +/* ecriture du placement dans mbk physique */ +/* Modified by : Xavier Picat Date : 09/07/1993 */ +/******************************************************************************/ +phfig_list *Placer2Scr(Nom,FigurePlacee) +char *Nom; +placement_fig *FigurePlacee; + +{ + phfig_list *ptphfig; + int iCell, iRow; + int Width; + int Height; + row_elt *Row; + cell_list *Cell; + long step, percent, i; + long NombreLignes, NombreCellules, Hauteur; + + fprintf (stderr,"Saving placement "); + /******** recuperation de la hauteur d'UNE cellule ***************/ + Row = FigurePlacee->Rows; + ptphfig = getphfig (Row[0].head->ins->FIGNAME,'A'); + sx2sc (ptphfig); + Hauteur = (ptphfig->YAB2 - ptphfig->YAB1) / SCALE_X; + + /****************** chargement du pointeur figure ********************/ + ptphfig = addphfig(Nom); + NombreCellules = FigurePlacee->NbCells; + NombreLignes = FigurePlacee->NbRows; + + /**************** calcul de la taille de la figure ********************/ + Width = 0; + for (iRow=0;iRowWidth) + Width=Row[iRow].length; + Height = NombreLignes*Hauteur; + ptphfig->XAB1 = 0; + ptphfig->YAB1 = 0; + ptphfig->XAB2 = Width*SCALE_X; + ptphfig->YAB2 = Height*SCALE_X; + + step = NombreCellules/100; + percent = 0; + i = step - 1; + /********************* placement des cellules *************************/ + Cell = FigurePlacee->Cells; + for (iCell=0;iCell < NombreCellules;iCell++) + { + i++; + if (i == step) + { + i = 0; + fprintf (stderr,"%3d%%\b\b\b\b", percent); + fflush (stderr); + percent++; + } + addphins (ptphfig, + Cell->ins->FIGNAME, + Cell->ins->INSNAME, + NOSYM, + (Cell->x-(Cell->width>>0 /* 99/9/21 1 */))*SCALE_X, + Cell->row*Hauteur*SCALE_X + ); + Cell++; + } + fprintf (stderr,"100%\n"); + mbkfree (FigurePlacee->Rows); + mbkfree (FigurePlacee->Cells); + return(ptphfig); +} /* fin de Placer2Scr */ + +/******************************************************************************/ +/* Function : Scr2Mbk */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : */ +/* Output parameters : */ +/* Output global Variables : */ +/* */ +/******************************************************************************/ +void Scr2Mbk(ptfig,FigName,ptOptionList, + ptXInsert,VerticalChannelWidth) +Figure *ptfig; +char *FigName; +OptionList *ptOptionList; +XSupplyRecallList *ptXInsert; +long VerticalChannelWidth; + +{ + phfig_list *ptMbkRoot = NULL; + Channel *ptScrChannel = NULL; + Line *ptScrLine = NULL; + Instance *ptScrIns = NULL; + Connector *ptScrCon = NULL; + Segment *ptScrSeg = NULL; + chain_list *ConList = NULL; + + XSupplyRecallList *ptXBreak = NULL; + ConnectorList *ptConList = NULL; + long NewYNextLine = 0; + SegmentList *CurrentSeg = NULL; + ViasList *CurrentVia = NULL; + long X1Symbolic = 0; + long X2Symbolic = 0; + long Y1Symbolic = 0; + long Y2Symbolic = 0; + long X1Segment = 0; + long X2Segment = 0; + long Y1Segment = 0; + long Y2Segment = 0; + long Y1 = 0; + long Y2 = 0; + long X1 = 0; + long X2 = 0; + long X3 = 0; + long X4 = 0; + long Xab1 = 0; + long Xab2 = 0; + long Yab1 = 0; + long Yab2 = 0; + long YLine = 0; + long VddWidth = 0; + long VssWidth = 0; + long ChannelWidth = 0; + long ChannelHeight = 0; + long CellLineNumber = 0; + char *NameSeg; + char Buffer[10]; + long IndexSignal = 0; + long ChannelNumber = 0; + static long Counter = 0; + + for (ptScrLine = ptfig->LINE; ptScrLine; ptScrLine = ptScrLine->NEXT) + { + if (ptScrLine->TYPE == PATH) + ChannelNumber ++; + } + ptScrLine = ptfig->LINE; + NewYNextLine = ptScrLine->HEIGTH; + LOGld("premier canal",ptScrLine->HEIGTH); + for (CellLineNumber = 0; ptScrLine; ptScrLine = ptScrLine->NEXT) { + if (ptScrLine->TYPE == PATH) { + ChannelWidth = ((ptScrLine->WIDTH - WESTOFFSET - EASTOFFSET) / PITCH_X) + 1; + ChannelHeight = ((ptScrLine->HEIGTH - SOUTHOFFSET - NORTHOFFSET) / + PITCH_Y) + 1; + if (L3MODE) /* pour que le canal ait au moins la taille d'une cellule */ + { + LOGld("",ptScrLine->HEIGTH); + if ((CellLineNumber == 0) || (CellLineNumber == (ChannelNumber-1))) + { + LOGld("numero canal",CellLineNumber); + LOGld("hauteur",ptScrLine->HEIGTH/SCALE_X); + if ((ptScrLine->HEIGTH) < (CELLAB/2)) + ptScrLine->HEIGTH = CELLAB/2; + } + else + { + if ((ptScrLine->HEIGTH) < CELLAB) + ptScrLine->HEIGTH = CELLAB; + } + } + ptMbkRoot = addphfig(ptScrLine->NAME); + ptScrChannel = ptScrLine->CHANNEL; + if (L3MODE && (CellLineNumber != 0)) + { + NewYNextLine -= CELLAB; + ptScrLine->Y += NewYNextLine; + } + else + ptScrLine->Y += NewYNextLine; + LOGld("hau",ptScrLine->Y); + YLine = ptScrLine->Y; + Xab1 = ptMbkRoot->XAB1 = ptScrLine->X; + Xab2 = ptMbkRoot->XAB2 = (Xab1 + (ptScrLine->WIDTH)); + Yab1 = ptMbkRoot->YAB1 = YLine; + Yab2 = ptMbkRoot->YAB2 = (Yab1 + (ptScrLine->HEIGTH)); + +/******************************************************************************/ +/* SAVING HORIZONTAL SEGMENT */ +/******************************************************************************/ + for (CurrentSeg = ptScrChannel->H_SEGMENT; CurrentSeg; + CurrentSeg = CurrentSeg->NextSeg) { + if ((X1Symbolic = CurrentSeg->X1Seg) == 0) + X1Segment = Xab1; + else + X1Segment = ((X1Symbolic - 1) * PITCH_X) + WESTOFFSET + Xab1; + if ((X2Symbolic = CurrentSeg->X2Seg) == (ChannelWidth + 1)) + X2Segment = Xab2; + else + X2Segment = ((X2Symbolic - 1) * PITCH_X) + WESTOFFSET + Xab1; + Y1Segment = Y2Segment = (((CurrentSeg->Y1Seg - 1) * PITCH_Y) + SOUTHOFFSET) + + YLine; + if (CurrentSeg->SegName != namealloc("HOR_FEED")) { + strcpy(Buffer,CurrentSeg->SegName); + strtok(Buffer,TRICE); + IndexSignal = atol(strtok(NULL,TRICE)); + if ((NameSeg = ScrGetSigName(ptfig->SIG, IndexSignal)) == NULL) + NameSeg = CurrentSeg->SegName; + ptMbkRoot->PHSEG = addphseg(ptMbkRoot, ((char )(L3MODE?ALU3:ALU1)), LAYER1WIDTH, + X1Segment, Y1Segment, X2Segment , Y2Segment, + NameSeg); + } + else ptMbkRoot->PHSEG = addphseg(ptMbkRoot, ((char )(L3MODE?TALU3:TALU1)), LAYER1WIDTH, + X1Segment, Y1Segment, X2Segment , Y2Segment, + NULL); + } + +/******************************************************************************/ +/* SAVING VERTICAL SEGMENT */ +/******************************************************************************/ + for (CurrentSeg = ptScrChannel->V_SEGMENT; CurrentSeg; + CurrentSeg = CurrentSeg->NextSeg) { + if ((Y1Symbolic = CurrentSeg->Y1Seg) == 0) + Y1Segment = Yab1 - ((SXMODE && !L3MODE) ? CELLAB*40/50:0); + else + Y1Segment = ((Y1Symbolic - 1) * PITCH_Y) + SOUTHOFFSET + YLine; + if ((Y2Symbolic = CurrentSeg->Y2Seg) == ChannelHeight + 1) + Y2Segment = Yab2 + ((SXMODE && !L3MODE)? CELLAB*40/50:0); + else + Y2Segment = ((Y2Symbolic - 1) * PITCH_Y) + SOUTHOFFSET + YLine; + X1Segment = X2Segment = ((CurrentSeg->X1Seg - 1) * PITCH_X) + WESTOFFSET + Xab1; + strcpy(Buffer,CurrentSeg->SegName); + strtok(Buffer,TRICE); + IndexSignal = atol(strtok(NULL,TRICE)); + if ((NameSeg = ScrGetSigName(ptfig->SIG, IndexSignal)) == NULL) + NameSeg = CurrentSeg->SegName; + ptMbkRoot->PHSEG = addphseg(ptMbkRoot, ((char )(L3MODE?ALU2:ALU2)), LAYER2WIDTH, + X1Segment, Y1Segment, X2Segment, Y2Segment, + NameSeg); + } + +/******************************************************************************/ +/* SAVING VIA */ +/******************************************************************************/ + for (CurrentVia = ptScrChannel->VIA; CurrentVia; + CurrentVia = CurrentVia->NextVia) { + ptMbkRoot->PHVIA = addphvia(ptMbkRoot, ((char ) (L3MODE?CONT_VIA2:CONT_VIA)), + ((CurrentVia->XVia - 1) * PITCH_X) + WESTOFFSET + + Xab1, + ((CurrentVia->YVia - 1) * PITCH_Y) + + SOUTHOFFSET + YLine,0,0,NULL); + } + +/******************************************************************************/ +/* SAVING CHANNEL CONNECTOR IF FIGURE MUST BE FLATTENED */ +/******************************************************************************/ +/* A REVOIR + + + if (ptOptionList->ChannelName) { + for (CurrentCon = ptScrChannel->NORTH_LIST; CurrentCon; + CurrentCon = CurrentCon->NextCon) { + if ((ConName = CurrentCon->ConName) != NONET) { + sprintf(Buffer,"%ld",CurrentCon->ConName); + addphcon(ptMbkRoot, NORTH, Buffer, + (((CurrentCon->Mark) * PITCH_X) - WESTOFFSET + Xab1), + Yab2, ((char ) ALU2), LAYER2WIDTH); + } + } + for (CurrentCon = ptScrChannel->SOUTH_LIST; CurrentCon; + CurrentCon = CurrentCon->NextCon) { + if ((ConName = CurrentCon->ConName) != NONET) { + sprintf(Buffer,"%ld",CurrentCon->ConName); + addphcon(ptMbkRoot, SOUTH, Buffer, + (((CurrentCon->Mark) * PITCH_X) - WESTOFFSET + Xab1), + Yab1, ((char ) ALU2), LAYER2WIDTH); + } + } + for (CurrentCon = ptScrChannel->WEST_LIST; + CurrentCon; CurrentCon = CurrentCon->NextCon) { + sprintf(Buffer,"%ld",CurrentCon->ConName); + addphcon(ptMbkRoot, WEST, Buffer, Xab1, + ((((CurrentCon->Mark) - 1) * PITCH_Y) + SOUTHOFFSET), + ((char ) ALU1), LAYER1WIDTH); + } + for (CurrentCon = ptScrChannel->EAST_LIST; CurrentCon; + CurrentCon = CurrentCon->NextCon) { + sprintf(Buffer,"%ld",CurrentCon->ConName); + addphcon(ptMbkRoot, EAST, Buffer, Xab2, + ((((CurrentCon->Mark) - 1) * PITCH_Y) + SOUTHOFFSET), + ((char ) ALU1), LAYER1WIDTH); + } + } +*/ + +/******************************************************************************/ +/* UP DATE THE X FATHER CONNECTOR */ +/******************************************************************************/ + if (ptScrChannel->WEST_LIST) + for (ptConList = ptScrChannel->WEST_LIST; ptConList; + ptConList = ptConList->NextCon) { + for (ptScrCon = ptfig->CON; ptScrCon; ptScrCon = ptScrCon->NEXT) { + if ((ptScrCon->ORIENT == WEST) && + (ptScrCon->SIG->INDEX == ptConList->ConName)) { + ptScrCon->Y = (((ptConList->Mark - 1) * PITCH_Y) + SOUTHOFFSET + YLine); + break; + } + } + } + + if (ptScrChannel->EAST_LIST) + for (ptConList = ptScrChannel->EAST_LIST; ptConList; + ptConList = ptConList->NextCon) { + for (ptScrCon = ptfig->CON; ptScrCon; ptScrCon = ptScrCon->NEXT) { + if ((ptScrCon->ORIENT == EAST) && + (ptScrCon->SIG->INDEX == ptConList->ConName)) { + ptScrCon->Y = (((ptConList->Mark - 1) * PITCH_Y) + SOUTHOFFSET + YLine); + break; + } + } + } + + if (ptOptionList->ChannelName) savephfig(ptMbkRoot); + LOGld("CANAL",ptScrLine->HEIGTH); + NewYNextLine += ptScrLine->HEIGTH; + LOGld("TOTAL",NewYNextLine); + } + else if (ptScrLine->TYPE == CELL) { + CellLineNumber++; + ptMbkRoot = addphfig(ptScrLine->NAME); + ptScrLine->Y += (NewYNextLine - (L3MODE ? CELLAB/2 : 0)); + ptMbkRoot->XAB1 = ptScrLine->X; + ptMbkRoot->YAB1 = ptScrLine->Y; + ptMbkRoot->XAB2 = ((ptScrLine->X) + (ptScrLine->WIDTH)); + ptMbkRoot->YAB2 = ((ptScrLine->Y) + (ptScrLine->HEIGTH)); + + for (ptScrIns = ptScrLine->INS; ptScrIns; ptScrIns = ptScrIns->NEXT) { + ptMbkRoot->PHINS = addphins(ptMbkRoot,ptScrIns->FIGNAME,ptScrIns->NAME, + ptScrIns->TRANSF,ptScrIns->X,ptScrLine->Y); + } + if (!L3MODE) + { + for (ConList = ptScrLine->CON; ConList; ConList = ConList->NEXT) { + ptScrCon = ((Connector *) ConList->DATA); + if (ptScrCon->ORIENT == NORTH) + ptMbkRoot->PHCON = addphcon(ptMbkRoot,ptScrCon->ORIENT,ptScrCon->NAME, + ptScrCon->X,ptMbkRoot->YAB2, + ptScrCon->LAYER,ptScrCon->WIDTH); + else + if (ptScrCon->ORIENT == SOUTH) + ptMbkRoot->PHCON = addphcon(ptMbkRoot,ptScrCon->ORIENT,ptScrCon->NAME, + ptScrCon->X,ptMbkRoot->YAB1, + ptScrCon->LAYER,ptScrCon->WIDTH); + } + } + if (SXMODE) + { + phfig_list * phfig; + phref_list * phref; + phseg_list * phseg; + phins_list * phins; + + for (phins = ptMbkRoot->PHINS; phins; phins = phins->NEXT) + { + phfig = getphfig (phins->FIGNAME, 'A'); + LOGs("",phins->FIGNAME); + for (phref = phfig->PHREF; phref; phref = phref->NEXT) + { + if (phref->NAME && strstr (phref->NAME, "_25")) + { + long xvia, yvia; + LOGld("tra",phins->TRANSF); + LOGs("name",phref->NAME); + LOGld("",phref->XREF); + LOGld("",phref->YREF); + LOGld("",phins->XINS); + LOGld("",phins->YINS); + LOGld("",ptMbkRoot->XAB1); + LOGld("",ptMbkRoot->YAB1); + LOGld("",ptMbkRoot->XAB2); + LOGld("",ptMbkRoot->YAB2); + xyflat (&xvia, &yvia, phref->XREF, phref->YREF, phins->XINS, phins->YINS, + ptMbkRoot->XAB1, ptMbkRoot->YAB1, ptMbkRoot->XAB2, ptMbkRoot->YAB2, + phins->TRANSF); + LOGld("",xvia); + LOGld("",yvia); + addphvia (ptMbkRoot, ((char ) CONT_VIA), xvia, yvia+ptMbkRoot->YAB1,0,0,NULL); + /* + if (L3MODE) + addphvia (ptMbkRoot, ((char ) CONT_VIA2), xvia, yvia+ptMbkRoot->YAB1,0,0,NULL); + */ + } + } + } + } + if (SXMODE==0) + { + for(ptScrSeg = ptScrLine->ALLOWUSED; ptScrSeg; ptScrSeg = ptScrSeg->NEXT) { + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,ptScrSeg->LAYER,ptScrSeg->WIDTH, + ptScrSeg->X1,ptScrSeg->Y1 + ptScrLine->Y, + ptScrSeg->X2,ptScrSeg->Y2 + ptScrLine->Y, + ptScrSeg->NAME); + } + } +#ifdef L3DEBUG + savephfig(ptMbkRoot); +#endif + if (ptOptionList->ChannelName && !SXMODE) savephfig(ptMbkRoot); + } + else if (ptScrLine->TYPE == UP) ptScrLine->Y = ptScrLine->Y + NewYNextLine; + + } + + VddWidth = (CellLineNumber * VDDWIDTH) / 2; + VssWidth = (CellLineNumber * VSSWIDTH) / 2; + + ptMbkRoot = addphfig(FigName); + + ptMbkRoot->XAB1 = (ptScrLine = ptfig->LINE)->X; + ptMbkRoot->YAB1 = ptScrLine->Y; +for (; ptScrLine->NEXT; ptScrLine = ptScrLine->NEXT); + ptMbkRoot->XAB2 = ptScrLine->X + ptScrLine->WIDTH; + ptMbkRoot->YAB2 = ptScrLine->Y + ptScrLine->HEIGTH; + + for (CellLineNumber = 0,ptScrLine = ptfig->LINE->NEXT; + ptScrLine->NEXT; + CellLineNumber++, ptScrLine = ptScrLine->NEXT) { + if (L3MODE && ((CellLineNumber%4)==3)) + { + ptMbkRoot->PHINS = addphins(ptMbkRoot,ptScrLine->NAME,ptScrLine->NAME, + SYM_Y, + ptScrLine->X,ptScrLine->Y); + } + else + ptMbkRoot->PHINS = addphins(ptMbkRoot,ptScrLine->NAME,ptScrLine->NAME, + NOSYM, + ptScrLine->X,ptScrLine->Y); + } + +/******************************************************************************/ +/* SAVING FATHER CONNECTOR */ +/******************************************************************************/ + + for (ptScrCon = ptfig->CON; ptScrCon; ptScrCon = ptScrCon->NEXT) { + if ((ptScrCon->ORIENT == WEST) || (ptScrCon->ORIENT == EAST)) + { + ptMbkRoot->PHCON = addphcon(ptMbkRoot,ptScrCon->ORIENT,ptScrCon->NAME, + ptScrCon->X,ptScrCon->Y, + (L3MODE?ALU3:ptScrCon->LAYER),ptScrCon->WIDTH); + } + else if (ptScrCon->ORIENT == NORTH) + { + ptMbkRoot->PHCON = addphcon(ptMbkRoot,ptScrCon->ORIENT,ptScrCon->NAME, + ptScrCon->X,ptMbkRoot->YAB2,(L3MODE?ALU2:ptScrCon->LAYER), + ptScrCon->WIDTH); + } + else if (ptScrCon->ORIENT == SOUTH) + { + ptMbkRoot->PHCON = addphcon(ptMbkRoot,ptScrCon->ORIENT, + ptScrCon->NAME,ptScrCon->X, + ptMbkRoot->YAB1,(L3MODE?ALU2:ptScrCon->LAYER), + ptScrCon->WIDTH); + } + } + /* connecteurs alimentations */ + for (ptScrLine = ptfig->LINE; ptScrLine; ptScrLine = ptScrLine->NEXT) { + if (ptScrLine->TYPE == CELL) { + if (ptOptionList->SupplyRecall == 0) { + ptMbkRoot->PHCON = addphcon(ptMbkRoot,WEST, + ScrNameIndex(NameVdd,ptScrLine->INDEX), + ptMbkRoot->XAB1, + (ptScrLine->Y + ptScrLine->HEIGTH - VDDOFFSET), + ALU1,VDDWIDTH); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,WEST, + ScrNameIndex(NameVss,ptScrLine->INDEX), + ptMbkRoot->XAB1, + (ptScrLine->Y + VSSOFFSET), + ALU1,VSSWIDTH); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,EAST, + ScrNameIndex(NameVdd,ptScrLine->INDEX), + ptMbkRoot->XAB2, + (ptScrLine->Y + ptScrLine->HEIGTH - VDDOFFSET), + ALU1,VDDWIDTH); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,EAST, + ScrNameIndex(NameVss,ptScrLine->INDEX), + ptMbkRoot->XAB2, + (ptScrLine->Y + VSSOFFSET), + ALU1,VSSWIDTH); + } + else { + ptMbkRoot->PHCON = addphcon(ptMbkRoot,WEST, NameVdd, ptMbkRoot->XAB1, + (ptScrLine->Y + ptScrLine->HEIGTH - VDDOFFSET), + ALU1,VDDWIDTH); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,WEST, NameVss, ptMbkRoot->XAB1, + (ptScrLine->Y + VSSOFFSET), + ALU1,VSSWIDTH); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,EAST, NameVdd, ptMbkRoot->XAB2, + (ptScrLine->Y + ptScrLine->HEIGTH - VDDOFFSET), + ALU1,VDDWIDTH); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,EAST, NameVss, ptMbkRoot->XAB2, + (ptScrLine->Y + VSSOFFSET), + ALU1,VSSWIDTH); + /* BARRES D'ALIMENTATIONS HORIZONTALES */ + for (ptXBreak = ptXInsert; ptXBreak; ptXBreak = ptXBreak->NEXT) { + long xins; + X1 = ptXBreak->X; + X2 = X1 + VerticalChannelWidth; + X3 = X1 + RIGHTSUPPLY + (VddWidth / 2); + X4 = X2 - LEFTSUPPLY - (VssWidth / 2); + Y1 = ptScrLine->Y + VSSOFFSET; + Y2 = ptScrLine->Y + ptScrLine->HEIGTH - VDDOFFSET; + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,ALU1,VSSWIDTH,X1,Y1,X2,Y1,NameVss); + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,ALU1,VDDWIDTH,X1,Y2,X2,Y2,NameVdd); + bigvia(ptMbkRoot, CONT_VIA,X3, Y2, VddWidth, VDDWIDTH); + bigvia(ptMbkRoot, CONT_VIA,X4, Y1, VssWidth, VSSWIDTH); + for(xins=X1; xins+10*SCALE_X <= X2; xins += 10*SCALE_X) { + addphins(ptMbkRoot,"tie_x0",ScrNameIndex("tiefeed",Counter++), + NOSYM, + xins,ptScrLine->Y); + } + for(; xins+5*SCALE_X <= X2; xins += 5*SCALE_X) { + addphins(ptMbkRoot,"rowend_x0",ScrNameIndex("tiefeed",Counter++), + NOSYM, + xins,ptScrLine->Y); + } + /* + if (L3MODE) + { + bigvia(ptMbkRoot, CONT_VIA2,X3, Y2, VddWidth, VDDWIDTH); + bigvia(ptMbkRoot, CONT_VIA2,X4, Y1, VssWidth, VSSWIDTH); + } + */ + } + } + } + } + /* BARRES D'ALIMENTATIONS VERTICALES */ + Yab1 = ptMbkRoot->YAB1; + Yab2 = ptMbkRoot->YAB2; + if (ptOptionList->SupplyRecall != 0) { + for (ptXBreak = ptXInsert; ptXBreak; ptXBreak = ptXBreak->NEXT) { + X1 = ptXBreak->X; + X2 = X1 + VerticalChannelWidth; + X3 = X1 + RIGHTSUPPLY + (VddWidth / 2); + X4 = X2 - LEFTSUPPLY - (VssWidth / 2); + + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,(L3MODE?ALU2:ALU2),VddWidth,X3,Yab1,X3,Yab2,NameVdd); + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,(L3MODE?ALU2:ALU2),VssWidth,X4,Yab1,X4,Yab2,NameVss); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,NORTH, NameVdd, X3,Yab2,(L3MODE?ALU2:ALU2),VddWidth); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,NORTH, NameVss, X4,Yab2,(L3MODE?ALU2:ALU2),VssWidth); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,SOUTH, NameVdd, X3,Yab1,(L3MODE?ALU2:ALU2),VddWidth); + ptMbkRoot->PHCON = addphcon(ptMbkRoot,SOUTH, NameVss, X4,Yab1,(L3MODE?ALU2:ALU2),VssWidth); + } + } + +/* TRANSPARENCES DE LA FIGURE */ + + for(ptScrSeg = ptfig->ALLOW; ptScrSeg; ptScrSeg = ptScrSeg->NEXT) { + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,ptScrSeg->LAYER,ptScrSeg->WIDTH, + ptScrSeg->X1,Yab1,ptScrSeg->X2,Yab2, + ptScrSeg->NAME); + } + + if (!(ptOptionList->ChannelName) || SXMODE) rflattenphfig(ptMbkRoot,'N','Y'); + + /* on rabote les fils vertical trop grand, le flaten est alors obligatoire */ + if (SXMODE && !L3MODE) + { + phseg_list * phseg; + for (phseg = ptMbkRoot->PHSEG; phseg; phseg = phseg->NEXT) + { + if (phseg->Y1 < ptMbkRoot->YAB1) + phseg->Y1 = ptMbkRoot->YAB1; + if (phseg->Y2 > ptMbkRoot->YAB2) + phseg->Y2 = ptMbkRoot->YAB2; + } + } + savephfig(ptMbkRoot); +} + +/******************************************************************************/ +/* Function : MakeVerticalFeed() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : none */ +/* Output parameters : none */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +void MakeVerticalFeed(ptFig,ptMbkTie,FeedNumber, + SupplyNumber,ptXInsert,Counter) +Figure *ptFig; +phfig_list *ptMbkTie; +long FeedNumber; +int SupplyNumber; +XSupplyRecallList *ptXInsert; +long *Counter; + +{ + XSupplyRecallList *ptXBreak = NULL; + XSupplyRecallList *ptXBreakList = NULL; + Line *ptLine = NULL; + Instance *ptInst = NULL; + Instance *PrevInst = NULL; + Instance *ptNewInst = NULL; + Connector *ptCon = NULL; + Segment *ptSeg = NULL; + Segment *ptNewAllow = NULL; + phseg_list *ptphSeg = NULL; + SegmentList *ptSegList = NULL; + ViasList *ptViaList = NULL; + long ChannelWidth = 0; + long WidthShiftSymb = 0; + long XOpen = 0; + long XOpenSymb = 0; + long TieWidth = (ptMbkTie->XAB2 - ptMbkTie->XAB1); + long TieHeight = (ptMbkTie->YAB2 - ptMbkTie->YAB1); + long X1 = 0; + long X2 = 0; + long Y1 = 0; + long Y2 = 0; + long FeedToPlace = 0; + long PositionCounter = 0; + long Divide = 0; + long Reste = 0; + + ChannelWidth = TieWidth; + WidthShiftSymb = ChannelWidth / PITCH_X; + if (FeedNumber <= (long) SupplyNumber) { + for (ptXBreak = ptXInsert; ptXBreak && (FeedNumber != 0); ptXBreak = ptXBreak->NEXT) { + FeedNumber--; + XOpen = ptXBreak->X; + XOpenSymb = (XOpen / PITCH_X) + 1; + for (ptLine = ptFig->LINE; ptLine; ptLine = ptLine->NEXT) { + ptLine->WIDTH += ChannelWidth; + if (ptLine->TYPE == CELL) { + for (PrevInst = NULL, ptInst = ptLine->INS; (ptInst && (ptInst->X < XOpen)); + PrevInst = ptInst, ptInst = ptInst->NEXT); + ptNewInst = CreateInstance(ScrNameIndex("verfeed",(*Counter)++), + ptMbkTie->NAME,XOpen,ptLine->Y, + TieWidth,TieHeight,NOSYM); + if (PrevInst) { + ptNewInst->NEXT = ptInst; + PrevInst->NEXT = ptNewInst; + } + else { + ptNewInst->NEXT = ptInst; + ptLine->INS = ptNewInst; + } + for (; ptInst; ptInst = ptInst->NEXT) { + ptInst->X += ChannelWidth; + for (ptCon = ptInst->CON; ptCon; ptCon = ptCon->NEXT) + ptCon->X += ChannelWidth; + for (ptSeg = ptInst->ALLOW; ptSeg; ptSeg = ptSeg->NEXT) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + } + else { + if (ptLine->TYPE == PATH) { + ptLine->CHANNEL->WIDTH += WidthShiftSymb; + for (ptSegList = ptLine->CHANNEL->H_SEGMENT; ptSegList; + ptSegList = ptSegList->NextSeg) { + if (ptSegList->X1Seg >= XOpenSymb) ptSegList->X1Seg += WidthShiftSymb; + if (ptSegList->X2Seg >= XOpenSymb) ptSegList->X2Seg += WidthShiftSymb; + } + for (ptSegList = ptLine->CHANNEL->V_SEGMENT; ptSegList; + ptSegList = ptSegList->NextSeg) { + if (ptSegList->X1Seg >= XOpenSymb) { + ptSegList->X1Seg += WidthShiftSymb; + ptSegList->X2Seg += WidthShiftSymb; + } + } + for (ptViaList = ptLine->CHANNEL->VIA; ptViaList; + ptViaList = ptViaList->NextVia) { + if (ptViaList->XVia >= XOpenSymb) + ptViaList->XVia += WidthShiftSymb; + } + } + } + } + +/* PLACEMENT DES TRANSPARENCES VERTICALES */ + for (ptphSeg = ptMbkTie->PHSEG; ptphSeg; ptphSeg = ptphSeg->NEXT) { + if(ptphSeg->LAYER == TALU2) { + xyflat(&X1,&Y1,ptphSeg->X1,ptphSeg->Y1,ptNewInst->X,ptNewInst->Y, + ptMbkTie->XAB1,ptMbkTie->YAB1,ptMbkTie->XAB2,ptMbkTie->YAB2,ptNewInst->TRANSF); + xyflat(&X2,&Y2,ptphSeg->X2,ptphSeg->Y2,ptNewInst->X,ptNewInst->Y, + ptMbkTie->XAB1,ptMbkTie->YAB1,ptMbkTie->XAB2,ptMbkTie->YAB2,ptNewInst->TRANSF); + ptNewAllow = CreateSegment(ptphSeg->NAME,X1,(Y1 - ptNewInst->Y),X2, + (Y2 - ptNewInst->Y),ptphSeg->WIDTH, + ptphSeg->TYPE,ptphSeg->LAYER); + if (ptFig->ALLOW == NULL) ptFig->ALLOW = ptNewAllow; + else { + ptNewAllow->NEXT = ptFig->ALLOW; + ptFig->ALLOW = ptNewAllow; + } + } + } + + /* MISE A JOUR DES CONNECTEURS EXTERNES */ + for (ptCon = ptFig->CON; ptCon; ptCon = ptCon->NEXT) { + if (ptCon->ORIENT == EAST) ptCon->X += ChannelWidth; + else if ((ptCon->ORIENT == NORTH) && (ptCon->X >= XOpen)) + ptCon->X += ChannelWidth; + else if ((ptCon->ORIENT == SOUTH) && (ptCon->X >= XOpen)) + ptCon->X += ChannelWidth; + } + + /* MISE A JOUR DES SEGMENTS DE LA FIGURE MERE */ + for (ptLine = ptFig->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == CELL) { + for (ptSeg = ptLine->ALLOWUSED; ptSeg; ptSeg = ptSeg->NEXT) { + if (ptSeg->X1 >= XOpen) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + } + } + for (ptXBreakList = ptXBreak->NEXT; ptXBreakList; + ptXBreakList = ptXBreakList->NEXT) { + ptXBreakList->X += ChannelWidth; + } + } + } +/*#################################################*/ + else { + Divide = FeedNumber / ((long ) SupplyNumber); + Reste = FeedNumber % ((long ) SupplyNumber); + for (PositionCounter = 1, ptXBreak = ptXInsert; ptXBreak ; ptXBreak = ptXBreak->NEXT) { + XOpen = ptXBreak->X; + XOpenSymb = (XOpen / PITCH_X) + 1; + if (PositionCounter <= Reste) { + FeedToPlace = Divide + 1; + PositionCounter++; + } + else FeedToPlace = Divide; + while (FeedToPlace != 0) { + for (ptLine = ptFig->LINE; ptLine; ptLine = ptLine->NEXT) { + ptLine->WIDTH += ChannelWidth; + if (ptLine->TYPE == CELL) { + for (PrevInst = NULL, ptInst = ptLine->INS; (ptInst && (ptInst->X < XOpen)); + PrevInst = ptInst, ptInst = ptInst->NEXT); + ptNewInst = CreateInstance(ScrNameIndex("verfeed",(*Counter)++), + ptMbkTie->NAME,XOpen,ptLine->Y, + TieWidth,TieHeight,NOSYM); + if (PrevInst) { + ptNewInst->NEXT = ptInst; + PrevInst->NEXT = ptNewInst; + } + else { + ptNewInst->NEXT = ptInst; + ptLine->INS = ptNewInst; + } + for (; ptInst; ptInst = ptInst->NEXT) { + ptInst->X += ChannelWidth; + for (ptCon = ptInst->CON; ptCon; ptCon = ptCon->NEXT) + ptCon->X += ChannelWidth; + for (ptSeg = ptInst->ALLOW; ptSeg; ptSeg = ptSeg->NEXT) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + } + else { + if (ptLine->TYPE == PATH) { + ptLine->CHANNEL->WIDTH += WidthShiftSymb; + for (ptSegList = ptLine->CHANNEL->H_SEGMENT; ptSegList; + ptSegList = ptSegList->NextSeg) { + if (ptSegList->X1Seg >= XOpenSymb) ptSegList->X1Seg += WidthShiftSymb; + if (ptSegList->X2Seg >= XOpenSymb) ptSegList->X2Seg += WidthShiftSymb; + } + for (ptSegList = ptLine->CHANNEL->V_SEGMENT; ptSegList; + ptSegList = ptSegList->NextSeg) { + if (ptSegList->X1Seg >= XOpenSymb) { + ptSegList->X1Seg += WidthShiftSymb; + ptSegList->X2Seg += WidthShiftSymb; + } + } + for (ptViaList = ptLine->CHANNEL->VIA; ptViaList; + ptViaList = ptViaList->NextVia) { + if (ptViaList->XVia >= XOpenSymb) + ptViaList->XVia += WidthShiftSymb; + } + } + } + } + +/* PLACEMENT DES TRANSPARENCES VERTICALES */ + for (ptphSeg = ptMbkTie->PHSEG; ptphSeg; ptphSeg = ptphSeg->NEXT) { + if(ptphSeg->LAYER == TALU2) { + xyflat(&X1,&Y1,ptphSeg->X1,ptphSeg->Y1,ptNewInst->X,ptNewInst->Y, + ptMbkTie->XAB1,ptMbkTie->YAB1,ptMbkTie->XAB2,ptMbkTie->YAB2,ptNewInst->TRANSF); + xyflat(&X2,&Y2,ptphSeg->X2,ptphSeg->Y2,ptNewInst->X,ptNewInst->Y, + ptMbkTie->XAB1,ptMbkTie->YAB1,ptMbkTie->XAB2,ptMbkTie->YAB2,ptNewInst->TRANSF); + ptNewAllow = CreateSegment(ptphSeg->NAME,X1,(Y1 - ptNewInst->Y),X2, + (Y2 - ptNewInst->Y),ptphSeg->WIDTH, + ptphSeg->TYPE,ptphSeg->LAYER); + if (ptFig->ALLOW == NULL) ptFig->ALLOW = ptNewAllow; + else { + ptNewAllow->NEXT = ptFig->ALLOW; + ptFig->ALLOW = ptNewAllow; + } + } + } + + /* MISE A JOUR DES CONNECTEURS EXTERNES */ + for (ptCon = ptFig->CON; ptCon; ptCon = ptCon->NEXT) { + if (ptCon->ORIENT == EAST) ptCon->X += ChannelWidth; + else if ((ptCon->ORIENT == NORTH) && (ptCon->X >= XOpen)) + ptCon->X += ChannelWidth; + else if ((ptCon->ORIENT == SOUTH) && (ptCon->X >= XOpen)) + ptCon->X += ChannelWidth; + } + + /* MISE A JOUR DES SEGMENTS DE LA FIGURE MERE */ + for (ptLine = ptFig->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == CELL) { + for (ptSeg = ptLine->ALLOWUSED; ptSeg; ptSeg = ptSeg->NEXT) { + if (ptSeg->X1 >= XOpen) { + ptSeg->X1 += ChannelWidth; + ptSeg->X2 += ChannelWidth; + } + } + } + } + for (ptXBreakList = ptXBreak->NEXT; ptXBreakList; + ptXBreakList = ptXBreakList->NEXT) { + ptXBreakList->X += ChannelWidth; + } + XOpen += ChannelWidth; + XOpenSymb = (XOpen / PITCH_X) + 1; + FeedToPlace--; + } + + + } + } +/*#################################################*/ + +} + +/******************************************************************************/ +/* Function : MakeHorizFeed() */ +/* */ +/* Description : */ +/* */ +/* Input parameters : */ +/* Input global Variables : none */ +/* Output parameters : none */ +/* Output global Variables : none */ +/* */ +/******************************************************************************/ +void MakeHorizFeed(ptFig,Number) +Figure *ptFig; +long Number; + +{ + Line *ptLine = NULL; + long Counter = 0; + long MiddleChannel = 0; + ConnectorList *ptCon = NULL; + SegmentList *ptSegment = NULL; + Channel *ptChannel = NULL; + long ChannelHeigth = 0; + + for (ptLine = ptFig->LINE; ptLine; ptLine = ptLine->NEXT) + if (ptLine->TYPE == PATH) Counter++; + if (IMPAIRE(Counter)) MiddleChannel = (Counter/2) + 1; + else MiddleChannel = (Counter/2); + Counter = 0; + for (ptLine = ptFig->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == PATH) Counter++; + if (Counter == MiddleChannel) break; + } + ptChannel = ptLine->CHANNEL; + ChannelHeigth = ptChannel->HEIGTH; + for (ptCon = ptChannel->NORTH_LIST; ptCon; ptCon = ptCon->NextCon) { + if (ptCon->Mark >= ChannelHeigth) ptCon->Mark += Number; + } + for (ptSegment = ptChannel->V_SEGMENT; ptSegment; ptSegment = ptSegment->NextSeg) { + if (ptSegment->Y2Seg > ChannelHeigth) ptSegment->Y2Seg += Number; + } + ptChannel->HEIGTH += Number; + ptLine->HEIGTH = ((ptChannel->HEIGTH - 1) * PITCH_Y) + SOUTHOFFSET + NORTHOFFSET; + for (Counter = 1; Counter <= Number; Counter++) { + ptSegment = (SegmentList *) mbkalloc (sizeof(SegmentList)); + ptSegment->SegName = namealloc("HOR_FEED"); + ptSegment->X1Seg = 0; + ptSegment->Y1Seg = ChannelHeigth + Counter; + ptSegment->X2Seg = (ptChannel->WIDTH) + 1; + ptSegment->Y2Seg = ChannelHeigth + Counter; + ptSegment->NextSeg = ptChannel->H_SEGMENT; + ptChannel->H_SEGMENT = ptSegment; + } +} + +/******************************************************************************/ +/* Function : main() */ +/******************************************************************************/ +int main(argc,argv) + +int argc; +char *argv[]; + +{ + Figure *ptfig = NULL; + Line *ptLine = NULL; + Channel *ptChannel = NULL; + phfig_list *ptphfig = NULL; + lofig_list *ptlofig = NULL; + phfig_list *NewphIns = NULL; + XSupplyRecallList *ptXInsertList = NULL; + BOOLEAN LineWidthChange = FALSE; + long Counter = 0; + long CounterInst = 0; + OptionList *ptOption = NULL; + long ChannelWidth = 0; + long CellLineNumber = 0; + extern FILE *yyin; + + mbkenv(); + NameVdd = namealloc(VDD); + NameVss = namealloc(VSS); + alliancebanner("SCR","5.3","Standard Cell router","1991",ALLIANCE_VERSION); + if (argc < 3) ScrUsage(argv[0]); + else + if (*argv[1] == '-') ptOption = GetOptions(argc,argv); + else ScrUsage(argv[0]); + + if (!((ptOption->Placer) || (ptOption->Router))) + ScrUsage(argv[0]); + + if ((yyin = mbkfopen(ptOption->InputFileName,"scr","r")) != NULL) { + yyparse(); + fclose(yyin); + } + + fprintf(stderr,"Loading logical view : %s\n",ptOption->InputFileName); + ptlofig = getlofig(ptOption->InputFileName,'A'); + rflattenlofig(ptlofig,'Y','Y'); + + if (ptlofig->LOTRS) { + fprintf(stderr,"scr_error : Check that the catalogue file existes and that it contains all the models instanciated in the figure.\n"); + exit(1); + } + + if (ptOption->Placer) { + fprintf(stderr,"Placing logical view : %s\n",ptOption->InputFileName); + ptphfig = + Placer2Scr(ptlofig->NAME,Place(ptlofig,ptOption->Iteration,ptOption->Row,0,7,5,5,NULL,SCR_RATIO)); + } + else { + fprintf(stderr,"Loading physical view : %s\n",ptOption->InputFileName); + ptphfig = getphfig(ptOption->InputFileName,'A'); + rflattenphfig(ptphfig,'Y','Y'); + } + if (ptOption->Router) { + + fprintf(stderr,"Checking consistency between logical and physical views\n"); + Sesame(ptphfig, ptlofig); + + fprintf(stderr,"Loading SCR data base ...\n"); + ptfig = LoadScrFig(ptphfig, ptlofig,LeadPlaceConList); + +# ifdef SCR_DEBUG + fprintf(stderr,"In ViewDataBase \n"); + ViewScrFigure(ptfig); + ViewScrChannel(ptfig); + fprintf(stderr,"Out ViewDataBase \n"); +# endif + + fprintf(stderr,"Deleting MBK data base ...\n"); + dellofig(ptlofig->NAME); + delphfig(ptphfig->NAME); + +# ifdef SCR_DEBUG + fprintf(stderr,"Get the transparencies model ...\n"); +# endif + + NewphIns = getphfig((SXMODE ? "tie_x0":"tie_y"),'A'); + sx2sc (NewphIns); + + +# ifdef SCR_DEBUG + fprintf(stderr,"Complete rows ...\n"); +# endif + + CompleteLine(ptfig,NewphIns,&CounterInst); + + NewphIns = getphfig((SXMODE ? "rowend_x0":"tie_y"),'A'); + sx2sc (NewphIns); + + +# ifdef SCR_DEBUG + fprintf(stderr,"Complete rows ...\n"); +# endif + + CompleteLine(ptfig,NewphIns,&CounterInst); + + NewphIns = getphfig((SXMODE ? "tie_x0":"tie_y"),'A'); + sx2sc (NewphIns); +# ifdef SCR_DEBUG + fprintf(stderr,"In ViewDataBase \n"); + ViewScrFigure(ptfig); + ViewScrChannel(ptfig); + fprintf(stderr,"Out ViewDataBase \n"); +# endif + + if (ptOption->SupplyRecall != 0) + ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, ptOption->SupplyRecall, &CounterInst); + else + if (LeadPlaceConList && (LeadPlaceConList->VER_FEED != 0)) + ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, 1, &CounterInst); + + NewphIns = getphfig((SXMODE ? "rowend_x0":"tie_y"),'A'); + sx2sc (NewphIns); + + if (ptOption->SupplyRecall != 0) + ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, ptOption->SupplyRecall, &CounterInst); + else + if (LeadPlaceConList && (LeadPlaceConList->VER_FEED != 0)) + ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, 1, &CounterInst); + + fprintf(stderr,"Global routing ...\n"); + GlobalRoute(ptfig,NewphIns,ptXInsertList); + + fprintf(stderr,"Channel routing ...\n"); + for (ptLine = ptfig->LINE; ptLine; ptLine = ptLine->NEXT) { + if (ptLine->TYPE == PATH) { + CellLineNumber++; + Counter++; + if (ptOption->ChannelName) + ptLine->NAME = ScrNameIndex(ptOption->ChannelName,Counter); + fprintf(stderr,"|_____Routing Channel : %s \n",ptLine->NAME); + ptChannel = ptLine->CHANNEL; + if (SymbolicChannelRouter(&ptChannel->NORTH_LIST,&ptChannel->SOUTH_LIST, + &ptChannel->WEST_LIST,&ptChannel->EAST_LIST, + &(ptChannel->WIDTH),&(ptChannel->HEIGTH), + &(ptChannel->H_SEGMENT),&(ptChannel->V_SEGMENT), + &(ptChannel->VIA))) + LineWidthChange = TRUE; + ptLine->WIDTH = ((ptChannel->WIDTH - 1) * PITCH_X) + WESTOFFSET + EASTOFFSET; + ptLine->HEIGTH = ((ptChannel->HEIGTH - 1) * PITCH_Y) + SOUTHOFFSET + NORTHOFFSET; + } + } + CellLineNumber--; + + if (LineWidthChange) { + +# ifdef SCR_DEBUG + fprintf(stderr,"Up date the width rows ... \n"); +# endif + + UpDateWidthLine(ptfig,NewphIns,&CounterInst); + } + +# ifdef SCR_DEBUG + fprintf(stderr,"In ViewDataBase \n"); + ViewScrFigure(ptfig); + ViewScrChannel(ptfig); + fprintf(stderr,"Out ViewDataBase \n"); +# endif + + if (LeadPlaceConList && (LeadPlaceConList->VER_FEED != 0)) { + fprintf(stderr,"Making vertical feed \n"); + if (ptOption->SupplyRecall != 0) + MakeVerticalFeed(ptfig,NewphIns,LeadPlaceConList->VER_FEED, + ptOption->SupplyRecall,ptXInsertList,&CounterInst); + else + MakeVerticalFeed(ptfig,NewphIns,LeadPlaceConList->VER_FEED, + 1,ptXInsertList,&CounterInst); + } + + if (LeadPlaceConList && (LeadPlaceConList->HOR_FEED != 0)) { + fprintf(stderr,"Making horizontal feed \n"); + MakeHorizFeed(ptfig,LeadPlaceConList->HOR_FEED); + } + + if (ptOption->SupplyRecall != 0) { + ChannelWidth = RIGHTSUPPLY + LEFTSUPPLY + MIDDLESUPPLY + + (long )((CellLineNumber * (VSSWIDTH + VDDWIDTH)) / 2 + 0.5); + if (ChannelWidth % PITCH_X) { + ChannelWidth = ((ChannelWidth / PITCH_X) + 1) * PITCH_X; + } + fprintf(stderr,"Making vertical power and ground wires \n"); + MakeVerticalChannel(ptfig, ptXInsertList, ChannelWidth); + } + + if (ptOption->OutputFileName == NULL) { + fprintf(stderr,"Saving layout : %s\n",ptOption->InputFileName); + Scr2Mbk(ptfig,ptOption->InputFileName,ptOption, ptXInsertList,ChannelWidth); + } + else { + fprintf(stderr,"Saving layout : %s\n",ptOption->OutputFileName); + Scr2Mbk(ptfig,ptOption->OutputFileName,ptOption, ptXInsertList,ChannelWidth); + } + } + else + if (!(ptOption->Placer)) ScrUsage(argv[0]); + else { + fprintf(stderr,"Saving layout : %s\n",ptOption->InputFileName); + savephfig(ptphfig); + } + return(0); +} diff --git a/alliance/src/scr/src/main.h b/alliance/src/scr/src/main.h new file mode 100644 index 00000000..fa13f1d3 --- /dev/null +++ b/alliance/src/scr/src/main.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +/******************************************************************************/ +/* */ +/* CAO & VLSI's cad tools chain Alliance */ +/* */ +/* Product : main.h */ +/* File : @(#) */ +/* Contents : */ +/* */ +/* (c) Copyright 1992 Laboratoire MASI equipe CAO & VLSI */ +/* All rights reserved */ +/* Hot line : cao-vlsi@masi.ibp.fr (e-mail) */ +/* */ +/* Author(s) : El housseine REJOUAN Date : 22/08/1992 */ +/* Modified by : Date : ../../.... */ +/* Modified by : Date : ../../.... */ +/* Modified by : Date : ../../.... */ +/* */ +/******************************************************************************/ +typedef struct Option + { + char *ChannelName; + char *InputFileName; + char *OutputFileName; + BOOLEAN Placer; + BOOLEAN Router; + int SupplyRecall; + int Row; + int Iteration; + }OptionList; + +typedef struct XSupplyRecall + { + struct XSupplyRecall *NEXT; + long X; + }XSupplyRecallList; +/******************************************************************************/ +/* Variables Globales */ +/******************************************************************************/ +char *NameVdd; +char *NameVss; diff --git a/alliance/src/scr/src/scr.patch b/alliance/src/scr/src/scr.patch new file mode 100755 index 00000000..c2657b12 --- /dev/null +++ b/alliance/src/scr/src/scr.patch @@ -0,0 +1,151 @@ +diff -Naur sources/patch2.patch ../../alliance-4.0-patchd/sources/patch2.patch +--- sources/patch2.patch 1970-01-01 09:00:00.000000000 +0900 ++++ ../../alliance-4.0-patchd/sources/patch2.patch 2017-03-06 18:52:25.604945300 +0900 +@@ -0,0 +1,5 @@ ++diff -r ../sources-old/scr/SCR_Type.h scr/SCR_Type.h ++68c68 ++< # define MIDDLESUPPLY ((long ) 2 * SCALE_X) ++--- ++> # define MIDDLESUPPLY ((long ) 3 * SCALE_X) +diff -Naur sources/scr/main.c ../../alliance-4.0-patchd/sources/scr/main.c +--- sources/scr/main.c 2017-03-06 18:55:30.274247300 +0900 ++++ ../../alliance-4.0-patchd/sources/scr/main.c 2017-03-06 18:52:37.108768700 +0900 +@@ -494,7 +494,7 @@ + for (CurrentLine = ptFig->LINE; CurrentLine; CurrentLine = CurrentLine->NEXT) { + if (CurrentLine->TYPE == CELL) { + CurrentInst = CurrentLine->INS; +- if (Xab1Figure != CurrentInst->X) { ++ if (Xab1Figure + NewInstWidth <= CurrentInst->X) { + CurrentInst = CreateInstance(ScrNameIndex("row",(*Counter)++), + NewphIns->NAME,Xab1Figure,CurrentLine->Y, + NewInstWidth,NewInstHeight,NOSYM); +@@ -505,7 +505,7 @@ + CurrentLine->ALLOW = addchain(CurrentLine->ALLOW,(char *)ptNewAllow); + } + while (CurrentInst->NEXT) { +- if ((CurrentInst->X + CurrentInst->WIDTH) != ++ if ((CurrentInst->X + CurrentInst->WIDTH) + NewInstWidth <= + (NextInst = CurrentInst->NEXT)->X) { + PrevInst = CurrentInst; + CurrentInst = CreateInstance(ScrNameIndex("row",(*Counter)++), +@@ -521,7 +521,7 @@ + } + else CurrentInst = CurrentInst->NEXT; + } +- while ((CurrentInst->X + CurrentInst->WIDTH) != Xab2Figure) { ++ while ((CurrentInst->X + CurrentInst->WIDTH) + NewInstWidth <= Xab2Figure) { + CurrentInst->NEXT = CreateInstance(ScrNameIndex("row",(*Counter)++), + NewphIns->NAME, + CurrentInst->X + CurrentInst->WIDTH, +@@ -768,6 +768,7 @@ + char Buffer[10]; + long IndexSignal = 0; + long ChannelNumber = 0; ++ static long Counter = 0; + + for (ptScrLine = ptfig->LINE; ptScrLine; ptScrLine = ptScrLine->NEXT) + { +@@ -850,11 +851,11 @@ + for (CurrentSeg = ptScrChannel->V_SEGMENT; CurrentSeg; + CurrentSeg = CurrentSeg->NextSeg) { + if ((Y1Symbolic = CurrentSeg->Y1Seg) == 0) +- Y1Segment = Yab1 - ((SXMODE && !L3MODE) ? CELLAB/2:0); ++ Y1Segment = Yab1 - ((SXMODE && !L3MODE) ? CELLAB*40/50:0); + else + Y1Segment = ((Y1Symbolic - 1) * PITCH_Y) + SOUTHOFFSET + YLine; + if ((Y2Symbolic = CurrentSeg->Y2Seg) == ChannelHeight + 1) +- Y2Segment = Yab2 + ((SXMODE && !L3MODE)? CELLAB/2:0); ++ Y2Segment = Yab2 + ((SXMODE && !L3MODE)? CELLAB*40/50:0); + else + Y2Segment = ((Y2Symbolic - 1) * PITCH_Y) + SOUTHOFFSET + YLine; + X1Segment = X2Segment = ((CurrentSeg->X1Seg - 1) * PITCH_X) + WESTOFFSET + Xab1; +@@ -1131,6 +1132,7 @@ + ALU1,VSSWIDTH); + /* BARRES D'ALIMENTATIONS HORIZONTALES */ + for (ptXBreak = ptXInsert; ptXBreak; ptXBreak = ptXBreak->NEXT) { ++ long xins; + X1 = ptXBreak->X; + X2 = X1 + VerticalChannelWidth; + X3 = X1 + RIGHTSUPPLY + (VddWidth / 2); +@@ -1141,6 +1143,16 @@ + ptMbkRoot->PHSEG = addphseg(ptMbkRoot,ALU1,VDDWIDTH,X1,Y2,X2,Y2,NameVdd); + bigvia(ptMbkRoot, CONT_VIA,X3, Y2, VddWidth, VDDWIDTH); + bigvia(ptMbkRoot, CONT_VIA,X4, Y1, VssWidth, VSSWIDTH); ++ for(xins=X1; xins+10*SCALE_X <= X2; xins += 10*SCALE_X) { ++ addphins(ptMbkRoot,"tie_x0",ScrNameIndex("tiefeed",Counter++), ++ NOSYM, ++ xins,ptScrLine->Y); ++ } ++ for(; xins+5*SCALE_X <= X2; xins += 5*SCALE_X) { ++ addphins(ptMbkRoot,"rowend_x0",ScrNameIndex("tiefeed",Counter++), ++ NOSYM, ++ xins,ptScrLine->Y); ++ } + /* + if (L3MODE) + { +@@ -1600,6 +1612,16 @@ + fprintf(stderr,"Get the transparencies model ...\n"); + # endif + ++ NewphIns = getphfig((SXMODE ? "tie_x0":"tie_y"),'A'); ++ sx2sc (NewphIns); ++ ++ ++# ifdef SCR_DEBUG ++ fprintf(stderr,"Complete rows ...\n"); ++# endif ++ ++ CompleteLine(ptfig,NewphIns,&CounterInst); ++ + NewphIns = getphfig((SXMODE ? "rowend_x0":"tie_y"),'A'); + sx2sc (NewphIns); + +@@ -1610,6 +1632,8 @@ + + CompleteLine(ptfig,NewphIns,&CounterInst); + ++ NewphIns = getphfig((SXMODE ? "tie_x0":"tie_y"),'A'); ++ sx2sc (NewphIns); + # ifdef SCR_DEBUG + fprintf(stderr,"In ViewDataBase \n"); + ViewScrFigure(ptfig); +@@ -1619,6 +1643,15 @@ + + if (ptOption->SupplyRecall != 0) + ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, ptOption->SupplyRecall, &CounterInst); ++ else ++ if (LeadPlaceConList && (LeadPlaceConList->VER_FEED != 0)) ++ ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, 1, &CounterInst); ++ ++ NewphIns = getphfig((SXMODE ? "rowend_x0":"tie_y"),'A'); ++ sx2sc (NewphIns); ++ ++ if (ptOption->SupplyRecall != 0) ++ ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, ptOption->SupplyRecall, &CounterInst); + else + if (LeadPlaceConList && (LeadPlaceConList->VER_FEED != 0)) + ptXInsertList = PreparVerticalChannel(ptfig, NewphIns, 1, &CounterInst); +diff -Naur sources/scr/ScrSesame.c ../../alliance-4.0-patchd/sources/scr/ScrSesame.c +--- sources/scr/ScrSesame.c 2017-03-06 18:55:30.258623000 +0900 ++++ ../../alliance-4.0-patchd/sources/scr/ScrSesame.c 2017-03-06 18:52:37.171269700 +0900 +@@ -117,6 +117,7 @@ + for (CurrentphIns = ptphIns; CurrentphIns; CurrentphIns = CurrentphIns->NEXT) { + /*if (!(incatalogfeed(CurrentphIns->FIGNAME))) {*/ + if (strcmp(CurrentphIns->FIGNAME,(SXMODE ? "rowend_x0":"tie_y"))) { ++// if (strcmp(CurrentphIns->FIGNAME,(SXMODE ? "tie_x0":"tie_y"))) { + for (CurrentloIns = ptloIns; CurrentloIns; CurrentloIns = CurrentloIns->NEXT) + if (CurrentloIns->INSNAME == CurrentphIns->INSNAME) break; + if (CurrentloIns == NULL) { +diff -Naur sources/scr/SCR_Type.h ../../alliance-4.0-patchd/sources/scr/SCR_Type.h +--- sources/scr/SCR_Type.h 2017-03-06 18:55:30.227372000 +0900 ++++ ../../alliance-4.0-patchd/sources/scr/SCR_Type.h 2017-03-06 18:52:37.108768700 +0900 +@@ -65,7 +65,7 @@ + # define VSSWIDTH ((long ) (SXMODE ? 6:8) * SCALE_X) + # define RIGHTSUPPLY (PITCH_X / (SXMODE ? 1:2)) + # define LEFTSUPPLY (PITCH_X / (SXMODE ? 1:2)) +-# define MIDDLESUPPLY ((long ) 2 * SCALE_X) ++# define MIDDLESUPPLY ((long ) 3 * SCALE_X) + # define CELLAB ((long ) 50 * SCALE_X) + + typedef struct SCR_Figure diff --git a/alliance/src/scr/src/scr_grammar.y b/alliance/src/scr/src/scr_grammar.y new file mode 100644 index 00000000..ce040484 --- /dev/null +++ b/alliance/src/scr/src/scr_grammar.y @@ -0,0 +1,313 @@ +%{ +#include +#include +#include +# include +# include +# include +# include +#include "SCR_Type.h" + +char *con_name; +long vect_begin; +long vect_end; +long vect_flag = 0; +char con_orient; +long con_order; +long order_begin; +long order_end; +char buffer[256]; + +extern PlaceConList *LeadPlaceConList; +/******************************************************************************/ +/* PROTOTYPES */ +/******************************************************************************/ +CaracConList *MakeCaracConList(); +PlaceConList *MakePlaceConList(); +/******************************************************************************/ + + + +int tpllineno=1; +%} + +%union + { + char cara; + long valu; + char *text; + } + +%token M_PLACE_PHCON_NORTH +%token M_PLACE_PHCON_SOUTH +%token M_PLACE_PHCON_WEST +%token M_PLACE_PHCON_EAST +%token M_VER_FEED_THROUGH +%token M_HOR_FEED_THROUGH +%token Semicolon +%token Colon +%token Coma +%token Identifier +%token Number +%token Lparen +%token Rparen +%token Lcro +%token Rcro + +%start placement + +%% +placement + : ldirective + ; + +ldirective + : + ldirective + directive + | directive + ; + +directive : + M_PLACE_PHCON_NORTH + { con_orient = 'N'; vect_flag = 0; } + name + order + Semicolon + | M_PLACE_PHCON_SOUTH + { con_orient = 'S'; vect_flag = 0; } + name + order + Semicolon + | M_PLACE_PHCON_WEST + { con_orient = 'W'; vect_flag = 0; } + name + order + Semicolon + | M_PLACE_PHCON_EAST + { con_orient = 'E'; vect_flag = 0; } + name + order + Semicolon + | M_VER_FEED_THROUGH + Number + Semicolon + { if (LeadPlaceConList == NULL) { + LeadPlaceConList = (PlaceConList *) mbkalloc (sizeof(PlaceConList)); + LeadPlaceConList->NORTH_CON = NULL; + LeadPlaceConList->SOUTH_CON = NULL; + LeadPlaceConList->WEST_CON = NULL; + LeadPlaceConList->EAST_CON = NULL; + LeadPlaceConList->VER_FEED = $2; + LeadPlaceConList->HOR_FEED = 0; + } + else LeadPlaceConList->VER_FEED = $2; + } + | M_HOR_FEED_THROUGH + Number + Semicolon + { if (LeadPlaceConList == NULL) { + LeadPlaceConList = (PlaceConList *) mbkalloc (sizeof(PlaceConList)); + LeadPlaceConList->NORTH_CON = NULL; + LeadPlaceConList->SOUTH_CON = NULL; + LeadPlaceConList->WEST_CON = NULL; + LeadPlaceConList->EAST_CON = NULL; + LeadPlaceConList->VER_FEED = 0; + LeadPlaceConList->HOR_FEED = $2; + } + else LeadPlaceConList->HOR_FEED = $2; + } + ; + +name + : + Identifier + { con_name = $1; } + | Identifier + Lcro + Number + Rcro + {sprintf(buffer,"%s %ld", $1, $3); + con_name = namealloc(buffer); + } + | Identifier + Lparen + Number + Rparen + {sprintf(buffer,"%s %ld", $1, $3); + con_name = namealloc(buffer); + } + | Identifier + Lparen + Number + Colon + Number + Rparen + { con_name = $1, vect_begin = $3; vect_end = $5; vect_flag = 1; } + | Identifier + Lcro + Number + Colon + Number + Rcro + { con_name = $1, vect_begin = $3; vect_end = $5; vect_flag = 1; } + ; + +order + : + Number + {long j = 0; + con_order = $1; + if ((vect_flag == 1) && (con_order == -1)) { + if (vect_begin < vect_end) { + for(j = vect_begin ; j <= vect_end ; j++) { + sprintf(buffer,"%s %ld",con_name,j); + LeadPlaceConList = MakePlaceConList(con_orient,buffer,con_order); + } + } + else { + for(j = vect_begin ; j >= vect_end ; j--) { + sprintf(buffer,"%s %ld",con_name,j); + LeadPlaceConList = MakePlaceConList(con_orient,buffer,con_order); + } + } + vect_flag = 0; + } + else + LeadPlaceConList = MakePlaceConList(con_orient,con_name,con_order); + } + | Number + Colon + Number + {long i = 0; long j = 0; + order_begin = $1; order_end = $3; + if (LABS(order_begin,order_end) != LABS(vect_begin,vect_end)) + yyerror(); + else { + if (vect_begin < vect_end) { + if (order_begin < order_end) { + for(j = vect_begin, i = order_begin ; i <= order_end ; j++, i++) { + sprintf(buffer,"%s %ld",con_name,j); + LeadPlaceConList = MakePlaceConList(con_orient,buffer,i); + } + } + else { + for(j = vect_begin, i = order_begin ; i >= order_end ; j++, i--) { + sprintf(buffer,"%s %ld",con_name,j); + LeadPlaceConList = MakePlaceConList(con_orient,buffer,i); + } + } + } + else { + if (order_begin < order_end) { + for(j = vect_begin, i = order_begin ; i <= order_end ; j--, i++) { + sprintf(buffer,"%s %ld",con_name,j); + LeadPlaceConList = MakePlaceConList(con_orient,buffer,i); + } + } + else { + for(j = vect_begin, i = order_begin ; i >= order_end ; j--, i--) { + sprintf(buffer,"%s %ld",con_name,j); + LeadPlaceConList = MakePlaceConList(con_orient,buffer,i); + } + } + } + } + } + + ; + +%% + +yyerror() +{ + fprintf(stdout,"SYNTAX ERROR at line %d \n",tpllineno); + exit(1); +} + +yywrap() { + return 1; +} + + +/******************************************************************************/ +/* Function : MakeCaracConList() le 17 juillet 1993 */ +/******************************************************************************/ +CaracConList *MakeCaracConList(LeadCaracConList, Name, OrderSlice) +CaracConList *LeadCaracConList; +char *Name; +long OrderSlice; + +{ + CaracConList *ptNewPhCon = NULL; + CaracConList *CurPhCon = NULL; + CaracConList *PrevPhCon = NULL; + + ptNewPhCon = (CaracConList *) mbkalloc (sizeof(CaracConList)); + ptNewPhCon->NEXT = NULL; + ptNewPhCon->NAME = namealloc(Name); + ptNewPhCon->USER = OrderSlice; + + if (LeadCaracConList == NULL) return(ptNewPhCon) ; + for(PrevPhCon = NULL, CurPhCon = LeadCaracConList; (CurPhCon && (OrderSlice > CurPhCon->USER)); + PrevPhCon = CurPhCon, CurPhCon = CurPhCon->NEXT); + if (OrderSlice != -1) { + if (CurPhCon && (OrderSlice == CurPhCon->USER)) { + fprintf(stdout,"The connectors ( %s ) and ( %s ) have a same order\n", CurPhCon->NAME, Name); + exit(1); + } + } + if (PrevPhCon == NULL ) { + ptNewPhCon->NEXT = LeadCaracConList; + LeadCaracConList = ptNewPhCon; + } + else { + ptNewPhCon->NEXT = CurPhCon; + PrevPhCon->NEXT = ptNewPhCon; + } + return(LeadCaracConList); +} + +/******************************************************************************/ +/* Function : MakePlaceConList() le 17 juillet 1993 */ +/******************************************************************************/ +PlaceConList *MakePlaceConList(Side, ConName, OrderSlice) +char Side; +char *ConName; +long OrderSlice; + +{ + + if (isvdd(ConName)) { + fprintf(stdout,"scr_warning : The power connector %s is placed automatically by scr.\n",ConName); + return(LeadPlaceConList); + } + else + if (isvss(ConName)) { + fprintf(stdout,"scr_warning : The ground connector %s is placed automatically by scr.\n",ConName); + return(LeadPlaceConList); + } + + if (LeadPlaceConList == NULL) { + LeadPlaceConList = (PlaceConList *) mbkalloc (sizeof(PlaceConList)); + LeadPlaceConList->NORTH_CON = NULL; + LeadPlaceConList->SOUTH_CON = NULL; + LeadPlaceConList->WEST_CON = NULL; + LeadPlaceConList->EAST_CON = NULL; + LeadPlaceConList->VER_FEED = 0; + LeadPlaceConList->HOR_FEED = 0; + } + if (Side == 'N') + LeadPlaceConList->NORTH_CON = MakeCaracConList(LeadPlaceConList->NORTH_CON,ConName,OrderSlice); + else + if (Side == 'S') + LeadPlaceConList->SOUTH_CON = MakeCaracConList(LeadPlaceConList->SOUTH_CON,ConName,OrderSlice); + else + if (Side == 'W') + LeadPlaceConList->WEST_CON = MakeCaracConList(LeadPlaceConList->WEST_CON,ConName,OrderSlice); + else + if (Side == 'E') + LeadPlaceConList->EAST_CON = MakeCaracConList(LeadPlaceConList->EAST_CON,ConName,OrderSlice); + return(LeadPlaceConList); +} +/******************************************************************************/ diff --git a/alliance/src/scr/src/scr_lexer.l b/alliance/src/scr/src/scr_lexer.l new file mode 100644 index 00000000..e7f7ebf9 --- /dev/null +++ b/alliance/src/scr/src/scr_lexer.l @@ -0,0 +1,40 @@ +%{ +#include +#include "scr_grammar.h" +#include +extern int tpllineno ; +%} + +%% +[Pp][Ll][Aa][Cc][Ee]_[Pp][Hh][Cc][Oo][Nn]_[Nn][Oo][Rr][Tt][Hh] { + return (M_PLACE_PHCON_NORTH);} +[Pp][Ll][Aa][Cc][Ee]_[Pp][Hh][Cc][Oo][Nn]_[Ss][Oo][Uu][Tt][Hh] { + return (M_PLACE_PHCON_SOUTH);} +[Pp][Ll][Aa][Cc][Ee]_[Pp][Hh][Cc][Oo][Nn]_[Ww][Ee][Ss][Tt] { + return (M_PLACE_PHCON_WEST);} +[Pp][Ll][Aa][Cc][Ee]_[Pp][Hh][Cc][Oo][Nn]_[Ee][Aa][Ss][Tt] { + return (M_PLACE_PHCON_EAST);} +[Vv][Ee][Rr]_[Ff][Ee][Ee][Dd]_[Tt][Hh][Rr][Oo][Uu][Gg][Hh] { + return (M_VER_FEED_THROUGH);} +[Hh][Oo][Rr]_[Ff][Ee][Ee][Dd]_[Tt][Hh][Rr][Oo][Uu][Gg][Hh] { + return (M_HOR_FEED_THROUGH);} +[0-9\-]+ { + sscanf(yytext,"%d",&(yylval.valu)); + return(Number); + } + +[a-zA-Z][a-zA-Z0-9\._]* { + yylval.text = namealloc (yytext); + return(Identifier); + } +\[ { return(Lcro); } +\] { return(Rcro); } +\( { return(Lparen); } +\) { return(Rparen); } +\, { return (Coma); } +\; { return (Semicolon); } +: { return (Colon); } +[ \t] ; +\n {tpllineno++;} +#.*$ ; +%%