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