Merge branch 'master' into netgen-1.5
This commit is contained in:
commit
9b2dc4b665
311
base/ext.c
311
base/ext.c
|
|
@ -31,6 +31,8 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
static int invlambda = 100; /* Used in sim and prm files */
|
||||||
|
|
||||||
void extCell(char *name, int filenum)
|
void extCell(char *name, int filenum)
|
||||||
{
|
{
|
||||||
struct nlist *tp, *tp2;
|
struct nlist *tp, *tp2;
|
||||||
|
|
@ -450,7 +452,8 @@ void simCell(char *name, int filenum)
|
||||||
struct nlist *tp, *tp2;
|
struct nlist *tp, *tp2;
|
||||||
struct objlist *ob, *ob2;
|
struct objlist *ob, *ob2;
|
||||||
char FileName[500], simclass;
|
char FileName[500], simclass;
|
||||||
short i;
|
char writeLine[1024], paramString[128];
|
||||||
|
short i, p, mult;
|
||||||
double l, w, v;
|
double l, w, v;
|
||||||
|
|
||||||
tp = LookupCellFile(name, filenum);
|
tp = LookupCellFile(name, filenum);
|
||||||
|
|
@ -459,6 +462,11 @@ void simCell(char *name, int filenum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check procedure disabled because new extensions to .sim format
|
||||||
|
* allow 'x' records to represent low-level components that are
|
||||||
|
* modeled as SPICE subcircuits.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
/* check to see that all children have been dumped */
|
/* check to see that all children have been dumped */
|
||||||
ob = tp->cell;
|
ob = tp->cell;
|
||||||
while (ob != NULL) {
|
while (ob != NULL) {
|
||||||
|
|
@ -470,6 +478,7 @@ void simCell(char *name, int filenum)
|
||||||
}
|
}
|
||||||
ob = ob->next;
|
ob = ob->next;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SetExtension(FileName, name, SIM_EXTENSION);
|
SetExtension(FileName, name, SIM_EXTENSION);
|
||||||
if (!OpenFile(FileName, 0)) {
|
if (!OpenFile(FileName, 0)) {
|
||||||
|
|
@ -478,9 +487,9 @@ void simCell(char *name, int filenum)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print out header list */
|
/* print out header list */
|
||||||
/* distance units are multiplied by 100 (distances are in um) */
|
/* distance units are multiplied by invlambda */
|
||||||
|
|
||||||
FlushString("| units: 100 tech: scmos\n");
|
FlushString("| units: %d tech: scmos\n", 100 * invlambda);
|
||||||
|
|
||||||
/* now run through cell's contents, print instances */
|
/* now run through cell's contents, print instances */
|
||||||
for (ob = tp->cell; ob != NULL; ob = ob->next) {
|
for (ob = tp->cell; ob != NULL; ob = ob->next) {
|
||||||
|
|
@ -516,13 +525,17 @@ void simCell(char *name, int filenum)
|
||||||
case CLASS_NPN:
|
case CLASS_NPN:
|
||||||
simclass = 'b';
|
simclass = 'b';
|
||||||
break;
|
break;
|
||||||
default:
|
case CLASS_SUBCKT:
|
||||||
|
case CLASS_MODULE:
|
||||||
simclass = 'x';
|
simclass = 'x';
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
simclass = '|';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simclass != 'x')
|
if (simclass != 'x')
|
||||||
FlushString("%c", simclass);
|
FlushString("%c", simclass);
|
||||||
|
|
||||||
switch (tp2->class) {
|
switch (tp2->class) {
|
||||||
case CLASS_NMOS: case CLASS_NMOS4:
|
case CLASS_NMOS: case CLASS_NMOS4:
|
||||||
|
|
@ -590,6 +603,115 @@ void simCell(char *name, int filenum)
|
||||||
FlushString(" %g\n", v);
|
FlushString(" %g\n", v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLASS_SUBCKT: case CLASS_MODULE:
|
||||||
|
*writeLine = 'x';
|
||||||
|
*(writeLine + 1) = '\0';
|
||||||
|
mult = 1;
|
||||||
|
|
||||||
|
/* Important---Need to look up the cell definition; if
|
||||||
|
* the first pin is "drain" then it is a FET, and pins
|
||||||
|
* get swapped from D-G-S-B to G-S-D-B. Source and drain
|
||||||
|
* are treated here as equivalent because the .sim format
|
||||||
|
* has no concept of an asymmetric source and drain.
|
||||||
|
*/
|
||||||
|
ob2 = tp2->cell;
|
||||||
|
if ((*matchfunc)(ob2->next->name, "gate"))
|
||||||
|
{
|
||||||
|
strcat(writeLine, " ");
|
||||||
|
strcat(writeLine, NodeAlias(tp, ob->next));
|
||||||
|
strcat(writeLine, " ");
|
||||||
|
strcat(writeLine, NodeAlias(tp, ob));
|
||||||
|
ob2 = ob->next->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ob2 = ob;
|
||||||
|
|
||||||
|
while (ob2 != NULL) {
|
||||||
|
strcat(writeLine, " ");
|
||||||
|
strcat(writeLine, NodeAlias(tp, ob2));
|
||||||
|
ob2 = ob2->next;
|
||||||
|
if ((ob2 == NULL) || (ob2->type <= FIRSTPIN)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ob2 && ob2->type == PROPERTY) {
|
||||||
|
struct valuelist *vl;
|
||||||
|
/* Only known parameters are L, W, X, and Y */
|
||||||
|
for (p = 0;; p++) {
|
||||||
|
vl = (struct valuelist *)(&(ob2->instance.props[p]));
|
||||||
|
if (vl->type == PROP_ENDLIST) {
|
||||||
|
strcat(writeLine, " l=1");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((*matchfunc)(vl->key, "L")) {
|
||||||
|
v = vl->value.dval;
|
||||||
|
sprintf(paramString, " l=%d", (int)(0.5 + (v * invlambda)));
|
||||||
|
strcat(writeLine, paramString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (p = 0;; p++) {
|
||||||
|
vl = (struct valuelist *)(&(ob2->instance.props[p]));
|
||||||
|
if (vl->type == PROP_ENDLIST) {
|
||||||
|
strcat(writeLine, " w=1");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((*matchfunc)(vl->key, "W")) {
|
||||||
|
v = vl->value.dval;
|
||||||
|
sprintf(paramString, " w=%d", (int)(0.5 + (v * invlambda)));
|
||||||
|
strcat(writeLine, paramString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (p = 0;; p++) {
|
||||||
|
vl = (struct valuelist *)(&(ob2->instance.props[p]));
|
||||||
|
if (vl->type == PROP_ENDLIST) {
|
||||||
|
strcat(writeLine, " x=0");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((*matchfunc)(vl->key, "X")) {
|
||||||
|
i = vl->value.ival;
|
||||||
|
sprintf(paramString, " x=%d", i);
|
||||||
|
strcat(writeLine, paramString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (p = 0;; p++) {
|
||||||
|
vl = (struct valuelist *)(&(ob2->instance.props[p]));
|
||||||
|
if (vl->type == PROP_ENDLIST) {
|
||||||
|
strcat(writeLine, " y=0");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((*matchfunc)(vl->key, "Y")) {
|
||||||
|
i = vl->value.ival;
|
||||||
|
sprintf(paramString, " y=%d", i);
|
||||||
|
strcat(writeLine, paramString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (p = 0;; p++) {
|
||||||
|
vl = (struct valuelist *)(&(ob2->instance.props[p]));
|
||||||
|
if (vl->type == PROP_ENDLIST) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((*matchfunc)(vl->key, "M")) {
|
||||||
|
if (vl->type == PROP_INTEGER)
|
||||||
|
mult = vl->value.ival;
|
||||||
|
else
|
||||||
|
mult = vl->value.dval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(writeLine, " ");
|
||||||
|
strcat(writeLine, tp2->name);
|
||||||
|
strcat(writeLine, "\n");
|
||||||
|
|
||||||
|
/* Multiple instances (M != 1) are written multiple times.
|
||||||
|
* NF is ignored in favor of having a single device with
|
||||||
|
* the total width.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < mult; i++)
|
||||||
|
FlushString(writeLine);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FlushString("| unhandled component %s\n", tp2->name);
|
FlushString("| unhandled component %s\n", tp2->name);
|
||||||
break;
|
break;
|
||||||
|
|
@ -626,6 +748,181 @@ int StrIsInt(char *s)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------*/
|
||||||
|
/* Read a .prm format file. This is specifically to */
|
||||||
|
/* get the "device" lines that indicate how a SPICE */
|
||||||
|
/* subcircuit model or a .sim "x" record needs to be */
|
||||||
|
/* translated into a specific component type like a */
|
||||||
|
/* FET, diode, resistor, etc. */
|
||||||
|
/*------------------------------------------------------*/
|
||||||
|
|
||||||
|
char *ReadPrm(char *fname, int *fnum)
|
||||||
|
{
|
||||||
|
int filenum;
|
||||||
|
struct keyvalue *kvlist = NULL;
|
||||||
|
struct nlist *tp;
|
||||||
|
|
||||||
|
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
|
||||||
|
char name[MAX_STR_LEN];
|
||||||
|
|
||||||
|
SetExtension(name, fname, PRM_EXTENSION);
|
||||||
|
if (OpenParseFile(name, *fnum) < 0) {
|
||||||
|
Printf("Error in prm file read: No file %s\n",name);
|
||||||
|
*fnum = filenum;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure all .prm file reading is case INsensitive */
|
||||||
|
/* This is because the only reason to read a PRM file */
|
||||||
|
/* is to find all the subcircuit device types so that */
|
||||||
|
/* a SPICE file can be read and a SIM file written. */
|
||||||
|
|
||||||
|
matchfunc = matchnocase;
|
||||||
|
matchintfunc = matchfile;
|
||||||
|
hashfunc = hashnocase;
|
||||||
|
|
||||||
|
CellDef(fname, filenum);
|
||||||
|
|
||||||
|
while (!EndParseFile()) {
|
||||||
|
char devicename[MAX_STR_LEN];
|
||||||
|
SkipTok(NULL);
|
||||||
|
|
||||||
|
if (EndParseFile()) break;
|
||||||
|
if (nexttok[0] == ';') continue; /* Comment line */
|
||||||
|
else if (nexttok[0] == '\0') continue; /* Blank line */
|
||||||
|
else if (match(nexttok, "lambda")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
invlambda = (int)(0.5 + (1.0 / atof(nexttok)));
|
||||||
|
SkipNewLine(NULL); /* skip any attributes */
|
||||||
|
}
|
||||||
|
else if (match(nexttok, "device")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
if (match(nexttok, "nfet")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
strcpy(devicename, nexttok);
|
||||||
|
/* Create 4-terminal nfet subcircuit device record */
|
||||||
|
if (LookupCellFile(devicename, filenum) == NULL) {
|
||||||
|
CellDef(devicename, filenum);
|
||||||
|
Port("drain");
|
||||||
|
Port("gate");
|
||||||
|
Port("source");
|
||||||
|
Port("bulk");
|
||||||
|
PropertyDouble(devicename, filenum, "l", 0.01, 0.0);
|
||||||
|
PropertyDouble(devicename, filenum, "w", 0.01, 0.0);
|
||||||
|
PropertyInteger(devicename, filenum, "nf", 0, 1);
|
||||||
|
PropertyInteger(devicename, filenum, "m", 0, 1);
|
||||||
|
SetClass(CLASS_SUBCKT);
|
||||||
|
EndCell();
|
||||||
|
ReopenCellDef(fname, filenum);
|
||||||
|
}
|
||||||
|
LinkProperties(devicename, kvlist);
|
||||||
|
SkipNewLine(NULL); /* skip any attributes */
|
||||||
|
}
|
||||||
|
else if (match(nexttok, "pfet")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
strcpy(devicename, nexttok);
|
||||||
|
/* Create 4-terminal pfet subcircuit device record */
|
||||||
|
if (LookupCellFile(devicename, filenum) == NULL) {
|
||||||
|
CellDef(devicename, filenum);
|
||||||
|
Port("drain");
|
||||||
|
Port("gate");
|
||||||
|
Port("source");
|
||||||
|
Port("well");
|
||||||
|
PropertyDouble(devicename, filenum, "l", 0.01, 0.0);
|
||||||
|
PropertyDouble(devicename, filenum, "w", 0.01, 0.0);
|
||||||
|
PropertyInteger(devicename, filenum, "nf", 0, 1);
|
||||||
|
PropertyInteger(devicename, filenum, "m", 0, 1);
|
||||||
|
SetClass(CLASS_SUBCKT);
|
||||||
|
EndCell();
|
||||||
|
ReopenCellDef(fname, filenum);
|
||||||
|
}
|
||||||
|
LinkProperties(devicename, kvlist);
|
||||||
|
SkipNewLine(NULL); /* skip various attributes */
|
||||||
|
}
|
||||||
|
else if (match(nexttok, "resistor")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
strcpy(devicename, nexttok);
|
||||||
|
/* Resistor device has additional record for the value */
|
||||||
|
/* (Need to do something with this. . . ?) */
|
||||||
|
SkipTok(NULL);
|
||||||
|
/* Create resistor subcircuit device record */
|
||||||
|
if (LookupCellFile(devicename, filenum) == NULL) {
|
||||||
|
CellDef(devicename, filenum);
|
||||||
|
Port("end_a");
|
||||||
|
Port("end_b");
|
||||||
|
PropertyDouble(devicename, filenum, "value", 0.01, 0.0);
|
||||||
|
PropertyDouble(devicename, filenum, "l", 0.01, 0.0);
|
||||||
|
PropertyDouble(devicename, filenum, "w", 0.01, 0.0);
|
||||||
|
PropertyInteger(devicename, filenum, "m", 0, 1);
|
||||||
|
SetClass(CLASS_SUBCKT);
|
||||||
|
EndCell();
|
||||||
|
ReopenCellDef(fname, filenum);
|
||||||
|
}
|
||||||
|
LinkProperties(devicename, kvlist);
|
||||||
|
SkipNewLine(NULL); /* skip various attributes */
|
||||||
|
}
|
||||||
|
else if (match(nexttok, "capacitor")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
strcpy(devicename, nexttok);
|
||||||
|
/* Capacitor device has additional record for the value */
|
||||||
|
/* (Need to do something with this. . . ?) */
|
||||||
|
SkipTok(NULL);
|
||||||
|
/* Create capacitor subcircuit device record */
|
||||||
|
if (LookupCellFile(devicename, filenum) == NULL) {
|
||||||
|
CellDef(devicename, filenum);
|
||||||
|
Port("top");
|
||||||
|
Port("bottom");
|
||||||
|
PropertyDouble(devicename, filenum, "value", 0.01, 0.0);
|
||||||
|
PropertyDouble(devicename, filenum, "l", 0.01, 0.0);
|
||||||
|
PropertyDouble(devicename, filenum, "w", 0.01, 0.0);
|
||||||
|
PropertyInteger(devicename, filenum, "m", 0, 1);
|
||||||
|
SetClass(CLASS_SUBCKT);
|
||||||
|
EndCell();
|
||||||
|
ReopenCellDef(fname, filenum); /* Reopen */
|
||||||
|
}
|
||||||
|
LinkProperties(devicename, kvlist);
|
||||||
|
SkipNewLine(NULL);
|
||||||
|
}
|
||||||
|
else if (match(nexttok, "diode")) {
|
||||||
|
SkipTok(NULL);
|
||||||
|
strcpy(devicename, nexttok);
|
||||||
|
/* Create diode subcircuit device record */
|
||||||
|
if (LookupCellFile(devicename, filenum) == NULL) {
|
||||||
|
CellDef(devicename, filenum);
|
||||||
|
Port("anode");
|
||||||
|
Port("cathode");
|
||||||
|
PropertyInteger(devicename, filenum, "m", 0, 1);
|
||||||
|
SetClass(CLASS_SUBCKT);
|
||||||
|
EndCell();
|
||||||
|
ReopenCellDef(fname, filenum); /* Reopen */
|
||||||
|
}
|
||||||
|
LinkProperties(devicename, kvlist);
|
||||||
|
SkipNewLine(NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Printf("Unknown device type in .prm: '%s'\n", nexttok);
|
||||||
|
InputParseError(stderr);
|
||||||
|
SkipNewLine(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Could spell out all the keywords used in .prm files */
|
||||||
|
/* but probably not worth the effort. */
|
||||||
|
SkipNewLine(NULL);
|
||||||
|
}
|
||||||
|
DeleteProperties(&kvlist);
|
||||||
|
}
|
||||||
|
EndCell();
|
||||||
|
CloseParseFile();
|
||||||
|
|
||||||
|
tp = LookupCellFile(fname, filenum);
|
||||||
|
if (tp) tp->flags |= CELL_TOP;
|
||||||
|
|
||||||
|
*fnum = filenum;
|
||||||
|
return fname;
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------*/
|
/*-------------------------*/
|
||||||
/* Read a .sim format file */
|
/* Read a .sim format file */
|
||||||
/*-------------------------*/
|
/*-------------------------*/
|
||||||
|
|
@ -644,7 +941,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||||
|
|
||||||
SetExtension(name, fname, SIM_EXTENSION);
|
SetExtension(name, fname, SIM_EXTENSION);
|
||||||
if (OpenParseFile(name, *fnum) < 0) {
|
if (OpenParseFile(name, *fnum) < 0) {
|
||||||
Printf("Error in ext file read: No file %s\n",name);
|
Printf("Error in sim file read: No file %s\n",name);
|
||||||
*fnum = filenum;
|
*fnum = filenum;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -847,7 +1144,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||||
}
|
}
|
||||||
else if (match(nexttok, "r")) { /* 2-port resistors */
|
else if (match(nexttok, "r")) { /* 2-port resistors */
|
||||||
if (IgnoreRC) {
|
if (IgnoreRC) {
|
||||||
/* ignore all capacitances */
|
/* ignore all resistances */
|
||||||
SkipNewLine(NULL);
|
SkipNewLine(NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -886,7 +886,7 @@ char *ReadNetlist(char *fname, int *fnum)
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef mips
|
#ifdef mips
|
||||||
struct filetype formats[7];
|
struct filetype formats[8];
|
||||||
|
|
||||||
formats[0].extension = NTK_EXTENSION;
|
formats[0].extension = NTK_EXTENSION;
|
||||||
formats[0].proc = ReadNtk;
|
formats[0].proc = ReadNtk;
|
||||||
|
|
@ -894,14 +894,16 @@ char *ReadNetlist(char *fname, int *fnum)
|
||||||
formats[1].proc = ReadExtHier;
|
formats[1].proc = ReadExtHier;
|
||||||
formats[2].extension = SIM_EXTENSION;
|
formats[2].extension = SIM_EXTENSION;
|
||||||
formats[2].proc = ReadSim;
|
formats[2].proc = ReadSim;
|
||||||
formats[3].extension = SPICE_EXTENSION;
|
formats[3].extension = PRM_EXTENSION;
|
||||||
formats[3].proc = ReadSpice;
|
formats[3].proc = ReadPrm;
|
||||||
formats[4].extension = NETGEN_EXTENSION;
|
formats[4].extension = SPICE_EXTENSION;
|
||||||
formats[4].proc = ReadNetgenFile;
|
formats[4].proc = ReadSpice;
|
||||||
formats[5].extension = VERILOG_EXTENSION;
|
formats[5].extension = NETGEN_EXTENSION;
|
||||||
formats[5].proc = ReadVerilogFile;
|
formats[5].proc = ReadNetgenFile;
|
||||||
formats[6].extension = NULL;
|
formats[6].extension = VERILOG_EXTENSION;
|
||||||
formats[6].proc = NULL;
|
formats[6].proc = ReadVerilogFile;
|
||||||
|
formats[7].extension = NULL;
|
||||||
|
formats[7].proc = NULL;
|
||||||
|
|
||||||
#else /* not mips (i.e. compiler with reasonable initializers) */
|
#else /* not mips (i.e. compiler with reasonable initializers) */
|
||||||
|
|
||||||
|
|
@ -910,6 +912,7 @@ char *ReadNetlist(char *fname, int *fnum)
|
||||||
{NTK_EXTENSION, ReadNtk},
|
{NTK_EXTENSION, ReadNtk},
|
||||||
{EXT_EXTENSION, ReadExtHier},
|
{EXT_EXTENSION, ReadExtHier},
|
||||||
{SIM_EXTENSION, ReadSim},
|
{SIM_EXTENSION, ReadSim},
|
||||||
|
{PRM_EXTENSION, ReadPrm},
|
||||||
{SPICE_EXTENSION, ReadSpice},
|
{SPICE_EXTENSION, ReadSpice},
|
||||||
{SPICE_EXT2, ReadSpice},
|
{SPICE_EXT2, ReadSpice},
|
||||||
{SPICE_EXT3, ReadSpice},
|
{SPICE_EXT3, ReadSpice},
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#define WOMBAT_EXTENSION ".wom"
|
#define WOMBAT_EXTENSION ".wom"
|
||||||
#define EXT_EXTENSION ".ext"
|
#define EXT_EXTENSION ".ext"
|
||||||
#define SIM_EXTENSION ".sim"
|
#define SIM_EXTENSION ".sim"
|
||||||
|
#define PRM_EXTENSION ".prm"
|
||||||
#define SPICE_EXTENSION ".spice"
|
#define SPICE_EXTENSION ".spice"
|
||||||
#define SPICE_EXT2 ".spc"
|
#define SPICE_EXT2 ".spc"
|
||||||
#define SPICE_EXT3 ".sp"
|
#define SPICE_EXT3 ".sp"
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,7 @@ extern char *ReadNtk (char *fname, int *fnum);
|
||||||
extern char *ReadExtHier(char *fname, int *fnum);
|
extern char *ReadExtHier(char *fname, int *fnum);
|
||||||
extern char *ReadExtFlat(char *fname, int *fnum);
|
extern char *ReadExtFlat(char *fname, int *fnum);
|
||||||
extern char *ReadSim(char *fname, int *fnum);
|
extern char *ReadSim(char *fname, int *fnum);
|
||||||
|
extern char *ReadPrm(char *fname, int *fnum);
|
||||||
extern char *ReadSpice(char *fname, int *fnum);
|
extern char *ReadSpice(char *fname, int *fnum);
|
||||||
extern char *ReadSpiceLib(char *fname, int *fnum);
|
extern char *ReadSpiceLib(char *fname, int *fnum);
|
||||||
extern char *ReadNetgenFile (char *fname, int *fnum);
|
extern char *ReadNetgenFile (char *fname, int *fnum);
|
||||||
|
|
|
||||||
|
|
@ -707,11 +707,11 @@ _netgen_readnet(ClientData clientData,
|
||||||
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
||||||
{
|
{
|
||||||
char *formats[] = {
|
char *formats[] = {
|
||||||
"automatic", "ext", "extflat", "sim", "ntk", "spice",
|
"automatic", "ext", "extflat", "sim", "prm", "ntk", "spice",
|
||||||
"verilog", "netgen", "actel", "xilinx", NULL
|
"verilog", "netgen", "actel", "xilinx", NULL
|
||||||
};
|
};
|
||||||
enum FormatIdx {
|
enum FormatIdx {
|
||||||
AUTO_IDX, EXT_IDX, EXTFLAT_IDX, SIM_IDX, NTK_IDX,
|
AUTO_IDX, EXT_IDX, EXTFLAT_IDX, SIM_IDX, PRM_IDX, NTK_IDX,
|
||||||
SPICE_IDX, VERILOG_IDX, NETGEN_IDX, ACTEL_IDX, XILINX_IDX
|
SPICE_IDX, VERILOG_IDX, NETGEN_IDX, ACTEL_IDX, XILINX_IDX
|
||||||
};
|
};
|
||||||
struct nlist *tc;
|
struct nlist *tc;
|
||||||
|
|
@ -807,6 +807,9 @@ _netgen_readnet(ClientData clientData,
|
||||||
case SIM_IDX:
|
case SIM_IDX:
|
||||||
retstr = ReadSim(savstr, &filenum);
|
retstr = ReadSim(savstr, &filenum);
|
||||||
break;
|
break;
|
||||||
|
case PRM_IDX:
|
||||||
|
retstr = ReadPrm(savstr, &filenum);
|
||||||
|
break;
|
||||||
case NTK_IDX:
|
case NTK_IDX:
|
||||||
retstr = ReadNtk(savstr, &filenum);
|
retstr = ReadNtk(savstr, &filenum);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue