This commit was generated by cvs2svn to track changes on a CVS vendor

branch.
This commit is contained in:
Frederic Petrot 2002-03-14 13:47:47 +00:00
commit bd71a62dc6
7 changed files with 1378 additions and 0 deletions

View File

@ -0,0 +1 @@
SUBDIRS = src

View File

@ -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
])

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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.
*/