@ -60,6 +60,7 @@ Modified: 2000 AlansFixes
# include "ngspice/ftedefs.h"
# include "ngspice/fteinp.h"
# include "ngspice/stringskip.h"
# include "ngspice/compatmode.h"
# include <stdarg.h>
@ -557,6 +558,10 @@ doit(struct card *deck, wordlist *modnames) {
}
# endif
double scale ;
if ( ! cp_getvar ( " scale " , CP_REAL , & scale , 0 ) )
scale = 1 ;
error = 0 ;
/* Second pass: do the replacements. */
do { /* while (!error && numpasses-- && gotone) */
@ -608,8 +613,114 @@ doit(struct card *deck, wordlist *modnames) {
* instance of a subckt that is defined above at higher level .
*/
if ( sss ) {
/ / tprint ( sss - > su_def ) ;
struct card * su_deck = inp_deckcopy_ln ( sss - > su_def ) ;
/* If we have modern PDKs, we have to reduce the amount of memory required.
We try to reduce the models to the one really used .
Otherwise su_deck is full of unused binning models . */
/ / struct card * su_deck = NULL ;
if ( ( newcompat . hs | | newcompat . spe ) & & c - > w > 0 & & c - > l > 0 ) {
/* extract wmin, wmax, lmin, lmax */
struct card * new_deck = su_deck ;
struct card * prev = NULL ;
while ( su_deck ) {
if ( ! ciprefix ( " .model " , su_deck - > line ) ) {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
char * curr_line = su_deck - > line ;
float fwmin , fwmax , flmin , flmax ;
char * wmin = strstr ( curr_line , " wmin= " ) ;
if ( wmin ) {
int err ;
wmin = wmin + 6 ;
fwmin = ( float ) INPevaluate ( & wmin , & err , 0 ) ;
if ( err ) {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
}
else {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
char * wmax = strstr ( curr_line , " wmax= " ) ;
if ( wmax ) {
int err ;
wmax = wmax + 6 ;
fwmax = ( float ) INPevaluate ( & wmax , & err , 0 ) ;
if ( err ) {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
}
else {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
char * lmin = strstr ( curr_line , " lmin= " ) ;
if ( lmin ) {
int err ;
lmin = lmin + 6 ;
flmin = ( float ) INPevaluate ( & lmin , & err , 0 ) ;
if ( err ) {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
}
else {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
char * lmax = strstr ( curr_line , " lmax= " ) ;
if ( lmax ) {
int err ;
lmax = lmax + 6 ;
flmax = ( float ) INPevaluate ( & lmax , & err , 0 ) ;
if ( err ) {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
}
else {
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
float csl = ( float ) scale * c - > l ;
float csw = ( float ) scale * c - > w ;
if ( csl > = flmin & & csl < flmax & & csw > = fwmin & & csw < fwmax ) {
/* use the current .model card */
prev = su_deck ;
su_deck = su_deck - > nextcard ;
continue ;
}
else {
struct card * tmpcard = su_deck - > nextcard ;
line_free_x ( prev - > nextcard , FALSE ) ;
su_deck = prev - > nextcard = tmpcard ;
}
}
su_deck = new_deck ;
}
if ( ! su_deck ) {
fprintf ( stderr , " \n Error: Could not find a model for device %s in subcircuit %s \n " ,
scname , sss - > su_name ) ;
controlled_exit ( 1 ) ;
}
struct card * su_deck = inp_deckcopy ( sss - > su_def ) ;
struct card * rest_of_c = c - > nextcard ;
/* Now we have to replace this line with the
@ -711,6 +822,8 @@ struct card * inp_deckcopy(struct card *deck) {
nd = d = TMALLOC ( struct card , 1 ) ;
}
d - > linenum = deck - > linenum ;
d - > w = deck - > w ;
d - > l = deck - > l ;
d - > line = copy ( deck - > line ) ;
if ( deck - > error )
d - > error = copy ( deck - > error ) ;
@ -720,7 +833,6 @@ struct card * inp_deckcopy(struct card *deck) {
return ( nd ) ;
}
/*
* Copy a deck , without the - > actualLine lines , without comment lines , and
* without . control section ( s ) .
@ -754,6 +866,8 @@ struct card *inp_deckcopy_oc(struct card * deck)
else { /* This is the first card */
nd = d = TMALLOC ( struct card , 1 ) ;
}
d - > w = deck - > w ;
d - > l = deck - > l ;
d - > linenum_orig = deck - > linenum ;
d - > linenum = i + + ;
d - > line = copy ( deck - > line ) ;
@ -770,6 +884,57 @@ struct card *inp_deckcopy_oc(struct card * deck)
return nd ;
} /* end of function inp_deckcopy_oc */
/*
* Copy a deck , without the - > actualLine lines , without comment lines , and
* without . control section ( s ) .
* First line is always copied ( except being . control ) .
* Keep the line numbers .
*/
struct card * inp_deckcopy_ln ( struct card * deck )
{
struct card * d = NULL , * nd = NULL ;
int skip_control = 0 ;
while ( deck ) {
/* exclude any command inside .control ... .endc */
if ( ciprefix ( " .control " , deck - > line ) ) {
skip_control + + ;
deck = deck - > nextcard ;
continue ;
}
else if ( ciprefix ( " .endc " , deck - > line ) ) {
skip_control - - ;
deck = deck - > nextcard ;
continue ;
}
else if ( skip_control > 0 ) {
deck = deck - > nextcard ;
continue ;
}
if ( nd ) { /* First card already found */
/* d is the card at the end of the deck */
d = d - > nextcard = TMALLOC ( struct card , 1 ) ;
}
else { /* This is the first card */
nd = d = TMALLOC ( struct card , 1 ) ;
}
d - > w = deck - > w ;
d - > l = deck - > l ;
d - > linenum_orig = deck - > linenum_orig ;
d - > linenum = deck - > linenum ;
d - > line = copy ( deck - > line ) ;
if ( deck - > error ) {
d - > error = copy ( deck - > error ) ;
}
d - > actualLine = NULL ;
deck = deck - > nextcard ;
while ( deck & & * ( deck - > line ) = = ' * ' ) { /* skip comments */
deck = deck - > nextcard ;
}
} /* end of loop over cards in the source deck */
return nd ;
} /* end of function inp_deckcopy_ln */
/*-------------------------------------------------------------------