Fixed numparam library (Steven Borley) and corrected bug in node translation (Hitoshi Tanaka).

This commit is contained in:
pnenzi 2005-04-16 22:45:32 +00:00
parent 7989c811fb
commit 1aa04ca10b
10 changed files with 183 additions and 52 deletions

View File

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

33
examples/numparam/pin.mod Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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