From 1aa04ca10b33accc358968874fb90810fc766e41 Mon Sep 17 00:00:00 2001 From: pnenzi Date: Sat, 16 Apr 2005 22:45:32 +0000 Subject: [PATCH] Fixed numparam library (Steven Borley) and corrected bug in node translation (Hitoshi Tanaka). --- examples/numparam/example.cir | 17 ++++++++ examples/numparam/pin.mod | 33 ++++++++++++++++ examples/numparam/pintest.cir | 28 ++++++++++++++ src/frontend/inpcom.c | 23 ++++++----- src/frontend/numparam/general.h | 4 +- src/frontend/numparam/mystring.c | 14 +++---- src/frontend/numparam/readme.txt | 4 +- src/frontend/numparam/spicenum.c | 66 ++++++++++++++++++++------------ src/frontend/numparam/xpressn.c | 7 ++-- src/frontend/subckt.c | 39 +++++++++++++++++-- 10 files changed, 183 insertions(+), 52 deletions(-) create mode 100644 examples/numparam/example.cir create mode 100644 examples/numparam/pin.mod create mode 100644 examples/numparam/pintest.cir diff --git a/examples/numparam/example.cir b/examples/numparam/example.cir new file mode 100644 index 000000000..a510eb518 --- /dev/null +++ b/examples/numparam/example.cir @@ -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 diff --git a/examples/numparam/pin.mod b/examples/numparam/pin.mod new file mode 100644 index 000000000..2f353242b --- /dev/null +++ b/examples/numparam/pin.mod @@ -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 diff --git a/examples/numparam/pintest.cir b/examples/numparam/pintest.cir new file mode 100644 index 000000000..f7b78bd1a --- /dev/null +++ b/examples/numparam/pintest.cir @@ -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 + diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index bf6a4542d..691d913eb 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -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) { diff --git a/src/frontend/numparam/general.h b/src/frontend/numparam/general.h index 1277a0af6..1ea052e77 100644 --- a/src/frontend/numparam/general.h +++ b/src/frontend/numparam/general.h @@ -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); diff --git a/src/frontend/numparam/mystring.c b/src/frontend/numparam/mystring.c index 15a9c7691..45dc4415d 100644 --- a/src/frontend/numparam/mystring.c +++ b/src/frontend/numparam/mystring.c @@ -797,7 +797,7 @@ EndFunc #ifndef _MATH_H -Func long round(double x) +Func long np_round(double x) /* using , 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 (nu) 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) diff --git a/src/frontend/numparam/readme.txt b/src/frontend/numparam/readme.txt index d83d6cf0e..24ce2be43 100644 --- a/src/frontend/numparam/readme.txt +++ b/src/frontend/numparam/readme.txt @@ -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 diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 12c1b8e84..0acb94d97 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -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; isrcline= 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 diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 1bf72d797..dc26505b3 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -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 ! */ diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 48cfe7d4f..db350f4ef 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -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;