From 97605a5df77622961c966f13179ba249f6b86e2f Mon Sep 17 00:00:00 2001 From: h_vogt Date: Thu, 6 Jan 2011 19:15:20 +0000 Subject: [PATCH] models 1N4001 also in subcircuits --- ChangeLog | 5 ++ examples/Monte_Carlo/MC_ring.sp | 20 +++-- src/frontend/inpcom.c | 142 +++++++++++++++++--------------- 3 files changed, 96 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54a998f70..8c10b3f92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +11-01-06 Holger Vogt + * inpcom.c: allow models like 2N2904 or 2SK136 also in subcircuits + * examples/Monte_Carlo/mc_ring.sp: reduce memory consumption by adding + 'save' command, add jitter measurement + 11-01-03 Holger Vogt * spiceif.c: add error checking for 'altermod' diff --git a/examples/Monte_Carlo/MC_ring.sp b/examples/Monte_Carlo/MC_ring.sp index 4069501fd..58e5c141f 100644 --- a/examples/Monte_Carlo/MC_ring.sp +++ b/examples/Monte_Carlo/MC_ring.sp @@ -30,7 +30,8 @@ cout buf ss 0.2pF * .options noacct .control - let mc_runs = 10 $ number of runs for monte carlo + save buf $ we just need buf, save memory by more than 10x + let mc_runs = 10 $ number of runs for monte carlo let run = 0 $ number of actual run set curplot = new $ create a new plot set curplottitle = "Transient outputs" @@ -42,7 +43,8 @@ cout buf ss 0.2pF set curplottitle = "Oscillation frequency" set max_fft = $curplot $ store its name to 'max_fft' let mc_runsp = mc_runs + 1 - let maxffts = unitvec(mc_runsp) $ vector for storing measure results + let maxffts = unitvec(mc_runsp) $ vector for storing max measure results + let halfffts = unitvec(mc_runsp)$ vector for storing measure results at -40dB rising * * define distributions for random numbers: * unif: uniform distribution, deviation relativ to nominal value @@ -82,7 +84,7 @@ cout buf ss 0.2pF altermod @n1[u0]=gauss($n1u0, 0.05, 3) altermod @n1[tox]=gauss($n1tox, 0.1, 3) altermod @n1[lint]=gauss($n1lint, 0.1, 3) - altermod @n1[wint]=gauss($n1wint, 0.1, 3) + altermod @n1[wint]=gauss($n1wint, 0.1, 3) altermod @p1[vth0]=gauss($p1vth0, 0.1, 3) altermod @p1[u0]=gauss($p1u0, 0.1, 3) altermod @p1[tox]=gauss($p1tox, 0.1, 3) @@ -103,7 +105,7 @@ cout buf ss 0.2pF set mc_runs ="$&mc_runs" $ create a variable from the vector echo simulation run no. $run of $mc_runs * save the linearized data for having equal time scales for all runs - linearize + linearize buf $ linearize only buf, no other vectors needed set dt = $curplot $ store the current plot to dt (tran i+1) setplot $plot_out $ make 'plt_out' the active plot * firstly save the time scale once to become the default scale @@ -116,9 +118,11 @@ cout buf ss 0.2pF let buf2=db(mag(buf)) * find the frequency where buf has its maximum of the fft signal meas sp fft_max MAX_AT buf2 from=0.1G to=0.7G + * find the frequency where buf is -40dB at rising fft signal + meas sp fft_40 WHEN buf2=-40 RISE=1 from=0.1G to=0.7G * store the fft vector set dt = $curplot $ store the current plot to dt (spec i) - setplot $plot_fft $ make 'plt_fft' the active plot + setplot $plot_fft $ make 'plot_fft' the active plot if run=0 let frequency={$dt}.frequency end @@ -126,6 +130,7 @@ cout buf ss 0.2pF * store the measured value setplot $max_fft $ make 'max_fft' the active plot let maxffts[{$run}]={$dt}.fft_max + let halfffts[{$run}]={$dt}.fft_40 * setplot $plot_out * The following command does not work here. Why not? Probably not a real copy. * destroy $dt $ save memory, we don't need this plot (spec) any more @@ -169,6 +174,10 @@ cout buf ss 0.2pF * plot the histogram set plotstyle=combplot plot yvec-1 vs xvec $ subtract 1 because with started with unitvec containing ones +* calculate jitter + let diff40 = (vecmax(halfffts) - vecmin(halfffts))*1e-6 + echo + echo Max. jitter is "$&diff40" MHz rusage .endc ******************************************************************************** @@ -207,6 +216,7 @@ cout buf ss 0.2pF +noimod=2 +af=1.075e+00 kf=9.670e-28 ef=1.056e+00 +noia=1.130e+20 noib=7.530e+04 noic=-8.950e-13 +**** PMOS *** .model p1 pmos +level=8 +version=3.3.0 diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index fd6e0adca..2273d06d2 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -645,79 +645,89 @@ get_subckts_for_subckt( struct line *start_card, char *subckt_name, char *used_model_names[], int *num_used_model_names, bool has_models ) { - struct line *card; - char *line = NULL, *curr_subckt_name, *inst_subckt_name, *model_name, *new_names[100]; - bool found_subckt = FALSE, have_subckt = FALSE, found_model = FALSE; - int i, num_terminals = 0, tmp_cnt = 0; - - for ( card = start_card; card != NULL; card = card->li_next ) { - line = card->li_line; + struct line *card; + char *line = NULL, *curr_subckt_name, *inst_subckt_name, *model_name, *new_names[100]; + bool found_subckt = FALSE, have_subckt = FALSE, found_model = FALSE; + int i, num_terminals = 0, tmp_cnt = 0; - if ( *line == '*' ) continue; + for ( card = start_card; card != NULL; card = card->li_next ) { + line = card->li_line; - if ( ( ciprefix( ".ends", line ) || ciprefix( ".eom", line ) ) && found_subckt ) - break; + if ( *line == '*' ) continue; - if ( ciprefix( ".subckt", line ) || ciprefix( ".macro", line ) ) { - curr_subckt_name = get_subckt_model_name( line ); + if ( ( ciprefix( ".ends", line ) || ciprefix( ".eom", line ) ) && found_subckt ) + break; - if ( strcmp( curr_subckt_name, subckt_name ) == 0 ) { - found_subckt = TRUE; - } + if ( ciprefix( ".subckt", line ) || ciprefix( ".macro", line ) ) { + curr_subckt_name = get_subckt_model_name( line ); - tfree(curr_subckt_name); - } - if ( found_subckt ) { - if ( *line == 'x' ) { - inst_subckt_name = get_instance_subckt( line ); - have_subckt = FALSE; - for ( i = 0; i < *num_used_subckt_names; i++ ) - if ( strcmp( used_subckt_names[i], inst_subckt_name ) == 0 ) - have_subckt = TRUE; - if ( !have_subckt ) { - new_names[tmp_cnt++] = used_subckt_names[*num_used_subckt_names] = inst_subckt_name; - *num_used_subckt_names = *num_used_subckt_names + 1; - } - else tfree( inst_subckt_name ); - } - else if ( *line == 'a' ) { - model_name = get_adevice_model_name( line ); - found_model = FALSE; - for ( i = 0; i < *num_used_model_names; i++ ) - if ( strcmp( used_model_names[i], model_name ) == 0 ) found_model = TRUE; - if ( !found_model ) { - used_model_names[*num_used_model_names] = model_name; - *num_used_model_names = *num_used_model_names + 1; - } - else tfree( model_name ); - } - else if ( has_models ) { - num_terminals = get_number_terminals( line ); + if ( strcmp( curr_subckt_name, subckt_name ) == 0 ) { + found_subckt = TRUE; + } - if ( num_terminals != 0 ) { - model_name = get_model_name( line, num_terminals ); - - if ( isalpha( *model_name ) ) { - found_model = FALSE; - for ( i = 0; i < *num_used_model_names; i++ ) - if ( strcmp( used_model_names[i], model_name ) == 0 ) found_model = TRUE; - if ( !found_model ) { - used_model_names[*num_used_model_names] = model_name; - *num_used_model_names = *num_used_model_names + 1; - } - else tfree( model_name ); - } - else { - tfree( model_name ); - } - } - } + tfree(curr_subckt_name); + } + if ( found_subckt ) { + if ( *line == 'x' ) { + inst_subckt_name = get_instance_subckt( line ); + have_subckt = FALSE; + for ( i = 0; i < *num_used_subckt_names; i++ ) + if ( strcmp( used_subckt_names[i], inst_subckt_name ) == 0 ) + have_subckt = TRUE; + if ( !have_subckt ) { + new_names[tmp_cnt++] = used_subckt_names[*num_used_subckt_names] = inst_subckt_name; + *num_used_subckt_names = *num_used_subckt_names + 1; + } + else tfree( inst_subckt_name ); + } + else if ( *line == 'a' ) { + model_name = get_adevice_model_name( line ); + found_model = FALSE; + for ( i = 0; i < *num_used_model_names; i++ ) + if ( strcmp( used_model_names[i], model_name ) == 0 ) found_model = TRUE; + if ( !found_model ) { + used_model_names[*num_used_model_names] = model_name; + *num_used_model_names = *num_used_model_names + 1; + } + else tfree( model_name ); + } + else if ( has_models ) { + num_terminals = get_number_terminals( line ); + + if ( num_terminals != 0 ) { + char *tmp_name, *tmp_name1; + tmp_name1 = tmp_name = model_name = get_model_name( line, num_terminals ); + + if ( isalpha( *model_name ) || + /* first character is digit, second is alpha, third is digit, + e.g. 1N4002 */ + ((strlen(model_name) > 2) && isdigit(*tmp_name) && + isalpha(*(++tmp_name)) && isdigit(*(++tmp_name))) || + /* first character is is digit, second is alpha, third is alpha, fourth is digit + e.g. 2SK456 */ + ((strlen(model_name) > 3) && isdigit(*tmp_name1) && isalpha(*(++tmp_name1)) && + isalpha(*(++tmp_name1)) && isdigit(*(++tmp_name1)))) + { + found_model = FALSE; + for ( i = 0; i < *num_used_model_names; i++ ) + if ( strcmp( used_model_names[i], model_name ) == 0 ) found_model = TRUE; + if ( !found_model ) { + used_model_names[*num_used_model_names] = model_name; + *num_used_model_names = *num_used_model_names + 1; + } + else tfree( model_name ); + } + else { + tfree( model_name ); + } + } + } + } } - } - // now make recursive call on instances just found above - for ( i = 0; i < tmp_cnt; i++ ) - get_subckts_for_subckt( start_card, new_names[i], used_subckt_names, num_used_subckt_names, - used_model_names, num_used_model_names, has_models ); + // now make recursive call on instances just found above + for ( i = 0; i < tmp_cnt; i++ ) + get_subckts_for_subckt( start_card, new_names[i], used_subckt_names, num_used_subckt_names, + used_model_names, num_used_model_names, has_models ); } /*