ring is back ...

This commit is contained in:
Christophe Alexandre 2002-03-13 19:23:37 +00:00
parent 42e4d454b1
commit 7f7488bbb2
39 changed files with 13134 additions and 0 deletions

View File

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

View File

@ -0,0 +1,52 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/ring2.c)
RING_MAJOR_VERSION=3
RING_MINOR_VERSION=0
RING_VERSION=$RING_MAJOR_VERSION.$RING_MINOR_VERSION
AC_SUBST(RING_MAJOR_VERSION)
AC_SUBST(RING_MINOR_VERSION)
AC_SUBST(RING_VERSION)
# libtool versioning
LT_RELEASE=$RING_MAJOR_VERSION.$RING_MINOR_VERSION
AC_SUBST(LT_RELEASE)
# For automake.
VERSION=$RING_VERSION
PACKAGE=ring
dnl Initialize automake stuff
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
dnl Specify a configuration file
dnl AM_CONFIG_HEADER(config.h)
dnl Initialize libtool
AM_PROG_LIBTOOL
dnl Checks for programs.
AC_PROG_CC
AM_PROG_LEX
AC_PROG_YACC
AC_PROG_MAKE_SET
changequote(,)dnl
INCLUDES=-I${ALLIANCE_TOP}/include
LDFLAGS=-L${ALLIANCE_TOP}/lib
changequote([,])dnl
AC_SUBST(INCLUDES)
AC_SUBST(LDFLAGS)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
dnl Checks for library functions.
AC_OUTPUT([
Makefile
doc/Makefile
src/Makefile
])

View File

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

View File

@ -0,0 +1,348 @@
.\" $Id: ring.1,v 1.1 2002/03/13 19:23:26 xtof Exp $
.\" @(#)Labo.l 0.0 90/22/08 UPMC;
.TH RING 1 "October 1, 1997" "ASIM/LIP6" "ALLIANCE USER COMMANDS"
.SH NAME
RING \- PAD RING router
.SH SYNOPSIS
RING \fIsource\fP \fIresult\fP \fB[ stat ]\fP
.so man1/alc_origin.1
.SH DESCRIPTION
.IR source
defines two input files:
.RS
\-\- the file describing the input netlist (MBK_IN_LO(1) format).
.br
.RS
example: source.al
.br
.LP
.RE
\-\- the parameter file: source.rin
.br
This file consists in 5 sections: 4 for the pad placement on circuit
sides, one to define the power sypply width (in lambda units).
.LP
.br
.TP 10
example:
.RS
.IR east
() # none pad at east side.
.br
.IR north
(
.br
p_pck p_i0 p_i1
.br
p_i3)
.br
.IR south
(p_vssb p_vddb p_i2)
.br
.IR width
(vss 50 vdd 80)
.br
.RE
.LP
Separators (spaces, tabulations and new line) are allowed between instance names.
.LP
.br
\-\- east(), north(), south(), west() define the relative pad order.
They use the pad instance names.
.LP
.br
For the north() and south() sections, the instance name declaration
are from the
.IR left
(first pad) to the
.IR right
(last pad).
.LP
.br
For the east() and west() sections, the instance name declaration
are from the
.IR bottom
(first pad) to the
.IR top
(last pad).
.LP
.br
Any section may be missing. It means so the revalive side has no pad,
however at least one side must has one pad.
.LP
.br
\-\- the width() section is optional and describes the
power (vdd), and ground (vss) track width.
.LP
.br
.RE
.IR \fIresult\fP
defines the output filename.
.LP
.br
.RS
This file contains the layout of the routed circuit (MBK_OUT_PH(1) format).
.br
.RS
example: result.ap
.LP
.RE
.br
RING uses a pad library whose path directory is defined with the
MBK_CATA_LIB(1) environment variable.
It also uses a catalog filename which is defined with the MBK_CATAL_NAME(1)
environment variable.
.br
The catalog must contain all the pad model names used in the
circuit. The core model-name must not be present in the catalog.
.br
.LP
Part of catalog file:
.RS
.br
a2_y C
.br
high_y C
.br
pck_sp C
.br
piot_sp C
.br
pvssick_sp C
.br
\.\.\.\.
.br
pvdde_sp C
.br
pvddi_sp C
.br
.LP
.RE
.br
.RE
.IR [stat]
(optional parameter) defines another output file:
.br
.LP
.RS
.br
\-\- the statistic file: result.stat
.br
.LP
It contains data about length (lambdas) and area (lambdas * lambdas) in ALU1 and ALU2, for each
equipotential. It describes how many vias were placed.
.br
.LP
.RS
example: *** STATISTIC FILE < result.stat > ***
.br
.LP
.RE
Equipotential list :
.br
.LP
.nf
.if t \{\
.ft CR \}
index| name |lgth A1|lgth A2|area A1|area A2| nb vias
.br
_________________________________________________________
.br
60 | vss | 9034 | 4408 | 614288| 454024| 1128
.br
_________________________________________________________
.br
59 | vdd | 7494 | 3968 | 574248| 408704| 1128
.br
_________________________________________________________
.br
54 | b2_coeur | 2253 | 1899 | 2253| 3798| 4
_________________________________________________________
.br
Total length alu1 : 18781 (lambdas)
.br
Total length alu2 : 10275 (lambdas)
.br
Total area alu1 : 1190789 (lambdas * lambdas)
.br
Total area alu2 : 866526 (lambdas * lambdas)
.br
Total of vias : 2260
.br
.ft R
.fi
.LP
.RE
.br
.LP
.SH ENVIRONMENT VARIABLES
.LP
.br
\fBMBK_IN_LO(1)\fP defines the input file format for the netlist.
.br
\fBMBK_IN_PH(1)\fP defines the input file format for the layout.
.br
\fBMBK_OUT_PH(1)\fP defines the output file format for the layout.
.br
\fBMBK_CATAL_NAME(1)\fP defines the catalog filename.
.br
\fBMBK_CATA_LIB(1)\fP defines the library pad cells directory.
.br
\fBMBK_WORK_LIB(1)\fP defines the work directory.
.br
.LP
.SH USAGE
.LP
.br
RING performs the physical routing between core of
circuit and pad ring.
RING is not a floor plan router and allows only one core.
.LP
.br
A core is designed, for example, with the standard
cells router SCR, which places the input and output connectors on
the abutment box. The physical core connectors must be
separated by more than one pitch in any metal (in ALU1 or ALU2).
.LP
.br
Netlist and layout views relative to the same figure must have
the same name. For example, the netlist core name and the routed core name.
.LP
.br
RING performs an automatic placement of the pad ring
and core. It is not necessary to place pads, but only
to describe their relative position on each side, in the parameter file
(source.rin).
.LP
.br
Distance between the first track and any instance (pad or core) is the pitch
so 5 lambdas.
.FF
.br
.SH EXAMPLE
.LP
.br
Let chip.al be the circuit netlist and core.ap the routed core.
80 lambdas for supply track width and the pad placement are described as follows.
.LP
.RE
.br
.br
.TP 10
.IR chip.rin:
.LP
.RS
# This is a comment: 1 comment per line
.br
north(p_a1 p_a2 p_a3 p_a4)
.br
south(
.br
p_i1 #another comment: the rest of the line
.br
p_i2
.br
p_i3
.br
p_i4)
.br
east(p_b4 p_b3 p_b2 p_b1)
.br
west(p_f1 p_f2 p_f3 p_f4)
.br
width(
.br
vdd 80
.br
vss 80
.br
)
.br
.TP 10
We want a ring of pads as follow:
.LP
.br
.RS
.nf
.if t \{\
.ft CR \}
+-------------------------------------------------+
.br
| |p_a1|p_a2|p_a3|p_a4| |
.br
|----+---------------------------------------+----|
.br
|p_f4| |p_b1|
.br
|----| +-------+ |----|
.br
|p_f3| | | |p_b2|
.br
|----| | CORE | |----|
.br
|p_f2| | | |p_b3|
.br
|----| +-------+ |----|
.br
|p_f1| |p_b4|
.br
|----+---------------------------------------+----|
.br
| |p_i1|p_i2|p_i3|p_i4| |
.br
+-------------------------------------------------+
.ft R
.fi
.LP
.RE
.br
.br
In order to obtain the routed circuit (chipr.ap):
.LP
.br
>
.IR ring
.IR chip
.IR chipr
.LP
.br
.SH "SEE ALSO"
genlib(1)
lvx(1)
ocp(1)
ocr(1)
druc(1)
.SH DIAGNOSTICS
Physical core must have at least one physical connector by side,
otherwise it can't place pads correctly, and maybe dump a core file.
.LP
.br
Whenever lots of core connectors (bus) are placed close ones from each others,
RING may have problems to connect pad connectors placed just in front of them.
In such a case, it is recommended to not have pad connectors at that place and
thus to place an instance pad without connector (as pvdde_sp)
or to cut the bus into several parts to let space between connectors.
.LP
.br
When core connectors are to close from corners, RING sometimes connects those
one to supply rings, to solve this bug, move core connectors or change pad
placement. In any case, use \fBdruc(1)\fP or \fBlvx(1)\fP to detect problem.
.br
.LP
Supply vdd and vss pads (resp. pvddi_sp and pvssi_sp)
must be placed as close as possible of the core side middle
(i.e. not in the corners).
Otherwise, RING cannot link supply pad connector to ring supplies and
exits with a error message.
.br
.LP
Supply tracks from pads and core are connected at the supply ring.
There is sometimes few problems when core and pad tracks are opposite.
Move pads usually corrects problem.
.br
.LP
.so man1/alc_bug_report.1

View File

@ -0,0 +1,41 @@
## Process this file with automake to produce Makefile.in
YACC = @YACC@ -d
bin_PROGRAMS = ring
ring_LDADD = @LIBS@ \
-lMpu -lMlu \
-lMcl -lMcp \
-lMal -lMap \
-lMsl \
-lMel -lMgl \
-lMhl \
-lMvl \
-lMgn \
-lMmg \
-lMlo \
-lMph -lMut \
-lRcn
ring_SOURCES = bigvia.c bigvia.h \
compress.c compress.h \
deport.c deport.h \
distance.c distance.h \
ringram.y rinscan.l \
lireplace.c \
lireplace.h lirevues.c \
lirevues.h \
param.c \
param.h placement.c \
placement.h posercircuit.c \
posercircuit.h ring2.c \
routage.c routage.h \
routalim.c routalim.h \
sesame.c sesame.h \
stat.c stat.h \
struct2.c struct.c \
struct.h \
barre.c barre.h
CLEANFILES = ringram.c ringram.h rinscan.c

View File

@ -0,0 +1,271 @@
/*
* 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 : ring router */
/* Fichier : barre.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*-----------------------------------------------------------------------------------*/
/* RING 26 mai 92 */
/* Fichier BARRE.C */
/* Fichier utilise pour construire les barres de plots avec genlib */
/* Interdiction d'utiliser les super structures de mbk ou autres car genlib */
/* generateur de macro. Type de donnees autorises long et char* exclusivement */
/*-----------------------------------------------------------------------------------*/
#include <stdio.h>
#include <genlib.h>
#include "barre.h"
extern char mode_debug;
/*-----------------------------------------------------------------------------------*/
/* cette fonction ajoute un transforme un nom de signal vectorise mbk */
/* avec des espaces en nom de signal GENLIB avec des crochets [ ] */
/*-----------------------------------------------------------------------------------*/
static char *busname(name)
char *name;
{
static char buffer[255];
char *s, *t;
char one = 1;
if (!name)
return NULL;
s = name;
t = buffer;
while (*s) {
if (*s == ' ')
{
if (one) {
*t++ = '[';
s++;
one = 0;
} else {
*t++ = ']';
*t++ = '[';
s++;
}
}
if (*s == '_' && !one) { /* was SEPAR and not / */
*t++ = ']';
one = 1;
}
*t++ = *s++;
}
if (!one)
*t++ = ']';
*t = '\0';
return buffer;
}
/*-----------------------------------------------------------------------------------*/
void definir_fig_ph(char *nomfig)
{
if (mode_debug)
printf("defphfig %s\n", nomfig);
GENLIB_DEF_PHFIG(nomfig);
}
/*-----------------------------------------------------------------------------------*/
/* Attention utiliser definir_reference_inst() avant d'utiliser cette fonction */
/*-----------------------------------------------------------------------------------*/
void abouteright_plot_fig(char *nomfig, char *nominst)
{
if (mode_debug)
printf("abouteright_plot_fig %s inst %s\n", nomfig, nominst);
GENLIB_PLACE_RIGHT(nomfig, nominst, NOSYM);
}
/*-----------------------------------------------------------------------------------*/
/* Attention utiliser definir_reference_inst() avant d'utiliser cette fonction */
/*-----------------------------------------------------------------------------------*/
void abouteleft_plot_fig(char *nomfig, char *nominst)
{
if (mode_debug)
printf("abouteleft_plot_fig %s inst %s\n", nomfig, nominst);
GENLIB_PLACE_LEFT(nomfig, nominst, NOSYM);
}
/*-----------------------------------------------------------------------------------*/
void definir_reference_inst(char *name)
{
if (mode_debug)
printf("definir reference instance %s\n", name);
GENLIB_DEF_PHINS(name);
}
/*-----------------------------------------------------------------------------------*/
void definir_ab_fig()
{
if (mode_debug)
printf("def ab 0000\n");
GENLIB_DEF_AB(0L, 0L, 0L, 0L);
}
void definir_ab_fig2()
{
if (mode_debug)
printf("def ab2\n");
GENLIB_DEF_AB(-100L, -100L, 100L, 100L);
}
/*-----------------------------------------------------------------------------------*/
void sauver_fig_ph()
{
if (mode_debug)
printf("sauve phfig\n");
GENLIB_SAVE_PHFIG();
}
/*-----------------------------------------------------------------------------------*/
void remonter_consud_instph(char *nominst)
{
if (mode_debug)
printf("Remonte con sud de l'inst %s\n", nominst);
GENLIB_COPY_UP_ALL_CON(SOUTH, nominst, YES);
}
/*-----------------------------------------------------------------------------------*/
void remonter_connord_instph(char *nominst)
{
if (mode_debug)
printf("Remonte con nord de l'inst %s\n", nominst);
GENLIB_COPY_UP_ALL_CON(NORTH, nominst, YES);
}
/*-----------------------------------------------------------------------------------*/
void placer_instph(char *nomfig, char *nominst, char symetrie,
long x, long y)
{
if (mode_debug)
printf("placer instance nomfig %s inst %s symetrie %c x %ld y %ld\n", nomfig, nominst, symetrie, x, y);
GENLIB_PLACE(nomfig, nominst, symetrie, x, y);
}
/*-----------------------------------------------------------------------------------*/
void placer_segph(char layer, long width, char *nameseg,
long x1, long y1, long x2, long y2)
{
if (mode_debug)
{
if (nameseg)
printf("placer segment layer %d width %ld name %s x1 %ld y1 %ld x2 %ld y2 %ld\n", (int)layer, width, nameseg,
x1, y1, x2, y2);
else
printf("placer segment layer %d width %ld x1 %ld y1 %ld x2 %ld y2 %ld\n", (int)layer, width,
x1, y1, x2, y2);
}
GENLIB_PHSEG(layer, width, busname(nameseg), x1, y1, x2, y2);
}
/*----------------------------------------------------------------------------------*/
void miseaplat_instph(char *insname, char cheminom)
{
if (mode_debug)
printf("mise a plat de l'instance %s et cheminon %d\n", insname, (int)cheminom);
GENLIB_FLATTEN_PHFIG(insname, cheminom);
}
/*----------------------------------------------------------------------------------*/
void remonter_uncon_instph(long index, char *locname, char *insname, char *newname)
{
if (mode_debug)
printf("remontee du con %s index %ld de l'instance %s et newname %s\n", locname, index, insname, newname);
locname = namealloc( busname(locname));
newname = namealloc( busname(newname));
GENLIB_COPY_UP_CON(index, locname, insname, newname);
}
/*----------------------------------------------------------------------------*/
void poser_wire1(char layer, long width, char* ins1, char *con1,
long index1, char* ins2, char* con2,long index2)
{
if (mode_debug)
printf("wire1 layer %d width %ld ins1 %s con1 %s index1 %ld ins2 %s con2 %s index2 %ld\n", (int) layer, width,
ins1, con1, index1, ins2, con2, index2);
GENLIB_WIRE1(layer, width, ins1, con1, index1, ins2, con2, index2);
}
/*--------------------------------------------------------------------------------------*/
void poser_wire2(char layer, long width, char* ins1, char* con1,
long index1, char* ins2, char* con2, long index2, long x, long y)
{
if (mode_debug)
printf("wire2 layer %d width %ld ins1 %s con1 %s index1 %ld ins2 %s con2 %s index2 %ld x %ld y %ld\n", (int) layer,
width, ins1, con1, index1, ins2, con2, index2, x, y);
GENLIB_WIRE2(layer, width, ins1, con1, index1, ins2, con2, index2, x, y);
}

View File

@ -0,0 +1,27 @@
#ifndef __BARRE_H
#define __BARRE_H
#include "struct.h"
extern void definir_fig_ph(char *nomfig);
extern void abouteright_plot_fig(char *nomfig, char *nominst);
extern void abouteleft_plot_fig(char *nomfig, char *nominst);
extern void definir_reference_inst(char *name);
extern void definir_ab_fig();
extern void definir_ab_fig2();
extern void sauver_fig_ph();
extern void remonter_consud_instph(char *nominst);
extern void remonter_connord_instph(char *nominst);
extern void placer_instph(char *nomfig, char *nominst, char symetrie,
long x, long y);
extern void placer_segph(char layer, long width, char *nameseg,
long x1, long y1, long x2, long y2);
extern void miseaplat_instph(char *insname, char cheminom);
extern void remonter_uncon_instph(long index, char *locname, char *insname, char *newname);
extern void poser_wire1(char layer, long width, char* ins1, char *con1,
long index1, char* ins2, char* con2,long index2);
extern void poser_wire2(char layer, long width, char* ins1, char* con1,
long index1, char* ins2, char* con2, long index2, long x, long y);
#endif /* __BARRE_H */

View File

@ -0,0 +1,169 @@
/*
* 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 : ring router */
/* Fichier : bigvia.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Fred le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
#include "bigvia.h"
/*-----------------------------------------------------------------------------*/
/* #define BV_VIA_VIA 4 must be even, whatever! */
/* #define BV_VIASIZE 3 design rule for equipotential vias */
/* */
/* this creates a mega-via, the best way we can do it, I hope */
/* the envelop of the bigvia is calculated, and then its center is placed */
/* as close as possible of the x, y coordinates given as arguments. */
/*-----------------------------------------------------------------------------*/
void
bigvia_ring(char l1, char l2, phfig_list* f, long x, long y, long dx, long dy)
{
int i, j;
long stepx, stepy, xv, yv, dxv, dyv;
if (((l1==ALU1)&&(l2==ALU2))
|| ((l2==ALU1)&&(l1==ALU2))) {
addphvia(f, CONT_VIA, x, y, dx, dy, (char *)NULL);
} else
if (((l1==ALU2)&&(l2==ALU3))
|| ((l2==ALU2)&&(l1==ALU3))) {
addphvia(f, CONT_VIA2, x, y, dx, dy, (char *)NULL);
} else {
fflush(stdout);
fprintf(stderr, "*** mbk error ***\n bigvia impossible :");
EXIT(1);
}
return;
if (dx < 0 || dy < 0) {
fflush(stdout);
fprintf(stderr, "*** mbk error ***\n bigvia impossible :");
fprintf(stderr, " negative values dx = %ld, dy = %ld\n", dx, dy);
fprintf(stderr, "in figure '%s' at (%ld, %ld)\n", f->NAME, x, y);
EXIT(1);
}
/* -------------------------------------------------------------------- */
/* euclidian division : */
/* dividing and then multipliing doesen't give the initial value. */
/* calculate the center of the bunch of vias and adjust it to the given */
/* x, y coordinates. */
/* -------------------------------------------------------------------- */
stepx = (dx - BV_VIASIZE * SCALE_X) / (BV_VIA_VIA * SCALE_X);
stepy = (dy - BV_VIASIZE * SCALE_X) / (BV_VIA_VIA * SCALE_X);
dxv = stepx * BV_VIA_VIA * SCALE_X;
dyv = stepy * BV_VIA_VIA * SCALE_X;
xv = x - dxv / 2;
yv = y - dyv / 2;
/* ------------- */
/* draw the vias */
/* ------------- */
for (i = 0; i <= stepx; i++)
for (j = 0; j <= stepy; j++) {
bigvias++;
if (mode_debug) {
/* ------------------------------------------------------------ */
/* new rules for disk space : just a ring of via for big pates. */
/* ------------------------------------------------------------ */
if (i == 0 || i == stepx || j == 0 || j == stepy) {
if (((l1==ALU1)&&(l2==ALU2))
|| ((l2==ALU1)&&(l1==ALU2))) {
addphvia(f, CONT_VIA,
xv + i * BV_VIA_VIA * SCALE_X, yv + j * BV_VIA_VIA * SCALE_X,0,0, NULL);
} else
if (((l1==ALU2)&&(l2==ALU3))
|| ((l2==ALU2)&&(l1==ALU3))) {
addphvia(f, CONT_VIA2,
xv + i * BV_VIA_VIA * SCALE_X, yv + j * BV_VIA_VIA * SCALE_X,0,0, NULL);
}
ringvias++;
}
} /* fin du if mode_debug */ else { /* pave complet de vias ! */
if (i == 0 || i == stepx || j == 0 || j == stepy)
ringvias++;
if (((l1==ALU1)&&(l2==ALU2))
|| ((l2==ALU1)&&(l1==ALU2))) {
addphvia(f, CONT_VIA,
xv + i * BV_VIA_VIA * SCALE_X, yv + j * BV_VIA_VIA * SCALE_X,0,0, NULL);
} else
if (((l1==ALU2)&&(l2==ALU3))
|| ((l2==ALU2)&&(l1==ALU3))) {
addphvia(f, CONT_VIA2,
xv + i * BV_VIA_VIA * SCALE_X, yv + j * BV_VIA_VIA * SCALE_X,0,0, NULL);
}
}
}
/* ----------------------------------------------------------------------------------------- */
/* put segments around the vias : this warranties that no notches may appear on the borders. */
/* ----------------------------------------------------------------------------------------- */
if (stepx)
addphseg(f, l1, BV_VIASIZE * SCALE_X, xv, yv, xv + stepx * BV_VIA_VIA * SCALE_X, yv, NULL);
if (stepx || stepy)
addphseg(f, l1, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv, xv + stepx * BV_VIA_VIA *
SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
if (stepx || stepy)
addphseg(f, l1, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X,
xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
if (stepy)
addphseg(f, l1, BV_VIASIZE * SCALE_X, xv, yv, xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
if (stepx)
addphseg(f, l2, BV_VIASIZE * SCALE_X, xv, yv, xv + stepx * BV_VIA_VIA * SCALE_X, yv, NULL);
if (stepx || stepy)
addphseg(f, l2, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv, xv + stepx * BV_VIA_VIA *
SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
if (stepx || stepy)
addphseg(f, l2, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X,
xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
if (stepy)
addphseg(f, l2, BV_VIASIZE * SCALE_X, xv, yv, xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
/* ----------------------------------------------------------------------------------------------------------------------------- */
/* fill the leftover space : we use computed via coordinates, and substract one in order not to take care of even or odd values. */
/* ----------------------------------------------------------------------------------------------------------------------------- */
if (dxv && dyv)
addphseg(f, l2, dyv - 1 * SCALE_X, xv, yv + dyv / 2, xv + dxv, yv + dyv / 2, NULL);
if (dxv && dyv)
addphseg(f, l1, dyv - 1 * SCALE_X, xv, yv + dyv / 2, xv + dxv, yv + dyv / 2, NULL);
}

View File

@ -0,0 +1,10 @@
#ifndef __BIGVIA_H
#define __BIGVIA_H
#include <mut.h>
#include <mph.h>
#include "struct.h"
extern void bigvia_ring(char l1, char l2, phfig_list* f, long x, long y, long dx, long dy);
#endif /* __BIGVIA_H */

View File

@ -0,0 +1,367 @@
/*
* 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 : ring router */
/* Fichier : compress.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*-----------------------------------------------------------------------------------*/
/* RING 24 juillet 92 COMPRESS.C */
/* compression des canaux libres + mise a jour des coordonnees de tous les segments */
/*-----------------------------------------------------------------------------------*/
#include "compress.h"
#include <stdio.h>
/*----------------------------------------------------------------------------------*/
/* cette procedure retourne la 1ere et la derniere instance du mode physique */
/* selon la face */
/*----------------------------------------------------------------------------------*/
void firstlastinst_barre(phfig_list *barre, phins_list **firstinst, phins_list **lastinst)
{
phins_list * lst = barre->PHINS;
long min, max;
max = min = lst->XINS;
*firstinst = *lastinst = lst;
lst = lst->NEXT;
while (NULL != lst) {
if (lst->XINS < min) {
min = lst->XINS;
*firstinst = lst;
}
if (lst->XINS > max) {
max = lst->XINS;
*lastinst = lst;
}
lst = lst->NEXT;
}
if (mode_debug)
printf("firstinst %s x %ld lastinst %s x %ld\n", (*firstinst)->INSNAME, (*firstinst)->XINS, (*lastinst)->INSNAME,
(*lastinst)->XINS);
}
/*------------------------------------------------------------------------------------*/
/* Cette procedure calcul le nombre de pistes libres pour chaque canal de chaque face */
/* et range dans: */
/* - nblibres: le nombre total de piste libres entre la derniere piste occupee par */
/* le routage et les pistes d'alim. */
/* - firstlibre: le numero de la 1ere piste libre dans la face concernee */
/*------------------------------------------------------------------------------------*/
void calcul_nbpiste_libre(BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long nblibres[NB_FACES], long firstlibre[NB_FACES])
{
PT_COORDONNEES debut, fin;
long piste, pistelibre, maxpiste = 0;
char niveaupiste = 0;
LST_SEGMENT * segpiste = NULL;
int face;
alloue_coord(0L, 0, &debut);
alloue_coord(0L, 0, &fin);
debut->xabs = lecoeur.coord.xabs - 10;
debut->yabs = lecoeur.coord.yabs - 10;
fin->xabs = lecoeur.coord.xabs + lecoeur.width + 10;
fin->yabs = lecoeur.coord.yabs + lecoeur.height + 10;
for (face = 0; face < NB_FACES; face++)
if ((0 != tab_plots[face].width) && (tab_plots[face].coord.piste > maxpiste))
maxpiste = tab_plots[face].coord.piste;
for (face = 0; face < NB_FACES; face++) {
firstlibre[face] = maxpiste;
nblibres[face] = 0;
}
for (face = 0; face < NB_FACES; face++) {
switch (face) {
case NORD:
case SUD:
segpiste = segx_occ;
niveaupiste = xmetal;
break;
case EST:
case OUEST:
segpiste = segy_occ;
niveaupiste = ymetal;
break;
}
for (piste = 2; piste < maxpiste; piste++)
if (segment_libre(debut, fin, piste, piste, face, SEG_PISTE, segpiste, niveaupiste)) {
firstlibre[face] = piste;
for (pistelibre = piste; pistelibre < maxpiste; pistelibre++)
if (!segment_libre(debut, fin, pistelibre, pistelibre, face, SEG_PISTE, segpiste,
niveaupiste)) {
nblibres[face] = pistelibre - piste;
break;
}
if (mode_debug)
printf("face %d firstpistelibre %ld nbpistelibres %ld\n", (int)face, firstlibre[face],
nblibres[face]);
break;
}
}
}
/*--------------------------------------------------------------------------------*/
/* Compression du canal de chaque face en prenant la contrainte la plus forte: */
/* - le nombre minimum de pistes libres entre le nb total de pistes libres et */
/* la difference de pistes entre 2 barres de plots mitoyennes. */
/* - les coordonnees sont mises a jour, et un champ compress marque la compression*/
/* deja effectuee. */
/*--------------------------------------------------------------------------------*/
void compression_canaux(BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long nblibres[NB_FACES], long firstlibre[NB_FACES])
{
long nblibresenv[NB_FACES];
long nblibresfin[NB_FACES];
long diff1, diff2;
LST_SEGMENT lstsegx, lstsegy;
int face;
for (face = 0; face < NB_FACES; face++) {
diff1 = diff2 = nblibresenv[face] = nblibres[face];
if (0 != tab_plots[face].width)
switch (face) {
case NORD:
if (mode_debug)
printf("nord");
if (0 != tab_plots[EST].width)
diff1 = ((lecoeur.coord.yabs + lecoeur.height + tab_plots[NORD].coord.piste * pitch)
-(tab_plots[EST].coord.yabs + tab_plots[EST].width)) / pitch;
if (0 != tab_plots[OUEST].width)
diff2 = ((lecoeur.coord.yabs + lecoeur.height + tab_plots[NORD].coord.piste * pitch)
-(tab_plots[OUEST].coord.yabs + tab_plots[OUEST].width)) / pitch;
if (diff1 < diff2)
nblibresenv[NORD] = diff1;
else
nblibresenv[NORD] = diff2;
break;
case SUD:
if (mode_debug)
printf("sud");
if (0 != tab_plots[EST].width)
diff1 = ( -(lecoeur.coord.yabs - tab_plots[SUD].coord.piste * pitch) + (tab_plots[EST].coord.yabs))
/ pitch;
if (0 != tab_plots[OUEST].width)
diff2 = ( -(lecoeur.coord.yabs - tab_plots[SUD].coord.piste * pitch) + (tab_plots[OUEST].coord.yabs))
/ pitch;
if (diff1 < diff2)
nblibresenv[SUD] = diff1;
else
nblibresenv[SUD] = diff2;
break;
case EST:
if (mode_debug)
printf("est");
if (0 != tab_plots[NORD].width)
diff1 = ((lecoeur.coord.xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch) -
(tab_plots[NORD].coord.xabs + tab_plots[NORD].width)) / pitch;
if (0 != tab_plots[SUD].width)
diff2 = ((lecoeur.coord.xabs + lecoeur.width + tab_plots[EST].coord.piste * pitch) -
(tab_plots[SUD].coord.xabs + tab_plots[SUD].width)) / pitch;
if (diff1 < diff2)
nblibresenv[EST] = diff1;
else
nblibresenv[EST] = diff2;
break;
case OUEST:
if (mode_debug)
printf("ouest");
if (0 != tab_plots[NORD].width)
diff1 = (-(lecoeur.coord.xabs - tab_plots[OUEST].coord.piste * pitch ) + (tab_plots[NORD].coord.xabs))
/ pitch;
if (0 != tab_plots[SUD].width)
diff2 = (-(lecoeur.coord.xabs - tab_plots[OUEST].coord.piste * pitch ) + (tab_plots[SUD].coord.xabs))
/ pitch;
if (diff1 < diff2)
nblibresenv[OUEST] = diff1;
else
nblibresenv[OUEST] = diff2;
break;
}
/* ------------------------------------------------------ */
/* on prend la contrainte la plus forte donc le min des 2 */
/* ------------------------------------------------------ */
if (nblibres[face] < nblibresenv[face])
nblibresfin[face] = nblibres[face];
else
nblibresfin[face] = nblibresenv[face];
if (mode_debug)
printf("nblibresenv face %d nb %ld nblibresfin %ld\n", (int)face, nblibresenv[face], nblibresfin[face]);
}
/* --------------------------------------------------------- */
/* compression des canaux avec la liste des segments occupes */
/* --------------------------------------------------------- */
for (face = 0; face < NB_FACES; face++) {
lstsegx = segx_occ[face];
lstsegy = segy_occ[face];
/* --------------------------------- */
/* rapprochement des barres de plots */
/* --------------------------------- */
tab_plots[face].coord.piste -= nblibresfin[face];
/* ------------------------------- */
/* parcours des listes de segments */
/* ------------------------------- */
if (mode_debug)
printf("compression face %d des segx\n", (int)face);
while (NULL != lstsegx) {
switch (face) {
case NORD:
case SUD:
if ((lstsegx->piste1 > firstlibre[face]) && (lstsegx->piste2 > firstlibre[face])) {
if ((lstsegx->c1->xabs < lecoeur.coord.xabs) && (SANS_COMPRESS == lstsegx->c1->compress) &&
(NULL == lstsegx->c1->proprio)) {
lstsegx->c1->xabs += nblibresfin[OUEST] * pitch;
lstsegx->c1->compress = AVEC_COMPRESS;
}
if ((lstsegx->c2->xabs > (lecoeur.coord.xabs + lecoeur.width)) && (SANS_COMPRESS ==
lstsegx->c2->compress) && (NULL == lstsegx->c2->proprio)) {
lstsegx->c2->xabs -= nblibresfin[EST] * pitch;
lstsegx->c2->compress = AVEC_COMPRESS;
}
}
break;
case EST:
case OUEST:
if ((lstsegx->piste1 > firstlibre[face]) && (lstsegx->piste2 > firstlibre[face])) {
if ((lstsegx->c1->yabs < lecoeur.coord.yabs) && (SANS_COMPRESS == lstsegx->c1->compress) &&
(NULL == lstsegx->c1->proprio)) {
lstsegx->c1->yabs += nblibresfin[SUD] * pitch;
lstsegx->c1->compress = AVEC_COMPRESS;
}
if ((lstsegx->c2->yabs > (lecoeur.coord.yabs + lecoeur.height)) && (SANS_COMPRESS ==
lstsegx->c2->compress) && (NULL == lstsegx->c2->proprio)) {
lstsegx->c2->yabs -= nblibresfin[NORD] * pitch;
lstsegx->c2->compress = AVEC_COMPRESS;
}
}
break;
}
if (lstsegx->piste1 > firstlibre[face])
lstsegx->piste1 -= nblibresfin[face];
if (lstsegx->piste2 > firstlibre[face])
lstsegx->piste2 -= nblibresfin[face];
lstsegx = lstsegx->suiv;
}
if (mode_debug)
printf("compression face %d des segy\n", (int)face);
while (NULL != lstsegy) {
switch (face) {
case NORD:
case SUD:
if ((lstsegy->piste1 > firstlibre[face]) && (lstsegy->piste2 > firstlibre[face])) {
if ((lstsegy->c1->xabs < lecoeur.coord.xabs) && (SANS_COMPRESS == lstsegy->c1->compress) &&
(NULL == lstsegy->c1->proprio)) {
lstsegy->c1->xabs += nblibresfin[OUEST] * pitch;
lstsegy->c1->compress = AVEC_COMPRESS;
}
if ((lstsegy->c2->xabs > (lecoeur.coord.xabs + lecoeur.width)) && (SANS_COMPRESS ==
lstsegy->c2->compress) && (NULL == lstsegy->c2->proprio)) {
lstsegy->c2->xabs -= nblibresfin[EST] * pitch;
lstsegy->c2->compress = AVEC_COMPRESS;
}
}
break;
case EST:
case OUEST:
if ((lstsegy->piste1 > firstlibre[face]) && (lstsegy->piste2 > firstlibre[face])) {
if ((lstsegy->c1->yabs < lecoeur.coord.yabs) && (SANS_COMPRESS == lstsegy->c1->compress) &&
(NULL == lstsegy->c1->proprio)) {
lstsegy->c1->yabs += nblibresfin[SUD] * pitch;
lstsegy->c1->compress = AVEC_COMPRESS;
}
if ((lstsegy->c2->yabs > (lecoeur.coord.yabs + lecoeur.height)) && (SANS_COMPRESS ==
lstsegy->c2->compress) && (NULL == lstsegy->c2->proprio)) {
lstsegy->c2->yabs -= nblibresfin[NORD] * pitch;
lstsegy->c2->compress = AVEC_COMPRESS;
}
}
break;
}
if (lstsegy->piste1 > firstlibre[face])
lstsegy->piste1 -= nblibresfin[face];
if (lstsegy->piste2 > firstlibre[face])
lstsegy->piste2 -= nblibresfin[face];
lstsegy = lstsegy->suiv;
}
} /* fin du for */
}

View File

@ -0,0 +1,18 @@
#ifndef __COMPRESS_H
#define __COMPRESS_H
#include <mut.h>
#include <mph.h>
#include "struct.h"
extern void firstlastinst_barre(phfig_list *barre, phins_list **firstinst, phins_list **lastinst);
extern void calcul_nbpiste_libre(BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long nblibres[NB_FACES], long firstlibre[NB_FACES]);
extern void compression_canaux(BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long nblibres[NB_FACES], long firstlibre[NB_FACES]);
#endif /* __COMPRESS_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
#ifndef __DEPORT_H
#define __DEPORT_H
#include "struct.h"
extern void attribuer_couronne_alim(LST_EQUIPO lst_equipo, char **coursup, char **courinf);
extern char* existe_unique_deport_alim(LST_EQUIPO equipo_vdd, LST_EQUIPO equipo_vss);
extern void deport_alim(LST_EQUIPO lst_equipo, BARRE_PLOTS tab_plots[NB_FACES],
char *coursup, char *courinf, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES]);
void deport_connecteurs(BARRE_PLOTS tab_plots[NB_FACES],
LST_PSEUDO_CON tab_coeur[NB_FACES],
COEUR lecoeur, GRILLE tab_grilles[NB_FACES]);
void pose_segdeport(BARRE_PLOTS tab_plots[NB_FACES],
LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur, LST_EQUIPO lst_equipo,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES]);
#endif /* __DEPORT_H */

View File

@ -0,0 +1,323 @@
/*
* 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 : ring router */
/* Fichier : distance.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*--------------------------------------------------------------------------*/
/* RING 19 aout 92 DISTANCE.C */
/*--------------------------------------------------------------------------*/
#include "distance.h"
#include <stdio.h>
#include <string.h>
/*-----------------------------------------------------------------------------------*/
/* Calcul de la distance entre deux connecteurs */
/* Si un des connecteurs n'est pas de largeur standard, on calcul la distance reelle.*/
/* A ce moment on prend en compte l'encombrement d'un via */
/* S'ils sont de largeur standard alors la distance est la diff des coordonnees */
/*-----------------------------------------------------------------------------------*/
long distance_con_con(long x1, long y1, long w1, char l1,
long x2, long y2, long w2, char l2, int face)
{
long dist, xa, ya, wa;
long largeurmin, dminmetalmetal;
char la;
switch (face) {
case NORD:
case SUD :
/* ------------------------------------------------- */
/* on garde dans x1 ,y1 les plus petites coordonnees */
/* ------------------------------------------------- */
if (x2 < x1) {
xa = x1;
ya = y1;
wa = w1;
la = l1;
x1 = x2;
y1 = y2;
w1 = w2;
l1 = l2;
x2 = xa;
y2 = ya;
w2 = wa;
l2 = la;
}
dminmetalmetal = ymetal_dmin;
if ((l1 != ymetal) || (l2 != ymetal)) {
if (ymetal_width < xmetal_width)
largeurmin = ymetal_width;
else
largeurmin = xmetal_width;
} else
{
largeurmin = ymetal_width;
}
if ((w1 > largeurmin) || (w2 > largeurmin)) {
dist = x2 - x1 - w2 / 2 - w1 / 2;
if ((w1 < taille_via) && (w2 < taille_via))
dist -= (taille_via - w1 / 2 - w2 / 2);
else if ((w1 < taille_via) && !(w2 < taille_via))
dist -= (taille_via / 2 - w1 / 2);
else if (!(w1 < taille_via) && (w2 < taille_via))
dist -= (taille_via / 2 - w2 / 2);
} else
dist = x2 - x1;
return(dist);
case EST :
case OUEST:
/* ------------------------------------------------- */
/* on garde dans x1 ,y1 les plus petites coordonnees */
/* ------------------------------------------------- */
if (y2 < y1) {
xa = x1;
ya = y1;
wa = w1;
la = l1;
x1 = x2;
y1 = y2;
w1 = w2;
l1 = l2;
x2 = xa;
y2 = ya;
w2 = wa;
l2 = la;
}
dminmetalmetal = xmetal_dmin;
if ((l1 != xmetal) || (l2 != xmetal)) {
if (ymetal_width < xmetal_width)
largeurmin = ymetal_width;
else
largeurmin = xmetal_width;
} else
{
largeurmin = xmetal_width;
}
if ((w1 > largeurmin) || (w2 > largeurmin)) {
dist = y2 - y1 - w2 / 2 - w1 / 2;
if ((w1 < taille_via) && (w2 < taille_via))
dist -= (taille_via - w1 / 2 - w2 / 2);
else if ((w1 < taille_via) && !(w2 < taille_via))
dist -= (taille_via / 2 - w1 / 2);
else if (!(w1 < taille_via) && (w2 < taille_via))
dist -= (taille_via / 2 - w2 / 2);
} else
dist = y2 - y1;
return(dist);
}
return 0;
}
/*-----------------------------------------------------------------------------------------*/
/* Cette fonction utilisee pour la fabrication de nouveaux pas de grille */
/* parcoure toutes les coordonnees precedentes correspondant a des pseudo-connecteurs */
/* pour donner la distance minimum qu'il existe entre le connecteur */
/* et les connecteurs precedents d'alim. Ceci pour corriger un bug */
/* qui vient du fait que des alim peuvent etre en vis a vis et que */
/* si on calcule seulement la distance avec le connecteur precedent */
/* on ne prend peut etre pas en compte un connecteur d'alim voisin */
/* plus gros qui recouvre largement le connecteur precedent. */
/* on retourne une coordonnee qui est soit la precedente soit */
/* une autre qui rcouvre la coordonne precedente */
/*-----------------------------------------------------------------------------------------*/
PT_COORDONNEES existe_con_precalim(long x2, long y2, long w2, char l2, int face,
PT_COORDONNEES liste_coor, long distance)
{
long mindist = distance;
long dist;
LST_PSEUDO_CON con;
PT_COORDONNEES coordalim = NULL;
if (mode_debug)
printf("Existeprecalim x %ld y %ld face %d ptcoor %d\n\n", x2, y2, face, (int)liste_coor);
switch (face) {
case NORD:
case SUD:
while (NULL != liste_coor) {
if ((NULL != liste_coor->proprio) && ((eq_vdd == ((LST_PSEUDO_CON)liste_coor->proprio)->nom_con) ||
(eq_vss == ((LST_PSEUDO_CON)liste_coor->proprio)->nom_con)) && (liste_coor->xabs < x2)) {
con = ((LST_PSEUDO_CON)liste_coor->proprio);
dist = distance_con_con(liste_coor->xabs, liste_coor->yabs, con->largeur, con->layer, x2,
y2, w2, l2, face);
if (dist < mindist) {
mindist = dist;
coordalim = liste_coor;
}
}
if (liste_coor->xabs >= x2)
break;
else
liste_coor = liste_coor->suiv;
}
return(coordalim);
break;
case EST:
case OUEST:
while (NULL != liste_coor) {
if ((NULL != liste_coor->proprio) && ((eq_vdd == ((LST_PSEUDO_CON)liste_coor->proprio)->nom_con) ||
(eq_vss == ((LST_PSEUDO_CON)liste_coor->proprio)->nom_con)) && (liste_coor->yabs < y2)) {
con = ((LST_PSEUDO_CON)liste_coor->proprio);
dist = distance_con_con(liste_coor->xabs, liste_coor->yabs, con->largeur, con->layer, x2,
y2, w2, l2, face);
if (dist < mindist) {
mindist = dist;
coordalim = liste_coor;
}
}
if (liste_coor->yabs >= y2)
break;
else
liste_coor = liste_coor->suiv;
}
return(coordalim);
}
return NULL;
}
/*-----------------------------------------------------------------------------------------*/
/* Cette fonction utilisee pour la fabrication de nouveaux pas de grille */
/* parcoure toutes les coordonnees suivantes correspondant a des pseudo-connecteurs */
/* pour donner la distance minimum qu'il existe entre le connecteur */
/* et les connecteurs suivants d'alim. Ceci pour corriger un bug */
/* qui vient du fait que des alim peuvent etre en vis a vis et que */
/* si on calcule seulement la distance avec le connecteur suivant */
/* on ne prend peut etre pas en compte un connecteur d'alim voisin */
/* plus gros qui recouvre largement le connecteur precedent. */
/* on retourne une coordonnee soit la precedente soit une autre qui */
/* recouvre la precedente. */
/*-----------------------------------------------------------------------------------------*/
PT_COORDONNEES existe_con_suiv(long x1, long y1, long w1, char l1,
int face, PT_COORDONNEES liste_coor)
{
long mindist = 0;
int first = 1;
long dist;
LST_PSEUDO_CON con;
PT_COORDONNEES coordalim = NULL;
if (mode_debug)
printf("Existesuivalim x %ld y %ld face %d ptcoor %d\n\n", x1, y1, face, (int)liste_coor);
switch (face) {
case NORD:
case SUD:
while (NULL != liste_coor) {
if (mode_debug)
printf("ptcoor %d proprio %d x %ld\n", (int) liste_coor, (int)liste_coor->proprio, liste_coor->xabs);
if (NULL != liste_coor->proprio) {
con = ((LST_PSEUDO_CON)liste_coor->proprio);
dist = distance_con_con(x1, y1, w1, l1, liste_coor->xabs, liste_coor->yabs, con->largeur,
con->layer, face);
if (first) {
mindist = dist;
first = 0;
coordalim = liste_coor;
} else if (dist < mindist) {
mindist = dist;
coordalim = liste_coor;
}
if (mode_debug)
printf("ptcoordalim %d\n", (int) coordalim);
}
liste_coor = liste_coor->suiv;
}
return(coordalim);
break;
case EST:
case OUEST:
while (NULL != liste_coor) {
if (mode_debug)
printf("ptcoor %d proprio %d x %ld\n", (int) liste_coor, (int)liste_coor->proprio, liste_coor->yabs);
if (NULL != liste_coor->proprio) {
con = ((LST_PSEUDO_CON)liste_coor->proprio);
dist = distance_con_con(x1, y1, w1, l1, liste_coor->xabs, liste_coor->yabs, con->largeur,
con->layer, face);
if (first) {
mindist = dist;
first = 0;
coordalim = liste_coor;
} else if (dist < mindist) {
mindist = dist;
coordalim = liste_coor;
}
if (mode_debug)
printf("ptcoordalim %d\n", (int) coordalim);
}
liste_coor = liste_coor->suiv;
}
return(coordalim);
}
return NULL;
}

View File

@ -0,0 +1,15 @@
#ifndef __DISTANCE_H
#define __DISTANCE_H
#include "struct.h"
extern long distance_con_con(long x1, long y1, long w1, char l1,
long x2, long y2, long w2, char l2, int face);
PT_COORDONNEES existe_con_precalim(long x2, long y2, long w2, char l2, int face,
PT_COORDONNEES liste_coor, long distance);
extern PT_COORDONNEES existe_con_suiv(long x1, long y1, long w1, char l1,
int face, PT_COORDONNEES liste_coor);
#endif /* __DISTANCE_H */

View File

@ -0,0 +1,401 @@
/*
* 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 : ring router */
/* Fichier : lireplace.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*-----------------------------------------------------------------------------------*/
/* RING 29 avril 92 LIREPLACE.C */
/* PHASE 3 */
/* */
/* Lecture du fichier de placement afin de connaitre les plots, leur orientation, */
/* ainsi que les signaux de largeur specifique. */
/* */
/* Pour la lecture et l'interpretation du fichier les outils lex et yacc sont */
/* utilises */
/*-----------------------------------------------------------------------------------*/
#include <stdio.h>
#include "lireplace.h"
#include "sesame.h"
/*-----------------------------------------------------------------------------------*/
/* Lecture et verification du fichier de parametres , suffixe .rin. Lancement de */
/* l'analyseur syntaxique */
/*-----------------------------------------------------------------------------------*/
void lecture_fic(char *nomfic, lofig_list *circuit_lo,
COEUR lecoeur, int nb_inst_plots)
{
FILE * fichier;
long longueur;
chain_list * liste;
int i, cpt_liste = 0, cpt_plots = 0, larg_con;
char *nom_du_plot, *nom_con;
loins_list * ptinst;
/* ------------------------------------------------------------------------- */
/* Ouverture et verification du fichier de parametre (existence et longueur) */
/* ------------------------------------------------------------------------- */
if ((fichier = mbkfopen(nomfic, NULL, READ_TEXT)) == NULL)
ringerreur(ERR_FICPARAM, nomfic, NULL);
if (fseek(fichier, (long)0, SEEK_END))
ringerreur(ERR_FICPARAM, nomfic, NULL);
if ((longueur = ftell(fichier)) == -1)
ringerreur(ERR_FICPARAM, nomfic, NULL);
if (longueur == 0)
ringerreur(ERR_VIDEFICPARAM, nomfic, NULL);
fclose(fichier);
if (mode_debug)
printf("Longueur fichier parametres: %ld\n", longueur);
for (i = 0; i < NB_FACES; i++)
nom_plot[i] = NULL;
liste_width = NULL; /* Initialisations des listes globales utilisees
par lex et yacc */
if (mode_debug)
printf("Avant analyse lex et yacc \n");
yyin = mbkfopen(nomfic, NULL, READ_TEXT);
/* ------------------------------------------------------------------ */
/* lancement de lex et yacc pour interpreter le fichier de parametres */
/* ------------------------------------------------------------------ */
yyparse();
if (mode_debug)
printf("Apres analyse lex et yacc\n");
/* ------------------------------------------------------------------ */
/* inversion des listes pour respecter l'ordre du placement des plots */
/* verification de la coherence des informations receuillies */
/* ------------------------------------------------------------------ */
for (i = 0; i < NB_FACES; i++) {
nom_plot[i] = reverse(nom_plot[i]);
if (nom_plot[i] != NULL)
cpt_liste++;
}
if (!cpt_liste)
ringerreur(ERR_AUCUNPLOTPARAM, NULL, NULL);
/* -------------------------------------------------------------------------- */
/* parcours des noms d'instances des plots et verif si existent ds circuit_lo */
/* -------------------------------------------------------------------------- */
for (i = 0; i < NB_FACES; i++) {
if (mode_debug)
printf("---------numero face :%d\n", i);
liste = nom_plot[i];
/*--------------------------------------------------------------------------- */
/* De part la modification des chain_list de nom_plot, je verifie d'abord sur */
/* l'ancienne structure (noms uniquement) qu'il y a une seule occurrence */
/*--------------------------------------------------------------------------- */
while (liste != NULL) {
nom_du_plot = (char *)(liste->DATA);
if (mode_debug)
printf("VERIF nom plot: --%s--\n", nom_du_plot);
/* ---------------------------------------------------- */
/* une seule occurence dans la liste des faces de plots */
/* ---------------------------------------------------- */
if (!uneseuleoccurence(nom_du_plot, nom_plot))
ringerreur(ERR_PLUSPLOTPARAM, nom_du_plot, NULL);
liste = liste->NEXT;
}
liste = nom_plot[i];
while (liste != NULL) {
nom_du_plot = (char *)(liste->DATA);
if (mode_debug)
printf("VERIF nom plot: --%s--\n", nom_du_plot);
/* --------------------------------------------------- */
/* existence du plot dans la liste du circuit logique */
/* --------------------------------------------------- */
if ((ptinst = existe_plot_circuit(nom_du_plot, circuit_lo)) == NULL)
ringerreur(ERR_NONPLOTPARAM, nom_du_plot, NULL);
else /* Chain_list modifiee pointe maintenant sur l'instance logique */
liste->DATA = (void * ) ptinst;
cpt_plots++;
liste = liste->NEXT;
}
}
if (cpt_plots != nb_inst_plots)
ringerreur(ERR_NBPLOTPARAM, circuit_lo, NULL);
liste = liste_width;
if (mode_debug)
printf("VERIF Liste width\n");
/* --------------------------------------------------------------- */
/* verification sur la liste des connecteurs de largeur specifique */
/* --------------------------------------------------------------- */
while (liste != NULL) {
nom_con = ((PTCEL)(liste->DATA))->chaine;
larg_con = ((PTCEL)(liste->DATA))->largeur;
if (mode_debug)
printf("Connecteur --%s-- largeur %d\n", nom_con, larg_con);
/* -------------------------------------------------------------------------- */
/* existence du connecteur dans la liste des connecteurs logiques du circuit */
/* -------------------------------------------------------------------------- */
if (!existe_signal_circuit(liste, circuit_lo, lecoeur))
ringerreur(ERR_NONCONWIDTHPARAM, nom_con, NULL);
if (larg_con < SCALE_X)
ringerreur(ERR_WIDTHPARAM, (void * )nom_con, (void * ) & larg_con);
liste = liste->NEXT;
}
}
/*-----------------------------------------------------------------------------------*/
/* Erreur dans la syntaxe du fichier de parametre */
/*-----------------------------------------------------------------------------------*/
void
yyerror(s)
char *s;
{
ringerreur(ERR_SYNPARAM, NULL, NULL);
}
/*-----------------------------------------------------------------------------------*/
/* Fabrication de la liste des equipotentielles a partir de la vue logique du coeur */
/* et circuit */
/*-----------------------------------------------------------------------------------*/
void fabrique_equipo(chain_list *nomplot[NB_FACES], COEUR lecoeur,
LST_EQUIPO *lst_equipo, chain_list *liste_plotsph)
{
locon_list * pt_coeur, *tete_coeur, *con_coeur = (lecoeur.coeur_lo)->LOCON ;
locon_list * con_plot, *liste_con, *liste_con2;
losig_list * sig_coeur;
loins_list * plot, *plot2;
int face, i, j, signal_ok;
chain_list * liste_plots, *liste_plots2;
LST_EQUIPO liste, pt_eq;
(*lst_equipo) = NULL;
if (mode_debug)
printf("Fabrication des equipo\n");
/* ------------------------- */
/* boucle des locon du coeur */
/* ------------------------- */
while (con_coeur != NULL) {
sig_coeur = con_coeur->SIG; /* un signal unique par connecteur */
if (mode_debug)
printf("pointeur Sigcoeur %d\n", (int) sig_coeur);
if (mode_debug)
printf("*******NOM concoeur %s signal %ld*********\n", con_coeur->NAME, sig_coeur->INDEX);
/* ---------------------------- */
/* Parcours des instances plots */
/* ---------------------------- */
for (face = 0; face < NB_FACES; face++) {
liste_plots = nomplot[face];
while (liste_plots != NULL) {
plot = (loins_list * ) liste_plots->DATA;
/* ----------------------------------------------------------------------------------------------------------- */
/* S'il s'agit d'un plot on regarde les signaux des connecteurs du plot pour trouver meme signal que con_coeur */
/* ----------------------------------------------------------------------------------------------------------- */
if (mode_debug) printf("PLOT %s de la face %d\n",plot->INSNAME,face);
if ((con_plot = existe_sig_plot(sig_coeur, plot, liste_plotsph)) != NULL) {
maj_equipo(con_coeur, con_plot, lst_equipo, COEUR_PLOT);
}
liste_plots = liste_plots->NEXT;
} /* fin parcours instances plots d'une face */
} /* fin de parcours de toutes les faces */
con_coeur = con_coeur->NEXT;
} /* fin de parcours des con du coeur */
/*------------------------- equipo PLOT_PLOT -----------------------------------------*/
for (i = 0; i < NB_FACES; i++) {
liste_plots = nomplot[i];
while (liste_plots != NULL) {
plot = (loins_list * ) liste_plots->DATA;
liste_con = plot->LOCON;
while (liste_con != NULL) {
pt_eq = existe_sig_equipo((*lst_equipo), (liste_con->SIG)->INDEX);
signal_ok = ((pt_eq == NULL) || (pt_eq->type == PLOT_PLOT));
if ((signal_ok)
&& existe_leconnecteur_faceplot(plot->FIGNAME, liste_con->NAME, SUD, liste_plotsph)){
for (j = 0; j < NB_FACES; j++) {
liste_plots2 = nomplot[j];
while (liste_plots2 != NULL) {
plot2 = (loins_list * ) liste_plots2->DATA;
liste_con2 = plot2->LOCON;
while (liste_con2 != NULL) {
if (existe_leconnecteur_faceplot(plot->FIGNAME, liste_con->NAME, SUD, liste_plotsph)
&& (liste_con2 != liste_con)
&& ((liste_con->SIG)->INDEX == (liste_con2->SIG)->INDEX)) {
if (mode_debug)
printf("TROUVE liste_con ->%s *** %s\n", liste_con->NAME, liste_con2->NAME);
maj_equipo(liste_con, liste_con2, lst_equipo, PLOT_PLOT);
}
liste_con2 = liste_con2->NEXT;
}
liste_plots2 = liste_plots2->NEXT;
}
} /* ffin du for */
} /* fin du if */
liste_con = liste_con->NEXT;
}
liste_plots = liste_plots->NEXT; /* fin du while */
}
} /* fin du 1er for */
/*-------------------- equipo de type COEUR_COEUR ----------------------------------*/
tete_coeur = con_coeur = (lecoeur.coeur_lo)->LOCON;
while (con_coeur != NULL) {
pt_eq = existe_sig_equipo((*lst_equipo), (con_coeur->SIG)->INDEX);
signal_ok = ((pt_eq == NULL) || (pt_eq->type == COEUR_COEUR));
pt_coeur = tete_coeur;
if (signal_ok)
while (pt_coeur != NULL) {
if ((pt_coeur != con_coeur) && ((con_coeur->SIG)->INDEX == (pt_coeur->SIG)->INDEX))
maj_equipo(con_coeur, pt_coeur, lst_equipo, COEUR_COEUR);
pt_coeur = pt_coeur->NEXT;
}
con_coeur = con_coeur->NEXT;
}
/*-----------------------------------------------------------------------------------*/
/* on inverse les chain list de pseudo connecteurs associes a chaque equipo, */
/* ce qui a pour but de mettre le connecteur du coeur en tete de liste */
/*-----------------------------------------------------------------------------------*/
liste = (*lst_equipo);
while (liste != NULL) {
liste->lst_con = reverse(liste->lst_con);
liste = liste->suiv;
}
}
/*-----------------------------------------------------------------------------------*/
/* Parcours des connecteurs de plots et des signaux associes */
/* Retourne le connecteur si signal identique */
/*-----------------------------------------------------------------------------------*/
locon_list *existe_sig_plot(losig_list *sig_coeur, loins_list *plot,
chain_list *liste_plotsph)
{
locon_list * con_plot = plot->LOCON;
losig_list * sig_plot;
if (mode_debug) printf("Existe sig_plot\n");
/* -------------------------------- */
/* Parcours des connecteurs du plot */
/* -------------------------------- */
while (con_plot != NULL) {
if (mode_debug)
printf("\tpointeur nom %d\n",(int)con_plot);
sig_plot = con_plot->SIG; /* un signal unique par connecteur */
if (mode_debug)
printf("\tnom conplot %s signal %ld sigcoeur %ld\n",con_plot->NAME,sig_plot->INDEX, sig_coeur->INDEX);
if (sig_plot->INDEX == sig_coeur->INDEX)
if ( ( !isvdd(con_plot->NAME) && !isvss(con_plot->NAME) )
|| ( ( isvdd(con_plot->NAME) || isvss(con_plot->NAME) )
&& ( existe_leconnecteur_faceplot(plot->FIGNAME, con_plot->NAME, SUD, liste_plotsph)
|| existe_leconnecteur_faceplot(plot->FIGNAME, con_plot->NAME, NORD, liste_plotsph))))
return(con_plot);
con_plot = con_plot->NEXT;
}
return(NULL);
}

View File

@ -0,0 +1,14 @@
#ifndef __LIREPLACE_H
#define __LIREPLACE_H
#include "struct.h"
extern void lecture_fic(char *nomfic, lofig_list *circuit_lo,
COEUR lecoeur, int nb_inst_plots);
extern void fabrique_equipo(chain_list *nomplot[NB_FACES], COEUR lecoeur,
LST_EQUIPO *lst_equipo, chain_list *liste_plotsph);
extern locon_list *existe_sig_plot(losig_list *sig_coeur, loins_list *plot,
chain_list *liste_plotsph);
#endif /* __LIREPLACE_H */

View File

@ -0,0 +1,317 @@
/*
* 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 : ring router */
/* Fichier : lirevues.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*----------------------------------------------------------------------------------------*/
/* RING 28 juillet 92 LIREVUES.C */
/* PHASE 2 */
/* */
/* Lecture des vues structurelles (circuit, coeur) et physiques (coeur, et chargement des */
/* plots */
/* Modif: suite a l'abandon d'utiliser des plots de fils, mais plutot tirer directement */
/* les fils, on verifie les modeles de plots physiques / con est <=> con ouest */
/*----------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "lirevues.h"
#include "sesame.h"
/*--------------------------------------------------------------------------------*/
/* Lors d ela lecture des modeles physiques des plots, on renomme les connecteurs */
/* vdd* et vss* en vdd et vss, sauf pour les connecteurs nord, car il s'agit */
/* de vdde ou vsse (alim de plots) a ne pas confondre avec alim de coeur */
/*--------------------------------------------------------------------------------*/
void lecture_vues(char *nom_circuit_lo, COEUR *lecoeur, lofig_list **circuit_lo,
chain_list **liste_plotsph, int *nbplots, chain_list **lst_conestouest)
{
chain_list * lstph;
phfig_list * ptfig;
loins_list * circuit_inst; /* instances dans le circuit logique */
loins_list * coeur_inst = NULL; /* instance du coeur */
int nbcoeur = 0; /* nombres d'instances susceptibles d'etre le coeur */
int retour;
*circuit_lo = getlofig(nom_circuit_lo, 'A');
if (!(*circuit_lo))
ringerreur(ERR_CIRCUITLO, nom_circuit_lo, NULL);
/* viewlo(); */
circuit_inst = (*circuit_lo)->LOINS;
if (!circuit_inst)
ringerreur(ERR_CIRCUITINST, nom_circuit_lo, NULL);
/* ---------------------------------------------------------------------------------------------------------- */
/* test la coherences des modeles logiques et physiques de toutes les modeles utilisee dans la figure logique */
/* ---------------------------------------------------------------------------------------------------------- */
testcon_modelfig(*circuit_lo);
/* ------------------------------------------------------------------------------------------------------------- */
/* Parcours des instances pour distinguer celles qui sont des plots et les autres (normalement 1 seule: le coeur */
/* ------------------------------------------------------------------------------------------------------------- */
*nbplots = 0;
(*liste_plotsph) = NULL; /* Initialisation de la liste de plots physiques */
while (circuit_inst != NULL) {
retour = incatalog(circuit_inst->FIGNAME);
if (mode_debug)
printf("FIGNAME %s incatalog %d\n", circuit_inst->FIGNAME, retour);
if (retour) {
(*nbplots)++;
/* -------------------------------------- */
/* Renommage des connecteurs vdd* et vss* */
/* -------------------------------------- */
ajout_listeplotsph(circuit_inst->FIGNAME, liste_plotsph);
} else /* le coeur est reconnu */ {
nbcoeur++;
coeur_inst = circuit_inst;
}
circuit_inst = circuit_inst->NEXT;
}
if (mode_debug)
printf("Lirevues: nb inst plots %d\n", *nbplots);
/* -------------------------------------------- */
/* Verification sur le nombres de coeur trouves */
/* -------------------------------------------- */
switch (nbcoeur) {
case 0:
ringerreur(ERR_NONCOEUR, NULL, NULL); /* aucun => ringerreur */
break;
case 1:
/* ------------------------------------------------------ */
/* un seul coeur, on charge les vues logique et physique */
/* ------------------------------------------------------ */
(*lecoeur).coeur_lo = coeur_inst;
if ((*lecoeur).coeur_lo == NULL)
ringerreur(ERR_COEURINSTLO, coeur_inst->FIGNAME, NULL);
ptfig = (*lecoeur).coeur_ph = getphfig(coeur_inst->FIGNAME, 'A');
(*lecoeur).coord.xabs = 0;
(*lecoeur).coord.yabs = 0; /* Coordonnees du coeur fixees a 0,0 par defaut */
(*lecoeur).width = ptfig->XAB2 - ptfig->XAB1;
(*lecoeur).height = ptfig->YAB2 - ptfig->YAB1;
(*lecoeur).coord.piste = 0;
(*lecoeur).rotation = NOSYM; /* pas de rotation par defaut */
/* viewphfig((*lecoeur).coeur_ph); */
if ((*lecoeur).coeur_ph == NULL)
ringerreur(ERR_COEURINSTPH, coeur_inst->FIGNAME, NULL);
break;
default:
/* ------------------------------------------ */
/* plusieurs candidats au coeur => ringerreur */
/* ------------------------------------------ */
ringerreur(ERR_PLUSCOEUR, (*circuit_lo)->LOINS, NULL);
}
/* ----------------------------------------------------- */
/* verification des modeles pour connexion alim internes */
/* ----------------------------------------------------- */
lstph = *liste_plotsph;
while (NULL != lstph) {
verif_con_estouest(lstph, lst_conestouest);
lstph = lstph->NEXT;
}
if (mode_debug)
affic_listeplotsph(*liste_plotsph);
}
/*---------------------------------------------------------------------------------*/
/* Verification du nombre de connecteurs de leur position en est et ouest des alim */
/* internse des plots. Une liste resultat lst_conestouest est fabriquee qui */
/* contient: */
/* - une liste de couples , connecteur ouest et connecteur est de meme nom et meme */
/* position */
/* Cette liste servira a relier les plots entre eux et finir la couronne de plots */
/* Modif: les connecteurs lateraux de plots etant renommes, on a des */
/* connecteurs de mem nom et meme index; il faut alors renumeroter */
/* les connecteurs (changement du champ INDEX dans tous les modeles */
/* de plots physiques */
/*---------------------------------------------------------------------------------*/
void verif_con_estouest(chain_list *liste_plotsph, chain_list **lst_conestouest)
{
static phfig_list *firstfig = NULL;
phfig_list * figcour;
phcon_list * lstcon, *con;
chain_list * lst, *lstwork;
static int cptest = 0, cptouest = 0;
int cptestcour = 0, cptouestcour = 0;
int index = 0; /* renumeroter les connecteurs physiques */
if (mode_debug)
printf("modele plot %s\n", ((phfig_list * )liste_plotsph->DATA)->NAME);
if (NULL == liste_plotsph)
ringerreur(ERR_INTERNE_CON, NULL, NULL);
if (NULL == firstfig) {
(*lst_conestouest ) = NULL;
firstfig = (phfig_list * ) liste_plotsph->DATA;
lstcon = firstfig->PHCON;
while (NULL != lstcon) {
if ('W' == lstcon->ORIENT) {
cptouest++;
if (mode_debug)
printf("REFERENCE con plot %s\n", lstcon->NAME);
(*lst_conestouest) = addchain((*lst_conestouest), (void * ) lstcon);
}
lstcon->INDEX = index;
index++;
lstcon = lstcon->NEXT;
}
lstcon = firstfig->PHCON;
while (NULL != lstcon) {
if ('E' == lstcon->ORIENT)
cptest++;
lstcon->INDEX = index;
index++;
lstcon = lstcon->NEXT;
}
if (cptouest != cptest)
ringerreur(ERR_NBCONESTOUEST , firstfig, firstfig);
lst = (*lst_conestouest);
while (NULL != lst) {
con = (phcon_list * ) lst->DATA;
if (mode_debug)
printf("REFERENCE con plot figcour %s ycon %ld width %ld\n", con->NAME, con->YCON, con->WIDTH);
lstcon = firstfig->PHCON;
while (NULL != lstcon) {
if (mode_debug)
printf("REFERENCE con plot figref %s ycon %ld width %ld\n", lstcon->NAME, lstcon->YCON, lstcon->WIDTH);
if (('E' == lstcon->ORIENT)
&& (lstcon->NAME == con->NAME)
&& (lstcon->YCON == con->YCON)
&& (lstcon->WIDTH == con->WIDTH)) {
lstwork = addchain(lst->NEXT, (void * ) lstcon);
lst->NEXT = lstwork;
lst = lst->NEXT;
break;
} else
lstcon = lstcon->NEXT;
}
if (NULL == lstcon)
ringerreur(ERR_NOCONPH , con, firstfig);
lst = lst->NEXT;
}
if (mode_debug)
printf("LISTE DES CONNECTEURS EST OUEST modele de reference\n");
lst = (*lst_conestouest);
while (NULL != lst) {
con = (phcon_list * ) lst->DATA;
if (mode_debug)
printf("con %s YCON %ld width %ld INDEX %ld face %c\n", con->NAME, con->YCON, con->WIDTH,
con->INDEX, con->ORIENT);
lst = lst->NEXT;
}
} else {
figcour = (phfig_list * ) liste_plotsph->DATA;
lstcon = figcour->PHCON;
while (NULL != lstcon) {
if (mode_debug)
printf("PADCOUR lstcon plot %s ycon %ld width %ld index %ld\n", lstcon->NAME, (lstcon->YCON - figcour->YAB1) , lstcon->WIDTH, lstcon->INDEX);
if (('W' == lstcon->ORIENT) || ('E' == lstcon->ORIENT)) {
if ('W' == lstcon->ORIENT)
cptouestcour++;
else
cptestcour++;
lst = (*lst_conestouest);
while (NULL != lst) {
con = (phcon_list * ) lst->DATA;
if (mode_debug)
printf("\tREFERENCEcon plot %s ycon %ld width %ld index %ld\n", con->NAME,
(con->YCON - firstfig->YAB1), con->WIDTH, con->INDEX);
if ((con->ORIENT == lstcon->ORIENT)
&& (con->NAME == lstcon->NAME)
&& ((con->YCON - firstfig->YAB1) == (lstcon->YCON - figcour->YAB1))
&& (con->WIDTH == lstcon->WIDTH)) {
lstcon->INDEX = con->INDEX;
break;
} else
lst = lst->NEXT;
}
if (NULL == lst)
ringerreur(ERR_NOCONPH , lstcon, figcour);
}
lstcon = lstcon->NEXT;
}
if ((cptest != cptestcour) || (cptouest != cptouestcour))
ringerreur(ERR_NBCONESTOUEST , figcour, firstfig);
}
}

View File

@ -0,0 +1,11 @@
#ifndef __LIREVUES_H
#define __LIREVUES_H
#include "struct.h"
extern void lecture_vues(char *nom_circuit_lo, COEUR *lecoeur, lofig_list **circuit_lo,
chain_list **liste_plotsph, int *nbplots, chain_list **lst_conestouest);
extern void verif_con_estouest(chain_list *liste_plotsph, chain_list **lst_conestouest);
#endif /* __LIREVUES_H */

View File

@ -0,0 +1,216 @@
/*
* 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 : ring router */
/* Fichier : param.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*--------------------------------------------------------------------------*/
/* RING 28 avril 92 PARAM.C */
/* PHASE 1 */
/* Lecture des parametres et de l'environnement mbk */
/*--------------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include "param.h"
#include "sesame.h"
/*-----------------------------------------------------------------------------------*/
/* lecture des arguments (ligne de commande), lecture envt mbk et */
/* initialisations des variables globales. */
/*-----------------------------------------------------------------------------------*/
void lecture_param(int nbarg, char** tab, char** nom_circuit_lo,
char** nom_circuit_ph, char** nom_fic_param)
{
long max1, max2, pitchalu1, pitchalu2;
FILE* f_catal;
/* ---------------------- */
/* arguments du programme */
/* ---------------------- */
if ((nbarg < 3) || (nbarg > 5))
ringerreur(ERR_ARGUMENT, NULL, NULL);
*nom_circuit_lo = tab[1];
*nom_circuit_ph = tab[2];
*nom_fic_param = (char * ) mbkalloc ((unsigned int) strlen(*nom_circuit_lo) + 5);
strcpy(*nom_fic_param, *nom_circuit_lo);
strcat(*nom_fic_param, ".rin");
mode_debug = 0;
mode_stat = 0;
if (nbarg == 4) {
if (!strcmp(tab[3], "debug")) {
mode_debug = 1;
if (mode_debug)
fprintf(stderr, "\n\t*** Debug mode ***\n\n");
}
if (!strcmp(tab[3], "stat")) {
mode_stat = 1;
nomfic_stat = (char * ) mbkalloc ((unsigned int) strlen(*nom_circuit_ph) + 6);
strcpy(nomfic_stat, *nom_circuit_ph);
strcat(nomfic_stat, ".stat");
if (mode_stat)
fprintf(stderr, "\n\t*** Statistic mode -> see the file < %s > ***\n\n", nomfic_stat);
}
if ((!mode_debug) && (!mode_stat))
ringerreur(ERR_ARGUMENT, NULL, NULL);
}
if (nbarg == 5) {
if ((!strcmp(tab[3], "debug")) || (!strcmp(tab[4], "debug"))) {
mode_debug = 1;
if (mode_debug)
fprintf(stderr, "\n\t*** Debug mode ***\n\n");
}
if ((!strcmp(tab[3], "stat")) || (!strcmp(tab[4], "stat"))) {
mode_stat = 1;
nomfic_stat = (char * ) mbkalloc ((unsigned int) strlen(*nom_circuit_ph) + 6);
strcpy(nomfic_stat, *nom_circuit_ph);
strcat(nomfic_stat, ".stat");
if (mode_stat)
fprintf(stderr, "\n\t*** Statistic mode -> see the file < %s > ***\n\n", nomfic_stat);
}
if (!(mode_debug && mode_stat))
ringerreur(ERR_ARGUMENT, NULL, NULL);
}
if (mode_debug)
printf("nbarg %d\n", nbarg);
if (mode_debug)
printf("circlo-%s-circph-%s-\n", *nom_circuit_lo, *nom_circuit_ph);
if (mode_debug)
printf("fic-paramr-%s-\n", *nom_fic_param);
/*---------------------------- INITIALISATIONS ----------------------------------------*/
/* ---------------- */
/* arguments de mbk */
/* ---------------- */
mbkenv(); /* choix de l'utilisateur mis dans des variables UNIX */
/* on recupere (long) SCALE_X */
if (mode_debug)
printf("CATALNAME is %s\n", CATAL);
if (NULL == (f_catal = mbkfopen(CATAL, NULL, READ_TEXT)))
ringerreur(ERR_CATAL, CATAL, NULL);
fclose(f_catal);
/* ----------------------------------------------------------------- */
/* Affectation des variables globales representnat les equipo d'alim */
/* ----------------------------------------------------------------- */
eq_vdd = namealloc(VDD);
eq_vss = namealloc(VSS);
#ifdef COMMENT
/* ------------------------------------------- */
/* Directions privilegiees de metaux inversees */
/* ------------------------------------------- */
ymetal = ALU1; /* Horizontal faces Est et Ouest */
ymetal_width = WMIN_ALU1 * SCALE_X;
ymetal_wvia = WVIA_ALU1 * SCALE_X;
ymetal_dmin = DMIN_ALU1_ALU1 * SCALE_X;
xmetal = ALU2; /* Vertical faces Nord et Sud */
xmetal_width = WMIN_ALU2 * SCALE_X;
xmetal_wvia = WVIA_ALU2 * SCALE_X;
xmetal_dmin = DMIN_ALU2_ALU2 * SCALE_X;
#endif
xmetal = ALU1; /* Horizontal faces Est et Ouest */
xmetal_width = WMIN_ALU1 * SCALE_X;
xmetal_wvia = WVIA_ALU1 * SCALE_X;
xmetal_dmin = DMIN_ALU1_ALU1 * SCALE_X;
ymetal = ALU2; /* Vertical faces Nord et Sud */
ymetal_width = WMIN_ALU2 * SCALE_X;
ymetal_wvia = WVIA_ALU2 * SCALE_X;
ymetal_dmin = DMIN_ALU2_ALU2 * SCALE_X;
lambda = 1 * SCALE_X;
if (mode_debug)
printf("xmetal_width %ld ymetal_width %ld scale_x %ld\n", xmetal_width, ymetal_width, SCALE_X);
if (mode_debug)
printf("xmetal_DMIN %ld ymetal_DMIN %ld\n", xmetal_dmin, ymetal_dmin);
vdd_width = 0;
vss_width = 0;
/* pitcha1= dmina1a1 + max (wminalu1, wviaa1) */
/* pitcha2= dmina2a2 + max (wminalu2, wviaa2) */
if (WMIN_ALU1 > WVIA_ALU1)
max1 = WMIN_ALU1;
else
max1 = WVIA_ALU1;
pitchalu1 = DMIN_ALU1_ALU1 + max1;
if (WMIN_ALU2 > WVIA_ALU2)
max2 = WMIN_ALU2;
else
max2 = WVIA_ALU2;
pitchalu2 = DMIN_ALU2_ALU2 + max2;
if (mode_debug)
printf("Pitch alu1 %ld Pitch alu2 %ld\n", pitchalu1, pitchalu2);
if (pitchalu1 > pitchalu2)
pitch = pitchalu1 * SCALE_X;
else
pitch = pitchalu2 * SCALE_X;
if (WVIA_ALU1 > WVIA_ALU2)
taille_via = WVIA_ALU1 * SCALE_X;
else
taille_via = WVIA_ALU2 * SCALE_X;
if (mode_debug)
printf("pitch %ld taille_via %ld\n", pitch, taille_via);
}

View File

@ -0,0 +1,7 @@
#ifndef __PARAM_H
#define __PARAM_H
void lecture_param(int nbarg, char** tab, char** nom_circuit_lo,
char** nom_circuit_ph, char** nom_fic_param);
#endif /* __PARAM_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
#ifndef __PLACEMENT_H
#define __PLACEMENT_H
#include "struct.h"
extern void remplir_tabplots(BARRE_PLOTS tab_plots[NB_FACES], LST_EQUIPO lst_equipo);
extern void remplir_tabcoeur(LST_PSEUDO_CON tabcoeur[NB_FACES], COEUR lecoeur, LST_EQUIPO lst_equipo);
extern void affic_tabcoeur(LST_PSEUDO_CON tabcoeur[NB_FACES]);
extern void affic_tabplots(BARRE_PLOTS tabplot[NB_FACES]);
extern void largeur_ab_plots(BARRE_PLOTS tab_plots[NB_FACES],
chain_list *nomplot[NB_FACES], chain_list *liste_plotsph);
extern void fabrique_barre_plots(BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
chain_list *nomplot[NB_FACES], chain_list *liste_plotsph,
chain_list *lst_conestouest);
extern void fabrique_grille_primaire(LST_PSEUDO_CON tab_coeur[NB_FACES],
GRILLE tab_grilles[NB_FACES]);
extern void place_et_cout_barreplot(LST_PSEUDO_CON tab_coeur[NB_FACES],
BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
LST_EQUIPO lst_equipo);
extern void place_vertical_barreplot(BARRE_PLOTS tab_plots[NB_FACES],
LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur,
LST_EQUIPO lst_equipo);
extern int calcul_nbdeport(BARRE_PLOTS tab_plots[NB_FACES],
LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur,
LST_EQUIPO lst_equipo, long barrecourant, int face);
extern int moins_dun_pitch_confacecoeur(long position, LST_PSEUDO_CON plotcon,
LST_PSEUDO_CON liste_coeur, LST_EQUIPO lst_equipo,
int face);
extern int calcul_nbdeport_cyclesface(LST_EQUIPO lst_equipo);
extern int calcul_nbdeport_equipo_alim(LST_EQUIPO lst_equipo, long barrecourant, int face);
extern int croisement_con(chain_list *ptcour, chain_list *ptalim,
long barrecourant, int face);
extern void recherche_equipo_alim(LST_EQUIPO *equipo_vdd,
LST_EQUIPO *equipo_vss,
LST_EQUIPO lst_equipo);
extern int conplotalim_dans_coeur(LST_EQUIPO lst_equipo, COEUR coeur,
long barrecourant, int face);
extern void maj_coordplots(BARRE_PLOTS tab_plots[NB_FACES], LST_EQUIPO lst_equipo);
extern void fabrique_grille_finale(BARRE_PLOTS tab_plots[NB_FACES],
LST_PSEUDO_CON tab_coeur[NB_FACES], COEUR lecoeur,
LST_EQUIPO lst_equipo, GRILLE tab_grilles[NB_FACES]);
extern void ajout_pas_grille(GRILLE tab_grilles[NB_FACES], COEUR lecoeur, int face);
extern void relier_plots_wire1(phins_list *lastinst, phins_list *lastinst2, chain_list *lst);
#endif /* __PLACEMENT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
#ifndef __POSERCIRCUIT_H
#define __POSERCIRCUIT_H
#include "struct.h"
extern void poser_blocs(phfig_list **circuit_ph, char *nomcircuit,
BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur);
extern void poser_segments(LST_EQUIPO lst_equipo, COEUR lecoeur,
lofig_list *circuit_lo, phfig_list *circuit_ph);
extern void poser_segments_eq(LST_EQUIPO equipo, COEUR lecoeur,
lofig_list *circuit_lo);
extern void poser_vias_eq(LST_EQUIPO equipo, COEUR lecoeur, phfig_list *circuit_ph);
extern void remonte_con_circuit(chain_list *nom_plot[NB_FACES],
chain_list *liste_plotsph, BARRE_PLOTS tab_plots[NB_FACES],
COEUR lecoeur, lofig_list *circuit_lo, phfig_list *circuit_ph,
char *nom_circuit_ph, chain_list *lst_conestouest);
extern void traite_equipo_ext(chain_list *nom_plot[NB_FACES],
chain_list *liste_plotsph,
BARRE_PLOTS tab_plots[NB_FACES], COEUR lecoeur,
lofig_list *circuit_lo, phfig_list *circuit_ph);
extern void remonte_con(locon_list *con_circuit, locon_list *con_plot,
chain_list *liste_plotsph, phfig_list *circuit_ph);
extern void tirer_coins(phfig_list *circuit_ph, BARRE_PLOTS tab_plots[NB_FACES],
chain_list *lst_conestouest);
extern void ajout_coin(long x, long y, long wx, long wy, char layer);
extern void poser_vias_visavisalim(LST_EQUIPO equipo, COEUR lecoeur,
phfig_list *circuit_ph);
#endif /* __POSERCIRCUIT_H */

View File

@ -0,0 +1,298 @@
/*
* 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 : ring router */
/* Fichier : ring2.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 13/11/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
#ident "@(#)ring 2.8 9/11/94 ALLIANCE 3.0 pad ring router"
/*----------------------------------------------------------------------------------- */
/* RING 27 avril 92 RING2.C */
/* Programme principal: declarations des variables (globales et locales) */
/*----------------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include "struct.h"
#include "param.h"
#include "sesame.h"
#include "lirevues.h"
#include "lireplace.h"
#include "placement.h"
#include "deport.h"
#include "routalim.h"
#include "routage.h"
#include "compress.h"
#include "posercircuit.h"
#include "stat.h"
/*----------------------------------------------------------------------------------- */
/* Variables globales */
char mode_debug; /* si debug alors mode_debug=1, 0 sinon */
char mode_stat; /* si stat alors mode_stat=1, 0 sinon */
char *nomfic_stat; /* nom du fichier stat */
char xmetal; /* metal horizontal, faces est et Ouest */
char ymetal; /* metal vertical, faces Nord et Sud */
long xmetal_width, ymetal_width; /* largeur des metaux x, y */
long xmetal_dmin, ymetal_dmin; /* dist minimum entre 2 meme metaux */
long xmetal_wvia, ymetal_wvia; /* taille des contacts pour chaque metal */
long pitch; /* pitch a calculer */
long lambda; /* lambda (=SCALE_X) */
long taille_via; /* taille du via a calculer */
long vdd_width; /* largeur couronnes d'alim */
long vss_width;
char *eq_vdd;
char *eq_vss;
char *nom_fic_param; /* nom du fichier parametre */
chain_list *nom_plot[NB_FACES]; /* liste pour l'analyseur des noms de plots */
/* contiendra aussi les instances logiques de plots */
chain_list *liste_width; /* liste pour l'analyseur des noms
et largeurs des connecteurs speciaux */
long bigvias = 0, ringvias = 0; /* nombres de vias poses en total par bigvia
ou en couronne (mode debug). car pb versatil
si bcp de vias (fichier .cif enorme) */
/*----------------------------------------------------------------------------------- */
int
main (argc, argv)
int argc;
char **argv;
{
/* declarations des variables locales */
BARRE_PLOTS tab_plots[NB_FACES]; /* nbfaces barres de plots */
LST_PSEUDO_CON tab_coeur[NB_FACES]; /* nbfaces listes de connecteurs du coeur */
chain_list * liste_plotsph; /* liste de pointeurs sur les modeles physiques
des plots */
chain_list * lst_conestouest; /* liste des con estouest alim */
int nb_inst_plots; /* nombres d'instances de plots rencontrees */
GRILLE tab_grilles[NB_FACES]; /* une grille symbolique par face */
LST_EQUIPO eq_interne; /* liste des equipo. internes (coeur/plots) */
LST_SEGMENT segx_occ[NB_FACES]; /* liste des segments occupes */
LST_SEGMENT segy_occ[NB_FACES]; /* liste des segments occupes */
long piste_supalim[NB_FACES]; /* No des pistes alim couronnes inf et sup */
long piste_infalim[NB_FACES];
long tabpiste[NB_FACES]; /* No des 1eres pistes libres en partant
de la barre de plots, sert pour les couronnes d'alim */
char * nom_circuit_lo, *nom_circuit_ph; /* nom du circuit logique et resultat (physique) */
COEUR lecoeur; /* structure contenant les informations du coeur */
lofig_list * circuit_lo; /* pointeur sur la figure logique du coeur */
phfig_list * circuit_ph; /* pointeur sur la figure physique du coeur */
char * coursup, *courinf; /* nom des couronnes d'alim */
long firstlibre[NB_FACES], nblibres[NB_FACES]; /* tab des 1eres pistes libres et nbre de piste */
/* ---------------------------------------------------------------------------------- */
/* PHASE 1 */
/* lecture et verification du nombre de parametres */
/* ---------------------------------------------------------------------------------- */
lecture_param(argc, argv, &nom_circuit_lo, &nom_circuit_ph, &nom_fic_param);
banner();
/* ---------------------------------------------------------------------------------- */
/* PHASE 2 */
/* lecture vues structurelles circuit et coeur */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to reading netlists, layout views of core and pads.\n");
lecture_vues(nom_circuit_lo, &lecoeur, &circuit_lo , &liste_plotsph, &nb_inst_plots, &lst_conestouest);
/* ---------------------------------------------------------------------------------- */
/* PHASE 3 */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to reading file of parameters, including the placements of pads.\n");
lecture_fic(nom_fic_param, circuit_lo, lecoeur, nb_inst_plots);
if (mode_debug)
affic_plotwidth();
fprintf(stderr, "\to making equipotential list.\n");
fabrique_equipo(nom_plot, lecoeur, &eq_interne, liste_plotsph);
if (mode_debug)
affic_equipo(eq_interne);
/* ---------------------------------------------------------------------------------- */
/* verification de la liste des equipotentielles internes */
/* ---------------------------------------------------------------------------------- */
verif_eq_interne(eq_interne, liste_plotsph);
/* ---------------------------------------------------------------------------------- */
/* PHASE 4 */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to making the first placement of pads.\n");
fabrique_barre_plots(tab_plots, lecoeur, nom_plot, liste_plotsph, lst_conestouest);
remplir_tabcoeur(tab_coeur, lecoeur, eq_interne);
if (mode_debug) {
printf("afficher tab_coeur\n");
affic_tabcoeur(tab_coeur);
}
fprintf(stderr, "\to filling data internal structures.\n");
remplir_tabplots(tab_plots, eq_interne);
if (mode_debug)
affic_tabplots(tab_plots);
if (mode_debug)
printf("*** (larg plot alim) vdd_width: %ld vss_width: %ld\n", vdd_width, vss_width);
fprintf(stderr, "\to reading the connectors positions of the core.\n");
fabrique_grille_primaire(tab_coeur, tab_grilles);
if (mode_debug)
affic_grille(tab_grilles);
fprintf(stderr, "\to computing the best placement of the pads.\n");
place_et_cout_barreplot(tab_coeur, tab_plots, lecoeur, eq_interne);
maj_coordplots(tab_plots, eq_interne);
fprintf(stderr, "\to reading the connectors positions of the pads.\n");
fabrique_grille_finale(tab_plots, tab_coeur, lecoeur, eq_interne, tab_grilles);
if (mode_debug)
affic_grille(tab_grilles);
if (mode_debug)
affic_tabplots(tab_plots);
if (mode_debug)
affic_grille(tab_grilles);
/* ---------------------------------------------------------------------------------- */
/* PHASE 5 */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to routing deportation of connectors.\n");
attribuer_couronne_alim(eq_interne, &coursup, &courinf);
/* ---------------------------------------------------------------------------------- */
/* initialisations de segx-occ[] et segy_occ[] */
/* on alloue exceptionnellement des faux segments pour deport plot alim ! */
/* ---------------------------------------------------------------------------------- */
deport_alim(eq_interne, tab_plots, coursup, courinf, segx_occ, segy_occ);
deport_connecteurs(tab_plots, tab_coeur, lecoeur, tab_grilles);
if (mode_debug)
affic_equipo(eq_interne);
pose_segdeport(tab_plots, tab_coeur, lecoeur, eq_interne, segx_occ, segy_occ);
fprintf(stderr, "\to routing supply tracks.\n");
/* ---------------------------------------------------------------------------------- */
/* tabpiste va contenir les no des 1eres pistes libres en partant des plots */
/* qui vont servir pour poser les couronnes d'alim */
/* ---------------------------------------------------------------------------------- */
pose_couralim(coursup, piste_supalim, piste_infalim, eq_interne, lecoeur, tab_plots, segx_occ, segy_occ, tabpiste);
/* ---------------------------------------------------------------------------------- */
/* On peut se servir de tabpiste pour poser des faux segments, au cas ou on */
/* tire une alim ds le mauvais layer, ceci pour eviter des croisements */
/* (courts-circuits) avec les deports eventuels de plots */
/* ---------------------------------------------------------------------------------- */
tire_etdeport_alim(coursup, piste_supalim, piste_infalim, eq_interne, tab_plots, segx_occ, segy_occ, tabpiste);
if (mode_debug)
printf("*** vdd_width: %ld vss_width: %ld\n", vdd_width, vss_width);
if (mode_debug)
affic_equipo(eq_interne);
/* ---------------------------------------------------------------------------------- */
/* PHASE 6 */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to routing equipotentials.\n");
remplit_eq_curv(eq_interne, lecoeur);
ordonne_equipotentielles(&eq_interne);
route_equipo(piste_infalim, eq_interne, lecoeur, segx_occ, segy_occ);
if (mode_debug)
affic_equipo(eq_interne);
if (mode_debug) {
printf("------------------------------------------------------------------\n\n\n");
printf("SEGMENT YMETAL\n");
affic_listeseg(segy_occ);
printf("SEGMENT XMETAL\n");
affic_listeseg(segx_occ);
}
/* ---------------------------------------------------------------------------------- */
/* PHASE 7 */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to compressing channels.\n");
calcul_nbpiste_libre(tab_plots, lecoeur, segx_occ, segy_occ, nblibres, firstlibre);
compression_canaux(tab_plots, lecoeur, segx_occ, segy_occ, nblibres, firstlibre);
/* ---------------------------------------------------------------------------------- */
/* PHASE 8 */
/* ---------------------------------------------------------------------------------- */
fprintf(stderr, "\to saving in MBK data structure.\n");
poser_blocs(&circuit_ph, nom_circuit_ph, tab_plots, lecoeur);
poser_segments(eq_interne, lecoeur, circuit_lo, circuit_ph);
remonte_con_circuit(nom_plot, liste_plotsph, tab_plots, lecoeur, circuit_lo, circuit_ph, nom_circuit_ph, lst_conestouest);
if (mode_stat)
finir_stat(eq_interne);
fprintf(stderr, "lucky, no error.\n");
exit(0); /* fin correcte du routeur */
}

View File

@ -0,0 +1,48 @@
%{
#include <stdlib.h>
#include "struct.h"
%}
%token M_NORTH, M_SOUTH, M_WEST, M_EAST, M_WIDTH
%token NOMBRE
%token IDENT
%union {
long i;
char *s;
}
%type <i> NOMBRE
%type <s> IDENT
%start programme
%%
programme: ldirective {if (mode_debug) printf("yacc: programme \n");}
;
ldirective: ldirective directive {if (mode_debug) printf("yacc: ldirective \n");}
| directive
;
directive: M_NORTH '(' lnom_n ')' {if (mode_debug) printf("yacc: north \n");}
| M_NORTH '(' ')' {if (mode_debug) printf("yacc: north \n");}
| M_SOUTH '(' lnom_s ')' {if (mode_debug) printf("yacc: south \n");}
| M_SOUTH '(' ')' {if (mode_debug) printf("yacc: south \n");}
| M_WEST '(' lnom_w ')' {if (mode_debug) printf("yacc: west \n");}
| M_WEST '(' ')' {if (mode_debug) printf("yacc: west \n");}
| M_EAST '(' lnom_e ')' {if (mode_debug) printf("yacc: east \n");}
| M_EAST '(' ')' {if (mode_debug) printf("yacc: east \n");}
| M_WIDTH '(' lnomchiffre ')' {if (mode_debug) printf("yacc: width \n");}
| M_WIDTH '(' ')' {if (mode_debug) printf("yacc: width \n");}
;
lnom_n: lnom_n IDENT { declaration_plot_n($2);if (mode_debug) printf("yacc: ident \n"); }
| IDENT { declaration_plot_n($1);if (mode_debug) printf("yacc: ident \n");}
;
lnom_s: lnom_s IDENT { declaration_plot_s($2); if (mode_debug) printf("yacc: ident \n");}
| IDENT { declaration_plot_s($1);if (mode_debug) printf("yacc: ident \n");}
;
lnom_w: lnom_w IDENT { declaration_plot_w($2);if (mode_debug) printf("yacc: ident \n");}
| IDENT { declaration_plot_w($1);if (mode_debug) printf("yacc: ident \n");}
;
lnom_e: lnom_e IDENT { declaration_plot_e($2);if (mode_debug) printf("yacc: ident \n");}
| IDENT { declaration_plot_e($1);if (mode_debug) printf("yacc: ident \n");}
;
lnomchiffre: lnomchiffre IDENT NOMBRE { declaration_width($2,$3);if (mode_debug) printf("yacc lnomchiffre \n");}
| IDENT NOMBRE { declaration_width($1,$2);if (mode_debug) printf("yacc lnomchiffre \n");}
;

View File

@ -0,0 +1,34 @@
%{
#include "ringram.h"
#include "struct.h"
#undef yywrap
%}
delim [ \n\t]
esp [ \t]
rc [\n]
pct [\.\,\;\:\'\"\?\/\~\`\@\^<>\!\&\*\(\)\-\_\=\+\{\}\[\]\$\%\\\|]
blanc {delim}+
chiffre [0-9]
nombre {chiffre}+
lettre [a-zA-Z_]
ident {lettre}({lettre}*{chiffre}*)*
comment [#]({lettre}*{chiffre}*{esp}*{pct}*)*{rc}
%%
{blanc} {if (mode_debug) ECHO;}
"north" {if (mode_debug) ECHO; return(M_NORTH);}
"south" {if (mode_debug) ECHO; return(M_SOUTH);}
"west" {if (mode_debug) ECHO; return(M_WEST) ;}
"east" {if (mode_debug) ECHO; return(M_EAST) ;}
"width" {if (mode_debug) ECHO; return(M_WIDTH);}
{nombre} {if (mode_debug) ECHO; sscanf(yytext,"%ld",&yylval.i);
return(NOMBRE);
}
{ident} {if (mode_debug) ECHO; yylval.s = namealloc(yytext);
return(IDENT);
}
{comment} {if (mode_debug) {ECHO; printf("commentaire\n");}}
. { return(*yytext);}
%%
int yywrap()
{return(1);}

View File

@ -0,0 +1,805 @@
/*
* 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 : ring router */
/* Fichier : routage.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*-----------------------------------------------------------------------------------*/
/* RING 22 juillet 92 ROUTAGE.C */
/* routage des equipotentielles sauf alim (deja fait) */
/*-----------------------------------------------------------------------------------*/
#include "routage.h"
#include "placement.h"
#include "sesame.h"
/*-----------------------------------------------------------------------------------*/
/* Remplit les ptype listes de projetes des equipotentielles, par calcul de leur */
/* abscisse curviligne, puis reordonnancement des coordonnees pour garder le bipoint */
/* le plus grand */
/*-----------------------------------------------------------------------------------*/
void remplit_eq_curv(LST_EQUIPO lst_equipo, COEUR lecoeur)
{
LST_EQUIPO equipo_vdd, equipo_vss;
recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
while (NULL != lst_equipo) {
if ((lst_equipo != equipo_vdd) && (lst_equipo != equipo_vss)) {
calcul_eq_proj(lst_equipo, lecoeur);
ordonne_eq_proj(lst_equipo, lecoeur);
}
lst_equipo = lst_equipo->suiv;
}
}
/*-----------------------------------------------------------------------------------*/
/* Remplit la ptype liste de coordonnees avec valeur de l'abscisse curviligne, en */
/* triant ds l'ordre croissant. */
/*-----------------------------------------------------------------------------------*/
void calcul_eq_proj(LST_EQUIPO equipo, COEUR lecoeur)
{
LST_PSEUDO_CON con;
chain_list * lst_con;
PT_COORDONNEES coord;
long valcurv;
lst_con = equipo->lst_con;
(equipo->cour).lst_projetes = NULL;
while (lst_con) {
con = (LST_PSEUDO_CON) lst_con->DATA;
if (NULL != con->deport)
coord = con->deport;
else
coord = con->coord;
valcurv = calcul_curv(con, lecoeur);
insere_valcurv(valcurv, coord, equipo);
lst_con = lst_con->NEXT;
}
}
/*-----------------------------------------------------------------------------------*/
/* Calcul de l'abscisse curviligne en fonctions des coordonnees et de la face */
/*-----------------------------------------------------------------------------------*/
long calcul_curv(LST_PSEUDO_CON con, COEUR lecoeur)
{
long valcurv = 0;
PT_COORDONNEES coord;
if (NULL != con->deport)
coord = con->deport;
else
coord = con->coord;
switch (con->face) {
case OUEST :
valcurv = coord->yabs - lecoeur.coord.yabs;
break;
case NORD :
valcurv = lecoeur.height + coord->xabs - lecoeur.coord.xabs;
break;
case EST :
valcurv = lecoeur.height + lecoeur.width + lecoeur.height - (coord->yabs - lecoeur.coord.yabs);
break;
case SUD :
valcurv = lecoeur.height + lecoeur.width + lecoeur.height + lecoeur.width - (coord->xabs - lecoeur.coord.xabs);
break;
}
if (mode_debug)
printf("Valcurv %ld con %s face %d \n", valcurv, con->nom_con, con->face);
return(valcurv);
}
/*-------------------------------------------------------------------------------------*/
/* cette procedure insere les coord et sa valeur curviligne dans la ptype list en */
/* triant par ordre croissant */
/*-------------------------------------------------------------------------------------*/
void insere_valcurv(long valcurv, PT_COORDONNEES coord, LST_EQUIPO equipo)
{
ptype_list * lst_proj, *prec_proj;
prec_proj = lst_proj = (equipo->cour).lst_projetes;
if (NULL == lst_proj)
(equipo->cour).lst_projetes = addptype(lst_proj, valcurv, (void * ) coord);
else {
while (NULL != lst_proj) {
if (valcurv <= lst_proj->TYPE) {
if (lst_proj == (equipo->cour).lst_projetes) /* tete de liste */
(equipo->cour).lst_projetes = addptype(lst_proj, valcurv, (void * ) coord);
else
{
lst_proj = addptype(lst_proj, valcurv, (void * ) coord);
prec_proj->NEXT = lst_proj;
}
break;
}
prec_proj = lst_proj;
lst_proj = lst_proj->NEXT;
}
if (NULL == lst_proj) {
lst_proj = addptype(lst_proj, valcurv, (void * ) coord);
prec_proj->NEXT = lst_proj;
}
} /* fin du else */
}
/*------------------------------------------------------------------------------------*/
/* Cette procedure ordonne les coordonnees des projetes en prenant pour depart et fin */
/* le bipoint le plus grand , ceci en utilisant les distances curvilignes calculees */
/* precedemment. */
/*------------------------------------------------------------------------------------*/
void ordonne_eq_proj(LST_EQUIPO equipo, COEUR lecoeur)
{
ptype_list * lst_proj = NULL, *prec_proj = NULL, *prem = NULL, *deux = NULL, *precprem = NULL;
long delta = 0, deltamax = 0;
prec_proj = lst_proj = (equipo->cour).lst_projetes;
if (mode_debug)
printf("Equipo no %ld\n", equipo->index);
while ((NULL != lst_proj) && (NULL != lst_proj->NEXT)) {
delta = (lst_proj->NEXT)->TYPE - lst_proj->TYPE;
if (mode_debug)
printf("Delta %5ld\n", delta);
if (delta > deltamax) {
prem = lst_proj;
precprem = prec_proj;
deux = lst_proj->NEXT;
deltamax = delta;
}
prec_proj = lst_proj;
lst_proj = lst_proj->NEXT;
}
/* -------------------------------------------------- */
/* dist curviligne entre le 1er et le dernier projete */
/* -------------------------------------------------- */
if (prec_proj == (equipo->cour).lst_projetes) /* tete liste */
prec_proj = ((equipo->cour).lst_projetes)->NEXT;
/* ---------------------------------------- */
/* prec_proj pointe sur la derniere cellule */
/* ---------------------------------------- */
delta = 2 * lecoeur.height + 2 * lecoeur.width + ((equipo->cour).lst_projetes)->TYPE - prec_proj->TYPE;
;
if (mode_debug)
printf("Delta entre 1er et der %5ld deltamax %5ld\n", delta, deltamax);
if (delta < deltamax) /* sinon deja ordonne on bouge pas (>=) */ {
/* ----------------------------------------------------------------------------- */
/* on remplit la valeur perimetre de la couronne , servira pour trier les equipo */
/* ----------------------------------------------------------------------------- */
(equipo->cour).perimetre = lecoeur.width * 2 + lecoeur.height * 2 - deltamax;
if (mode_debug)
printf("Deltamax trouve %ld\n", deltamax);
lst_proj = deux;
while (NULL != deux->NEXT)
deux = deux->NEXT; /* on va en fin de liste */
/* ----------------------------------------------- */
/* et on chaine avec le debut de la liste suivante */
/* ----------------------------------------------- */
deux->NEXT = (equipo->cour).lst_projetes;
prem->NEXT = NULL; /* fin de la liste */
(equipo->cour).lst_projetes = lst_proj; /* tete de liste */
} else {
/* ----------------------------------------------------------------------------- */
/* on remplit la valeur perimetre de la couronne , servira pour trier les equipo */
/* ----------------------------------------------------------------------------- */
(equipo->cour).perimetre = lecoeur.width * 2 + lecoeur.height * 2 - delta;
}
}
/*-------------------------------------------------------------------------------------*/
/* Cette procedure route toutes les equipotentielles (sauf alim) en 2 phases: */
/* - routage de la couronne associee */
/* - routage des colonnes a partir des connecteurs de l'equipotentielle */
/*-------------------------------------------------------------------------------------*/
void route_equipo(long piste_infalim[NB_FACES], LST_EQUIPO lst_equipo,
COEUR lecoeur, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES])
{
long piste_cour[NB_FACES];
LST_EQUIPO equipo_vdd, equipo_vss;
recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
while (NULL != lst_equipo) {
if ((lst_equipo != equipo_vdd) && (lst_equipo != equipo_vss)) {
if (mode_debug)
printf("Routage des equipotentielles (sauf alim) %ld \n", lst_equipo->index);
construit_couronne(piste_cour, piste_infalim, lst_equipo, lecoeur, segx_occ, segy_occ);
poseseg_colonnes(piste_cour, lst_equipo, segx_occ, segy_occ);
}
lst_equipo = lst_equipo->suiv;
}
}
/*------------------------------------------------------------------------------------*/
/* Cette procedure contruit la couronne associee a l'equipotentielle a partir de la */
/* liste des projetes construite. */
/*------------------------------------------------------------------------------------*/
void construit_couronne(long piste_cour[NB_FACES], long piste_infalim[NB_FACES],
LST_EQUIPO equipo, COEUR lecoeur, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES])
{
PT_COORDONNEES coin = NULL, nouveaucoin = NULL, debut_coor;
LST_PSEUDO_CON prec_con = NULL, con = NULL;
LST_SEGMENT * segpiste = NULL;
long pistealim = 0, largmetalpiste = 0, pistedebut = 0;
ptype_list * lst_proj, *prec_proj;
int change_face = 0, firstface = 1, segpiste_enplus = 0;
char metalpiste = 0;
lst_proj = (equipo->cour).lst_projetes;
while (NULL != lst_proj) {
if (!firstface)
if (segpiste_enplus) {
debut_coor = nouveaucoin;
segpiste_enplus = 0;
switch (prec_con->face) /* mise a jour de la fin du segment supplementaire */ {
case SUD:
nouveaucoin->xabs = lecoeur.coord.xabs - piste_cour[OUEST] * pitch;
break;
case NORD:
nouveaucoin->xabs = lecoeur.coord.xabs + lecoeur.width + piste_cour[EST] * pitch;
break;
case EST:
nouveaucoin->yabs = lecoeur.coord.yabs - piste_cour[SUD] * pitch;
break;
case OUEST:
nouveaucoin->yabs = lecoeur.coord.xabs + lecoeur.height + piste_cour[NORD] * pitch;
break;
}
if (mode_debug)
printf("construit cour face %d debutcoorx %ld nouveaucoin x %ld debpt %d coinpt%d\n",
(int)prec_con->face, debut_coor->xabs, nouveaucoin->xabs, (int)debut_coor, (int)nouveaucoin);
} /* fin du if */
else {
debut_coor = coin;
switch (prec_con->face) /* mise a jour des coord du coin pour la face suivante */ {
case SUD:
coin->yabs = lecoeur.coord.yabs - pistedebut * pitch;
break;
case NORD:
coin->yabs = lecoeur.height + lecoeur.coord.yabs + pistedebut * pitch;
break;
case EST:
coin->xabs = lecoeur.width + lecoeur.coord.xabs + pistedebut * pitch;
break;
case OUEST:
coin->xabs = lecoeur.coord.xabs - pistedebut * pitch;
break;
}
} /* fin du else */
else
debut_coor = (PT_COORDONNEES)lst_proj->DATA; /* c'est la 1ere fois */
prec_proj = lst_proj ;
prec_con = (LST_PSEUDO_CON)((PT_COORDONNEES)lst_proj->DATA)->proprio;
lst_proj = lst_proj->NEXT;
change_face = 0;
if (mode_debug)
printf("prec-con-pt %d\n", (int)prec_con);
while ((NULL != lst_proj) && (!change_face)) {
con = (LST_PSEUDO_CON)((PT_COORDONNEES)lst_proj->DATA)->proprio;
if (mode_debug)
printf("con-pt %d\n", (int)con);
change_face = prec_con->face != con->face;
if (!change_face) {
prec_con = con;
prec_proj = lst_proj;
lst_proj = lst_proj->NEXT;
}
}
switch (prec_con->face) {
case SUD :
case NORD:
segpiste = segx_occ;
metalpiste = xmetal;
largmetalpiste = xmetal_width;
break;
case EST :
case OUEST:
segpiste = segy_occ;
metalpiste = ymetal;
largmetalpiste = ymetal_width;
break;
}
if (change_face) {
alloue_coord(0L, 0, &coin);
switch (prec_con->face) {
/* ---------------------------------------------------------------------- */
/* Au plus un seul segment piste est rajoute */
/* les valeurs 10 ajoutees ou enlevees sont totalement arbitraires, mais */
/* sont destinees pour les connecteurs placees en face des coins du coeur */
/* sinon mauvais tri des coordonnes ds alloue_etchainesegment */
/* cas tres rare mais POSSIBLE ! */
/* ---------------------------------------------------------------------- */
case SUD :
coin->xabs = lecoeur.coord.xabs - 10;
if (con->face != OUEST) {
segpiste_enplus = 1;
ajout_segmentpiste(coin, &nouveaucoin, OUEST, piste_cour, piste_infalim, equipo,
lecoeur, segx_occ, segy_occ);
}
break;
case NORD:
coin->xabs = lecoeur.width + lecoeur.coord.xabs + 10;
if (con->face != EST) {
segpiste_enplus = 1;
ajout_segmentpiste(coin, &nouveaucoin, EST, piste_cour, piste_infalim, equipo, lecoeur,
segx_occ, segy_occ);
}
break;
case EST :
coin->yabs = lecoeur.coord.yabs - 10;
if (con->face != SUD) {
segpiste_enplus = 1;
ajout_segmentpiste(coin, &nouveaucoin, SUD, piste_cour, piste_infalim, equipo, lecoeur,
segx_occ, segy_occ);
}
break;
case OUEST:
coin->yabs = lecoeur.height + lecoeur.coord.yabs + 10;
if (con->face != NORD) {
segpiste_enplus = 1;
ajout_segmentpiste(coin, &nouveaucoin, NORD, piste_cour, piste_infalim, equipo, lecoeur,
segx_occ, segy_occ);
}
break;
}
} /* fin du if */ else
coin = (PT_COORDONNEES)prec_proj->DATA;
pistedebut = 1;
pistealim = piste_infalim[prec_con->face];
while ((pistedebut != pistealim) && (!segment_libre(debut_coor, coin, pistedebut, pistedebut, prec_con->face,
SEG_PISTE, segpiste, metalpiste)))
pistedebut++;
if (pistedebut == pistealim)
ringerreur(ERR_NOPISTE, &(prec_con->face), NULL);
piste_cour[prec_con->face] = pistedebut;
alloue_etchaine_segment(debut_coor, coin, pistedebut, pistedebut, prec_con->face, SEG_PISTE, segpiste, largmetalpiste,
metalpiste, VRAI_SEG, AVEC_VIA, equipo);
if (segpiste_enplus) {
switch (prec_con->face) /* mise a jour du debut segment supplementaire */ {
case SUD:
coin->yabs = lecoeur.coord.yabs - pistedebut * pitch;
coin->xabs = lecoeur.coord.xabs - piste_cour[OUEST] * pitch;
break;
case NORD:
coin->yabs = lecoeur.height + lecoeur.coord.yabs + pistedebut * pitch;
coin->xabs = lecoeur.coord.xabs + lecoeur.width + piste_cour[EST] * pitch;
break;
case EST:
coin->xabs = lecoeur.width + lecoeur.coord.xabs + pistedebut * pitch;
coin->yabs = lecoeur.coord.yabs - piste_cour[SUD] * pitch;
break;
case OUEST:
coin->xabs = lecoeur.coord.xabs - pistedebut * pitch;
coin->yabs = lecoeur.coord.yabs + lecoeur.height + piste_cour[NORD] * pitch;
break;
}
} /* fin du if */
if (firstface)
firstface = 0 ;
else /* mise a jour des coordonnees du precedent coin de la face precedente */ {
switch (prec_con->face) {
case SUD:
debut_coor->yabs = lecoeur.coord.yabs - pistedebut * pitch;
break;
case NORD:
debut_coor->yabs = lecoeur.height + lecoeur.coord.yabs + pistedebut * pitch;
break;
case EST:
debut_coor->xabs = lecoeur.width + lecoeur.coord.xabs + pistedebut * pitch;
break;
case OUEST:
debut_coor->xabs = lecoeur.coord.xabs - pistedebut * pitch;
break;
}
} /* fin du else */
if (mode_debug)
printf("construit cour face %d debutcoorx %ld coin x %ld debpt %d coinpt%d\n", (int)prec_con->face,
debut_coor->xabs, coin->xabs, (int)debut_coor, (int)coin);
} /* fin du 1er while */
}
/*----------------------------------------------------------------------------------*/
/* Cette procedure tire un segment de type seg_piste pour completer une couronne. */
/* Rq: on ajoutera au maximum un segment de ce type par couronne, sinon ca veut dire*/
/* qu'il existe un plus court chemin dans l'autre sens. */
/*----------------------------------------------------------------------------------*/
void ajout_segmentpiste(PT_COORDONNEES coin, PT_COORDONNEES *nouveaucoin,
int face, long piste_cour[NB_FACES], long piste_infalim[NB_FACES],
LST_EQUIPO equipo, COEUR lecoeur, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES])
{
LST_SEGMENT * segpiste = NULL;
long pistealim = 0, largmetalpiste = 0, pistedebut = 0;
char metalpiste = 0;
alloue_coord(0L, 0, nouveaucoin);
switch (face) {
/* ---------------------------------------------------------------------- */
/* les valeurs 10 ajoutees ou enlevees sont totalement arbitraires, mais */
/* sont destinees pour les connecteurs placees en face des coins du coeur */
/* sinon mauvais tri des coordonnes ds alloue_etchainesegment */
/* cas tres rare mais POSSIBLE ! */
/* ---------------------------------------------------------------------- */
case SUD :
coin->xabs = lecoeur.coord.xabs + lecoeur.width + 10;
(*nouveaucoin)->xabs = lecoeur.coord.xabs - 10;
segpiste = segx_occ;
metalpiste = xmetal;
largmetalpiste = xmetal_width;
break;
case NORD:
coin->xabs = lecoeur.coord.xabs - 10;
(*nouveaucoin)->xabs = lecoeur.width + lecoeur.coord.xabs + 10;
segpiste = segx_occ;
metalpiste = xmetal;
largmetalpiste = xmetal_width;
break;
case EST :
coin->yabs = lecoeur.coord.yabs + lecoeur.height + 10;
(*nouveaucoin)->yabs = lecoeur.coord.yabs - 10;
segpiste = segy_occ;
metalpiste = ymetal;
largmetalpiste = ymetal_width;
break;
case OUEST:
coin->yabs = lecoeur.coord.yabs - 10;
(*nouveaucoin)->yabs = lecoeur.height + lecoeur.coord.yabs + 10;
segpiste = segy_occ;
metalpiste = ymetal;
largmetalpiste = ymetal_width;
break;
}
pistedebut = 1;
pistealim = piste_infalim[face];
while ((pistedebut != pistealim) && (!segment_libre(coin, (*nouveaucoin), pistedebut, pistedebut, face, SEG_PISTE,
segpiste, metalpiste)))
pistedebut++;
if (pistedebut == pistealim)
ringerreur(ERR_NOPISTE, &face, NULL);
piste_cour[face] = pistedebut;
alloue_etchaine_segment(coin, (*nouveaucoin), pistedebut, pistedebut, face, SEG_PISTE, segpiste, largmetalpiste,
metalpiste, VRAI_SEG, AVEC_VIA, equipo);
}
/*--------------------------------------------------------------------------------------*/
/* Une fois la couronne partielle de l'equipotentielle posee, on tire les colonnes */
/* issues des connecteurs, no de piste sont dans piste_cour */
/* Modif Verif de la largeur metal colonne pour eviter bug avec pad12 et pad15 */
/*--------------------------------------------------------------------------------------*/
void poseseg_colonnes(long piste_cour[NB_FACES], LST_EQUIPO equipo,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES])
{
PT_COORDONNEES debut_coor;
LST_PSEUDO_CON con;
LST_SEGMENT * segcol = NULL;
long largeurmin = 0, largeurvia = 0, largeurseg = 0;
char metalcol = 0;
ptype_list * lst_proj;
lst_proj = (equipo->cour).lst_projetes;
while (NULL != lst_proj) {
con = (LST_PSEUDO_CON) ((PT_COORDONNEES)lst_proj->DATA)->proprio;
if (NULL == con)
ringerreur(ERR_INTERNE_EQ, NULL, NULL);
debut_coor = (PT_COORDONNEES) lst_proj->DATA;
switch (con->face) {
case SUD :
case NORD:
segcol = segy_occ;
metalcol = ymetal;
largeurmin = ymetal_width;
largeurvia = ymetal_wvia;
break;
case EST :
case OUEST:
segcol = segx_occ;
metalcol = xmetal;
largeurvia = xmetal_wvia;
largeurmin = xmetal_width;
break;
}
if (segment_libre(debut_coor, debut_coor, debut_coor->piste, piste_cour[con->face], con->face, SEG_COL, segcol,
metalcol)) {
if (con->largeur > largeurvia)
largeurseg = largeurvia;
else if (con->largeur < largeurmin)
largeurseg = largeurmin;
else
largeurseg = con->largeur;
alloue_etchaine_segment(debut_coor, debut_coor, debut_coor->piste, piste_cour[con->face], con->face,
SEG_COL, segcol, largeurseg, metalcol, VRAI_SEG, AVEC_VIA, equipo);
} else
ringerreur(ERR_NOCOL, (void * )con, NULL);
lst_proj = lst_proj->NEXT;
}
}
/*----------------------------------------------------------------------------------*/
/* Cette procedure ordonne les equipotentielles selon les criteres: */
/* -- les alim en tete (pour acces plus rapide */
/* -- les coeur-coeur par ordre curviligne decroissant */
/* -- les coeur-plot par ordre curviligne decroissant */
/* -- les plot-plot par ordre curviligne decroissant */
/* -- les autres equipotentielles restantes */
/*----------------------------------------------------------------------------------*/
void ordonne_equipotentielles(LST_EQUIPO *lst_equipo)
{
LST_EQUIPO eq, lst_eq = *lst_equipo;
chain_list * lst_alim = NULL, *lst_coeurcoeur = NULL, *lst_coeurplot = NULL;
chain_list * lst_plotplot = NULL, *lst_reste = NULL, *lst, *prec_lst;
long perimetre;
/* eclatement en 4 liste triees */
while (NULL != lst_eq) {
switch (lst_eq->type) {
case ALIM:
lst_alim = addchain(lst_alim, (void * )lst_eq);
break;
case COEUR_COEUR:
perimetre = (lst_eq->cour).perimetre;
prec_lst = lst = lst_coeurcoeur;
if (NULL == lst)
lst_coeurcoeur = addchain(lst_coeurcoeur, (void * )lst_eq);
else
{
while (NULL != lst) {
if (perimetre > (((LST_EQUIPO)lst->DATA)->cour).perimetre) {
if (lst == lst_coeurcoeur) /* tete de liste */
lst_coeurcoeur = addchain(lst_coeurcoeur, (void * )lst_eq);
else
{
lst = addchain(lst, (void * ) lst_eq);
prec_lst->NEXT = lst;
}
break;
}
prec_lst = lst;
lst = lst->NEXT;
}
if (NULL == lst) {
lst = addchain(lst, (void * ) lst_eq);
prec_lst->NEXT = lst;
}
} /* fin du else */
break;
case COEUR_PLOT:
perimetre = (lst_eq->cour).perimetre;
prec_lst = lst = lst_coeurplot;
if (NULL == lst)
lst_coeurplot = addchain(lst_coeurplot, (void * )lst_eq);
else
{
while (NULL != lst) {
if (perimetre > (((LST_EQUIPO)lst->DATA)->cour).perimetre) {
if (lst == lst_coeurplot) /* tete de liste */
lst_coeurplot = addchain(lst_coeurplot, (void * )lst_eq);
else
{
lst = addchain(lst, (void * ) lst_eq);
prec_lst->NEXT = lst;
}
break;
}
prec_lst = lst;
lst = lst->NEXT;
}
if (NULL == lst) {
lst = addchain(lst, (void * ) lst_eq);
prec_lst->NEXT = lst;
}
} /* fin du else */
break;
case PLOT_PLOT:
perimetre = (lst_eq->cour).perimetre;
prec_lst = lst = lst_plotplot;
if (NULL == lst)
lst_plotplot = addchain(lst_plotplot, (void * )lst_eq);
else
{
while (NULL != lst) {
if (perimetre > (((LST_EQUIPO)lst->DATA)->cour).perimetre) {
if (lst == lst_plotplot) /* tete de liste */
lst_plotplot = addchain(lst_plotplot, (void * )lst_eq);
else
{
lst = addchain(lst, (void * ) lst_eq);
prec_lst->NEXT = lst;
}
break;
}
prec_lst = lst;
lst = lst->NEXT;
}
if (NULL == lst) {
lst = addchain(lst, (void * ) lst_eq);
prec_lst->NEXT = lst;
}
} /* fin du else */
break;
default:
lst_reste = addchain(lst_reste, (void * )lst_reste);
break;
}
lst_eq = lst_eq->suiv;
}
/* --------------------------------------------------- */
/* fusion des listes triees selon les criteres choisis */
/* --------------------------------------------------- */
if ((NULL == lst_alim) || (NULL == lst_alim->NEXT))
ringerreur(ERR_INTERNE_EQ, NULL, NULL);
eq = lst_eq = (LST_EQUIPO) lst_alim->DATA;
lst = lst_alim->NEXT;
eq->suiv = (LST_EQUIPO) lst->DATA;
eq = eq->suiv;
lst = lst_coeurcoeur;
while (NULL != lst) {
eq->suiv = (LST_EQUIPO) lst->DATA;
eq = eq->suiv;
lst = lst->NEXT;
}
lst = lst_coeurplot;
while (NULL != lst) {
eq->suiv = (LST_EQUIPO) lst->DATA;
eq = eq->suiv;
lst = lst->NEXT;
}
lst = lst_plotplot;
while (NULL != lst) {
eq->suiv = (LST_EQUIPO) lst->DATA;
eq = eq->suiv;
lst = lst->NEXT;
}
lst = lst_reste;
while (NULL != lst) {
eq->suiv = (LST_EQUIPO) lst->DATA;
eq = eq->suiv;
lst = lst->NEXT;
}
eq->suiv = NULL;
(*lst_equipo) = lst_eq;
}

View File

@ -0,0 +1,28 @@
#ifndef __ROUTAGE_H
#define __ROUTAGE_H
#include "struct.h"
extern void remplit_eq_curv(LST_EQUIPO lst_equipo, COEUR lecoeur);
extern void insere_valcurv(long valcurv, PT_COORDONNEES coord, LST_EQUIPO equipo);
extern void ordonne_eq_proj(LST_EQUIPO equipo, COEUR lecoeur);
extern void route_equipo(long piste_infalim[NB_FACES], LST_EQUIPO lst_equipo,
COEUR lecoeur, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES]);
extern void construit_couronne(long piste_cour[NB_FACES], long piste_infalim[NB_FACES],
LST_EQUIPO equipo, COEUR lecoeur, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES]);
extern void ajout_segmentpiste(PT_COORDONNEES coin, PT_COORDONNEES *nouveaucoin,
int face, long piste_cour[NB_FACES], long piste_infalim[NB_FACES],
LST_EQUIPO equipo, COEUR lecoeur, LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES]);
extern void poseseg_colonnes(long piste_cour[NB_FACES], LST_EQUIPO equipo,
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES]);
extern void ordonne_equipotentielles(LST_EQUIPO *lst_equipo);
void calcul_eq_proj(LST_EQUIPO equipo, COEUR lecoeur);
long calcul_curv(LST_PSEUDO_CON con, COEUR lecoeur);
#endif /* __ROUTAGE_H */

View File

@ -0,0 +1,688 @@
/*
* 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 : ring router */
/* Fichier : routalim.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*-----------------------------------------------------------------------------------*/
/* RING 21 juillet 92 ROUTALIM.C */
/* routage des alim : couronne + colonnes + deports eventuels */
/*-----------------------------------------------------------------------------------*/
#include "routalim.h"
#include "placement.h"
#include "sesame.h"
/*-------------------------------------------------------------------------------------*/
/* Cette joyeuse procedure pose les couronnes d'alimentation superieures et inferieures*/
/* et retourne les numeros des pistes d'alim dans 2 tableaux coursup[] et courinf[] */
/*-------------------------------------------------------------------------------------*/
void pose_couralim(char *coursup, long piste_sup[NB_FACES], long piste_inf[NB_FACES],
LST_EQUIPO lst_equipo, COEUR lecoeur, BARRE_PLOTS tab_plots[NB_FACES],
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long tabpiste[NB_FACES])
{
long wtheovdd, wtheovss, wreelvdd_ymetal, wreelvdd_xmetal, wreelvss_xmetal;
long wreelvss_ymetal, maxlarg_y, maxlarg_x;
long nbpistemoinsvdd_ymetal, nbpistemoinsvdd_xmetal;
long nbpistemoinsvss_ymetal, nbpistemoinsvss_xmetal;
long nbpistemoinsalim_sup = 0, wreelalim_sup = 0, nbpistemoinsalim_inf = 0, wreelalim_inf = 0, pistealim = 0;
long largmetalpiste = 0, pistefin = 0, pistefinpardefaut = 0;
/* ------------------------------------------------ */
/* stocker la derniere piste libre pour chaque face */
/* ------------------------------------------------ */
int face;
char metalpiste = 0;
LST_SEGMENT * segpiste = NULL;
LST_EQUIPO equipo_vdd = NULL, equipo_vss = NULL, eqalim_sup = NULL, eqalim_inf = NULL;
PT_COORDONNEES c1alim_sup = NULL, c2alim_sup = NULL, c1alim_inf = NULL, c2alim_inf = NULL;
PT_COORDONNEES c1horalim_sup, c2horalim_sup, c1horalim_inf, c2horalim_inf;
PT_COORDONNEES c1veralim_sup, c2veralim_sup, c1veralim_inf, c2veralim_inf;
recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
largeur_vddvss(equipo_vdd, equipo_vss, &wtheovdd, &wtheovss);
if (ymetal_width > ymetal_wvia)
maxlarg_y = ymetal_width;
else
maxlarg_y = ymetal_wvia;
if (xmetal_width > xmetal_wvia)
maxlarg_x = xmetal_width;
else
maxlarg_x = xmetal_wvia;
/* ---------------------------------------------------------- */
/* ON se debrouille pour tomber sur un nombre de pistes paire */
/* ---------------------------------------------------------- */
wreelvdd_ymetal = ((wtheovdd + pitch) / (2 * pitch )) * (2 * pitch) + maxlarg_y;
wreelvdd_xmetal = ((wtheovdd + pitch) / (2 * pitch )) * (2 * pitch) + maxlarg_x;
wreelvss_ymetal = ((wtheovss + pitch) / (2 * pitch )) * (2 * pitch) + maxlarg_y;
wreelvss_xmetal = ((wtheovss + pitch) / (2 * pitch )) * (2 * pitch) + maxlarg_x;
if (mode_debug)
printf("VDD largeury %5ld largeurx %5ld\n", wreelvdd_ymetal, wreelvdd_xmetal);
if (mode_debug)
printf("VSS largeury %5ld largeurx %5ld\n", wreelvss_ymetal, wreelvss_xmetal);
if (mode_debug)
printf("VDDpitch largeury %5ld largeurx %5ld\n", wreelvdd_ymetal / pitch, wreelvdd_xmetal / pitch);
if (mode_debug)
printf("VSSpitch largeury %5ld largeurx %5ld\n", wreelvss_ymetal / pitch, wreelvss_xmetal / pitch);
if (mode_debug)
printf("COEUR width %ld height %ld\n", lecoeur.width, lecoeur.height);
nbpistemoinsvdd_ymetal = ((wtheovdd + pitch) / (2 * pitch ));
nbpistemoinsvdd_xmetal = ((wtheovdd + pitch) / (2 * pitch ));
nbpistemoinsvss_ymetal = ((wtheovdd + pitch) / (2 * pitch ));
nbpistemoinsvss_xmetal = ((wtheovdd + pitch) / (2 * pitch ));
if (mode_debug)
printf("VDDretirepiste largeury %5ld largeurx %5ld\n", nbpistemoinsvdd_ymetal, nbpistemoinsvdd_xmetal);
if (mode_debug)
printf("VSSretirepiste largeury %5ld largeurx %5ld\n", nbpistemoinsvss_ymetal, nbpistemoinsvss_xmetal);
/*-------------------------- POSE DES COURONNES D'ALIM -------------------------------*/
/* ---------------------------------------------------------- */
/* recherche de la derniere piste libre vers la barre de plot */
/* ---------------------------------------------------------- */
alloue_coord(0L, 0, &c1horalim_sup);
alloue_coord(0L, 0, &c2horalim_sup);
alloue_coord(0L, 0, &c1veralim_sup);
alloue_coord(0L, 0, &c2veralim_sup);
alloue_coord(0L, 0, &c1horalim_inf);
alloue_coord(0L, 0, &c2horalim_inf);
alloue_coord(0L, 0, &c1veralim_inf);
alloue_coord(0L, 0, &c2veralim_inf);
/*-----------------------------------------------------------------------------------*/
/* REPRESENTATION DES 2 COURONNES D ALIM SUPERIEURE ET INFERIEURE */
/* */
/*c1horalim_sup alim_sup c2horalim_sup */
/*c2veralim_sup +-------------------------------------------+c2veralim_sup */
/* | | */
/* | alim_inf | */
/* |c1horalim_inf +--------------+c2horalim_inf| */
/* |c2veralim_inf | |c2horalim_inf| */
/* | | | | */
/* | | | | */
/* | | | | */
/* | | | | */
/* | | | | */
/* |c1horalim_inf | |c2horalim_inf| */
/* |c1veralim_sup +--------------+c1horalim_inf| */
/*c1horalim_sup | |c2horalim_sup */
/*c1veralim_sup +-------------------------------------------+c1veralim_sup */
/*-----------------------------------------------------------------------------------*/
for (face = 0 ; face < NB_FACES; face++) {
if (0 != tab_plots[face].width) {
pistefin = tab_plots[face].coord.piste - 2; /* On part de apres le deport */
switch (face) {
case NORD:
case SUD :
segpiste = segx_occ;
c1horalim_sup->xabs = lecoeur.coord.xabs;
c2horalim_sup->xabs = lecoeur.coord.xabs + lecoeur.width;
metalpiste = xmetal;
largmetalpiste = xmetal_width;
break;
case EST :
case OUEST:
segpiste = segy_occ;
c1horalim_sup->yabs = lecoeur.coord.yabs;
c2horalim_sup->yabs = lecoeur.coord.yabs + lecoeur.height;
metalpiste = ymetal;
largmetalpiste = ymetal_width;
break;
}
while ((0 != pistefin) && (!segment_libre(c1horalim_sup, c2horalim_sup, pistefin, pistefin, face,
SEG_PISTE, segpiste, metalpiste)))
pistefin--;
if (0 == pistefin)
ringerreur(ERR_NOPISTE, &face, NULL);
tabpiste[face] = pistefinpardefaut = pistefin;
} else
tabpiste[face] = 0; /* pas de barre de plots, on ne sait pas */
}
for (face = 0; face < NB_FACES; face++) /* maintenant on sait, valeur par defaut */
if (0 == tabpiste[face])
tabpiste[face] = pistefinpardefaut;
/*----------------------- PLACEMENT DES COURONNES -------------------------------------*/
for (face = 0 ; face < NB_FACES; face++) {
switch (face) {
case NORD:
case SUD :
segpiste = segx_occ;
metalpiste = xmetal;
largmetalpiste = xmetal_width;
if (coursup == eq_vdd) {
nbpistemoinsalim_sup = nbpistemoinsvdd_xmetal;
wreelalim_sup = wreelvdd_xmetal;
eqalim_sup = equipo_vdd;
nbpistemoinsalim_inf = nbpistemoinsvss_xmetal;
wreelalim_inf = wreelvss_xmetal;
eqalim_inf = equipo_vss;
} else
{
nbpistemoinsalim_sup = nbpistemoinsvss_xmetal;
wreelalim_sup = wreelvss_xmetal;
eqalim_sup = equipo_vss;
nbpistemoinsalim_inf = nbpistemoinsvdd_xmetal;
wreelalim_inf = wreelvdd_xmetal;
eqalim_inf = equipo_vdd;
}
c1veralim_sup->yabs = lecoeur.coord.yabs - ((tabpiste[SUD] - nbpistemoinsalim_sup) * pitch);
c1veralim_sup->xabs = 0;
c2veralim_sup->yabs = lecoeur.coord.yabs + lecoeur.height + ((tabpiste[NORD] - nbpistemoinsalim_sup) *
pitch);
c2veralim_sup->xabs = 0;
c1veralim_inf->yabs = c1veralim_sup->yabs + ((nbpistemoinsalim_sup + nbpistemoinsalim_inf + 2) *
pitch);
c1veralim_inf->xabs = 0;
c2veralim_inf->yabs = c2veralim_sup->yabs - ((nbpistemoinsalim_sup + nbpistemoinsalim_inf + 2) *
pitch);
c2veralim_inf->xabs = 0;
c1alim_sup = c1horalim_sup;
c2alim_sup = c2horalim_sup;
c1alim_inf = c1horalim_inf;
c2alim_inf = c2horalim_inf;
break;
case EST :
case OUEST:
segpiste = segy_occ;
metalpiste = ymetal;
largmetalpiste = ymetal_width;
if (coursup == eq_vdd) {
nbpistemoinsalim_sup = nbpistemoinsvdd_ymetal;
wreelalim_sup = wreelvdd_ymetal;
eqalim_sup = equipo_vdd;
nbpistemoinsalim_inf = nbpistemoinsvss_ymetal;
wreelalim_inf = wreelvss_ymetal;
eqalim_inf = equipo_vss;
} else
{
nbpistemoinsalim_sup = nbpistemoinsvss_ymetal;
wreelalim_sup = wreelvss_ymetal;
eqalim_sup = equipo_vss;
nbpistemoinsalim_inf = nbpistemoinsvdd_ymetal;
wreelalim_inf = wreelvdd_ymetal;
eqalim_inf = equipo_vdd;
}
c1horalim_sup->xabs = lecoeur.coord.xabs - ((tabpiste[OUEST] - nbpistemoinsalim_sup) * pitch);
c1horalim_sup->yabs = 0 ;
c2horalim_sup->xabs = lecoeur.coord.xabs + lecoeur.width + ((tabpiste[EST] - nbpistemoinsalim_sup) *
pitch);
c2horalim_sup->yabs = 0;
c1horalim_inf->xabs = c1horalim_sup->xabs + ((nbpistemoinsalim_sup + nbpistemoinsalim_inf + 2) *
pitch);
c1horalim_inf->yabs = 0;
c2horalim_inf->xabs = c2horalim_sup->xabs - ((nbpistemoinsalim_sup + nbpistemoinsalim_inf + 2) *
pitch);
c2horalim_inf->yabs = 0;
c1alim_sup = c1veralim_sup;
c2alim_sup = c2veralim_sup;
c1alim_inf = c1veralim_inf;
c2alim_inf = c2veralim_inf;
break;
} /* fin du switch */
pistefin = tabpiste[face]; /* derniere piste libre */
piste_sup[face] = pistealim = pistefin - nbpistemoinsalim_sup ;
/*----------------------------- ALIM COURONNE SUPERIEURE ------------------------------*/
/* ------------ */
/* faux segment */
/* ------------ */
for (; pistefin > pistealim; pistefin--)
alloue_etchaine_segment(c1alim_sup, c2alim_sup, pistefin, pistefin, face, SEG_PISTE, segpiste, largmetalpiste,
metalpiste, FAUX_SEG, AVEC_VIA, eqalim_sup);
/* ------------ */
/* vrai segment */
/* ------------ */
alloue_etchaine_segment(c1alim_sup, c2alim_sup, pistealim, pistealim, face, SEG_PISTE, segpiste, wreelalim_sup,
metalpiste, VRAI_SEG, AVEC_VIA, eqalim_sup);
/* ------------ */
/* faux segment */
/* ------------ */
for (pistefin = pistealim - 1; pistefin >= pistealim - nbpistemoinsalim_sup; pistefin--)
alloue_etchaine_segment(c1alim_sup, c2alim_sup, pistefin, pistefin, face, SEG_PISTE, segpiste, largmetalpiste,
metalpiste, FAUX_SEG, AVEC_VIA, eqalim_sup);
/*----------------------------- ALIM COURONNE INFERIEURE ------------------------------*/
pistefin --;
piste_inf[face] = pistealim = pistefin - nbpistemoinsalim_inf;
/* ------------ */
/* faux segment */
/* ------------ */
for (; pistefin > pistealim; pistefin--)
alloue_etchaine_segment(c1alim_inf, c2alim_inf, pistefin, pistefin, face, SEG_PISTE, segpiste, largmetalpiste,
metalpiste, FAUX_SEG, AVEC_VIA, eqalim_inf);
/* ------------ */
/* vrai segment */
/* ------------ */
alloue_etchaine_segment(c1alim_inf, c2alim_inf, pistealim, pistealim, face, SEG_PISTE, segpiste, wreelalim_inf,
metalpiste, VRAI_SEG, AVEC_VIA, eqalim_inf);
/* ------------ */
/* faux segment */
/* ------------ */
for (pistefin = pistealim - 1; pistefin > pistealim - nbpistemoinsalim_inf - 1; pistefin--)
alloue_etchaine_segment(c1alim_inf, c2alim_inf, pistefin, pistefin, face, SEG_PISTE, segpiste, largmetalpiste,
metalpiste, FAUX_SEG, AVEC_VIA, eqalim_inf);
} /* fin du for */
}
/*-------------------------------------------------------------------------------------*/
void tire_etdeport_alim(char *coursup, long piste_sup[NB_FACES],
long piste_inf[NB_FACES], LST_EQUIPO lst_equipo,
BARRE_PLOTS tab_plots[NB_FACES], LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES], long tabpiste[NB_FACES])
{
LST_EQUIPO equipo_vdd, equipo_vss;
recherche_equipo_alim(&equipo_vdd, &equipo_vss, lst_equipo);
tire_etdeport_unealim(coursup, eq_vdd, piste_sup, piste_inf, equipo_vdd, tab_plots, segx_occ, segy_occ, tabpiste);
tire_etdeport_unealim(coursup, eq_vss, piste_sup, piste_inf, equipo_vss, tab_plots, segx_occ, segy_occ, tabpiste);
}
/*----------------------------------------------------------------------------------------*/
/* cette procedure tire les fils d'une alim sur la couronne precedemment posees et traite */
/* les deports eventuels */
/* On peut se servir de tabpiste pour poser des faux segments, au cas ou on */
/* tire une alim ds le mauvais layer, ceci pour eviter des croisements */
/* (courts-circuits) avec les deports eventuels de plots */
/*----------------------------------------------------------------------------------------*/
void tire_etdeport_unealim(char *coursup, char *eq_alim, long piste_sup[NB_FACES],
long piste_inf[NB_FACES], LST_EQUIPO equipo, BARRE_PLOTS tab_plots[NB_FACES],
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long tabpiste[NB_FACES])
{
chain_list * ptcour;
LST_PSEUDO_CON con;
PT_COORDONNEES c1, c2;
long p1 = 0, p2 = 0, *tabpistealim = NULL, pistealim = 0, largmetalpiste = 0, nbpistemoinsfil = 0, pistefin = 0;
long largmetalcol = 0, piste = 0, largeur = 0;
char niveaucol = 0, niveaupiste = 0;
LST_SEGMENT * segcol = NULL;
LST_SEGMENT * segpiste = NULL;
int visavis;
/* ---------------------- */
/* traitement de une alim */
/* ---------------------- */
if (mode_debug)
printf("Traitement segment alim %s\n", eq_alim);
ptcour = equipo->lst_con;
if (coursup == eq_alim)
tabpistealim = piste_sup;
else
tabpistealim = piste_inf;
while (ptcour != NULL) {
con = (LST_PSEUDO_CON) ptcour->DATA;
switch (con->face) {
case NORD:
case SUD :
niveaucol = ymetal;
niveaupiste = xmetal;
segcol = segy_occ;
segpiste = segx_occ;
largmetalpiste = xmetal_width;
largmetalcol = ymetal_width;
break;
case EST :
case OUEST:
niveaucol = xmetal;
niveaupiste = ymetal;
segcol = segx_occ;
segpiste = segy_occ;
largmetalpiste = ymetal_width;
largmetalcol = xmetal_width;
break;
} /* FIN DU SWITCH */
if ((con->coeur_plot == PLOT_CON) && (con->deport != NULL)) {
if (con->nom_con != coursup) /* foutu, on est oblige de deporter arghh */ {
/* ----------------------- */
/* deport layer uniquement */
/* ----------------------- */
if (mode_debug)
printf("POSEDEPORTALIM %s\n", con->nom_con);
c1 = c2 = con->coord; /* segment col */
p1 = con->deport->piste; /* piste calculee precedemment */
p2 = tab_plots[con->face].coord.piste;
/* ------------------------------------------------------------- */
/* ici ce n'est pas la peine de poser des faux segments, car ils */
/* ont deja ete poses dans deport_alim() */
/* ------------------------------------------------------------- */
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->layer))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->largeur,
con->layer, VRAI_SEG, AVEC_VIA, equipo) ;
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
/* -------------------------------- */
/* reste du fil jusqu'a la couronne */
/* -------------------------------- */
p2 = p1;
p1 = tabpistealim[con->face];
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, niveaucol))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->largeur,
niveaucol, VRAI_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
} /* fin trt deport layer plot */ else {
/* ----------------------------------------- */
/* on tire le fil d'alim ds le mauvais layer */
/* ----------------------------------------- */
c1 = c2 = con->coord;
p1 = tabpistealim[con->face];
p2 = tab_plots[con->face].coord.piste;
/* -------------------------------- */
/* reste du fil jusqu'a la couronne */
/* -------------------------------- */
/* -------------------------------------------------- */
/* ALLOCATION DE FAUX SEGMENTS CAR MAUVAIS LAYER TIRE */
/* -------------------------------------------------- */
for (piste = tab_plots[con->face].coord.piste; piste > (tabpiste[con->face] + 1); piste--)
if (segment_libre(c1, c2, piste, piste, con->face, SEG_PISTE, segpiste, niveaupiste))
alloue_etchaine_segment(c1, c2, piste, piste, con->face, SEG_PISTE, segpiste,
largmetalpiste, niveaupiste, FAUX_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_TIREALIM, con, NULL);
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->layer))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->largeur,
con->layer, VRAI_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
} /* fin du else */
} /* fin trt deport plot */ else {
if ((COEUR_CON == con->coeur_plot) && (con->deport != NULL)) /* deport coeur */ {
if (mode_debug)
printf("deport coeur %s xdep %ld ydep %ld piste %ld face %d width %ld\n", con->nom_con,
con->deport->xabs, con->deport->yabs, con->deport->piste, (int)con->face, con->largeur);
if (con->layer != niveaucol) /* deport layer */ {
if (mode_debug)
printf("SEGPOSEDEPORTALIM %s\n", con->nom_con);
c1 = c2 = con->coord; /* segment col */
p1 = 0;
p2 = con->deport->piste;
if ((con->face == NORD) || (con->face == SUD)) {
if ((con->deport)->xabs == (con->coord)->xabs)
p2 = con->deport->piste; /* piste calculee precedemment */
else
p2 = (con->largeur + pitch) / pitch;
} else
{
if ((con->deport)->yabs == (con->coord)->yabs)
p2 = con->deport->piste; /* piste calculee precedemment */
else
p2 = (con->largeur + pitch) / pitch;
}
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->layer))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->largeur,
con->layer, VRAI_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
if (mode_debug)
printf("seg colonne mauvais layer tire \n");
/* --------------------------- */
/* Allocation de faux segments */
/* --------------------------- */
if (con->largeur > largmetalcol) {
for (piste = 1; piste <= (p2 + (con->largeur / 2 + pitch) / pitch); piste++)
alloue_etchaine_segment(c1, c2, piste, piste, con->face, SEG_PISTE,
segpiste, largmetalpiste, niveaupiste, FAUX_SEG, AVEC_VIA, equipo);
}
} /* fin trt changement layer */ else {
p1 = 0;
p2 = 0;
c1 = c2 = con->coord;
}
/* ------------------------------------------- */
/* pose du reste de fil sur la couronne d'alim */
/* ------------------------------------------- */
if (con->largeur < largmetalcol)
largeur = largmetalcol;
else
largeur = con->largeur;
if ((con->face == NORD) || (con->face == SUD)) {
if ((con->deport)->xabs == (con->coord)->xabs) /* fil direct sur couronne */ {
p1 = p2;
p2 = tabpistealim[con->face];
visavis = 0;
} else
visavis = 1; /* vis a vis d'alim */
} else {
if ((con->deport)->yabs == (con->coord)->yabs) /* fil direct sur couronne */ {
p1 = p2;
p2 = tabpistealim[con->face];
visavis = 0;
} else
visavis = 1; /* vis a vis d'alim */
}
if (!visavis) /* pas d'autre deport */ {
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, niveaucol)) {
if (!croisementok_alimequi(con, equipo->lst_con, AVEC_TESTLAYER))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol,
largeur, niveaucol, VRAI_SEG, AVEC_VIA, equipo);
else
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol,
largeur, niveaucol, VRAI_SEG, SANS_VIA, equipo);
if (mode_debug)
printf("seg colonne layer tire sans vis a vis \n");
} else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
} else /* Pas de chance , il faut traiter vis a vis d'alim */ {
if (mode_debug)
printf("vis a vis d'alim a traiter\n");
pistefin = piste_inf[con->face];
c1 = con->coord;
c2 = con->deport;
while ((0 != pistefin) && (!segment_libre(c1, c2, pistefin, pistefin, con->face,
SEG_PISTE, segpiste, niveaupiste)))
pistefin--;
if (0 == pistefin)
ringerreur(ERR_NOPISTE, &(con->face), NULL);
nbpistemoinsfil = ((con->largeur + pitch) / (2 * pitch ));
pistealim = pistefin - nbpistemoinsfil;
c2 = con->coord;
p1 = p2;
p2 = pistealim; /* colonne tiree */
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, niveaucol))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, largeur,
niveaucol, VRAI_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
c2 = con->deport;
/* ------------ */
/* deport piste */
/* faux segment */
/* ------------ */
for (; pistefin > pistealim; pistefin--)
alloue_etchaine_segment(c1, c2, pistefin, pistefin, con->face, SEG_PISTE,
segpiste, largmetalpiste, niveaupiste, FAUX_SEG, AVEC_VIA, equipo);
/* ------------ */
/* vrai segment */
/* ------------ */
alloue_etchaine_segment(c1, c2, pistealim, pistealim, con->face, SEG_PISTE, segpiste,
largeur, niveaupiste, VRAI_SEG, AVEC_VIA, equipo);
/* ------------ */
/* faux segment */
/* ------------ */
for (pistefin = pistealim - 1; pistefin >= (pistealim - nbpistemoinsfil); pistefin--)
alloue_etchaine_segment(c1, c2, pistefin, pistefin, con->face, SEG_PISTE,
segpiste, largmetalpiste, niveaupiste, FAUX_SEG, AVEC_VIA, equipo);
/* ----------------- */
/* dernier col tiree */
/* ----------------- */
c1 = c2 = con->deport;
p1 = pistealim;
p2 = tabpistealim[con->face];
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, niveaucol))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, largeur,
niveaucol, VRAI_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
} /* fin trt vis a vis */
} /* fin trt du fil deporte du coeur */ else {
/* ----------------------------------- */
/* trt du fil d'alim sans aucun deport */
/* reste du fil jusqu'a la couronne */
/* ----------------------------------- */
c1 = c2 = con->coord;
if (con->coeur_plot == PLOT_CON) {
p2 = tab_plots[con->face].coord.piste;
p1 = tabpistealim[con->face];
} else {
p1 = 0;
p2 = tabpistealim[con->face];
}
if (COEUR_CON == con->coeur_plot) {
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->layer)) {
if (!croisementok_alimequi(con, equipo->lst_con, AVEC_TESTLAYER))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol,
con->largeur, con->layer, VRAI_SEG, AVEC_VIA, equipo);
else
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol,
con->largeur, con->layer, VRAI_SEG, SANS_VIA, equipo);
} else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
} else
{
if (segment_libre(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->layer))
alloue_etchaine_segment(c1, c2, p1, p2, con->face, SEG_COL, segcol, con->largeur,
con->layer, VRAI_SEG, AVEC_VIA, equipo);
else
ringerreur(ERR_SEGDEPORT, (void * )con, NULL);
}
} /* fin trt plot ou coeur alim sans deport */
} /* fin du if coeur */
ptcour = ptcour->NEXT;
} /* fin du while */
}

View File

@ -0,0 +1,22 @@
#ifndef __ROUTALIM_H
#define __ROUTALIM_H
#include "struct.h"
extern void pose_couralim(char *coursup, long piste_sup[NB_FACES],
long piste_inf[NB_FACES],
LST_EQUIPO lst_equipo, COEUR lecoeur, BARRE_PLOTS tab_plots[NB_FACES],
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long tabpiste[NB_FACES]);
extern void tire_etdeport_alim(char *coursup, long piste_sup[NB_FACES],
long piste_inf[NB_FACES], LST_EQUIPO lst_equipo,
BARRE_PLOTS tab_plots[NB_FACES], LST_SEGMENT segx_occ[NB_FACES],
LST_SEGMENT segy_occ[NB_FACES], long tabpiste[NB_FACES]);
void tire_etdeport_unealim(char *coursup, char *eq_alim, long piste_sup[NB_FACES],
long piste_inf[NB_FACES], LST_EQUIPO equipo, BARRE_PLOTS tab_plots[NB_FACES],
LST_SEGMENT segx_occ[NB_FACES], LST_SEGMENT segy_occ[NB_FACES],
long tabpiste[NB_FACES]);
#endif /* __ROUTALIM_H */

View File

@ -0,0 +1,608 @@
/*
* 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 : ring router */
/* Fichier : sesame.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*---------------------------------------------------------------------------------*/
/* RING 28 avril 92 SESAME.C */
/* sesame: verification de la coherence des donnees fournies (parametres, netlist, */
/* fichier parametre) et affichage de message d'ringerreur */
/*---------------------------------------------------------------------------------*/
#include <stdlib.h>
#include "sesame.h"
/*---------------------------------------------------------------------------------*/
void ringerreur(int code, void *pt_liste, void *pt_liste2)
{
loins_list * circuit_inst, *liste_inst;
locon_list * con_lo;
chain_list * liste;
int i, trouve, face;
char car;
LST_PSEUDO_CON con;
long largeurmax;
switch (code) {
case ERR_CONPH_SANS_LO:
fprintf(stderr, "The physical connector <%s> in model <%s> has no logical corresponding\n",(char *)pt_liste,(char *)pt_liste2);
break;
case ERR_CONLO_SANS_PH:
fprintf(stderr, "The logical connector <%s> in model <%s> has no physical corresponding\n",(char *)pt_liste,(char *)pt_liste2);
break;
case ERR_CONCOEUREMPTY:
fprintf(stderr, "The physical core <%s> has no connectors\n",(char *)(((COEUR *)pt_liste)->coeur_lo->INSNAME));
break;
case ERR_ARGUMENT:
usage();
break;
case ERR_CATAL:
fprintf(stderr, "The catalog file <%s> hasn't been found in MBK_WORK_LIB, and MBK_CATA_LIB path.\n", (char
*) pt_liste);
fprintf(stderr, "See your environment (command \"env\").\n");
break;
case ERR_NONCOEUR:
fprintf(stderr, "The instance of the core wasn't found.\n");
fprintf(stderr, "be carefull: logical figure core and physical figure core\n");
fprintf(stderr, " must have the same name.\n");
fprintf(stderr, "The core must not be in the catalog (see MBK_CATAL_NAME in your environment).\n");
break;
case ERR_PLUSCOEUR:
fprintf(stderr, "Several instances of the core have been found:\n");
circuit_inst = (loins_list * ) pt_liste;
while (circuit_inst != NULL) {
if (!incatalog(circuit_inst->FIGNAME))
fprintf(stderr, "\tcore name: %s\n", circuit_inst->INSNAME);
circuit_inst = circuit_inst->NEXT;
}
break;
case ERR_CIRCUITLO:
fprintf(stderr, "The figure named <%s> hasn't been found.\n", (char *) pt_liste);
break;
case ERR_CIRCUITINST:
fprintf(stderr, "The figure named <%s> doesn't own any instance.\n", (char *) pt_liste);
break;
case ERR_COEURINSTLO:
fprintf(stderr, "The logical instance core which name is <%s>, hasn't been found.\n", (char *) pt_liste);
fprintf(stderr, "Logical and physical figure core must have the same name.\n");
break;
case ERR_COEURINSTPH:
fprintf(stderr, "The physical instance core which name is <%s>, hasn't been found.\n", (char *) pt_liste);
fprintf(stderr, "Logical and physical figure core must have the same name.\n");
break;
case ERR_FICPARAM:
fprintf(stderr, "The parameter file <%s> doesn't exist.\n", (char *) pt_liste);
fprintf(stderr, "It must be present in your MBK path.\n");
break;
case ERR_VIDEFICPARAM:
fprintf(stderr, "The parameter file <%s> is empty.\n", (char *) pt_liste);
break;
case ERR_SYNPARAM:
fprintf(stderr, "Syntax error from the analysis of the parameter file .rin <%s>\n: ",
nom_fic_param);
#if 0
if ((fichier = mbkfopen(nom_fic_param, NULL, READ_TEXT)) != NULL) {
tmp = (char *) mbkalloc (800 * (unsigned int) sizeof(char));
for (i = 0; i < (*((int *) pt_liste)); i++)
ret = fgets(tmp, 799, fichier);
if (NULL != ret)
fprintf(stderr, "%s\n", tmp);
fclose(fichier);
}
#endif
fprintf(stderr, "Warning: if you use # for comments, the rest of the line will be ignored.\n");
break;
case ERR_WIDTHPARAM:
fprintf(stderr, "the width track <%d> of <%s> is too small.\n", *((int *)pt_liste2), (char *)pt_liste);
break;
case ERR_AUCUNPLOTPARAM:
fprintf(stderr, "No pad has been founded in the paramater file .rin.\n");
fprintf(stderr, "You must define at least one group of pads.\n");
break;
case ERR_NONPLOTPARAM:
fprintf(stderr, "The instance pad <%s> hasn't been found in the logical figure.\n", (char *) pt_liste);
break;
case ERR_PLUSPLOTPARAM:
fprintf(stderr, "The instance of the pad <%s>, has been found\n", (char *) pt_liste);
fprintf(stderr, "in different sections of pads in the parameter file .rin.\n");
break;
case ERR_NBPLOTPARAM:
fprintf(stderr, "Some instance pads of the logical figure\n");
fprintf(stderr, "haven't been found in the parameter file.\n");
/* ---------------------------------------------------------------------------------- */
/* Affichage des plots de la figure logique non trouves dans le fichier de parametres */
/* ---------------------------------------------------------------------------------- */
liste_inst = ((lofig_list * ) pt_liste)->LOINS;
/* ------------------------------- */
/* Parcours des instances logiques */
/* ------------------------------- */
while (liste_inst != NULL) {
trouve = 0;
/* -------------------------------------------------------- */
/* Parcours des noms d'instances definis dans fichier param */
/* -------------------------------------------------------- */
for (i = 0; ((i < NB_FACES) && (!trouve)); i++) {
liste = nom_plot[i];
while (liste != NULL) {
/* ------------------------------------------------------------------------- */
/* si trouve , on sort du while et du for, et on passe a l'instance suivante */
/* modif : chain_list pointe sur des loins maintenant */
/* ------------------------------------------------------------------------- */
if ((trouve = liste_inst->INSNAME == ((loins_list * ) liste->DATA)->INSNAME ))
break;
liste = liste->NEXT;
}
}
if ((!trouve) && (incatalog(liste_inst->FIGNAME)))
fprintf(stderr, "\tInstance not found: <%s>\n", liste_inst->INSNAME);
liste_inst = liste_inst->NEXT;
}
break;
case ERR_NONCONWIDTHPARAM:
fprintf(stderr, "The connector <%s> from the parameter file hasn't been found\n", (char *) pt_liste);
fprintf(stderr, "as a logical connector of a pad, or as a physical connector\n");
fprintf(stderr, "of the core.\n");
break;
case ERR_INTERNE_CON:
fprintf(stderr, "Internal error from the connector list.\n");
break;
case ERR_INTERNE_FIG:
fprintf(stderr, "Internal error from the physical figure list.\n");
break;
case ERR_INTERNE_EQ:
fprintf(stderr, "Internal error from the equipotential list.\n");
break;
case ERR_GRILLEINTERNE:
fprintf(stderr, "Internal error from the gate list.\n");
break;
case ERR_CONCOEUR_ENLAIR :
fprintf(stderr, "Connector <%s> of the core isn't connected.\n", (char *) pt_liste);
break;
case ERR_CONPLOT_ENLAIR :
fprintf(stderr, "Connector <%s> of the pad isn't connected.\n", (char *) pt_liste);
break;
case ERR_CONLARGEUR:
if (ymetal_width > xmetal_width)
largeurmax = ymetal_width;
else
largeurmax = xmetal_width;
if (((LST_PSEUDO_CON) pt_liste)->coeur_plot == COEUR_CON) {
fprintf(stderr, "Width of the connector <%s> is <%ld> of the core ", ((LST_PSEUDO_CON) pt_liste)->nom_con,
((LST_PSEUDO_CON) pt_liste)->largeur / SCALE_X);
if (((LST_PSEUDO_CON) pt_liste)->largeur > largeurmax)
fprintf(stderr, "is too big.\n");
else
fprintf(stderr, "isn't big enough.\n");
} else {
fprintf(stderr, "Width of the connector <%s> is <%ld> of the pad <%s> ", ((LST_PSEUDO_CON) pt_liste)->nom_con,
((LST_PSEUDO_CON) pt_liste)->largeur / SCALE_X, ((loins_list * )((LST_PSEUDO_CON) pt_liste)->con_lo->ROOT)->INSNAME);
if (((LST_PSEUDO_CON) pt_liste)->largeur > largeurmax)
fprintf(stderr, "is too big.\n");
else
fprintf(stderr, "isn't big enough.\n");
}
break;
case ERR_CONDISTANCE:
con = (LST_PSEUDO_CON) pt_liste;
if (con->coeur_plot == COEUR_CON) {
if (con->prec != NULL)
fprintf(stderr, "Distance between connector <%s> and connector <%s> of the core isn't big enough.\n",
(con->prec)->nom_con, con->nom_con);
/* con->prec si pas d'ringerreur c'est lesieur */
else
fprintf(stderr, "Distance between connector <%s> and... of the core isn't big enough.\n", con->nom_con);
} else {
if (con->prec != NULL)
fprintf(stderr, "Distance between connector <%s> of the pad <%s>, and connector <%s> of the pad <%s> isn't big enough.\n",
(con->prec)->nom_con, ((loins_list * )(con->prec)->con_lo->ROOT)->INSNAME, con->nom_con,
((loins_list * )con->con_lo->ROOT)->INSNAME);
/* con->prec si pas d'ringerreur c'est lesieur */
else
fprintf(stderr, "Distance between connector <%s> of the pad <%s> and... of the core isn't big enough.\n",
con->nom_con, ((loins_list * ) con->con_lo->ROOT)->INSNAME);
}
break;
case ERR_MANQUEALIM:
fprintf(stderr, "Power supply <vdd> and/or <vss> weren't found in the chip.\n");
break;
case ERR_BARREALIM :
face = *((int *) pt_liste);
switch (face) {
case NORD:
car = 'N';
break;
case SUD :
car = 'S';
break;
case EST:
car = 'E';
break;
case OUEST:
car = 'W';
break;
default:
car = 'X';
break;
}
fprintf(stderr, "The pads <vdd> and/or <vss> aren't place in front of the side '%c' of the core.\n", car);
fprintf(stderr, "You may place again the supply pads, in order to center them in front of the core.\n");
break;
case ERR_ECHECDEPORT :
con = (LST_PSEUDO_CON) pt_liste;
fprintf(stderr, "No space hasn't been found for the connector <%s> of the instance <%s>.\n", con->nom_con,
((loins_list * )(con->con_lo)->ROOT)->INSNAME);
break;
case ERR_SEGDEPORT :
con = (LST_PSEUDO_CON) pt_liste;
fprintf(stderr, "No space hasn't been found for the deport of the connector <%s> of the instance <%s>.\n",
con->nom_con, ((loins_list * )(con->con_lo)->ROOT)->INSNAME);
break;
case ERR_NOPISTE :
face = *((int *) pt_liste);
switch (face) {
case NORD:
car = 'N';
break;
case SUD :
car = 'S';
break;
case EST:
car = 'E';
break;
case OUEST:
car = 'W';
break;
default:
car = 'X';
break;
}
fprintf(stderr, "No space has been found in side %c to put the power supply <vdd> and <vss> around the core.\n",
car);
break;
case ERR_NOCOL :
con = (LST_PSEUDO_CON) pt_liste;
face = con->face;
switch (face) {
case NORD:
car = 'N';
break;
case SUD :
car = 'S';
break;
case EST:
car = 'E';
break;
case OUEST:
car = 'W';
break;
default:
car = 'X';
break;
}
fprintf(stderr, "No space has been found in side '%c', in order to put the connector <%s> of the instance <%s> on the ring.\n",
car, con->nom_con, ((loins_list * ) (con->con_lo)->ROOT)->INSNAME);
break;
case ERR_INSTPH_PLOT:
fprintf(stderr, "The physical instance of the pad <%s> hasn't been found in the circuit.\n", (char *) pt_liste);
break;
case ERR_NOCONPH_PLOT:
con_lo = (locon_list * ) pt_liste;
fprintf(stderr, "The connector <%s> hasn't been found as an external connector of the pad <%s>.\n", con_lo->NAME,
((loins_list * )con_lo->ROOT)->INSNAME);
break;
case ERR_FIGPH_PLOT:
fprintf(stderr, "The physical figure of pad <%s> hasn't been found.\n", (char *) pt_liste);
break;
case ERR_CONEXT_ENLAIR:
fprintf(stderr, "The connector <%s> of the circuit isn't connected to a pad.\n", (char *) pt_liste);
break;
case ERR_NBCONESTOUEST:
fprintf(stderr, "There isn't the same number of physical connectors on side east and west from the model of pad <%s>\n",
(char *) ((phfig_list * ) pt_liste)->NAME) ;
fprintf(stderr, "It's impossible to link this pad to the others.\n");
break;
case ERR_NOCONPH:
fprintf(stderr, "The connector <%s> of the figure pad <%s> hasn't been found or doesn't have the physical features required.\n",
(char *) ((phcon_list * )pt_liste)->NAME, (char *) ((phfig_list * )pt_liste2)->NAME);
break;
case ERR_EQINTERNE:
liste = (chain_list * ) pt_liste;
fprintf(stderr, "Some errors have been found in the internal equipotential list, pad connectors must be on the internal side of pads.\n");
fprintf(stderr, "That's to say, your C file using GENLIB functions may be wrong.\n");
fprintf(stderr, "The following connector names do not belong to the SOUTH side of the figure of pads.\n");
while (NULL != liste) {
fprintf(stderr, "- The connector <%s> of the instance pad <%s> isn't placed on the SOUTH side.\n",
(char *)liste->NEXT->DATA, (char *)liste->DATA);
liste = liste->NEXT->NEXT;
}
break;
case ERR_EQEXTERNE:
liste = (chain_list * ) pt_liste;
fprintf(stderr, "Some errors have been found in the external equipotential list, pad connectors must be on the external side of pads.\n");
fprintf(stderr, "That's to say, your C file using GENLIB functions may be wrong.\n");
fprintf(stderr, "The following connector names do not belong to the NORTH side of the figure of pads.\n");
while (NULL != liste) {
fprintf(stderr, "- The connector <%s> of the instance pad <%s> isn't placed on the NORTH side.\n",
(char *)liste->NEXT->NEXT->DATA, (char *)liste->NEXT->DATA);
fprintf(stderr, "- It isn't possible to link it with the connector <%s> of the circuit.\n", (char
*)liste->DATA);
liste = liste->NEXT->NEXT->NEXT;
}
break;
case ERR_TIREALIM:
fprintf(stderr, "The supply connector <%s> of the pad <%s> cannot be routed, there's no place.\n", ((LST_PSEUDO_CON) pt_liste)->nom_con,
((loins_list * )((LST_PSEUDO_CON) pt_liste)->con_lo->ROOT)->INSNAME);
fprintf(stderr, "You may center this pad, in the pad section of your parameter file .rin.\n");
break;
default:
fprintf(stderr, "Unknown error code: <%d>.\n", code);
}
exit(code);
}
/*---------------------------------------------------------------------------------*/
void usage ()
{
fprintf(stderr, "Usage : ring source result [stat]\n");
EXIT(1);
}
/*------------------------------------------------------------------------*/
void banner()
{
alliancebanner("RinG", VERSION, "PAD ring router", "1991", "5.0");
}
/*----------------------------------------------------------------------*/
/* cette procedure verifie les equipotentielles internes, c'est a dire */
/* que tous les connecteurs de plot doivent etre des connnecteurs */
/* sud du modele physique, sinon ca veut dire qu'il a des equipo */
/* interdites qui ont ete fabriquees par genlib dans le fichier */
/* de description C. */
/*----------------------------------------------------------------------*/
void verif_eq_interne(LST_EQUIPO lst_equipo, chain_list *liste_plotsph)
{
chain_list * lst_con, *lsterr = NULL;
LST_PSEUDO_CON con;
while (NULL != lst_equipo) {
lst_con = lst_equipo->lst_con;
while (NULL != lst_con) {
con = (LST_PSEUDO_CON) lst_con->DATA;
if (con->coeur_plot == PLOT_CON) {
if (!existe_leconnecteur_faceplot(((loins_list * )con->con_lo->ROOT)->FIGNAME, con->con_lo->NAME, SUD, liste_plotsph)) {
lsterr = addchain(lsterr, (void * ) con->con_lo->NAME);
lsterr = addchain(lsterr, (void * ) (((loins_list * )con->con_lo->ROOT)->INSNAME));
}
}
lst_con = lst_con->NEXT;
}
lst_equipo = lst_equipo->suiv;
}
if (NULL != lsterr)
ringerreur(ERR_EQINTERNE, (void * )lsterr, (void*) NULL);
}
/* ---------------------------------------------------------------------------------------- */
/* Fonction qui regarde si le modele physique possede des connecteurs sur une certaine face */
/* ---------------------------------------------------------------------------------------- */
int existe_leconnecteur_faceplot(char* figure, char* conname, int face,
chain_list *liste_plotsph)
{
phfig_list * modele;
phcon_list * liste_con;
char orient = '0';
if (mode_debug)
printf("Existe-t-il le con %s au %d figure %s\n", conname, face, figure);
switch (face) {
case NORD:
orient = 'N';
break;
case SUD :
orient = 'S';
break;
case OUEST:
orient = 'W';
break;
case EST :
orient = 'E';
break;
}
if ((modele = appartient_listeplotsph(figure, liste_plotsph)) != NULL) {
liste_con = modele->PHCON;
while (liste_con != NULL) {
if ((liste_con->NAME == conname) && (liste_con->ORIENT == orient)) {
if (mode_debug)
printf("Il existe ok\n.");
return (1);
}
liste_con = liste_con->NEXT;
}
if (mode_debug)
printf("Il n'existe PAS\n.");
return(0); /* connecteur de la face non trouve */
}
if (mode_debug)
printf("Il n'existe PAS\n.");
return(0); /* Modele physique non existant ! */
}
/*-------------------------------------------------------------*/
/* testcon_modelfig() */
/* check for all instanciated models in logic figure: */
/* - if each logical connector has at least one corresponding */
/* physical connector. */
/* - if each physical connector has one corresponding */
/* logical connector. */
/*-------------------------------------------------------------*/
void testcon_modelfig(lofig_list* ptfiglo)
{
chain_list * ptcmodel;
char *ptmodel;
lofig_list * ptfigins_lo;
phfig_list * ptfigins_ph;
locon_list * ptconlo;
phcon_list * ptconph;
char *loconname;
char *phconname;
for (ptcmodel = ptfiglo->MODELCHAIN; ptcmodel; ptcmodel = ptcmodel->NEXT) {
ptmodel = (char *)ptcmodel->DATA;
ptfigins_lo = getlofig(ptmodel, 'P');
ptfigins_ph = getphfig(ptmodel, 'P');
for (ptconlo = ptfigins_lo->LOCON; ptconlo; ptconlo = ptconlo->NEXT) {
loconname = ptconlo->NAME;
if (isvdd(loconname)) loconname = eq_vdd;
if (isvss(loconname)) loconname = eq_vss;
for (ptconph = ptfigins_ph->PHCON; ptconph; ptconph = ptconph->NEXT) {
phconname = ptconph->NAME;
if (isvdd(phconname)) phconname = eq_vdd;
if (isvss(phconname)) phconname = eq_vss;
if (phconname == loconname) break;
}
if (!ptconph) {
ringerreur(ERR_CONLO_SANS_PH, loconname, ptmodel);
}
}
for (ptconph = ptfigins_ph->PHCON; ptconph; ptconph = ptconph->NEXT) {
phconname = ptconph->NAME;
if (isvdd(phconname)) phconname = eq_vdd;
if (isvss(phconname)) phconname = eq_vss;
for (ptconlo = ptfigins_lo->LOCON; ptconlo; ptconlo = ptconlo->NEXT) {
loconname = ptconlo->NAME;
if (isvdd(loconname)) loconname = eq_vdd;
if (isvss(loconname)) loconname = eq_vss;
if (phconname == loconname) break;
}
if (!ptconlo) {
ringerreur(ERR_CONPH_SANS_LO, phconname, ptmodel);
}
}
}
}

View File

@ -0,0 +1,13 @@
#ifndef __SESAME_H
#define __SESAME_H
#include "struct.h"
extern void ringerreur(int code, void *pt_liste, void *pt_liste2);
extern void usage ();
extern void banner();
extern void verif_eq_interne(LST_EQUIPO lst_equipo, chain_list *liste_plotsph);
extern int existe_leconnecteur_faceplot(char* figure, char* conname, int face,
chain_list *liste_plotsph);
extern void testcon_modelfig(lofig_list* ptfiglo);
#endif /* __SESAME_H */

View File

@ -0,0 +1,135 @@
/*
* 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 : ring router */
/* Fichier : status.c */
/* */
/* (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI */
/* Tous droits reserves */
/* Support : e-mail cao-vlsi@masi.ibp.fr */
/* */
/* Ecrit par : Olivier Van Hautte le : 01/08/92 */
/* Modifie par : Franck Wajsburt le : 9/11/94 */
/* */
/****************************************************************************/
/*--------------------------------------------------------------------------------*/
/* RING 28 aout 92 STAT.C */
/* Emission de statistiques sur les equipotentielles, un fichier de stat est cree */
/*--------------------------------------------------------------------------------*/
#include "stat.h"
#include "sesame.h"
extern long bigvias, ringvias;
/*-----------------------------------------------------------------------------------*/
void remplit_stat(LST_SEGMENT seg, LST_EQUIPO eq)
{
switch (seg->layer) {
case ALU1:
if (seg->c1 == seg->c2) {
eq->status.lg_a1 += ((seg->piste2 - seg->piste1) * pitch / lambda);
eq->status.su_a1 += (((seg->piste2 - seg->piste1) * pitch / lambda) * (seg->largeur / lambda));
} else if ((seg->face == NORD) || (seg->face == SUD)) {
eq->status.lg_a1 += ((seg->c2->xabs - seg->c1->xabs) / lambda);
eq->status.su_a1 += (((seg->c2->xabs - seg->c1->xabs) / lambda) * (seg->largeur / lambda));
} else
{
eq->status.lg_a1 += ((seg->c2->yabs - seg->c1->yabs) / lambda);
eq->status.su_a1 += (((seg->c2->yabs - seg->c1->yabs) / lambda) * (seg->largeur / lambda));
}
break;
case ALU2:
if (seg->c1 == seg->c2) {
eq->status.lg_a2 += ((seg->piste2 - seg->piste1) * pitch / lambda);
eq->status.su_a2 += (((seg->piste2 - seg->piste1) * pitch / lambda) * (seg->largeur / lambda));
} else if ((seg->face == NORD) || (seg->face == SUD)) {
eq->status.lg_a2 += ((seg->c2->xabs - seg->c1->xabs) / lambda);
eq->status.su_a2 += (((seg->c2->xabs - seg->c1->xabs) / lambda) * (seg->largeur / lambda));
} else
{
eq->status.lg_a2 += ((seg->c2->yabs - seg->c1->yabs) / lambda);
eq->status.su_a2 += (((seg->c2->yabs - seg->c1->yabs) / lambda) * (seg->largeur / lambda));
}
break;
} /* fin switch */
}
void finir_stat(LST_EQUIPO eq)
{
FILE * ficstat;
static long totlga1, totlga2, totsua1, totsua2, totnbvias;
if ((ficstat = mbkfopen(nomfic_stat, NULL, WRITE_TEXT)) == NULL)
ringerreur(ERR_FICSTAT, nomfic_stat, NULL);
fprintf(ficstat, "#\t\t\t *** STATISTIC FILE < %s > ***\n\n\n", nomfic_stat);
fprintf(ficstat, "\t\t\t Equipotential list : \n\n");
fprintf(ficstat, " index | name | length alu1 | length alu2 | area alu1 | area alu2 | nb vias\n\n");
fprintf(ficstat, "__________________________________________________________________________________________________________________\n");
while (NULL != eq) {
fprintf(ficstat, " %3ld | %20s |", eq->index, ((LST_PSEUDO_CON)eq->lst_con->DATA)->nom_con);
fprintf(ficstat, " %7ld | %7ld | %10ld | %10ld | %7ld\n\n", eq->status.lg_a1, eq->status.lg_a2,
eq->status.su_a1, eq->status.su_a2, eq->status.nb_vias);
if (((LST_PSEUDO_CON)eq->lst_con->DATA)->coeur_plot == PLOT_CON)
fprintf(ficstat, " (%20s)\n", ((loins_list * )((LST_PSEUDO_CON)eq->lst_con->DATA)->con_lo->ROOT)->INSNAME);
fprintf(ficstat, "__________________________________________________________________________________________________________________\n");
totlga1 += eq->status.lg_a1;
totlga2 += eq->status.lg_a2;
totsua1 += eq->status.su_a1;
totsua2 += eq->status.su_a2;
totnbvias += eq->status.nb_vias;
eq = eq->suiv;
}
fprintf(ficstat, "\n\nTotal length alu1 : %10ld (lambdas)\n", totlga1);
fprintf(ficstat, "Total length alu2 : %10ld (lambdas)\n", totlga2);
fprintf(ficstat, "Total area alu1 : %10ld (lambdas * lambdas)\n", totsua1);
fprintf(ficstat, "Total area alu2 : %10ld (lambdas * lambdas)\n", totsua2);
fprintf(ficstat, "Total of vias : %10ld\n", totnbvias);
fclose(ficstat);
}
void maj_stat_vias(LST_EQUIPO eq, long ancr, long ancp, long r, long p)
{
if (mode_debug)
eq->status.nb_vias += (r - ancr); /* maj couronne nb vias */
else
eq->status.nb_vias += (p - ancp); /* maj pave nb vias */
}

View File

@ -0,0 +1,10 @@
#ifndef __STAT_H
#define __STAT_H
#include "struct.h"
extern void remplit_stat(LST_SEGMENT seg, LST_EQUIPO eq);
extern void finir_stat(LST_EQUIPO eq);
extern void maj_stat_vias(LST_EQUIPO eq, long ancr, long ancp, long r, long p);
#endif /* __STAT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,387 @@
/*
* 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.
*/
/*-----------------------------------------------------------------------------------*/
/* RING. 27 avril 92 */
/* Definition des types et structures de donnees utilisees par RING */
#ifndef __STRUCT_H
#define __STRUCT_H
#include <mut.h>
#include <mlo.h>
#include <mph.h>
#define NB_FACES 4
#define NB_ITERATIONS 50 /* nb iterations a effectuer pour bon placement barre de plots */
#define SEG_PISTE 0 /* type segment parallele a face coeur */
#define SEG_COL 1 /* type segment perpendiculaire face coeur */
#define VRAI_SEG 0 /* vrai segment qui sera a poser physiquement */
#define FAUX_SEG 1 /* faux segment utile uniquement au routage */
#define AVEC_VIA 0 /* pose d'un via uniquement pour alim */
#define SANS_VIA 1 /* pas de via uniquement pour alim */
#define AVEC_TESTLAYER 0 /* on teste le layer dans la fonction croisementok_alimequi() */
#define SANS_TESTLAYER 1 /* on ne teste pas le layer dans la fonction croisementok_alimequi() */
#define AVEC_COMPRESS 0 /* coordonee deja compressee */
#define SANS_COMPRESS 1 /* coordonne non compresse (par defaut) */
#define DEPORTG 0 /* localisation deport gauche droite face par rapport au coeur */
#define DEPORTD 1 /* des connecteurs plots ou coeur (centre uniquement) */
#define DEPORTC 2
#define COEUR_PLOT 0
#define COEUR_COEUR 1
#define PLOT_PLOT 2
#define ALIM 3 /* equipo de type alim */
#define AUTRE 4 /* equipo de type autre que les precedents */
#define FBARRE_N "fzigopadn1992" /* Noms futiles pour definir les figures barres de plots*/
#define FBARRE_S "fzigopads1992"
#define FBARRE_E "fzigopade1992"
#define FBARRE_O "fzigopado1992"
#define IBARRE_N "izigopadn1992" /* Noms futiles pour definir les instances barres de plots*/
#define IBARRE_S "izigopads1992"
#define IBARRE_E "izigopade1992"
#define IBARRE_O "izigopado1992"
#define NORD 0
#define SUD 1
#define OUEST 2
#define EST 3
/* Nombres entiers obligatoires ! */
#define WMIN_ALU1 2 /* largeur minimum de l'alu1,l'alu2,dist mini alu1<->alu2 */
#define WMIN_ALU2 2 /* et largeur du via */
#define DMIN_ALU1_ALU1 3 /* dmin en a1 a1 2.5 arrondi a 3 */
#define DMIN_ALU2_ALU2 3
#define WVIA_ALU1 2 /* largeur du via pour l'alu1 */
#define WVIA_ALU2 3 /* largeur du via pour l'alu2 */
#define EXTENSION_ALU2 1 /* extension alu2 pour fignoler coin couronne */
#define BV_VIA_VIA 4 /* must be even, whatever! */
#define BV_VIASIZE WVIA_ALU2 /* design rule for equipotential vias */
#define WALIM 60 /* largeur prdefinie des alim */
/*#define PISTE_DEP_ALIMPLOT 10 Nombre de piste a considerer pour une deport alim plot */
/* code des ringerreurs traitees par ringerreur(code) */
#define ERR_ARGUMENT 1
#define ERR_NONCOEUR 2
#define ERR_PLUSCOEUR 3
#define ERR_COEURINSTLO 4
#define ERR_COEURINSTPH 5
#define ERR_CIRCUITLO 6
#define ERR_CIRCUITINST 7
#define ERR_FICPARAM 8
#define ERR_VIDEFICPARAM 9
#define ERR_SYNPARAM 10
#define ERR_AUCUNPLOTPARAM 11
#define ERR_NONPLOTPARAM 12
#define ERR_PLUSPLOTPARAM 13
#define ERR_NBPLOTPARAM 14
#define ERR_NONCONWIDTHPARAM 15
#define ERR_INTERNE_CON 16
#define ERR_CONCOEUR_ENLAIR 17
#define ERR_CONPLOT_ENLAIR 18
#define ERR_CONLARGEUR 19
#define ERR_CONDISTANCE 20
#define ERR_MANQUEALIM 21
#define ERR_BARREALIM 22
#define ERR_ECHECDEPORT 23
#define ERR_INTERNE_EQ 24
#define ERR_SEGDEPORT 25
#define ERR_NOPISTE 26
#define ERR_NOCOL 27
#define ERR_INSTPH_PLOT 28
#define ERR_NOCONPH_PLOT 29
#define ERR_FIGPH_PLOT 30
#define ERR_CONEXT_ENLAIR 31
#define ERR_INTERNE_FIG 32
#define ERR_NBCONESTOUEST 33
#define ERR_NOCONPH 34
#define ERR_CATAL 35
#define ERR_WIDTHPARAM 36
#define ERR_EQINTERNE 37
#define ERR_EQEXTERNE 38
#define ERR_TIREALIM 39
#define ERR_FICSTAT 40
#define ERR_GRILLEINTERNE 41
#define ERR_CONCOEUREMPTY 42
#define ERR_CONLO_SANS_PH 43
#define ERR_CONPH_SANS_LO 44
/*-----------------------------------------------------------------------------------*/
/* type liste de pseudo-connecteurs. Il sert pour les listes de plots et du
coeur */
#define COEUR_CON 1
#define PLOT_CON 0
/* type coordonnees : contient les coordonnees absolues et symboliques */
typedef struct coord {
long piste; /* coordonnee piste (horizontal par rapport a la face) */
long xabs; /* coordonnees x,y absolues dans la figure circuit physique */
long yabs;
void * proprio; /* pointeur sur le pseudo-connecteur appartenant */
int compress; /* coordonnees compressee ou pas */
struct coord *suiv; /* chainage avant arriere sur la grille ou appartient */
struct coord *prec; /* le point courant */
} COORDONNEES, *PT_COORDONNEES;
typedef struct pseudo_con {
char coeur_plot; /* soit COEUR, soit PLOT */
PT_COORDONNEES coord; /* coordonnees symboliques et relatives */
PT_COORDONNEES deport; /* pointeur sur coordonnees symboliques et relatives
d'un eventuel point de deport, si pointeur null
alors pas de deport ,
deport-> piste = 1 si deport uniquement pour layer */
int situe_deport; /* deport gauche droit ou centre */
int face; /* face a laquelle appartient le pseudo_connecteur */
long largeur; /* largeur du connecteur */
char layer; /* niveau physique du connecteur */
char *nom_con; /* nom du connecteur */
locon_list * con_lo; /* pointeur sur connecteur logique de la figure */
struct pseudo_con *suiv; /* pointeur sur structure suivante */
struct pseudo_con *prec; /* pointeur sur structure precedente */
} PSEUDO_CON, *LST_PSEUDO_CON;
/* type liste de segments. Il sert pour les placements des segments physiques
pour chaque equipotentielle et chaque direction (horizontal/vertical). Il renseigne
aussi pour les segments occupes. ON ne sert que exclusivement que des coordonnees
en xabs ou yabs. Il y a un champ piste associe au segment et a sa direction dans la
face. */
typedef struct segment {
int face; /* face a laquelle est associee le segment */
long piste1; /* piste associee au segment de type SEG_COL et SEG_PISTE */
long piste2; /* 2eme piste associee au segment de type SEG_COL */
PT_COORDONNEES c1; /* coordonnees symboliques et absolues du debut segment */
PT_COORDONNEES c2; /* coordonnees symboliques et absolues de fin segment */
long largeur; /* largeur physique du segment */
char layer; /* layer segment */
int vraifaux; /* vraifaux segment. c'est un faux si largeur speciale */
int via; /* pose d' un via ou pas, utile uniquement pour alim */
struct segment *suiv; /* pointeur sur structure suivante ds liste segments occupes */
struct segment *prec; /* pointeur sur structure precedente " " " */
} SEGMENT, *LST_SEGMENT;
/* type couronne: couronne (complete ou incomplete necessaires au
routage, les segments sont completes au fur et a mesure (projetes ...-> segments */
typedef struct couronne {
ptype_list *lst_projetes; /* liste de coordonnees projetees sur la cour
avec leur valeur curviligne */
long perimetre; /* perimetre curviligne de la couronne */
} COURONNE;
/* type stat: caracteristiques de l'equipotentielles en
longueur, surface, nb vias */
typedef struct stat {
long lg_a1; /* longueur en lambdas en alu1 alu2 de l'equipo */
long lg_a2;
long su_a1; /* surface en lamdas carres en alu1 alu2 de l'equipo */
long su_a2;
long nb_vias;
} STAT;
/* type equipotentielle: liste de pseudo-connecteurs portant le meme signal (nom+index) */
typedef struct equipo {
int type; /* type de l'eq: normal, alim, autre) */
long index;
chain_list * lst_con; /* tete de chain-list pointant sur des pseudo connecteurs */
chain_list * lst_seg; /* tete de liste des segments associes */
ptype_list * lst_visavis; /* liste de pointeurs sur des connecteurs en vis a vis */
COURONNE cour; /* structure couronne associee a l'equipo */
STAT status; /* stats en longueur et surface */
struct equipo *suiv; /* pointeur sur structure suivante */
} EQUIPO, *LST_EQUIPO;
/* type lst_piste_col: liste de segments occupes pour piste ou colonne */
typedef struct piste_col {
long numero; /* numero de la piste ou de la colonne */
chain_list * lst_seg; /* liste de pointeurs sur segments */
struct piste_col *suiv; /* pointeur sur structure suivante */
struct piste_col *prec; /* pointeur sur structure precedente */
} PISTE_COL, *LST_PISTE_COL;
/* type barre_plots: contient les donnees necessaires a la construction de
la barre de plots */
typedef struct barre_plots {
LST_PSEUDO_CON lst_con; /* liste de pointeurs sur connecteurs de plots */
COORDONNEES coord; /* coordonnees symboliques et absolues de la barre de plots */
long width; /* longueur de la barre de plots */
long height; /* hauteur de la barre de plots */
int nb_deport; /* nombre de deports prevus par le placement de la barre */
char *nomfig; /* nom de la figure physique */
char *nominst; /* nom de l'instance physique */
} BARRE_PLOTS;
/* type grille_symbo_piste: grille des pistes (pas fixes definis par le pitch) */
typedef struct symbo_piste {
long premiere; /* coordonnee absolue de la premiere piste */
int largeur_pas; /* valeur du pas de grille */
long nb_pas; /* nombre de pas de grilles definis maximum */
} GRILLE_SYMBO_PISTE;
/* type grille: regroupe les 2 types precedents pour obtenir la grille qui permettra de
transformer les coordonnees symboliques en absolues et vice-versa */
typedef struct grille {
PT_COORDONNEES lst_pas; /* liste des points formant la grille */
PT_COORDONNEES lst_deportg;/* liste des deports gauches de la grille */
PT_COORDONNEES lst_deportd;/* liste des deports droits de la grille */
GRILLE_SYMBO_PISTE piste; /* donnees pour le calcul des pas de piste */
} GRILLE;
/* type coeur: regroupe les informations le concernant */
typedef struct coeur {
loins_list *coeur_lo; /* pointeur sur figure logique du coeur */
phfig_list *coeur_ph; /* pointeur sur figure physique du coeur */
COORDONNEES coord; /* coordonnees symboliques(0,0) et absolues */
long width;
long height;
char rotation; /* rotation du coeur */
} COEUR;
/* type cel : cellule contient la largeur specifique d'un signal, fera parti de la
chain_list liste_width, remplie par l'analyseur syntaxique */
typedef struct cel {
char *chaine;
long largeur;
locon_list * con_lo;
} CEL, *PTCEL;
/*-----------------------------------------------------------------------------------*/
/* Variables globales */
extern char mode_debug; /* si debug alors mode_debug=1, 0 sinon */
extern char mode_stat; /* si stat alors mode_stat=1, 0 sinon */
extern char *nomfic_stat; /* nom du fichier statistique */
extern char xmetal; /* metal utilise dans les x */
extern char ymetal; /* metal utilise dans les y */
extern long xmetal_width, ymetal_width; /* largeur des metaux x, y */
extern long xmetal_dmin, ymetal_dmin; /* dist minimum entre 2 meme metaux */
extern long xmetal_wvia, ymetal_wvia; /* taille des contacts pour chaque metal */
extern long pitch; /* pitch a calculer */
extern long lambda; /* lambda (= SCALE_X) */
extern long taille_via; /* taille du via a calculer */
extern long vdd_width; /* largeur couronnes d'alim */
extern long vss_width;
extern char *eq_vdd; /* nom equipo alim */
extern char *eq_vss; /* nom equipo alim */
extern char *n_vdde;
extern char *n_vsse;
extern char *n_vddi;
extern char *n_vssi;
extern char *n_pad;
extern char *pvddi_p;
extern char *pvssi_p;
extern char *nom_fic_param; /* nom du fichier parametre */
extern FILE *yyin; /* pointeur sur fichier lex */
extern int yylineno; /* no de la ligne traitee par lex */
extern chain_list *nom_plot[NB_FACES]; /* liste pour l'analyseur des noms de
plots */
extern chain_list *liste_width; /* liste pour l'analyseur des noms
et largeurs des connecteurs speciaux */
extern long bigvias , ringvias ; /* nombres de vias poses en total par bigvia
ou en couronne (mode debug). car pb versatil
si bcp de vias (fichier .cif enorme) */
/*-----------------------------------------------------------------------------------*/
/* Declarations des fonctions */
/* Fichier struct.c */
extern void ajout_listeplotsph();
extern int existe_connecteur_faceplot();
extern phfig_list*appartient_listeplotsph();
extern void affic_listeplotsph();
extern loins_list*existe_plot_circuit();
extern int existe_signal_circuit();
extern int uneseuleoccurence();
extern void declaration_plot_n();
extern void declaration_plot_s();
extern void declaration_plot_w();
extern void declaration_plot_e();
extern void declaration_width();
extern void affic_plotwidth();
extern int reorientation_con();
extern void ajout_pseudo_con_coeur();
extern void ajout_pseudo_con_plot();
extern void inserer_apres_lstcon();
extern void inserer_avant_lstcon();
extern void affic_lstcon();
extern LST_PSEUDO_CON existe_concoeur_lstequipo();
extern LST_EQUIPO existe_concoeur_lstequipo2();
extern LST_PSEUDO_CON existe_conplot_lstequipo();
extern void maj_equipo();
extern LST_EQUIPO existe_sig_equipo();
extern void affic_equipo();
extern locon_list*vraifaux_conlogic();
extern LST_PSEUDO_CON existe_conlogicplot_lstequipo();
extern void rename_vddxvssx();
extern void ignoble_multiple_ck_delete_from_south_side();
/* Fichier struct2.c */
extern int moins_dun_pitch_preccon();
extern void ajout_coordonnees_grille();
extern void ajout_visavis();
extern int existe_visavis();
extern void affic_grille();
extern void alloue_coord();
extern PT_COORDONNEES cherche_deport_grille();
extern void chaine_deportcon_grille();
extern void alloue_etchaine_segment();
extern int segment_libre();
extern void affic_listeseg();
extern phcon_list *cherche_conph_circuit();
extern int croisement_con_alim();
extern void largeur_vddvss();
extern int croisementok_alimequi();
extern long compte_nbplotsface();
#endif /* __STRUCT_H */

File diff suppressed because it is too large Load Diff