Add parsing and translation of the FREQ form of E-source devices,
integrated with the existing parsing of AND/NAND/OR/NOR forms (inpcom.c). For the implementation, add a new analog XSPICE code model, xfer. Add an example to examples/sp.
This commit is contained in:
parent
1fdf7dac51
commit
d31568bd83
|
|
@ -0,0 +1,185 @@
|
|||
.SUBCKT filter 1 2 3
|
||||
*2-port S-parameter file
|
||||
*Title: * simple test for xfer code model: comparison
|
||||
*Generated by ngspice at Tue May 23 06:49:31 2023
|
||||
* Hz S RI R
|
||||
* Z1=50.000000 Z2=50.000000
|
||||
|
||||
R1N 1 10 -5.000000e+01
|
||||
R1P 10 11 1.000000e+02
|
||||
R2N 2 20 -5.000000e+01
|
||||
R2P 20 21 1.000000e+02
|
||||
|
||||
*S11 FREQ DB PHASE
|
||||
E11 11 12 FREQ {V(10,3)}= DB
|
||||
+( 1.000000e+07Hz, 3.654967e-07, -7.619541e+01)
|
||||
+( 1.487179e+07Hz, 1.964030e-07, -1.157703e+02)
|
||||
+( 1.974359e+07Hz, -1.084219e-07, -1.569277e+02)
|
||||
+( 2.461538e+07Hz, -5.321598e-06, -1.985756e+02)
|
||||
+( 2.948718e+07Hz, -1.265047e-05, -2.395114e+02)
|
||||
+( 3.435897e+07Hz, -2.727603e-05, -2.792878e+02)
|
||||
+( 3.923077e+07Hz, -6.620604e-05, -3.184596e+02)
|
||||
+( 4.410256e+07Hz, -1.624082e-04, -3.582070e+02)
|
||||
+( 4.897436e+07Hz, -3.755273e-04, -3.996839e+02)
|
||||
+( 5.384615e+07Hz, -7.725656e-04, -4.432805e+02)
|
||||
+( 5.871795e+07Hz, -1.320643e-03, -4.881884e+02)
|
||||
+( 6.358974e+07Hz, -1.599290e-03, -5.330311e+02)
|
||||
+( 6.846154e+07Hz, -4.631092e-04, -5.776220e+02)
|
||||
+( 7.333333e+07Hz, -1.388239e-02, -6.262936e+02)
|
||||
+( 7.820513e+07Hz, -1.245578e+01, -8.015034e+02)
|
||||
+( 8.307692e+07Hz, -1.142468e+00, -6.888087e+02)
|
||||
+( 8.794872e+07Hz, -1.292324e+00, -7.542062e+02)
|
||||
+( 9.282051e+07Hz, -2.163078e+00, -8.283885e+02)
|
||||
+( 9.769231e+07Hz, -3.764829e+00, -9.213357e+02)
|
||||
+( 1.025641e+08Hz, -4.165673e+00, -1.041098e+03)
|
||||
+( 1.074359e+08Hz, -2.143343e+00, -1.139856e+03)
|
||||
+( 1.123077e+08Hz, -1.084156e+00, -1.201868e+03)
|
||||
+( 1.171795e+08Hz, -7.962690e-01, -1.249480e+03)
|
||||
+( 1.220513e+08Hz, -1.204024e+00, -1.318959e+03)
|
||||
+( 1.269231e+08Hz, -4.148462e-01, -1.169292e+03)
|
||||
+( 1.317949e+08Hz, -1.026085e-02, -1.240330e+03)
|
||||
+( 1.366667e+08Hz, -1.360661e-04, -1.265793e+03)
|
||||
+( 1.415385e+08Hz, -2.410965e-03, -1.281511e+03)
|
||||
+( 1.464103e+08Hz, -3.787891e-03, -1.293132e+03)
|
||||
+( 1.512821e+08Hz, -3.602264e-03, -1.302433e+03)
|
||||
+( 1.561538e+08Hz, -2.547410e-03, -1.310211e+03)
|
||||
+( 1.610256e+08Hz, -1.530232e-03, -1.316893e+03)
|
||||
+( 1.658974e+08Hz, -8.667728e-04, -1.322741e+03)
|
||||
+( 1.707692e+08Hz, -4.905888e-04, -1.327928e+03)
|
||||
+( 1.756410e+08Hz, -2.840626e-04, -1.332578e+03)
|
||||
+( 1.805128e+08Hz, -1.688713e-04, -1.336783e+03)
|
||||
+( 1.853846e+08Hz, -1.041703e-04, -1.340612e+03)
|
||||
+( 1.902564e+08Hz, -6.546576e-05, -1.344121e+03)
|
||||
+( 1.951282e+08Hz, -4.228835e-05, -1.347353e+03)
|
||||
+( 2.000000e+08Hz, -2.867354e-05, -1.350343e+03)
|
||||
|
||||
*S12 FREQ DB PHASE
|
||||
E12 12 3 FREQ {V(20,3)}= DB
|
||||
+( 1.000000e+07Hz, -1.248758e+02, -1.373971e+02)
|
||||
+( 1.487179e+07Hz, -9.831399e+01, -1.647281e+02)
|
||||
+( 1.974359e+07Hz, -7.673566e+01, -2.026127e+02)
|
||||
+( 2.461538e+07Hz, -5.898226e+01, -2.906518e+02)
|
||||
+( 2.948718e+07Hz, -5.542440e+01, -3.666485e+02)
|
||||
+( 3.435897e+07Hz, -5.204910e+01, -4.009490e+02)
|
||||
+( 3.923077e+07Hz, -4.814977e+01, -4.271950e+02)
|
||||
+( 4.410256e+07Hz, -4.426072e+01, -4.514100e+02)
|
||||
+( 4.897436e+07Hz, -4.063346e+01, -4.755494e+02)
|
||||
+( 5.384615e+07Hz, -3.749934e+01, -5.003303e+02)
|
||||
+( 5.871795e+07Hz, -3.516924e+01, -5.256223e+02)
|
||||
+( 6.358974e+07Hz, -3.433887e+01, -5.509590e+02)
|
||||
+( 6.846154e+07Hz, -3.971774e+01, -5.765977e+02)
|
||||
+( 7.333333e+07Hz, -2.496027e+01, -4.260244e+02)
|
||||
+( 7.820513e+07Hz, -2.540060e-01, -5.317362e+02)
|
||||
+( 8.307692e+07Hz, -6.358120e+00, -6.335796e+02)
|
||||
+( 8.794872e+07Hz, -5.894279e+00, -6.719727e+02)
|
||||
+( 9.282051e+07Hz, -4.063864e+00, -7.129969e+02)
|
||||
+( 9.769231e+07Hz, -2.367660e+00, -7.603597e+02)
|
||||
+( 1.025641e+08Hz, -2.098602e+00, -8.143919e+02)
|
||||
+( 1.074359e+08Hz, -4.094614e+00, -8.636479e+02)
|
||||
+( 1.123077e+08Hz, -6.557734e+00, -8.998592e+02)
|
||||
+( 1.171795e+08Hz, -7.759301e+00, -9.295624e+02)
|
||||
+( 1.220513e+08Hz, -6.159604e+00, -9.703161e+02)
|
||||
+( 1.269231e+08Hz, -1.040475e+01, -1.077742e+03)
|
||||
+( 1.317949e+08Hz, -2.627115e+01, -1.123641e+03)
|
||||
+( 1.366667e+08Hz, -4.503397e+01, -9.675219e+02)
|
||||
+( 1.415385e+08Hz, -3.255698e+01, -9.893598e+02)
|
||||
+( 1.464103e+08Hz, -3.059532e+01, -1.012566e+03)
|
||||
+( 1.512821e+08Hz, -3.081422e+01, -1.036661e+03)
|
||||
+( 1.561538e+08Hz, -3.231825e+01, -1.058931e+03)
|
||||
+( 1.610256e+08Hz, -3.453111e+01, -1.077318e+03)
|
||||
+( 1.658974e+08Hz, -3.699828e+01, -1.091740e+03)
|
||||
+( 1.707692e+08Hz, -3.947129e+01, -1.103061e+03)
|
||||
+( 1.756410e+08Hz, -4.184769e+01, -1.112161e+03)
|
||||
+( 1.805128e+08Hz, -4.409577e+01, -1.119694e+03)
|
||||
+( 1.853846e+08Hz, -4.621280e+01, -1.126103e+03)
|
||||
+( 1.902564e+08Hz, -4.820666e+01, -1.131686e+03)
|
||||
+( 1.951282e+08Hz, -5.008836e+01, -1.136645e+03)
|
||||
+( 2.000000e+08Hz, -5.186916e+01, -1.141123e+03)
|
||||
|
||||
*S21 FREQ DB PHASE
|
||||
E21 21 22 FREQ {V(10,3)}= DB
|
||||
+( 1.000000e+07Hz, -1.248758e+02, -1.373971e+02)
|
||||
+( 1.487179e+07Hz, -9.831399e+01, -1.647281e+02)
|
||||
+( 1.974359e+07Hz, -7.673566e+01, -2.026127e+02)
|
||||
+( 2.461538e+07Hz, -5.898226e+01, -2.906518e+02)
|
||||
+( 2.948718e+07Hz, -5.542440e+01, -3.666485e+02)
|
||||
+( 3.435897e+07Hz, -5.204910e+01, -4.009490e+02)
|
||||
+( 3.923077e+07Hz, -4.814977e+01, -4.271950e+02)
|
||||
+( 4.410256e+07Hz, -4.426072e+01, -4.514100e+02)
|
||||
+( 4.897436e+07Hz, -4.063346e+01, -4.755494e+02)
|
||||
+( 5.384615e+07Hz, -3.749934e+01, -5.003303e+02)
|
||||
+( 5.871795e+07Hz, -3.516924e+01, -5.256223e+02)
|
||||
+( 6.358974e+07Hz, -3.433887e+01, -5.509590e+02)
|
||||
+( 6.846154e+07Hz, -3.971774e+01, -5.765977e+02)
|
||||
+( 7.333333e+07Hz, -2.496027e+01, -4.260244e+02)
|
||||
+( 7.820513e+07Hz, -2.540060e-01, -5.317362e+02)
|
||||
+( 8.307692e+07Hz, -6.358120e+00, -6.335796e+02)
|
||||
+( 8.794872e+07Hz, -5.894279e+00, -6.719727e+02)
|
||||
+( 9.282051e+07Hz, -4.063864e+00, -7.129969e+02)
|
||||
+( 9.769231e+07Hz, -2.367660e+00, -7.603597e+02)
|
||||
+( 1.025641e+08Hz, -2.098602e+00, -8.143919e+02)
|
||||
+( 1.074359e+08Hz, -4.094614e+00, -8.636479e+02)
|
||||
+( 1.123077e+08Hz, -6.557734e+00, -8.998592e+02)
|
||||
+( 1.171795e+08Hz, -7.759301e+00, -9.295624e+02)
|
||||
+( 1.220513e+08Hz, -6.159604e+00, -9.703161e+02)
|
||||
+( 1.269231e+08Hz, -1.040475e+01, -1.077742e+03)
|
||||
+( 1.317949e+08Hz, -2.627115e+01, -1.123641e+03)
|
||||
+( 1.366667e+08Hz, -4.503397e+01, -9.675219e+02)
|
||||
+( 1.415385e+08Hz, -3.255698e+01, -9.893598e+02)
|
||||
+( 1.464103e+08Hz, -3.059532e+01, -1.012566e+03)
|
||||
+( 1.512821e+08Hz, -3.081422e+01, -1.036661e+03)
|
||||
+( 1.561538e+08Hz, -3.231825e+01, -1.058931e+03)
|
||||
+( 1.610256e+08Hz, -3.453111e+01, -1.077318e+03)
|
||||
+( 1.658974e+08Hz, -3.699828e+01, -1.091740e+03)
|
||||
+( 1.707692e+08Hz, -3.947129e+01, -1.103061e+03)
|
||||
+( 1.756410e+08Hz, -4.184769e+01, -1.112161e+03)
|
||||
+( 1.805128e+08Hz, -4.409577e+01, -1.119694e+03)
|
||||
+( 1.853846e+08Hz, -4.621280e+01, -1.126103e+03)
|
||||
+( 1.902564e+08Hz, -4.820666e+01, -1.131686e+03)
|
||||
+( 1.951282e+08Hz, -5.008836e+01, -1.136645e+03)
|
||||
+( 2.000000e+08Hz, -5.186916e+01, -1.141123e+03)
|
||||
|
||||
*S22 FREQ DB PHASE
|
||||
E22 22 3 FREQ {V(20,3)}= DB
|
||||
+( 1.000000e+07Hz, 1.633257e-07, -1.859873e+01)
|
||||
+( 1.487179e+07Hz, -1.597472e-07, -3.368599e+01)
|
||||
+( 1.974359e+07Hz, -9.840549e-08, -6.829764e+01)
|
||||
+( 2.461538e+07Hz, -5.748843e-06, -2.027281e+02)
|
||||
+( 2.948718e+07Hz, -1.209271e-05, -3.137855e+02)
|
||||
+( 3.435897e+07Hz, -2.686288e-05, -3.426102e+02)
|
||||
+( 3.923077e+07Hz, -6.619051e-05, -3.559304e+02)
|
||||
+( 4.410256e+07Hz, -1.626503e-04, -3.646130e+02)
|
||||
+( 4.897436e+07Hz, -3.750315e-04, -3.714149e+02)
|
||||
+( 5.384615e+07Hz, -7.720713e-04, -3.773802e+02)
|
||||
+( 5.871795e+07Hz, -1.321131e-03, -3.830562e+02)
|
||||
+( 6.358974e+07Hz, -1.599127e-03, -3.888868e+02)
|
||||
+( 6.846154e+07Hz, -4.639695e-04, -3.955734e+02)
|
||||
+( 7.333333e+07Hz, -1.388161e-02, -4.057551e+02)
|
||||
+( 7.820513e+07Hz, -1.245578e+01, -4.419690e+02)
|
||||
+( 8.307692e+07Hz, -1.142468e+00, -3.983505e+02)
|
||||
+( 8.794872e+07Hz, -1.292324e+00, -4.097393e+02)
|
||||
+( 9.282051e+07Hz, -2.163078e+00, -4.176053e+02)
|
||||
+( 9.769231e+07Hz, -3.764828e+00, -4.193838e+02)
|
||||
+( 1.025641e+08Hz, -4.165672e+00, -4.076855e+02)
|
||||
+( 1.074359e+08Hz, -2.143343e+00, -4.074397e+02)
|
||||
+( 1.123077e+08Hz, -1.084156e+00, -4.178506e+02)
|
||||
+( 1.171795e+08Hz, -7.962687e-01, -4.296447e+02)
|
||||
+( 1.220513e+08Hz, -1.204024e+00, -4.416736e+02)
|
||||
+( 1.269231e+08Hz, -4.148459e-01, -4.461929e+02)
|
||||
+( 1.317949e+08Hz, -1.026073e-02, -4.669521e+02)
|
||||
+( 1.366667e+08Hz, -1.361528e-04, -4.892508e+02)
|
||||
+( 1.415385e+08Hz, -2.411138e-03, -5.172082e+02)
|
||||
+( 1.464103e+08Hz, -3.788042e-03, -5.519999e+02)
|
||||
+( 1.512821e+08Hz, -3.601989e-03, -5.908887e+02)
|
||||
+( 1.561538e+08Hz, -2.547212e-03, -6.276516e+02)
|
||||
+( 1.610256e+08Hz, -1.529976e-03, -6.577430e+02)
|
||||
+( 1.658974e+08Hz, -8.674572e-04, -6.807399e+02)
|
||||
+( 1.707692e+08Hz, -4.901623e-04, -6.981937e+02)
|
||||
+( 1.756410e+08Hz, -2.836349e-04, -7.117446e+02)
|
||||
+( 1.805128e+08Hz, -1.694495e-04, -7.226059e+02)
|
||||
+( 1.853846e+08Hz, -1.034247e-04, -7.315943e+02)
|
||||
+( 1.902564e+08Hz, -6.587183e-05, -7.392507e+02)
|
||||
+( 1.951282e+08Hz, -4.251059e-05, -7.459375e+02)
|
||||
+( 2.000000e+08Hz, -2.798303e-05, -7.519027e+02)
|
||||
|
||||
.ENDS
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
* Simple test for xfer code model: comparison
|
||||
*
|
||||
* This circuit compares the results of an AC analysis of a filter (node out)
|
||||
* with those from a behavioural model controlled by measured S-parameters
|
||||
* of that circuit (node xout). The AC analysis has more data points than
|
||||
* that used to measure the S-parameters, to prevent the results from matching
|
||||
* exactly.
|
||||
|
||||
* The use of S-parameters to create a behavioural simulation of a component
|
||||
* was discussed here:
|
||||
* https://sourceforge.net/p/ngspice/discussion/120973/thread/51228e0b01/
|
||||
|
||||
* Circuit from:
|
||||
* Novarianti, Dini. (2019).
|
||||
* Design and Implementation of Chebyshev Band Pass Filter with
|
||||
* M-Derived Section in Frequency Band 88 - 108 MHz.
|
||||
* Jurnal Jartel: Jurnal Jaringan Telekomunikasi. 8. 7-11.
|
||||
* 10.33795/jartel.v8i1.147.
|
||||
*
|
||||
* https://www.researchgate.net/publication/352822864_Design_and_Implementation_of_Chebyshev_Band_Pass_Filter_with_M-Derived_Section_in_Frequency_Band_88_-_108_MHz
|
||||
|
||||
* Set this parameter to 1 to generate a Touchstone file that can be used
|
||||
* to generate the behavioural part of the circuit, filter.lib
|
||||
|
||||
.param do_sp=0
|
||||
.csparam do_sp=do_sp
|
||||
|
||||
.if (do_sp)
|
||||
|
||||
.csparam Rbase=50 ; This is required by "wrs2p", below.
|
||||
vgen 1 0 dc 0 ac 1 portnum 1
|
||||
|
||||
.else
|
||||
|
||||
vgen in 0 dc 0 ac 1
|
||||
rs in 1 50
|
||||
|
||||
.endif
|
||||
|
||||
l1 1 2 0.058u
|
||||
c2 2 0 40.84p
|
||||
l3 2 3 0.128u
|
||||
c4 3 0 47.91p
|
||||
l5 3 4 0.128u
|
||||
c6 4 0 40.48p
|
||||
l7 4 5 0.058u
|
||||
|
||||
la 5 6 0.044u
|
||||
lb 6 a 0.078u
|
||||
cb a 0 17.61p
|
||||
lc 6 b 0.151u
|
||||
cc b 0 34.12p
|
||||
c7 6 7 26.035p
|
||||
|
||||
l8 7 0 0.0653u
|
||||
c8 7 8 20.8p
|
||||
l9 8 0 0.055u
|
||||
c9 8 9 20.8p
|
||||
l10 9 0 0.653u
|
||||
|
||||
c10 9 out 45.64p
|
||||
|
||||
.if (do_sp)
|
||||
|
||||
vl out 0 dc 0 ac 0 portnum 2
|
||||
|
||||
.else
|
||||
|
||||
rl out 0 50
|
||||
|
||||
* Behavioural circuit, for comparison.
|
||||
|
||||
.inc filter.lib
|
||||
R1 in port1 50
|
||||
xsp port1 xout 0 filter
|
||||
R2 xout 0 50
|
||||
|
||||
.endif
|
||||
|
||||
.control
|
||||
if $&do_sp
|
||||
sp lin 40 10meg 200meg
|
||||
wrs2p filter.s2p
|
||||
plot S_1_1 S_2_2 polar
|
||||
else
|
||||
ac lin 400 10meg 200meg
|
||||
plot db(mag(out)) 5*unwrap(ph(out)) db(mag(xout)) 5*unwrap(ph(xout))
|
||||
end
|
||||
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -152,7 +152,7 @@ static char inp_get_elem_ident(char *type);
|
|||
static void rem_mfg_from_models(struct card *start_card);
|
||||
static void inp_fix_macro_param_func_paren_io(struct card *begin_card);
|
||||
static void inp_fix_gnd_name(struct card *deck);
|
||||
static void inp_chk_for_multi_in_vcvs(struct card *deck, int *line_number);
|
||||
static void inp_chk_for_e_source_to_xspice(struct card *deck, int *line_number);
|
||||
static void inp_add_control_section(struct card *deck, int *line_number);
|
||||
static char *get_quoted_token(char *string, char **token);
|
||||
static void replace_token(char *string, char *token, int where, int total);
|
||||
|
|
@ -985,7 +985,7 @@ struct card *inp_readall(FILE *fp, const char *dir_name,
|
|||
subckt_w_params = NULL;
|
||||
if (!cp_getvar("no_auto_gnd", CP_BOOL, NULL, 0))
|
||||
inp_fix_gnd_name(working);
|
||||
inp_chk_for_multi_in_vcvs(working, &rv.line_number);
|
||||
inp_chk_for_e_source_to_xspice(working, &rv.line_number);
|
||||
|
||||
/* "addcontrol" variable is set if "ngspice -a file" was used. */
|
||||
|
||||
|
|
@ -1899,7 +1899,6 @@ static void inp_fix_gnd_name(struct card *c)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transform a VCVS "gate" instance into a XSPICE instance
|
||||
*
|
||||
|
|
@ -1917,7 +1916,336 @@ static void inp_fix_gnd_name(struct card *c)
|
|||
* the x,y list is fixed to length 2
|
||||
*/
|
||||
|
||||
static void inp_chk_for_multi_in_vcvs(struct card *c, int *line_number)
|
||||
static int inp_chk_for_multi_in_vcvs(struct card *c, int *line_number)
|
||||
{
|
||||
char *fcn_b, *line;
|
||||
|
||||
line = c->line;
|
||||
if (((fcn_b = strstr(line, "nand(")) != NULL ||
|
||||
(fcn_b = strstr(line, "and(")) != NULL ||
|
||||
(fcn_b = strstr(line, "nor(")) != NULL ||
|
||||
(fcn_b = strstr(line, "or(")) != NULL) &&
|
||||
isspace_c(fcn_b[-1])) {
|
||||
#ifndef XSPICE
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"Error: XSPICE is required to run the 'multi-input "
|
||||
"pwl' option in line %d\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"See manual chapt. 31 for installation "
|
||||
"instructions\n",
|
||||
*line_number, line);
|
||||
controlled_exit(EXIT_BAD);
|
||||
#else
|
||||
char keep, *comma_ptr, *xy_values1[5], *xy_values2[5];
|
||||
char *out_str, *ctrl_nodes_str,
|
||||
*xy_values1_b = NULL, *ref_str, *fcn_name,
|
||||
*fcn_e = NULL, *out_b, *out_e, *ref_e;
|
||||
char *m_instance, *m_model;
|
||||
char *xy_values2_b = NULL, *xy_values1_e = NULL,
|
||||
*ctrl_nodes_b = NULL, *ctrl_nodes_e = NULL;
|
||||
int xy_count1, xy_count2;
|
||||
bool ok = FALSE;
|
||||
|
||||
do {
|
||||
ref_e = skip_non_ws(line);
|
||||
|
||||
out_b = skip_ws(ref_e);
|
||||
|
||||
out_e = skip_back_ws(fcn_b, out_b);
|
||||
if (out_e <= out_b)
|
||||
break;
|
||||
|
||||
fcn_e = strchr(fcn_b, '(');
|
||||
|
||||
ctrl_nodes_b = strchr(fcn_e, ')');
|
||||
if (!ctrl_nodes_b)
|
||||
break;
|
||||
ctrl_nodes_b = skip_ws(ctrl_nodes_b + 1);
|
||||
|
||||
comma_ptr = strchr(ctrl_nodes_b, ',');
|
||||
if (!comma_ptr)
|
||||
break;
|
||||
|
||||
xy_values1_b = skip_back_ws(comma_ptr, ctrl_nodes_b);
|
||||
if (xy_values1_b[-1] == '}') {
|
||||
while (--xy_values1_b >= ctrl_nodes_b)
|
||||
if (*xy_values1_b == '{')
|
||||
break;
|
||||
} else {
|
||||
xy_values1_b = skip_back_non_ws(xy_values1_b, ctrl_nodes_b);
|
||||
}
|
||||
if (xy_values1_b <= ctrl_nodes_b)
|
||||
break;
|
||||
|
||||
ctrl_nodes_e = skip_back_ws(xy_values1_b, ctrl_nodes_b);
|
||||
if (ctrl_nodes_e <= ctrl_nodes_b)
|
||||
break;
|
||||
|
||||
xy_values1_e = skip_ws(comma_ptr + 1);
|
||||
if (*xy_values1_e == '{') {
|
||||
xy_values1_e = inp_spawn_brace(xy_values1_e);
|
||||
} else {
|
||||
xy_values1_e = skip_non_ws(xy_values1_e);
|
||||
}
|
||||
if (!xy_values1_e)
|
||||
break;
|
||||
|
||||
xy_values2_b = skip_ws(xy_values1_e);
|
||||
|
||||
ok = TRUE;
|
||||
} while (0);
|
||||
|
||||
if (!ok) {
|
||||
fprintf(stderr, "ERROR: malformed line: %s\n", line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ref_str = copy_substring(line, ref_e);
|
||||
out_str = copy_substring(out_b, out_e);
|
||||
fcn_name = copy_substring(fcn_b, fcn_e);
|
||||
ctrl_nodes_str = copy_substring(ctrl_nodes_b, ctrl_nodes_e);
|
||||
|
||||
keep = *xy_values1_e;
|
||||
*xy_values1_e = '\0';
|
||||
xy_count1 =
|
||||
get_comma_separated_values(xy_values1, xy_values1_b);
|
||||
*xy_values1_e = keep;
|
||||
|
||||
xy_count2 = get_comma_separated_values(xy_values2, xy_values2_b);
|
||||
|
||||
// place restrictions on only having 2 point values; this can
|
||||
// change later
|
||||
if (xy_count1 != 2 && xy_count2 != 2)
|
||||
fprintf(stderr,
|
||||
"ERROR: only expecting 2 pair values for "
|
||||
"multi-input vcvs!\n");
|
||||
|
||||
m_instance = tprintf("%s %%vd[ %s ] %%vd( %s ) %s", ref_str,
|
||||
ctrl_nodes_str, out_str, ref_str);
|
||||
m_instance[0] = 'a';
|
||||
|
||||
m_model = tprintf(".model %s multi_input_pwl ( x = [%s %s] y "
|
||||
"= [%s %s] model = \"%s\" )",
|
||||
ref_str, xy_values1[0], xy_values2[0], xy_values1[1],
|
||||
xy_values2[1], fcn_name);
|
||||
|
||||
tfree(ref_str);
|
||||
tfree(out_str);
|
||||
tfree(fcn_name);
|
||||
tfree(ctrl_nodes_str);
|
||||
tfree(xy_values1[0]);
|
||||
tfree(xy_values1[1]);
|
||||
tfree(xy_values2[0]);
|
||||
tfree(xy_values2[1]);
|
||||
|
||||
*c->line = '*';
|
||||
c = insert_new_line(c, m_instance, (*line_number)++, c->linenum_orig);
|
||||
c = insert_new_line(c, m_model, (*line_number)++, c->linenum_orig);
|
||||
#endif
|
||||
return 1;
|
||||
} else {
|
||||
return 0; // No keyword match. */
|
||||
}
|
||||
}
|
||||
|
||||
/* replace the E and G source FREQ function by an XSPICE xfer instance
|
||||
* (used by Touchstone to netlist converter programs).
|
||||
* E1 n1 n2 FREQ {expression} = DB values ...
|
||||
* will become
|
||||
* B1_gen 1_gen 0 v = expression
|
||||
* A1_gen 1_gen %d(n1 n2) 1_gen
|
||||
* .model 1_gen xfer db=true table=[ values ]
|
||||
*/
|
||||
|
||||
static void replace_freq(struct card *c, int *line_number)
|
||||
{
|
||||
#ifdef XSPICE
|
||||
char *line, *e, *e_e, *n1, *n1_e, *n2, *n2_e, *freq;
|
||||
char *expr, *expr_e, *in, *in_e, *keywd, *cp, *list, *list_e;
|
||||
int db, ri, rad, got_key, diff;
|
||||
char pt, key[4];
|
||||
|
||||
line = c->line;
|
||||
|
||||
/* First token is a node name. */
|
||||
|
||||
e = line + 1;
|
||||
e_e = skip_non_ws(e);
|
||||
n1 = skip_ws(e_e);
|
||||
n1_e = skip_non_ws(n1);
|
||||
freq = strstr(n1_e, "freq");
|
||||
if (!freq || !isspace_c(freq[-1]) || !isspace_c(freq[4]))
|
||||
return;
|
||||
n2 = skip_ws(n1_e);
|
||||
if (n2 == freq) {
|
||||
n2 = NULL;
|
||||
} else {
|
||||
n2_e = skip_non_ws(n2);
|
||||
if (freq != skip_ws(n2_e)) // Three nodes or another keyword.
|
||||
return;
|
||||
}
|
||||
|
||||
/* Isolate the input expression. */
|
||||
|
||||
expr = skip_ws(freq + 4);
|
||||
if (*expr != '{')
|
||||
return;
|
||||
expr = skip_ws(expr + 1);
|
||||
expr_e = strchr(expr, '}');
|
||||
if (!expr_e)
|
||||
return;
|
||||
skip_back_ws(expr_e, expr);
|
||||
|
||||
/* Is the expression just a node name, or v(node) or v(node1, node2)? */
|
||||
|
||||
in = NULL;
|
||||
diff = 0;
|
||||
if (*expr < '0' || *expr > '9') {
|
||||
for (in_e = expr; in_e < expr_e; ++in_e) {
|
||||
if ((*in_e < '0' || *in_e > '9') && (*in_e < 'a' || *in_e > 'z') &&
|
||||
*in_e != '_')
|
||||
break;
|
||||
}
|
||||
if (in_e == expr_e) {
|
||||
/* A simple identifier. */
|
||||
|
||||
in = expr;
|
||||
}
|
||||
}
|
||||
if (expr[0] == 'v' && expr[1] == '(' && expr_e[-1] == ')') {
|
||||
in = expr + 2;
|
||||
in_e = expr_e - 1;
|
||||
cp = strchr(in, ',');
|
||||
diff = (cp && cp < in_e); // Assume v(n1, n2)
|
||||
}
|
||||
|
||||
/* Look for a keyword. Previous processing may put braces around it. */
|
||||
|
||||
keywd = skip_ws(expr_e + 1);
|
||||
if (*keywd == '=')
|
||||
keywd = skip_ws(keywd + 1);
|
||||
|
||||
db = 1;
|
||||
rad = 0;
|
||||
ri = 0;
|
||||
do {
|
||||
if (!keywd)
|
||||
return;
|
||||
list = keywd; // Perhaps not keyword
|
||||
if (*keywd == '{')
|
||||
++keywd;
|
||||
cp = key;
|
||||
while (*keywd && !isspace_c(*keywd) && *keywd != '}' &&
|
||||
cp - key < sizeof key - 1) {
|
||||
*cp++ = *keywd++;
|
||||
}
|
||||
*cp = 0;
|
||||
if (*keywd == '}')
|
||||
++keywd;
|
||||
if (!isspace_c(*keywd))
|
||||
return;
|
||||
|
||||
/* Parse the format keyword, if any. */
|
||||
|
||||
got_key = 0;
|
||||
if (!strcmp(key, "mag")) {
|
||||
db = 0;
|
||||
got_key = 1;
|
||||
} else if (!strcmp(key, "db")) {
|
||||
db = 1;
|
||||
got_key = 1;
|
||||
} else if (!strcmp(key, "rad")) {
|
||||
rad = 1;
|
||||
got_key = 1;
|
||||
} else if (!strcmp(key, "deg")) {
|
||||
rad = 0;
|
||||
got_key = 1;
|
||||
} else if (!strcmp(key, "r_i")) {
|
||||
ri = 1;
|
||||
got_key = 1;
|
||||
}
|
||||
|
||||
/* Get the list of values. */
|
||||
|
||||
if (got_key)
|
||||
list = skip_ws(keywd);
|
||||
if (!list)
|
||||
return;
|
||||
keywd = list;
|
||||
} while(got_key);
|
||||
|
||||
list_e = list + strlen(list) - 1;
|
||||
skip_back_ws(list_e, list);
|
||||
if (list >= list_e)
|
||||
return;
|
||||
|
||||
/* All good, rewrite the line.
|
||||
* Macro BSTR is used to pass counted string arguments to tprintf().
|
||||
*/
|
||||
|
||||
#define BSTR(s) (int)(s##_e - s), s
|
||||
|
||||
pt = (*line == 'e') ? 'v' : 'i';
|
||||
*line = '*'; // Make a comment
|
||||
if (in) {
|
||||
/* Connect input nodes directly. */
|
||||
|
||||
if (diff) {
|
||||
/* Differential input. */
|
||||
|
||||
if (n2) {
|
||||
line = tprintf("a_gen_%.*s %%vd(%.*s) %%%cd(%.*s %.*s) "
|
||||
"gen_model_%.*s",
|
||||
BSTR(e), BSTR(in), pt, BSTR(n1), BSTR(n2), BSTR(e));
|
||||
} else {
|
||||
line = tprintf("a_gen_%.*s %%vd(%.*s) %%%c(%.*s) "
|
||||
"gen_model_%.*s",
|
||||
BSTR(e), BSTR(in), pt, BSTR(n1), BSTR(e));
|
||||
}
|
||||
} else {
|
||||
/* Single node input. */
|
||||
|
||||
if (n2) {
|
||||
line = tprintf("a_gen_%.*s %.*s %%%cd(%.*s %.*s) "
|
||||
"gen_model_%.*s",
|
||||
BSTR(e), BSTR(in), pt, BSTR(n1), BSTR(n2),
|
||||
BSTR(e));
|
||||
} else {
|
||||
line = tprintf("a_gen_%.*s %.*s %%%c(%.*s) gen_model_%.*s",
|
||||
BSTR(e), BSTR(in), pt, BSTR(n1), BSTR(e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Use a B-source for input. */
|
||||
|
||||
line = tprintf("b_gen_%.*s gen_node_%.*s 0 v=%.*s",
|
||||
BSTR(e), BSTR(e), BSTR(expr));
|
||||
c = insert_new_line(c, line, (*line_number)++, c->linenum_orig);
|
||||
if (n2) {
|
||||
line = tprintf("a_gen_%.*s gen_node_%.*s %%%cd(%.*s %.*s) "
|
||||
"gen_model_%.*s",
|
||||
BSTR(e), BSTR(e), pt, BSTR(n1), BSTR(n2), BSTR(e));
|
||||
} else {
|
||||
line = tprintf("a_gen_%.*s gen_node_%.*s %%%c(%.*s) "
|
||||
"gen_model_%.*s",
|
||||
BSTR(e), BSTR(e), pt, BSTR(n1), BSTR(e));
|
||||
}
|
||||
}
|
||||
c = insert_new_line(c, line, (*line_number)++, c->linenum_orig);
|
||||
|
||||
line = tprintf(".model gen_model_%.*s xfer %s table = [%.*s]",
|
||||
BSTR(e),
|
||||
ri ? "r_i=true" : rad ? "rad=true" : !db ? "db=false" : "",
|
||||
BSTR(list));
|
||||
c = insert_new_line(c, line, (*line_number)++, c->linenum_orig);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Convert some E and G-source variants to XSPICE code models. */
|
||||
|
||||
static void inp_chk_for_e_source_to_xspice(struct card *c, int *line_number)
|
||||
{
|
||||
int skip_control = 0;
|
||||
|
||||
|
|
@ -1938,143 +2266,17 @@ static void inp_chk_for_multi_in_vcvs(struct card *c, int *line_number)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (*line == 'e') {
|
||||
if (*line == 'e' && inp_chk_for_multi_in_vcvs(c, line_number))
|
||||
continue;
|
||||
if (*line != 'e' && *line != 'g')
|
||||
continue;
|
||||
|
||||
char *fcn_b;
|
||||
/* Is it the FREQ form with S-parameter table? */
|
||||
|
||||
if (((fcn_b = strstr(line, "nand(")) != NULL ||
|
||||
(fcn_b = strstr(line, "and(")) != NULL ||
|
||||
(fcn_b = strstr(line, "nor(")) != NULL ||
|
||||
(fcn_b = strstr(line, "or(")) != NULL) &&
|
||||
isspace_c(fcn_b[-1])) {
|
||||
#ifndef XSPICE
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"Error: XSPICE is required to run the 'multi-input "
|
||||
"pwl' option in line %d\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"See manual chapt. 31 for installation "
|
||||
"instructions\n",
|
||||
*line_number, line);
|
||||
controlled_exit(EXIT_BAD);
|
||||
#else
|
||||
char keep, *comma_ptr, *xy_values1[5], *xy_values2[5];
|
||||
char *out_str, *ctrl_nodes_str,
|
||||
*xy_values1_b = NULL, *ref_str, *fcn_name,
|
||||
*fcn_e = NULL, *out_b, *out_e, *ref_e;
|
||||
char *m_instance, *m_model;
|
||||
char *xy_values2_b = NULL, *xy_values1_e = NULL,
|
||||
*ctrl_nodes_b = NULL, *ctrl_nodes_e = NULL;
|
||||
int xy_count1, xy_count2;
|
||||
bool ok = FALSE;
|
||||
|
||||
do {
|
||||
ref_e = skip_non_ws(line);
|
||||
|
||||
out_b = skip_ws(ref_e);
|
||||
|
||||
out_e = skip_back_ws(fcn_b, out_b);
|
||||
if (out_e <= out_b)
|
||||
break;
|
||||
|
||||
fcn_e = strchr(fcn_b, '(');
|
||||
|
||||
ctrl_nodes_b = strchr(fcn_e, ')');
|
||||
if (!ctrl_nodes_b)
|
||||
break;
|
||||
ctrl_nodes_b = skip_ws(ctrl_nodes_b + 1);
|
||||
|
||||
comma_ptr = strchr(ctrl_nodes_b, ',');
|
||||
if (!comma_ptr)
|
||||
break;
|
||||
|
||||
xy_values1_b = skip_back_ws(comma_ptr, ctrl_nodes_b);
|
||||
if (xy_values1_b[-1] == '}') {
|
||||
while (--xy_values1_b >= ctrl_nodes_b)
|
||||
if (*xy_values1_b == '{')
|
||||
break;
|
||||
}
|
||||
else {
|
||||
xy_values1_b =
|
||||
skip_back_non_ws(xy_values1_b, ctrl_nodes_b);
|
||||
}
|
||||
if (xy_values1_b <= ctrl_nodes_b)
|
||||
break;
|
||||
|
||||
ctrl_nodes_e = skip_back_ws(xy_values1_b, ctrl_nodes_b);
|
||||
if (ctrl_nodes_e <= ctrl_nodes_b)
|
||||
break;
|
||||
|
||||
xy_values1_e = skip_ws(comma_ptr + 1);
|
||||
if (*xy_values1_e == '{') {
|
||||
xy_values1_e = inp_spawn_brace(xy_values1_e);
|
||||
}
|
||||
else {
|
||||
xy_values1_e = skip_non_ws(xy_values1_e);
|
||||
}
|
||||
if (!xy_values1_e)
|
||||
break;
|
||||
|
||||
xy_values2_b = skip_ws(xy_values1_e);
|
||||
|
||||
ok = TRUE;
|
||||
} while (0);
|
||||
|
||||
if (!ok) {
|
||||
fprintf(stderr, "ERROR: malformed line: %s\n", line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ref_str = copy_substring(line, ref_e);
|
||||
out_str = copy_substring(out_b, out_e);
|
||||
fcn_name = copy_substring(fcn_b, fcn_e);
|
||||
ctrl_nodes_str = copy_substring(ctrl_nodes_b, ctrl_nodes_e);
|
||||
|
||||
keep = *xy_values1_e;
|
||||
*xy_values1_e = '\0';
|
||||
xy_count1 =
|
||||
get_comma_separated_values(xy_values1, xy_values1_b);
|
||||
*xy_values1_e = keep;
|
||||
|
||||
xy_count2 =
|
||||
get_comma_separated_values(xy_values2, xy_values2_b);
|
||||
|
||||
// place restrictions on only having 2 point values; this can
|
||||
// change later
|
||||
if (xy_count1 != 2 && xy_count2 != 2)
|
||||
fprintf(stderr,
|
||||
"ERROR: only expecting 2 pair values for "
|
||||
"multi-input vcvs!\n");
|
||||
|
||||
m_instance = tprintf("%s %%vd[ %s ] %%vd( %s ) %s", ref_str,
|
||||
ctrl_nodes_str, out_str, ref_str);
|
||||
m_instance[0] = 'a';
|
||||
|
||||
m_model = tprintf(".model %s multi_input_pwl ( x = [%s %s] y "
|
||||
"= [%s %s] model = \"%s\" )",
|
||||
ref_str, xy_values1[0], xy_values2[0], xy_values1[1],
|
||||
xy_values2[1], fcn_name);
|
||||
|
||||
tfree(ref_str);
|
||||
tfree(out_str);
|
||||
tfree(fcn_name);
|
||||
tfree(ctrl_nodes_str);
|
||||
tfree(xy_values1[0]);
|
||||
tfree(xy_values1[1]);
|
||||
tfree(xy_values2[0]);
|
||||
tfree(xy_values2[1]);
|
||||
|
||||
*c->line = '*';
|
||||
c = insert_new_line(c, m_instance, (*line_number)++, c->linenum_orig);
|
||||
c = insert_new_line(c, m_model, (*line_number)++, c->linenum_orig);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
replace_freq(c, line_number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If ngspice is started with option -a, then variable 'autorun'
|
||||
* will be set and a control section is inserted to try and ensure
|
||||
* some analysis is done;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ sine
|
|||
slew
|
||||
square
|
||||
summer
|
||||
xfer
|
||||
s_xfer
|
||||
triangle
|
||||
file_source
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
/* Transfer function block for AC simulation, based on s_xfer code model. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PI 3.141592653589793238462643383279502884197
|
||||
|
||||
/* How the table information is stored internally. */
|
||||
|
||||
struct data_pt {
|
||||
double f; /* Frequency, radians/sec. */
|
||||
Mif_Complex_t s; /* The S-parameter. */
|
||||
};
|
||||
|
||||
static void cleanup(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
struct data_pt *table;
|
||||
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY:
|
||||
table = (struct data_pt *)STATIC_VAR(table);
|
||||
if (table) {
|
||||
free(table);
|
||||
STATIC_VAR(table) = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cm_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
||||
{
|
||||
struct data_pt *table;
|
||||
Mif_Complex_t ac_gain;
|
||||
double factor;
|
||||
int span, size, i;
|
||||
|
||||
span = PARAM(span);
|
||||
if (INIT) {
|
||||
Mif_Boolean_t ri, db, rad;
|
||||
int offset, bad = 0, j;
|
||||
|
||||
/* Validate table. */
|
||||
|
||||
offset = PARAM(offset);
|
||||
size = PARAM_SIZE(table);
|
||||
bad = size % span;
|
||||
if (!bad) {
|
||||
for (i = 0; i < size - span; i += span) {
|
||||
if (PARAM(table[i]) < 0 ||
|
||||
PARAM(table[i + span]) < PARAM(table[i])) {
|
||||
bad = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bad) {
|
||||
cm_message_send("Warning: badly formed table.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate the internal table. */
|
||||
|
||||
size /= span;
|
||||
table = (struct data_pt *)calloc(size, sizeof(struct data_pt));
|
||||
STATIC_VAR(table) = table;
|
||||
CALLBACK = cleanup;
|
||||
|
||||
/* Fill it. */
|
||||
|
||||
ri = PARAM(r_i);
|
||||
db = PARAM(db);
|
||||
rad = PARAM(rad);
|
||||
for (i = 0, j = 0; i < size; i++, j += span) {
|
||||
table[i].f = PARAM(table[j]) * 2.0 * PI;
|
||||
if (ri) {
|
||||
table[i].s.real = PARAM(table[j + offset]);
|
||||
table[i].s.imag = PARAM(table[j + offset + 1]);
|
||||
} else {
|
||||
double phase, mag;
|
||||
|
||||
mag = PARAM(table[j + offset]);
|
||||
if (db)
|
||||
mag = pow(10, mag / 20);
|
||||
phase = PARAM(table[j + offset + 1]);
|
||||
if (!rad)
|
||||
phase *= 2 * PI / 360;
|
||||
table[i].s.real = mag * cos(phase);
|
||||
table[i].s.imag = mag * sin(phase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table = (struct data_pt *)STATIC_VAR(table);
|
||||
if (!table)
|
||||
return;
|
||||
if (ANALYSIS == MIF_AC) {
|
||||
double rv;
|
||||
|
||||
size = PARAM_SIZE(table) / span;
|
||||
rv = RAD_FREQ;
|
||||
if (rv <= table[0].f) {
|
||||
ac_gain = table[0].s;
|
||||
} else if (rv >= table[size - 1].f) {
|
||||
ac_gain = table[size - 1].s;
|
||||
} else {
|
||||
for (i = 0; i < size; i++) {
|
||||
if (table[i].f > rv)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Linear interpolation. */
|
||||
|
||||
factor = (rv - table[i - 1].f) / (table[i].f - table[i - 1].f);
|
||||
ac_gain.real = table[i - 1].s.real +
|
||||
factor * (table[i].s.real - table[i - 1].s.real);
|
||||
ac_gain.imag = table[i - 1].s.imag +
|
||||
factor * (table[i].s.imag - table[i - 1].s.imag);
|
||||
}
|
||||
AC_GAIN(out, in) = ac_gain;
|
||||
} else { /* DC, transient ... */
|
||||
if (ANALYSIS == MIF_TRAN) {
|
||||
if (!STATIC_VAR(warned)) {
|
||||
STATIC_VAR(warned) = 1;
|
||||
cm_message_send("The xfer code model does not support "
|
||||
"transient analysis.");
|
||||
}
|
||||
}
|
||||
OUTPUT(out) = table[0].s.real * INPUT(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/* Interface specification for PWL transfer function code model. */
|
||||
|
||||
NAME_TABLE:
|
||||
|
||||
Spice_Model_Name: xfer
|
||||
C_Function_Name: cm_xfer
|
||||
Description: "AC transfer function block"
|
||||
|
||||
|
||||
PORT_TABLE:
|
||||
|
||||
Port_Name: in out
|
||||
Description: "input" "output"
|
||||
Direction: in out
|
||||
Default_Type: v v
|
||||
Allowed_Types: [v,vd,i,id] [v,vd,i,id]
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: no no
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: table
|
||||
Description: "PWL table: frequency/magnitude/phase"
|
||||
Data_Type: real
|
||||
Default_Value: -
|
||||
Limits: -
|
||||
Vector: yes
|
||||
Vector_Bounds: [3 -]
|
||||
Null_Allowed: no
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: r_i
|
||||
Description: "table is in real/imaginary format"
|
||||
Data_Type: boolean
|
||||
Default_Value: false
|
||||
Limits: -
|
||||
Vector: no
|
||||
Vector_Bounds: -
|
||||
Null_Allowed: yes
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: db
|
||||
Description: "table is in magnitude(dB)/phase format"
|
||||
Data_Type: boolean
|
||||
Default_Value: true
|
||||
Limits: -
|
||||
Vector: no
|
||||
Vector_Bounds: -
|
||||
Null_Allowed: yes
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: rad
|
||||
Description: "phase in radians, not degrees"
|
||||
Data_Type: boolean
|
||||
Default_Value: false
|
||||
Limits: -
|
||||
Vector: no
|
||||
Vector_Bounds: -
|
||||
Null_Allowed: yes
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: span offset
|
||||
Description: "Length of table rows" "Offset within row"
|
||||
Data_Type: int int
|
||||
Default_Value: 3 1
|
||||
Limits: [ 3 - ] [ 1 - ]
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
/* This is used internally to store the table in compact complex form. */
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
||||
Static_Var_Name: table
|
||||
Description: "Internal copy of data"
|
||||
Data_Type: pointer
|
||||
|
||||
/* Only warn once about use in transient analysis. */
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
||||
Static_Var_Name: warned
|
||||
Description: "Warning indicator"
|
||||
Data_Type: int
|
||||
|
||||
Loading…
Reference in New Issue