This commit was generated by cvs2svn to track changes on a CVS vendor
branch.
This commit is contained in:
commit
bd71a62dc6
|
@ -0,0 +1 @@
|
|||
SUBDIRS = src
|
|
@ -0,0 +1,54 @@
|
|||
dnl
|
||||
dnl This file is part of the Alliance CAD System
|
||||
dnl Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
dnl Universite Pierre et Marie Curie
|
||||
dnl
|
||||
dnl Home page : http://www-asim.lip6.fr/alliance/
|
||||
dnl E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
dnl
|
||||
dnl This library is free software; you can redistribute it and/or modify it
|
||||
dnl under the terms of the GNU Library General Public License as published
|
||||
dnl by the Free Software Foundation; either version 2 of the License, or (at
|
||||
dnl your option) any later version.
|
||||
dnl
|
||||
dnl Alliance VLSI CAD System is distributed in the hope that it will be
|
||||
dnl useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
dnl Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License along
|
||||
dnl with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
dnl Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
dnl
|
||||
dnl Purpose : Auto stuffing Alliance
|
||||
dnl Almost ten years since I wrote this stuff, I just can't
|
||||
dnl believe it
|
||||
dnl Date : 01/02/2002
|
||||
dnl Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
|
||||
dnl $Id: configure.in,v 1.1 2002/03/14 13:47:47 fred Exp $
|
||||
dnl
|
||||
dnl
|
||||
AC_INIT(src/mbk2mg.c)
|
||||
AM_INIT_AUTOMAKE(mbkmg, 1.0)
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CC
|
||||
AC_PROG_YACC
|
||||
AM_PROG_LEX
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(strings.h unistd.h)
|
||||
AC_C_CONST
|
||||
AC_PROG_RANLIB
|
||||
|
||||
changequote(,)dnl
|
||||
INCLUDES=-I${ALLIANCE_TOP}/include
|
||||
LDFLAGS=-L${ALLIANCE_TOP}/lib
|
||||
changequote([,])dnl
|
||||
|
||||
AC_SUBST(INCLUDES)
|
||||
AC_SUBST(LDFLAGS)
|
||||
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
src/Makefile
|
||||
])
|
|
@ -0,0 +1,8 @@
|
|||
lib_LIBRARIES = libMmg.a
|
||||
libMmg_a_SOURCES = mbk2mg.c mg2mbk_y.y mg2mbk_l.l mmg.h
|
||||
CLEANFILES = mg2mbk_y.c mg2mbk_y.h mg2mbk_l.c
|
||||
|
||||
mg2mbk_y.c mg2mbk_y.h : $(srcdir)/mg2mbk_y.y
|
||||
$(YACC) -d $(YFLAGS) $(srcdir)/mg2mbk_y.y && sed -e "s/yy/mgn/g" -e "s/YY/MGN/g" y.tab.c > mg2mbk_y.c && sed -e "s/yy/mgn/g" -e "s/YY/MGN/g" y.tab.h > mg2mbk_y.h
|
||||
mg2mbk_l.c : $(srcdir)/mg2mbk_l.l mg2mbk_y.h
|
||||
$(LEX) -t $(srcdir)/mg2mbk_l.l | sed -e "s/yy/mgn/g" -e "s/YY/MGN/g" > mg2mbk_l.c
|
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Library General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* version 1.1 : mbk2mg or how to translate symbolic leaf cells to modgen format*
|
||||
* Written by Frederic Petrot, to be used on leafs cells for idps generators *
|
||||
* This update uses macros for contacts and transistors as described in *
|
||||
* idps.atoms *
|
||||
* *
|
||||
* version 1.2 : now includes instances also *
|
||||
* *
|
||||
* e-mail : cao-vlsi@masi.ibp.fr *
|
||||
* *
|
||||
* version : 1.2 *
|
||||
* date : 22/01/92 *
|
||||
*******************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <mut.h>
|
||||
#include <mph.h>
|
||||
|
||||
static float RTrans = 1.5; /* o_ps_aa : Poly overlap on Dif */
|
||||
static float MWTrans = 1.0; /* w_ps : Min transistor width */
|
||||
|
||||
static int number;
|
||||
|
||||
static int Ext[LAST_LAYER + 1] = {
|
||||
/* NWELL */ 0,
|
||||
/* PWELL */ 0,
|
||||
/* NTIE */ 1,
|
||||
/* PTIE */ 1,
|
||||
/* NDIF */ 1,
|
||||
/* PDIF */ 1,
|
||||
/* NTRANS */ 0, /* meant for N transistor grid */
|
||||
/* PTRANS */ 0, /* meant for P transistor grid */
|
||||
/* POLY */ 1,
|
||||
/* ALU1 */ 1,
|
||||
/* ALU2 */ 2,
|
||||
/* ALU3 */ 2,
|
||||
/* TPOLY */ 1,
|
||||
/* TALU1 */ 1,
|
||||
/* TALU2 */ 2,
|
||||
/* TALU3 */ 2 };
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro *
|
||||
*******************************************************************************/
|
||||
#define HALF(X) ((X) >> 1)
|
||||
|
||||
/*******************************************************************************
|
||||
* Functions declaration *
|
||||
*******************************************************************************/
|
||||
static void segments();
|
||||
static void connectors();
|
||||
static void virtualconnectors();
|
||||
static void vias();
|
||||
static void instances();
|
||||
static void abutmentbox();
|
||||
static void figure();
|
||||
|
||||
/*******************************************************************************
|
||||
* Layers, Vias, Orientation & Gemetrical operation translation table *
|
||||
*******************************************************************************/
|
||||
static char *
|
||||
busname(name)
|
||||
char *name;
|
||||
{
|
||||
static char buffer[255];
|
||||
char *s, *t;
|
||||
char one = 1;
|
||||
|
||||
if (!name || *name == '*')
|
||||
return NULL;
|
||||
|
||||
s = name;
|
||||
t = buffer;
|
||||
while (*s) {
|
||||
if (*s == ' ' || (*s == '_' && !one))
|
||||
if (one) {
|
||||
*t++ = '[';
|
||||
s++;
|
||||
one = 0;
|
||||
} else {
|
||||
*t++ = ']';
|
||||
*t++ = '[';
|
||||
s++;
|
||||
}
|
||||
if ((*s == '/' || *s == '_') && !one) {
|
||||
*t++ = ']';
|
||||
one = 1;
|
||||
}
|
||||
*t++ = *s++;
|
||||
}
|
||||
if (!one)
|
||||
*t++ = ']';
|
||||
*t = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char *
|
||||
layer(mbk_layer)
|
||||
char mbk_layer;
|
||||
{
|
||||
static char *mg_layer[] = {
|
||||
/* NWELL */ "nw",
|
||||
/* PWELL */ "pw",
|
||||
/* NTIE */ "xn",
|
||||
/* PTIE */ "xp",
|
||||
/* NDIF */ "nn",
|
||||
/* PDIF */ "pp",
|
||||
/* NTRANS */ "NULL",
|
||||
/* PTRANS */ "NULL",
|
||||
/* POLY */ "ps",
|
||||
/* ALU1 */ "m1",
|
||||
/* ALU2 */ "m2",
|
||||
/* ALU3 */ "NULL",
|
||||
/* TPOLY */ "NULL",
|
||||
/* TALU1 */ "am1",
|
||||
/* TALU2 */ "am2",
|
||||
/* TALU3 */ "NULL"
|
||||
};
|
||||
return mg_layer[(int)mbk_layer];
|
||||
}
|
||||
|
||||
static char *
|
||||
via(mbk_via)
|
||||
char mbk_via;
|
||||
{
|
||||
static char *mg_via[] = {
|
||||
/* CONT_POLY */ "cops",
|
||||
/* CONT_VIA */ "pvia",
|
||||
/* CONT_DIFN */ "con",
|
||||
/* CONT_DIFP */ "cop",
|
||||
/* CONT_BODY_N */ "conw",
|
||||
/* CONT_BODY_P */ "copw",
|
||||
/* C_X_N */ "cxn",
|
||||
/* C_X_P */ "cxp",
|
||||
/* CONT_VIA2 */ "NULL"
|
||||
};
|
||||
return mg_via[(int)mbk_via];
|
||||
}
|
||||
|
||||
static char *
|
||||
orient(face)
|
||||
char face;
|
||||
{
|
||||
switch (face) {
|
||||
case NORTH :
|
||||
return "top";
|
||||
case SOUTH :
|
||||
return "bottom";
|
||||
case EAST :
|
||||
return "right";
|
||||
case WEST :
|
||||
return "left";
|
||||
default :
|
||||
return "allside";
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
geop(trsf, s)
|
||||
char trsf;
|
||||
char **s;
|
||||
{
|
||||
|
||||
switch (trsf) {
|
||||
case NOSYM :
|
||||
*s = "ll";
|
||||
return NULL;
|
||||
case SYM_X :
|
||||
*s = "lr";
|
||||
return "my";
|
||||
case SYM_Y :
|
||||
*s = "ul";
|
||||
return "mx";
|
||||
case SYMXY :
|
||||
*s = "ur";
|
||||
return "mx my";
|
||||
case ROT_P :
|
||||
*s = "ul";
|
||||
return "r 90";
|
||||
case ROT_M :
|
||||
*s = "lr";
|
||||
return "r 270";
|
||||
case SY_RP :
|
||||
*s = "ll";
|
||||
return "mx r 90";
|
||||
case SY_RM :
|
||||
*s = "ur";
|
||||
return "mx r 270";
|
||||
default :
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "Unknown geometrical operation\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mgnsavephfig(Cell)
|
||||
phfig_list *Cell;
|
||||
{
|
||||
chain_list *Model;
|
||||
char *CellName;
|
||||
int i;
|
||||
FILE *file;
|
||||
static int notfirst;
|
||||
|
||||
if (!notfirst) {
|
||||
for (i = 0; i < LAST_LAYER + 1; i++)
|
||||
Ext[i] = HALF(Ext[i] * SCALE_X);
|
||||
notfirst++;
|
||||
}
|
||||
|
||||
CellName = Cell->NAME;
|
||||
if ((file = mbkfopen(CellName, "mg", WRITE_TEXT)) == NULL) {
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "Can't open %s.%s for writing\n", CellName, "mg");
|
||||
exit(1);
|
||||
}
|
||||
Model = Cell->MODELCHAIN;
|
||||
|
||||
fputs("/", file);
|
||||
for (i = 1; i < 80; i++)
|
||||
fputs("*", file);
|
||||
fputs("\n", file);
|
||||
i = fprintf(file, "* file %s.mg has been generated by mbk2mg translator",
|
||||
CellName);
|
||||
for (; i < 79; i++)
|
||||
fputs(" ", file);
|
||||
fputs("*\n", file);
|
||||
i = fprintf(file,
|
||||
"* for cao-vlsi generators in order to fit IDPS standard modgen");
|
||||
for (; i < 79; i++)
|
||||
fputs(" ", file);
|
||||
fputs("*\n", file);
|
||||
for (i = 0; i < 79; i++)
|
||||
fputs("*", file);
|
||||
fputs("/\n", file);
|
||||
fprintf(file, "#ifndef BULLATOMS\n");
|
||||
fprintf(file, "#define BULLATOMS\n");
|
||||
fprintf(file, "#include \"%s/tech/bull.atoms\"\n", mbkgetenv("MODGEN"));
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
while (Model) {
|
||||
fprintf(file, "#include \"%s\"\n",
|
||||
filepath((char *)Model->DATA, "mg"));
|
||||
Model = Model->NEXT;
|
||||
}
|
||||
/* last figure :
|
||||
this is the real one, boys. */
|
||||
figure(file, Cell);
|
||||
}
|
||||
|
||||
static void
|
||||
rect(file, mg_layer, x0, y0, x1, y1)
|
||||
FILE *file;
|
||||
char *mg_layer;
|
||||
long x0, y0, x1, y1;
|
||||
{
|
||||
|
||||
if (!strcmp(mg_layer, "NULL"))
|
||||
return;
|
||||
fprintf(file, "\tra(%s, %.2f, %.2f, %.2f, %.2f);\n",
|
||||
mg_layer, (float)x0 / SCALE_X, (float)x1 / SCALE_X,
|
||||
(float)y0 / SCALE_X, (float)y1 / SCALE_X);
|
||||
}
|
||||
|
||||
static void
|
||||
figure(file, Cell)
|
||||
FILE *file;
|
||||
phfig_list *Cell;
|
||||
{
|
||||
fprintf(file, "\ncell %s\n{\n", Cell->NAME);
|
||||
abutmentbox(file, Cell);
|
||||
connectors(file, Cell->PHCON);
|
||||
virtualconnectors(file, Cell->PHREF);
|
||||
instances(file, Cell->PHINS);
|
||||
segments(file, Cell->PHSEG);
|
||||
vias(file, Cell->PHVIA);
|
||||
fputs("}\n", file);
|
||||
}
|
||||
|
||||
static void
|
||||
abutmentbox(file, Cell)
|
||||
FILE *file;
|
||||
phfig_list *Cell;
|
||||
{
|
||||
rect(file, "zd", Cell->XAB1, Cell->YAB1, Cell->XAB2, Cell->YAB2);
|
||||
fprintf(file, "\tterminal ll (WIDTH = 1.00) left zd at (%.2f, %.2f);\n",
|
||||
(float)Cell->XAB1/SCALE_X, (float)Cell->YAB1/SCALE_X);
|
||||
fprintf(file, "\tterminal lr (WIDTH = 1.00) right zd at (%.2f, %.2f);\n",
|
||||
(float)Cell->XAB2/SCALE_X, (float)Cell->YAB1/SCALE_X);
|
||||
fprintf(file, "\tterminal ul (WIDTH = 1.00) left zd at (%.2f, %.2f);\n",
|
||||
(float)Cell->XAB1/SCALE_X, (float)Cell->YAB2/SCALE_X);
|
||||
fprintf(file, "\tterminal ur (WIDTH = 1.00) right zd at (%.2f, %.2f);\n",
|
||||
(float)Cell->XAB2/SCALE_X, (float)Cell->YAB2/SCALE_X);
|
||||
}
|
||||
|
||||
static void
|
||||
segments(file, HeadOfList)
|
||||
FILE *file;
|
||||
phseg_list *HeadOfList;
|
||||
{
|
||||
register phseg_list *Ptr;
|
||||
register long Xbl, Ybl, Xtr, Ytr; /* bl : bottom left, tr : top right */
|
||||
register long Twidth, Tlenght;
|
||||
register long Xcenter, Ycenter;
|
||||
|
||||
for (Ptr = HeadOfList; Ptr; Ptr = Ptr->NEXT) {
|
||||
if (Ptr->TYPE == LEFT || Ptr->TYPE == RIGHT) {
|
||||
switch (Ptr->LAYER) {
|
||||
case NTRANS :
|
||||
case PTRANS :
|
||||
Xbl = Ptr->X1;
|
||||
Ybl = Ptr->Y1;
|
||||
Xtr = Ptr->X2;
|
||||
Twidth = Xtr - Xbl - 2 * (int)((RTrans) * SCALE_X);
|
||||
Tlenght = MWTrans * Ptr->WIDTH;
|
||||
Xcenter = Xbl + HALF(Xtr - Xbl);
|
||||
Ycenter = Ybl;
|
||||
|
||||
(void)fprintf(file,"\tplace x%x$ = ", number++);
|
||||
(void)fprintf(file,"%s(%.2f, %.2f) ",
|
||||
Ptr->LAYER == NTRANS ? "ntr" : "ptr",
|
||||
(float)Twidth / SCALE_X,
|
||||
(float)Tlenght / SCALE_X);
|
||||
(void)fprintf(file,"at (%.2f,%.2f);\n",
|
||||
(float)Xcenter / SCALE_X,
|
||||
(float)Ycenter / SCALE_X);
|
||||
break;
|
||||
case TPOLY :
|
||||
case TALU3 :
|
||||
case ALU3 :
|
||||
break;
|
||||
default :
|
||||
(void)fprintf(file,
|
||||
"\tstretch(%s, %.2f, %s, %.2f, %.2f, %.2f, %.2f);\n",
|
||||
layer(Ptr->LAYER),
|
||||
(float)Ptr->WIDTH / SCALE_X, "hor",
|
||||
(float)(Ptr->X1 - Ext[(int)Ptr->LAYER]) / SCALE_X,
|
||||
(float)Ptr->Y1 / SCALE_X,
|
||||
(float)(Ptr->X2 + Ext[(int)Ptr->LAYER]) / SCALE_X,
|
||||
(float)Ptr->Y2 / SCALE_X);
|
||||
}
|
||||
} else {
|
||||
switch (Ptr->LAYER) {
|
||||
case NTRANS :
|
||||
case PTRANS :
|
||||
Xbl = Ptr->X1;
|
||||
Ybl = Ptr->Y1;
|
||||
Ytr = Ptr->Y2;
|
||||
Twidth = Ytr - Ybl - 2 * (int)((RTrans) * SCALE_X);
|
||||
Tlenght = MWTrans * Ptr->WIDTH;
|
||||
Xcenter = Xbl;
|
||||
Ycenter = Ybl + HALF(Ytr - Ybl);
|
||||
|
||||
(void)fprintf(file,"\tplace x%x$ = ", number++);
|
||||
(void)fprintf(file,"%s(%.2f, %.2f) r 90 ",
|
||||
Ptr->LAYER == NTRANS ? "ntr" : "ptr",
|
||||
(float)Twidth / SCALE_X,
|
||||
(float)Tlenght / SCALE_X);
|
||||
(void)fprintf(file,"at (%.2f,%.2f);\n",
|
||||
(float)Xcenter / SCALE_X,
|
||||
(float)Ycenter / SCALE_X);
|
||||
break;
|
||||
case TPOLY :
|
||||
case TALU3 :
|
||||
case ALU3 :
|
||||
break;
|
||||
default :
|
||||
(void)fprintf(file,
|
||||
"\tstretch(%s, %.2f, %s, %.2f, %.2f, %.2f, %.2f);\n",
|
||||
layer(Ptr->LAYER), (float)Ptr->WIDTH/SCALE_X, "ver",
|
||||
(float)Ptr->X1 / SCALE_X,
|
||||
(float)(Ptr->Y1 - Ext[(int)Ptr->LAYER]) / SCALE_X,
|
||||
(float)Ptr->X2 / SCALE_X,
|
||||
(float)(Ptr->Y2 + Ext[(int)Ptr->LAYER]) / SCALE_X);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connectors(file, HeadOfList)
|
||||
FILE *file;
|
||||
phcon_list *HeadOfList;
|
||||
{
|
||||
register phcon_list *pt;
|
||||
|
||||
for (pt = HeadOfList; pt; pt = pt->NEXT) {
|
||||
char *l = layer(pt->LAYER);
|
||||
if (!strcmp("NULL", l))
|
||||
continue;
|
||||
/* text because we don't know how to print anything */
|
||||
fprintf(file, "\ttext %s \"%s\" ", l, busname(pt->NAME));
|
||||
fprintf(file, "at (%.2f, %.2f);\n",
|
||||
(float)pt->XCON/SCALE_X, (float)pt->YCON/SCALE_X);
|
||||
fprintf(file, "\tterminal %s[%ld] ", busname(pt->NAME), pt->INDEX);
|
||||
fprintf(file, "(WIDTH = %.2f) %s %s ",
|
||||
(float)pt->WIDTH/SCALE_X, orient(pt->ORIENT), l);
|
||||
fprintf(file, "at (%.2f, %.2f);\n",
|
||||
(float)pt->XCON/SCALE_X, (float)pt->YCON/SCALE_X);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virtualconnectors(file, HeadOfList)
|
||||
FILE *file;
|
||||
phref_list *HeadOfList;
|
||||
{
|
||||
register phref_list *pt;
|
||||
static refindex;
|
||||
|
||||
for (pt = HeadOfList; pt; pt = pt->NEXT) {
|
||||
/* text because we don't know how to print anything */
|
||||
(void)fprintf(file, "\ttext zd \"%s\" ", busname(pt->NAME));
|
||||
(void)fprintf(file, "at (%.2f, %.2f);\n",
|
||||
(float)pt->XREF / SCALE_X,
|
||||
(float)pt->YREF / SCALE_X);
|
||||
/* object itself */
|
||||
(void)fprintf(file,"\tplace %s[%d] = ", busname(pt->NAME), refindex++);
|
||||
(void)fprintf(file,"%s at (%.2f,%.2f);\n", pt->FIGNAME,
|
||||
(float)pt->XREF / SCALE_X,
|
||||
(float)pt->YREF / SCALE_X);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vias(file, HeadOfViasList)
|
||||
FILE *file;
|
||||
phvia_list *HeadOfViasList;
|
||||
{
|
||||
#define SIZE_C_X (5 * SCALE_X)
|
||||
register phvia_list *ViaPtr;
|
||||
|
||||
for (ViaPtr = HeadOfViasList; ViaPtr; ViaPtr = ViaPtr->NEXT) {
|
||||
switch (ViaPtr->TYPE) {
|
||||
#ifdef NOTLABOTEC
|
||||
case C_X_N :
|
||||
rect(file, layer(POLY),
|
||||
ViaPtr->XVIA - HALF(SCALE_X), ViaPtr->YVIA - HALF(SCALE_X),
|
||||
ViaPtr->XVIA + HALF(SCALE_X), ViaPtr->YVIA + HALF(SCALE_X));
|
||||
rect(file, layer(NDIF),
|
||||
ViaPtr->XVIA - HALF(SIZE_C_X), ViaPtr->YVIA - HALF(SIZE_C_X),
|
||||
ViaPtr->XVIA + HALF(SIZE_C_X), ViaPtr->YVIA + HALF(SIZE_C_X));
|
||||
continue;
|
||||
case C_X_P :
|
||||
rect(file, layer(POLY),
|
||||
ViaPtr->XVIA - HALF(SCALE_X), ViaPtr->YVIA - HALF(SCALE_X),
|
||||
ViaPtr->XVIA + HALF(SCALE_X), ViaPtr->YVIA + HALF(SCALE_X));
|
||||
rect(file, layer(PDIF),
|
||||
ViaPtr->XVIA - HALF(SIZE_C_X), ViaPtr->YVIA - HALF(SIZE_C_X),
|
||||
ViaPtr->XVIA + HALF(SIZE_C_X), ViaPtr->YVIA + HALF(SIZE_C_X));
|
||||
continue;
|
||||
#endif
|
||||
default :
|
||||
(void)fprintf(file,"\tplace %s%d = ", via(ViaPtr->TYPE), number++);
|
||||
(void)fprintf(file,"%s at (%.2f,%.2f);\n", via(ViaPtr->TYPE),
|
||||
(float)ViaPtr->XVIA / SCALE_X,
|
||||
(float)ViaPtr->YVIA / SCALE_X);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
instances(file, List)
|
||||
FILE *file;
|
||||
phins_list *List;
|
||||
{
|
||||
register phins_list *insPtr;
|
||||
char *trsf, *corner;
|
||||
|
||||
for (insPtr = List; insPtr; insPtr = insPtr->NEXT) {
|
||||
trsf = geop(insPtr->TRANSF, &corner);
|
||||
(void)fprintf(file,"\tplace %s.%s = ", insPtr->INSNAME, corner);
|
||||
if (trsf)
|
||||
(void)fprintf(file,"%s %s ", insPtr->FIGNAME, trsf);
|
||||
else
|
||||
(void)fprintf(file,"%s ", insPtr->FIGNAME);
|
||||
(void)fprintf(file,"at (%.2f,%.2f);\n",
|
||||
(float)insPtr->XINS / SCALE_X,
|
||||
(float)insPtr->YINS / SCALE_X);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
%{
|
||||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Library General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Parsing Philips modgen format, done during the IDPS project.
|
||||
* Author: Frédéric Pétrot
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <mut.h>
|
||||
#include "mg2mbk_y.h"
|
||||
static void zweep();
|
||||
extern char *filenameforlex();
|
||||
/* change lex input routine to a non case sensitive one */
|
||||
#ifdef FLEX_SCANNER
|
||||
#ifdef YY_INPUT
|
||||
#undef YY_INPUT
|
||||
#endif
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
do { \
|
||||
int c = getc(yyin); \
|
||||
result = (c == EOF) ? YY_NULL \
|
||||
: (buf[0] = isupper(c) ? tolower(c) : c, 1); \
|
||||
} while(0)
|
||||
|
||||
int yylineno;
|
||||
#else /* using lex, for sure */
|
||||
#ifdef input
|
||||
#undef input
|
||||
#endif
|
||||
#define input() (((yytchar = yysptr > yysbuf ? U(*--yysptr) \
|
||||
: getc(yyin)) == 10 ?(yylineno++,yytchar) \
|
||||
: yytchar) == EOF ? 0 \
|
||||
: isupper(yytchar) ? tolower(yytchar) \
|
||||
: yytchar)
|
||||
#endif
|
||||
%}
|
||||
|
||||
cset [a-zA-Z_/]
|
||||
digit [0-9]
|
||||
sign [-+]
|
||||
blank [ \t]*
|
||||
ident {cset}({cset}|{digit}|\[{digit}+\]|\.|$)*
|
||||
fp {sign}?{digit}*\.?{digit}+
|
||||
|
||||
%%
|
||||
{blank} {}
|
||||
\n {
|
||||
#ifdef FLEX_SCANNER
|
||||
yylineno++;
|
||||
#endif
|
||||
}
|
||||
\/\* {zweep('/');}
|
||||
\# {zweep('\n');}
|
||||
property {zweep('}');}
|
||||
node {zweep('}');}
|
||||
text {zweep(';');}
|
||||
constraint {zweep(';');}
|
||||
cell {return CELL;}
|
||||
place {return PLACE;}
|
||||
terminal {return TERMINAL;}
|
||||
ra {return RA;}
|
||||
stretch {return STRETCH;}
|
||||
wire {return WIRE;}
|
||||
width {return MWIDTH;}
|
||||
hor {return HORIZ;}
|
||||
ver {return VERTI;}
|
||||
left {return MLEFT;}
|
||||
right {return MRIGHT;}
|
||||
top {return MTOP;}
|
||||
bottom {return MBOTTOM;}
|
||||
at {return AT;}
|
||||
mx {return MX;}
|
||||
my {return MY;}
|
||||
r {return R;}
|
||||
ntr {return NTR;}
|
||||
ptr {return PTR;}
|
||||
cop {return COP;}
|
||||
con {return CON;}
|
||||
cops {return COPS;}
|
||||
copw {return COPW;}
|
||||
conw {return CONW;}
|
||||
pvia {return PVIA;}
|
||||
cxn {return CXN;}
|
||||
cxp {return CXP;}
|
||||
"=" {return '=';}
|
||||
"{" {return '{';}
|
||||
"}" {return '}';}
|
||||
"(" {return '(';}
|
||||
")" {return ')';}
|
||||
"," {return ',';}
|
||||
";" {return ';';}
|
||||
{ident} { yylval.s = mbkstrdup(yytext);
|
||||
return STRING;}
|
||||
{fp} {float f;
|
||||
sscanf(yytext, "%f", &f);
|
||||
yylval.n = (long)(f * SCALE_X);
|
||||
#ifdef GRIDDED
|
||||
yylval.n *= 2;
|
||||
#endif
|
||||
return NUM;}
|
||||
%%
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void zweep(find_it)
|
||||
char find_it;
|
||||
{
|
||||
char c;
|
||||
|
||||
while (1) {
|
||||
if ((c = input()) == 0) {
|
||||
(void)fprintf(stderr, "reached EOF before expected end line %d\n",
|
||||
yylineno);
|
||||
exit(12);
|
||||
}
|
||||
/* special case for comments */
|
||||
if (c == '*')
|
||||
if (find_it == '/')
|
||||
if ((c = input()) == 0) {
|
||||
(void)fprintf(stderr,
|
||||
"reached EOF before expected end of comment\n");
|
||||
exit(12);
|
||||
}
|
||||
if (c == find_it)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int yyerror(s)
|
||||
char *s;
|
||||
{
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "modgen parser : syntax error line %d on %s file %s\n",
|
||||
yylineno, yytext, filenameforlex());
|
||||
exit(13);
|
||||
}
|
|
@ -0,0 +1,625 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Library General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* small modgen parser for absolute placement only *
|
||||
* no control flow statement allowed, nor fancy stuff. *
|
||||
* Written By Frederic Petrot, petrot@masi.ibp.fr for Masi/cao-vlsi team *
|
||||
* Done for the IDPS project *
|
||||
******************************************************************************/
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <mut.h>
|
||||
#include <mph.h>
|
||||
#define MAXLAYER (LAST_LAYER + 1)
|
||||
|
||||
static phfig_list *mgleaf; /* modgen leaf cell parsed */
|
||||
static char mbk_layer();
|
||||
static char *checkinsname();
|
||||
static char *checkconname();
|
||||
static char *checkrefname();
|
||||
static chain_list *pl;
|
||||
static int Extension[MAXLAYER] = {
|
||||
/* NWELL */ 0,
|
||||
/* PWELL */ 0,
|
||||
/* NTIE */ 1,
|
||||
/* PTIE */ 1,
|
||||
/* NDIF */ 1,
|
||||
/* PDIF */ 1,
|
||||
/* NTRANS */ 0, /* meant for N transistor grid */
|
||||
/* PTRANS */ 0, /* meant for P transistor grid */
|
||||
/* POLY */ 1,
|
||||
/* ALU1 */ 1,
|
||||
/* ALU2 */ 2,
|
||||
/* ALU3 */ 2,
|
||||
/* TPOLY */ 1,
|
||||
/* TALU1 */ 1,
|
||||
/* TALU2 */ 2,
|
||||
/* TALU3 */ 2 };
|
||||
|
||||
#define O_PS_AA 1.5
|
||||
#define O_AA_PS 2
|
||||
|
||||
#ifdef GRIDDED
|
||||
#define TWO 2
|
||||
#else
|
||||
#define TWO 1
|
||||
#endif
|
||||
|
||||
/* note :
|
||||
All STRINGs are allocated using mbkstrdup since the pointer to yytext
|
||||
will change when more than a STRING is used in the grammar.
|
||||
So all STRINGs are freed once used. */
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *s;
|
||||
long n;
|
||||
struct pxy {
|
||||
long x;
|
||||
long y;
|
||||
} *p;
|
||||
}
|
||||
|
||||
%token CELL
|
||||
%token PLACE
|
||||
%token TERMINAL
|
||||
%token RA
|
||||
%token STRETCH
|
||||
%token WIRE
|
||||
%token MWIDTH
|
||||
%token HORIZ
|
||||
%token VERTI
|
||||
%token MLEFT
|
||||
%token MRIGHT
|
||||
%token MTOP
|
||||
%token MBOTTOM
|
||||
%token AT
|
||||
%token MX
|
||||
%token MY
|
||||
%token R
|
||||
%token NTR
|
||||
%token PTR
|
||||
%token COP
|
||||
%token CON
|
||||
%token COPS
|
||||
%token COPW
|
||||
%token CONW
|
||||
%token PVIA
|
||||
%token CXN
|
||||
%token CXP
|
||||
%token STRING
|
||||
%token NUM
|
||||
|
||||
%type <p> point
|
||||
%type <s> STRING
|
||||
%type <n> NUM
|
||||
%type <n> face
|
||||
%type <n> dir
|
||||
%type <n> op
|
||||
|
||||
%start design
|
||||
|
||||
%%
|
||||
design : cells
|
||||
;
|
||||
|
||||
cells : leafcell
|
||||
| cells leafcell
|
||||
;
|
||||
|
||||
leafcell : CELL STRING '{' lines '}'
|
||||
{
|
||||
mbkfree($2);
|
||||
}
|
||||
;
|
||||
|
||||
lines : line
|
||||
| line lines
|
||||
;
|
||||
|
||||
line : PLACE STRING '=' elm ';'
|
||||
{
|
||||
mbkfree($2);
|
||||
}
|
||||
| PLACE STRING '=' STRING op AT '(' point ')' ';'
|
||||
{
|
||||
if (!strcmp($4, "ref_ref") || !strcmp($4, "ref_con"))
|
||||
addphref(mgleaf, $4, checkrefname($2), $8->x, $8->y);
|
||||
else /* unknown internally! */
|
||||
addphins(mgleaf, $4, checkinsname($2), $5, $8->x, $8->y);
|
||||
mbkfree($2);
|
||||
mbkfree($4);
|
||||
mbkfree($8);
|
||||
}
|
||||
| elm ';'
|
||||
;
|
||||
|
||||
elm : RA '(' STRING ',' point ',' point ')'
|
||||
{
|
||||
if (strncmp($3, "zd", 2)) {
|
||||
fprintf(stderr, "modgen parser warning : ra not for ab box\n");
|
||||
/* exit(18); */
|
||||
} else
|
||||
defab(mgleaf, $5->x, $7->x, $5->y, $7->y);
|
||||
mbkfree($3);
|
||||
mbkfree($5);
|
||||
mbkfree($7);
|
||||
}
|
||||
| TERMINAL STRING '(' MWIDTH '=' NUM ')' face STRING AT '(' point ')'
|
||||
{
|
||||
if (strcmp($2, "ul") && strcmp($2, "ur")
|
||||
&& strcmp($2, "lr") && strcmp($2, "ll"))
|
||||
addphcon(mgleaf, (char)$8, checkconname($2),
|
||||
$12->x, $12->y, mbk_layer($9), $6);
|
||||
mbkfree($2);
|
||||
mbkfree($9);
|
||||
mbkfree($12);
|
||||
}
|
||||
| STRETCH '(' STRING ',' NUM ',' dir ',' point ',' point ')'
|
||||
{
|
||||
char layer = mbk_layer($3);
|
||||
int x1 = $9->x, y1 = $9->y, x2 = $11->x, y2 = $11->y;
|
||||
|
||||
mbkfree($3);
|
||||
mbkfree($9);
|
||||
mbkfree($11);
|
||||
if ($7 == VERTI) {
|
||||
if (y2 > y1) {
|
||||
y2 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
y1 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
} else {
|
||||
y2 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
y1 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
}
|
||||
} else {
|
||||
if (x2 > x1) {
|
||||
x2 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
x1 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
} else {
|
||||
x2 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
x1 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
}
|
||||
}
|
||||
addphseg(mgleaf, layer, $5, x1, y1, x2, y2, NULL);
|
||||
}
|
||||
| WIRE {pl = NULL;} '(' STRING ',' NUM ',' point_list ')'
|
||||
{
|
||||
chain_list *l;
|
||||
int x1, y1, x2, y2;
|
||||
char layer = mbk_layer($4);
|
||||
|
||||
mbkfree($4);
|
||||
/* points in inverted order, but doesn't matter, same algo */
|
||||
for (l = pl; l->NEXT; l = l->NEXT) {
|
||||
x1 = (int)((struct pxy *)(l->DATA))->x;
|
||||
y1 = (int)((struct pxy *)(l->DATA))->y;
|
||||
x2 = (int)((struct pxy *)(l->NEXT->DATA))->x;
|
||||
y2 = (int)((struct pxy *)(l->NEXT->DATA))->y;
|
||||
if (l == pl) { /* last point */
|
||||
if (x1 == x2) {
|
||||
if (y2 > y1) {
|
||||
y1 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
} else {
|
||||
y1 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
}
|
||||
} else {
|
||||
if (x2 > x1) {
|
||||
x1 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
} else {
|
||||
x1 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!l->NEXT->NEXT) { /* first point */
|
||||
if (x1 == x2) {
|
||||
if (y2 > y1) {
|
||||
y2 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
} else {
|
||||
y2 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
}
|
||||
} else {
|
||||
if (x2 > x1) {
|
||||
x2 -= Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
} else {
|
||||
x2 += Extension[(int)layer] * SCALE_X * TWO / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
addphseg(mgleaf, layer, $6, x1, y1, x2, y2, NULL);
|
||||
}
|
||||
}
|
||||
| NTR '(' NUM ',' NUM ')' op AT '(' point ')'
|
||||
{ /* bounding box of transistors is knows for idps technology */
|
||||
float tx; /* used to compute transistor bbox */
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
/* +-----------+ when not placed yet */
|
||||
tx = ((float)$3 / 2 + (float)O_PS_AA * SCALE_X * TWO);
|
||||
|
||||
switch ((char)$7) {
|
||||
case NOSYM:
|
||||
case SYM_X:
|
||||
case SYM_Y:
|
||||
case SYMXY:
|
||||
y2 = y1 = $10->y;
|
||||
x1 = $10->x + tx;
|
||||
x2 = $10->x - tx;
|
||||
addphseg(mgleaf, NTRANS, $5, x1, y1, x2, y2, NULL);
|
||||
break;
|
||||
case ROT_P:
|
||||
case ROT_M:
|
||||
case SY_RP:
|
||||
case SY_RM:
|
||||
x2 = x1 = $10->x;
|
||||
y1 = $10->y + tx;
|
||||
y2 = $10->y - tx;
|
||||
addphseg(mgleaf, NTRANS, $5, x1, y1, x2, y2, NULL);
|
||||
break;
|
||||
}
|
||||
mbkfree($10);
|
||||
}
|
||||
| PTR '(' NUM ',' NUM ')' op AT '(' point ')'
|
||||
{ /* bounding box of transistors is knows for idps technology */
|
||||
float tx; /* used to compute transistor bbox */
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
/* +-----------+ when not placed yet */
|
||||
tx = ((float)$3 / 2 + (float)O_PS_AA * SCALE_X * TWO);
|
||||
|
||||
switch ((char)$7) {
|
||||
case NOSYM:
|
||||
case SYM_X:
|
||||
case SYM_Y:
|
||||
case SYMXY:
|
||||
y2 = y1 = $10->y;
|
||||
x1 = $10->x + tx;
|
||||
x2 = $10->x - tx;
|
||||
addphseg(mgleaf, PTRANS, $5, x1, y1, x2, y2, NULL);
|
||||
break;
|
||||
case ROT_P:
|
||||
case ROT_M:
|
||||
case SY_RP:
|
||||
case SY_RM:
|
||||
x2 = x1 = $10->x;
|
||||
y1 = $10->y + tx;
|
||||
y2 = $10->y - tx;
|
||||
addphseg(mgleaf, PTRANS, $5, x1, y1, x2, y2, NULL);
|
||||
break;
|
||||
}
|
||||
mbkfree($10);
|
||||
}
|
||||
| COP AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, CONT_DIF_P, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| CON AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, CONT_DIF_N, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| COPS AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, CONT_POLY, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| COPW AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, CONT_BODY_P, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| CONW AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, CONT_BODY_N, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| PVIA AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, CONT_VIA, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| CXN AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, C_X_N, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
| CXP AT '(' point ')'
|
||||
{
|
||||
addphvia(mgleaf, C_X_P, $4->x, $4->y, 0, 0,NULL);
|
||||
mbkfree($4);
|
||||
}
|
||||
;
|
||||
|
||||
point : NUM ',' NUM
|
||||
{
|
||||
struct pxy *pp;
|
||||
|
||||
pp = (struct pxy *)mbkalloc(sizeof(struct pxy));
|
||||
pp->x = $1;
|
||||
pp->y = $3;
|
||||
$$ = pp;
|
||||
}
|
||||
;
|
||||
|
||||
point_list : point
|
||||
{
|
||||
pl = addchain(pl, (void *)$1);
|
||||
}
|
||||
| point ',' point_list
|
||||
{
|
||||
pl = addchain(pl, (void *)$1);
|
||||
}
|
||||
;
|
||||
|
||||
dir : HORIZ {$$ = (long)HORIZ;}
|
||||
| VERTI {$$ = (long)VERTI;}
|
||||
;
|
||||
|
||||
face : MLEFT {$$ = (long)WEST;}
|
||||
| MRIGHT {$$ = (long)EAST;}
|
||||
| MBOTTOM {$$ = (long)SOUTH;}
|
||||
| MTOP {$$ = (long)NORTH;}
|
||||
;
|
||||
|
||||
op : {$$ = (long)NOSYM;}
|
||||
| MX
|
||||
{$$ = (long)SYM_Y;}
|
||||
| MY
|
||||
{$$ = (long)SYM_X;}
|
||||
| MX MY
|
||||
{$$ = (long)SYMXY;}
|
||||
| R NUM
|
||||
{
|
||||
if ($2 / SCALE_X / TWO == 90)
|
||||
$$ = (long)ROT_P;
|
||||
if ($2 / SCALE_X / TWO == 270)
|
||||
$$ = (long)ROT_M;
|
||||
}
|
||||
| MX R NUM
|
||||
{
|
||||
if ($3 / SCALE_X / TWO == 90)
|
||||
$$ = (long)SY_RM;
|
||||
if ($3 / SCALE_X / TWO == 270)
|
||||
$$ = (long)SY_RP;
|
||||
}
|
||||
| MY R NUM
|
||||
{
|
||||
if ($3 / SCALE_X / TWO == 90)
|
||||
$$ = (long)SY_RP;
|
||||
if ($3 / SCALE_X / TWO == 270)
|
||||
$$ = (long)SY_RM;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
char *
|
||||
filenameforlex()
|
||||
{
|
||||
return mgleaf->NAME;
|
||||
}
|
||||
|
||||
void
|
||||
mgnloadphfig(fig, name, mode)
|
||||
phfig_list *fig;
|
||||
char *name;
|
||||
char mode;
|
||||
{
|
||||
extern FILE *yyin; /* declared in the lex.yy.c by default */
|
||||
extern int yylineno;
|
||||
chain_list *c;
|
||||
|
||||
mgleaf = fig;
|
||||
if ((yyin = mbkfopen(name, IN_PH, READ_TEXT)) == NULL) {
|
||||
fflush(stdout);
|
||||
fprintf(stderr,
|
||||
"*** mbk error *** modgen parser failed opening file %s.%s\n",
|
||||
name, IN_PH);
|
||||
EXIT(1);
|
||||
}
|
||||
yylineno = 0;
|
||||
if (yyparse()) {
|
||||
fflush(stdout);
|
||||
fprintf(stderr,
|
||||
"*** mbk error *** modgen parser failed while reading file %s\n",
|
||||
filepath(name, IN_PH));
|
||||
EXIT(1);
|
||||
}
|
||||
(void)fclose(yyin);
|
||||
/* free :
|
||||
temporary space for point list must be freed. */
|
||||
for (c = pl; c; c = c->NEXT)
|
||||
mbkfree(c->DATA);
|
||||
freechain(pl);
|
||||
/* not so nice :
|
||||
It would be nice if I'd parse only the necessary stuff when reading
|
||||
the file, but it's a little painful, and would need some checks
|
||||
I can't afford right now. */
|
||||
if (mode == 'P') {
|
||||
void **ppobj;
|
||||
void *next;
|
||||
|
||||
/* delete instances */
|
||||
for (ppobj = (void**)&HEAD_PHFIG->PHINS; *ppobj != NULL;) {
|
||||
next = (void *)((phins_list *)*ppobj)->NEXT;
|
||||
mbkfree((phins_list *)*ppobj);
|
||||
*ppobj = next;
|
||||
}
|
||||
|
||||
/* delete vias */
|
||||
for (ppobj = (void**)&HEAD_PHFIG->PHVIA; *ppobj != NULL;) {
|
||||
next = (void *)((phvia_list *)*ppobj)->NEXT;
|
||||
mbkfree((phvia_list *)*ppobj);
|
||||
*ppobj = next;
|
||||
}
|
||||
|
||||
/* delete segments */
|
||||
for (ppobj = (void**)&HEAD_PHFIG->PHSEG; *ppobj != NULL;) {
|
||||
if (((phseg_list *)*ppobj)->LAYER != TPOLY
|
||||
&& ((phseg_list *)*ppobj)->LAYER != TALU1
|
||||
&& ((phseg_list *)*ppobj)->LAYER != TALU2
|
||||
&& ((phseg_list *)*ppobj)->LAYER != TALU3) {
|
||||
next = (void *)((phseg_list *)*ppobj)->NEXT;
|
||||
mbkfree((phseg_list *)*ppobj);
|
||||
*ppobj = next;
|
||||
} else
|
||||
ppobj = (void **)&((phseg_list *)*ppobj)->NEXT;
|
||||
}
|
||||
}
|
||||
/* mbk strategy :
|
||||
only one cell per modgen file. */
|
||||
fig = HEAD_PHFIG;
|
||||
}
|
||||
|
||||
static char
|
||||
mbk_layer(mg_layer)
|
||||
char *mg_layer;
|
||||
{
|
||||
if (!strcmp(mg_layer, "nw"))
|
||||
return NWELL;
|
||||
if (!strcmp(mg_layer, "pw"))
|
||||
return PWELL;
|
||||
if (!strcmp(mg_layer, "xn"))
|
||||
return NTIE;
|
||||
if (!strcmp(mg_layer, "xp"))
|
||||
return PTIE;
|
||||
if (!strcmp(mg_layer, "nn"))
|
||||
return NDIF;
|
||||
if (!strcmp(mg_layer, "pp"))
|
||||
return PDIF;
|
||||
if (!strcmp(mg_layer, "ps"))
|
||||
return POLY;
|
||||
if (!strcmp(mg_layer, "m1"))
|
||||
return ALU1;
|
||||
if (!strcmp(mg_layer, "m2"))
|
||||
return ALU2;
|
||||
if (!strcmp(mg_layer, "m3"))
|
||||
return ALU3;
|
||||
if (!strcmp(mg_layer, "am1"))
|
||||
return TALU1;
|
||||
if (!strcmp(mg_layer, "am2"))
|
||||
return TALU2;
|
||||
if (!strcmp(mg_layer, "am3"))
|
||||
return TALU3;
|
||||
}
|
||||
|
||||
/* decode a reference name :
|
||||
xxx[?] -> xxx
|
||||
xxx[?][??] -> xxx ?,
|
||||
xxx[?][??][???] -> xxx ?_??.
|
||||
I always have added an index since here also two instances can't have
|
||||
the same name. */
|
||||
|
||||
static char
|
||||
*checkrefname(name)
|
||||
char *name;
|
||||
{
|
||||
char *s, *t, *u = NULL;
|
||||
char one = 0;
|
||||
|
||||
s = t = name;
|
||||
|
||||
while (*t) {
|
||||
if (*t == '[')
|
||||
if (!one) {
|
||||
*t = ' ';
|
||||
u = s;
|
||||
one = 1;
|
||||
} else if (one == 1) {
|
||||
*t = '_';
|
||||
u = s;
|
||||
one++;
|
||||
} else {
|
||||
*t = ' ';
|
||||
u = s;
|
||||
}
|
||||
else if (*t == ']')
|
||||
if (*(++t) == '\0') /* ok, it's finished */
|
||||
goto end;
|
||||
else if (*t == '[') /* multiple array */
|
||||
continue;
|
||||
*s++ = *t++;
|
||||
}
|
||||
end:
|
||||
*s = '\0';
|
||||
/* last vectorized value :
|
||||
it shall be skipped since I introduced it while driving the file. */
|
||||
if (u)
|
||||
*u = '\0';
|
||||
return name;
|
||||
}
|
||||
|
||||
/* decode a connector name :
|
||||
in modgen, 'cause we haven't the same conventions, a by me driven
|
||||
connector has the forms :
|
||||
xxx[?] -> xxx, where ? is a number, because I suffix all connectors that
|
||||
way.
|
||||
xxx[??][?] -> xxx[??], because this was previously a vector. */
|
||||
|
||||
static char
|
||||
*checkconname(name)
|
||||
char *name;
|
||||
{
|
||||
char *s, *t, *u = NULL;
|
||||
|
||||
s = t = name;
|
||||
while (*t) {
|
||||
if (*t == '[') {
|
||||
*t = ' ';
|
||||
u = s; /* last vector at that time */
|
||||
} else if (*t == ']') {
|
||||
if (*(++t) == '\0') /* ok, it's finished */
|
||||
goto end;
|
||||
else if (*t == '[') /* multiple array */
|
||||
continue;
|
||||
}
|
||||
*s++ = *t++;
|
||||
}
|
||||
end:
|
||||
*s = '\0';
|
||||
/* last vectorized value :
|
||||
it shall be skipped since I introduced it while driving the file. */
|
||||
if (u)
|
||||
*u = '\0';
|
||||
return name;
|
||||
}
|
||||
|
||||
/* decode an instance name :
|
||||
in modgen, 'cause we haven't the same conventions, a by me driven
|
||||
instance has the forms :
|
||||
xxx.corner
|
||||
since I arranged to put the corner in such a place that it makes it
|
||||
automatically good for mbk, I just forgot about the corner. */
|
||||
|
||||
static char
|
||||
*checkinsname(name)
|
||||
char *name;
|
||||
{
|
||||
char *s = name;
|
||||
|
||||
s = strrchr(name, '.');
|
||||
*s = '\0';
|
||||
return name;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Library General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Alliance VLSI CAD System is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue