models 1N4001 also in subcircuits
This commit is contained in:
parent
8a4b0e9bce
commit
97605a5df7
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
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;
|
||||
for ( card = start_card; card != NULL; card = card->li_next ) {
|
||||
line = card->li_line;
|
||||
|
||||
if ( *line == '*' ) continue;
|
||||
if ( *line == '*' ) continue;
|
||||
|
||||
if ( ( ciprefix( ".ends", line ) || ciprefix( ".eom", line ) ) && found_subckt )
|
||||
break;
|
||||
if ( ( ciprefix( ".ends", line ) || ciprefix( ".eom", line ) ) && found_subckt )
|
||||
break;
|
||||
|
||||
if ( ciprefix( ".subckt", line ) || ciprefix( ".macro", line ) ) {
|
||||
curr_subckt_name = get_subckt_model_name( line );
|
||||
if ( ciprefix( ".subckt", line ) || ciprefix( ".macro", line ) ) {
|
||||
curr_subckt_name = get_subckt_model_name( line );
|
||||
|
||||
if ( strcmp( curr_subckt_name, subckt_name ) == 0 ) {
|
||||
found_subckt = TRUE;
|
||||
}
|
||||
if ( strcmp( curr_subckt_name, subckt_name ) == 0 ) {
|
||||
found_subckt = TRUE;
|
||||
}
|
||||
|
||||
tfree(curr_subckt_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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 ) {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue