Fixed numparam library (Steven Borley) and corrected bug in node translation (Hitoshi Tanaka).
This commit is contained in:
parent
7989c811fb
commit
1aa04ca10b
|
|
@ -0,0 +1,17 @@
|
|||
* Param-example
|
||||
.param amplitude= 1V
|
||||
|
||||
.subckt myfilter in out
|
||||
+ params: rval=100k cval= 100nF
|
||||
Ra in p1 {2*rval}
|
||||
Rb p1 out {2*rval}
|
||||
C1 p1 0 {2*cval}
|
||||
Ca in p2 {cval}
|
||||
Cb p2 out {cval}
|
||||
R1 p2 0 {rval}
|
||||
.ends myfilter
|
||||
|
||||
X1 input output myfilter 1k 1nF
|
||||
V1 input 0 AC {amplitude}
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
* PIN model
|
||||
* line 2
|
||||
* line 3
|
||||
* -- Summary -------------------------------
|
||||
* This is a simple spice model of a PIN diode.
|
||||
*
|
||||
* -- Description ---------------------------
|
||||
* It is a three node device; one input node (relative to ground) and two
|
||||
* output nodes (cathode and anode)
|
||||
*
|
||||
|
||||
* -- Model ----------------------------------
|
||||
.subckt SIMPLE_PIN input cathode anode params: resp=0.5
|
||||
|
||||
* Input photocurrent is modled by a voltage
|
||||
* This generates a current using a linear voltage-controlled current source
|
||||
Gin dk da input 0 {resp}
|
||||
Rin input 0 1G
|
||||
Cin input 0 {resp}
|
||||
|
||||
* The pn-junction that generates this photocurrent in the real device is modelled
|
||||
* here by a simple diode
|
||||
Dpn da dk pndiode
|
||||
|
||||
* terminal resistances
|
||||
Ra anode da 0.001ohm
|
||||
Rk cathode dk 0.001ohm
|
||||
|
||||
* subsircuit models:
|
||||
.MODEL pndiode D IS=0.974p RS=0.1 N=1.986196 BV=7.1 IBV=0.1n
|
||||
+ CJO=99.2p VJ=0.455536 M=0.418717 TT=500n
|
||||
|
||||
.ends
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
* Test circuit for pin.mod
|
||||
|
||||
.include pin.mod
|
||||
|
||||
* Photodiode supply
|
||||
Vbias psu 0 10V
|
||||
|
||||
* Light input is modeled by a voltage source that we can vary
|
||||
Vlight input 0 2mW
|
||||
|
||||
* The pin diode
|
||||
Xpin input cathode anode SIMPLE_PIN 0.7
|
||||
|
||||
* monitor resistor
|
||||
Rmon anode 0 1ohm
|
||||
|
||||
* Quench restistor
|
||||
Rq psu cathode 1k
|
||||
|
||||
*.dc vlight 0 5mW 0.01mW
|
||||
|
||||
.control
|
||||
dc vlight 0 10mW 0.01mW
|
||||
plot V(anode)
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
||||
|
|
@ -32,6 +32,8 @@ Author: 1985 Wayne A. Christopher
|
|||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
/* SJB - Uncomment this line for debug tracing */
|
||||
/*#define TRACE */
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* This routine reads a line (of arbitrary length), up to a '\n' or 'EOF' *
|
||||
|
|
@ -132,7 +134,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
char *buffer, *s, *t, c;
|
||||
/* segfault fix */
|
||||
char *copys=NULL;
|
||||
int line = 1;
|
||||
int line_number = 1; /* sjb - renamed to avoid confusion with struct line */
|
||||
FILE *newfp;
|
||||
|
||||
/* Must set this to NULL or non-tilde includes segfault. -- Tim Molteno */
|
||||
|
|
@ -179,12 +181,12 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf ("in inp_readall, just read %s . . .\n", buffer);
|
||||
printf ("in inp_readall, just read '%s' . . .\n", buffer);
|
||||
#endif
|
||||
|
||||
/* OK -- now we have loaded the next line into 'buffer'. Process it. */
|
||||
/* OK -- now we have loaded the next line into 'buffer'. Process it. */
|
||||
/* If input line is blank, ignore it & continue looping. */
|
||||
if ( (strcmp(buffer,"\n") == 0)
|
||||
if ( (strcmp(buffer,"\n") == 0)
|
||||
|| (strcmp(buffer,"\r\n") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -204,7 +206,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
fprintf(cp_err, "Warning: premature EOF\n");
|
||||
}
|
||||
*s = '\0'; /* Zap the newline. */
|
||||
|
||||
|
||||
if(*(s-1) == '\r') /* Zop the carriage return under windows */
|
||||
*(s-1) = '\0';
|
||||
|
||||
|
|
@ -265,12 +267,13 @@ inp_readall(FILE *fp, struct line **data)
|
|||
end->li_error = NULL;
|
||||
end->li_actual = NULL;
|
||||
end->li_line = copy(buffer);
|
||||
end->li_linenum = line++;
|
||||
end->li_linenum = line_number++;
|
||||
end->li_next = newcard;
|
||||
|
||||
/* Renumber the lines */
|
||||
for (end = newcard; end && end->li_next; end = end->li_next)
|
||||
end->li_linenum = line++;
|
||||
for (end = newcard; end && end->li_next; end = end->li_next)
|
||||
end->li_linenum = line_number++;
|
||||
end->li_linenum = line_number++; /* SJB - renumber the last line */
|
||||
|
||||
/* Fix the buffer up a bit. */
|
||||
(void) strncpy(buffer + 1, "end of:", 7);
|
||||
|
|
@ -290,7 +293,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
end->li_error = NULL;
|
||||
end->li_actual = NULL;
|
||||
end->li_line = buffer;
|
||||
end->li_linenum = line++;
|
||||
end->li_linenum = line_number++;
|
||||
}
|
||||
|
||||
if (!end) { /* No stuff here */
|
||||
|
|
@ -312,7 +315,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_readall, processing linked list element s = %s . . . \n", s);
|
||||
printf("In inp_readall, processing linked list element line = %d, s = %s . . . \n", working->li_linenum,s);
|
||||
#endif
|
||||
|
||||
switch (c) {
|
||||
|
|
|
|||
|
|
@ -195,8 +195,8 @@ Func short freadstr(Pfile f, Pchar s, short max);
|
|||
Func char freadc(Pfile f);
|
||||
Func long freadi(Pfile f);
|
||||
|
||||
Func long round(double d);
|
||||
Func long trunc(double x);
|
||||
Func long np_round(double d); // sjb to avoid clash with round() in math.h
|
||||
Func long np_trunc(double x); // sjb to avoid clash with trunc() in math.h
|
||||
Func double sqr(double x);
|
||||
Func double absf(double x); /* abs */
|
||||
Func long absi( long i);
|
||||
|
|
|
|||
|
|
@ -797,7 +797,7 @@ EndFunc
|
|||
|
||||
#ifndef _MATH_H
|
||||
|
||||
Func long round(double x)
|
||||
Func long np_round(double x)
|
||||
/* using <math.h>, it would be simpler: floor(x+0.5) */
|
||||
Begin
|
||||
double u;
|
||||
|
|
@ -816,9 +816,9 @@ Begin
|
|||
return z
|
||||
EndFunc
|
||||
|
||||
Func long trunc(double x)
|
||||
Func long np_trunc(double x)
|
||||
Begin
|
||||
long n=round(x);
|
||||
long n=np_round(x);
|
||||
If (n>x) And (x>=0.0) Then
|
||||
Dec(n)
|
||||
ElsIf (n<x) And (x<0.0) Then
|
||||
|
|
@ -829,7 +829,7 @@ EndFunc
|
|||
|
||||
Func double frac(double x)
|
||||
Begin
|
||||
return x- trunc(x)
|
||||
return x- np_trunc(x)
|
||||
EndFunc
|
||||
|
||||
Func double intp(double x)
|
||||
|
|
@ -838,18 +838,18 @@ Begin
|
|||
If (x>u) Or (x< -u) Then
|
||||
return x
|
||||
Else
|
||||
return trunc(x)
|
||||
return np_trunc(x)
|
||||
EndIf
|
||||
EndFunc
|
||||
|
||||
#else /* use floor() and ceil() */
|
||||
|
||||
Func long round(double r)
|
||||
Func long np_round(double r)
|
||||
Begin
|
||||
return (long)floor(r+0.5)
|
||||
EndFunc
|
||||
|
||||
Func long trunc(double r)
|
||||
Func long np_trunc(double r)
|
||||
Begin
|
||||
If r>=0.0 Then
|
||||
return (long)floor(r)
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ R1 p2 0 1k
|
|||
|
||||
X1 input output myfilter
|
||||
V1 input 0 AC 1V
|
||||
|
||||
.end
|
||||
|
||||
Let us recall what the Spice "front-end" essentially does to your
|
||||
circuit-description (CDL) file whenever it is submitted, either at program
|
||||
|
|
@ -201,7 +201,7 @@ R1 p2 0 {rval}
|
|||
|
||||
X1 input output myfilter 1k 1nF
|
||||
V1 input 0 AC {amplitude}
|
||||
|
||||
.end
|
||||
|
||||
Note:
|
||||
Now, there is some possible confusion in Spice because of multiple numerical
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ Todo:
|
|||
#include "general.h"
|
||||
#include "numparam.h"
|
||||
|
||||
/* Uncomment this line to allow debug tracing */
|
||||
/*#define TRACE_NUMPARAMS */
|
||||
|
||||
/* the nupa_signal arguments sent from Spice:
|
||||
|
||||
sig=1: Start of the subckt expansion.
|
||||
|
|
@ -356,15 +359,28 @@ Intern tdico * dico=Null;
|
|||
/* Darray(refptr, Pchar, Maxline) pointers to source code lines */
|
||||
/* Darray(category, char, Maxline) category of each line */
|
||||
|
||||
/*
|
||||
Open ouput to a log file.
|
||||
takes no action if logging is disabled.
|
||||
Open the log if not already open.
|
||||
*/
|
||||
Intern
|
||||
Proc putlogfile(char c, int num, Pchar t)
|
||||
Begin
|
||||
Str(Llen, u);
|
||||
If dologfile And (logfile != Null) Then
|
||||
cadd(u,c); nadd(u,num);
|
||||
cadd(u,':'); cadd(u,' ');
|
||||
sadd(u,t); cadd(u,'\n');
|
||||
fputs(u,logfile);
|
||||
Str(20,fname);
|
||||
If dologfile Then
|
||||
If(logfile == Null) Then
|
||||
scopy(fname,"logfile.");
|
||||
Inc(nblog); nadd(fname,nblog);
|
||||
logfile=fopen(fname, "w");
|
||||
EndIf
|
||||
If(logfile != Null) Then
|
||||
cadd(u,c); nadd(u,num);
|
||||
cadd(u,':'); cadd(u,' ');
|
||||
sadd(u,t); cadd(u,'\n');
|
||||
fputs(u,logfile);
|
||||
EndIf
|
||||
EndIf
|
||||
EndProc
|
||||
|
||||
|
|
@ -372,18 +388,11 @@ Intern
|
|||
Proc nupa_init( Pchar srcfile)
|
||||
Begin
|
||||
short i;
|
||||
Str(20,fname);
|
||||
/* init the symbol table and so on, before the first nupa_copy. */
|
||||
evalcount=0;
|
||||
linecount= 0;
|
||||
incontrol=False;
|
||||
placeholder= 0;
|
||||
/* If logfile != Null Then fclose(logfile) EndIf */
|
||||
If dologfile And (logfile==Null) Then
|
||||
scopy(fname,"logfile.");
|
||||
Inc(nblog); nadd(fname,nblog);
|
||||
logfile=fopen(fname, "w");
|
||||
EndIf
|
||||
dico= New(tdico);
|
||||
initdico(dico);
|
||||
For i=0; i<Maxline; Inc(i) Do
|
||||
|
|
@ -411,18 +420,18 @@ Begin
|
|||
Done
|
||||
Dispose(dico);
|
||||
dico= Null;
|
||||
/* debug: ask if spice run really wanted */
|
||||
scopy(rep," Copies="); nadd(rep,linecount);
|
||||
sadd(rep," Evals="); nadd(rep,evalcount);
|
||||
sadd(rep," Placeholders="); nadd(rep,placeholder);
|
||||
sadd(rep," Symbols="); nadd(rep,dictsize);
|
||||
sadd(rep," Errors="); nadd(rep,nerrors);
|
||||
cadd(rep,'\n'); ws(rep);
|
||||
ws("Expansion ");
|
||||
If Zero(nerrors) Then ws("done") Else ws("errors") EndIf
|
||||
ws(": Really run Spice y/n ? \n");
|
||||
rs(rep);
|
||||
If upcase(rep[0]) != 'Y' Then exit(-1) EndIf
|
||||
If NotZ(nerrors) Then
|
||||
/* debug: ask if spice run really wanted */
|
||||
scopy(rep," Copies="); nadd(rep,linecount);
|
||||
sadd(rep," Evals="); nadd(rep,evalcount);
|
||||
sadd(rep," Placeholders="); nadd(rep,placeholder);
|
||||
sadd(rep," Symbols="); nadd(rep,dictsize);
|
||||
sadd(rep," Errors="); nadd(rep,nerrors);
|
||||
cadd(rep,'\n'); ws(rep);
|
||||
ws("Numparam expansion errors: Run Spice anyway? y/n ? \n");
|
||||
rs(rep);
|
||||
If upcase(rep[0]) != 'Y' Then exit(-1) EndIf
|
||||
EndIf
|
||||
linecount= 0;
|
||||
evalcount= 0;
|
||||
placeholder= 0;
|
||||
|
|
@ -502,6 +511,11 @@ Begin
|
|||
Str(80,subname);
|
||||
dico->srcline= linenum;
|
||||
c= dico->category[linenum];
|
||||
#ifdef TRACE_NUMPARAMS
|
||||
printf("** SJB - in nupa_eval()\n");
|
||||
printf("** SJB - processing line %3d: %s\n",linenum,s);
|
||||
printf("** SJB - category '%c'\n");
|
||||
#endif /* TRACE_NUMPARAMS */
|
||||
If c=='P' Then /* evaluate parameters */
|
||||
nupa_assignment( dico, dico->refptr[linenum] , 'N');
|
||||
ElsIf c=='B' Then /* substitute braces line */
|
||||
|
|
@ -519,6 +533,10 @@ Begin
|
|||
EndIf
|
||||
putlogfile('e',linenum,s);
|
||||
Inc(evalcount);
|
||||
#ifdef TRACE_NUMPARAMS
|
||||
ws("** SJB - --> "); ws(s); wln();
|
||||
ws("** SJB - leaving nupa_eval()"); wln(); wln();
|
||||
#endif /* TRACE_NUMPARAMS */
|
||||
return 1
|
||||
EndFunc
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ Intern
|
|||
Proc dicostack(tdico *dico, char op)
|
||||
/* push or pop operation for nested subcircuit locals */
|
||||
Begin
|
||||
|
||||
If op==Push Then
|
||||
If dico->tos < (20-1) Then Inc(dico->tos)
|
||||
Else message(dico, " Subckt Stack overflow")
|
||||
|
|
@ -748,10 +749,10 @@ Begin
|
|||
Case '!' Is /*Not*/
|
||||
If y==z Then x=u Else x=z EndIf;
|
||||
Case '%' Is /*Mod*/
|
||||
t= trunc(x/y);
|
||||
t= np_trunc(x/y);
|
||||
x= x-y*t
|
||||
Case '\\' Is /*Div*/
|
||||
x= trunc(absf(x/y));
|
||||
x= np_trunc(absf(x/y));
|
||||
EndSw /*case*/
|
||||
return x;
|
||||
EndFunc
|
||||
|
|
@ -986,7 +987,7 @@ Begin
|
|||
If numeric Then
|
||||
fmt= fmttype(u);
|
||||
If fmt=='I' Then
|
||||
stri(round(u), q)
|
||||
stri(np_round(u), q)
|
||||
Else
|
||||
strf(u,6,-1,q)
|
||||
EndIf /* strf() arg 2 doesnt work: always >10 significant digits ! */
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ Modified: 2000 AlansFixes
|
|||
#include "subckt.h"
|
||||
#include "variable.h"
|
||||
|
||||
/* Uncomment to turn on tracing for the Numparam */
|
||||
//#define TRACE_NUMPARAMS
|
||||
|
||||
#ifdef NUMPARAMS
|
||||
#define NUPADECKCOPY 0
|
||||
|
|
@ -164,12 +166,32 @@ inp_subcktexpand(struct line *deck)
|
|||
#ifdef NUMPARAMS
|
||||
/* deck has .control sections already removed, but not comments */
|
||||
if ( NumParams == 'y' ) {
|
||||
|
||||
#ifdef TRACE_NUMPARAMS
|
||||
printf("Numparams is processing this deck:\n");
|
||||
c=deck;
|
||||
while( c!=NULL) {
|
||||
printf("%3d:%s\n",c->li_linenum, c->li_line);
|
||||
c= c->li_next;
|
||||
}
|
||||
#endif
|
||||
|
||||
ok = nupa_signal( NUPADECKCOPY, NULL);
|
||||
c=deck;
|
||||
while ( c != NULL) { /* first Numparam pass */
|
||||
c->li_line = nupa_copy(c->li_line, c->li_linenum);
|
||||
c= c->li_next;
|
||||
}
|
||||
|
||||
#ifdef TRACE_NUMPARAMS
|
||||
printf("Numparams transformed deck:\n");
|
||||
c=deck;
|
||||
while( c!=NULL) {
|
||||
printf("%3d:%s\n",c->li_linenum, c->li_line);
|
||||
c= c->li_next;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -259,15 +281,23 @@ inp_subcktexpand(struct line *deck)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NUMPARAM
|
||||
#ifdef NUMPARAMS
|
||||
if ( NumParams == 'y' ) {
|
||||
/* the NUMPARAM final line translation pass */
|
||||
ok= ok && nupa_signal(NUPASUBDONE, NULL);
|
||||
c= ll;
|
||||
while (c != NULL) {
|
||||
while (c != NULL) {
|
||||
ok= ok && nupa_eval( c->li_line, c->li_linenum);
|
||||
c= c->li_next;
|
||||
c= c->li_next;
|
||||
}
|
||||
#ifdef TRACE_NUMPARAMS
|
||||
printf("Numparams converted deck:\n");
|
||||
c=ll;
|
||||
while( c!=NULL) {
|
||||
printf("%3d:%s\n",c->li_linenum, c->li_line);
|
||||
c= c->li_next;
|
||||
}
|
||||
#endif
|
||||
ok= ok && nupa_signal(NUPAEVALDONE, NULL);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1130,7 +1160,8 @@ finishLine(char *dst, char *src, char *scname)
|
|||
/*
|
||||
*
|
||||
*/
|
||||
if (buf[0] == 'v' || buf[0] == 'V') {
|
||||
if ((which == 'i' || which == 'I') &&
|
||||
(buf[0] == 'v' || buf[0] == 'V')) {
|
||||
*dst++ = buf[0];
|
||||
*dst++ = ':';
|
||||
i = 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue