committed by
Holger Vogt
4 changed files with 667 additions and 16 deletions
-
40src/xspice/evt/evtcheck_nodes.c
-
446src/xspice/icm/digital/bidi_bridge/cfunc.mod
-
196src/xspice/icm/digital/bidi_bridge/ifspec.ifs
-
1src/xspice/icm/digital/modpath.lst
@ -0,0 +1,446 @@ |
|||||
|
/* -*- mode: C;-*- (emacs magic) |
||||
|
* |
||||
|
* Simple bidirectional digital/analog bridge. |
||||
|
* Giles Atkinson 2022 |
||||
|
*/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <ctype.h> |
||||
|
#include <math.h> |
||||
|
#include <string.h> |
||||
|
|
||||
|
/* These define driver cut-off: use PARAMs? */ |
||||
|
|
||||
|
#define OFF_LOW 0.7 |
||||
|
#define OFF_HIGH 0.3 |
||||
|
|
||||
|
/* Structure for analogue state: input and output. */ |
||||
|
|
||||
|
struct a_data { |
||||
|
Digital_t i; // Previous output drive |
||||
|
double svoc; // Previous scaled open-circuit estimate |
||||
|
double o; // Previous output |
||||
|
}; |
||||
|
|
||||
|
/* Structure for digital state: input and output. */ |
||||
|
|
||||
|
struct d_data { |
||||
|
Digital_t i, n, o; // Input, new output, previous output |
||||
|
double i_changed; // Time of first input change. |
||||
|
}; |
||||
|
|
||||
|
/* Called at end to free memory. */ |
||||
|
|
||||
|
void cm_bidi_bridge(ARGS) |
||||
|
{ |
||||
|
Digital_State_t atod; |
||||
|
struct d_data *d; |
||||
|
struct a_data *a, *olda; |
||||
|
int i, size, dsize, strength, dir_param; |
||||
|
double delta, rise_delay, fall_delay, t_rise, t_fall; |
||||
|
|
||||
|
|
||||
|
size = PORT_SIZE(a); |
||||
|
dsize = PORT_NULL(dir) ? 0 : PORT_SIZE(dir); |
||||
|
|
||||
|
if (INIT) { |
||||
|
/* Allocate storage for previous values on both sides */ |
||||
|
|
||||
|
cm_analog_alloc(0, size * (int) sizeof (struct a_data)); |
||||
|
a = (struct a_data *)cm_analog_get_ptr(0, 1); |
||||
|
cm_event_alloc(0, size * (int) sizeof (struct d_data)); |
||||
|
d = (struct d_data *)cm_event_get_ptr(0, 0); |
||||
|
|
||||
|
for (i = 0; i < size; ++i) { |
||||
|
LOAD(d[i]) = PARAM(input_load); |
||||
|
a[i].o = 0.0; |
||||
|
a[i].i.state = UNKNOWN; |
||||
|
a[i].i.strength = HI_IMPEDANCE; |
||||
|
|
||||
|
/* Force port initialisation on first event call. */ |
||||
|
|
||||
|
d[i].i.state = UNKNOWN; |
||||
|
d[i].i.strength = UNDETERMINED; |
||||
|
d[i].o.state = (Digital_State_t)(UNKNOWN + 1); // Force update |
||||
|
d[i].n.state = UNKNOWN; |
||||
|
d[i].i_changed = -1.0; |
||||
|
OUTPUT_STATE(d[i]) = UNKNOWN; |
||||
|
OUTPUT_STRENGTH(d[i]) = d[i].o.strength = HI_IMPEDANCE; |
||||
|
} |
||||
|
for (i = 0; i < dsize; ++i) |
||||
|
LOAD(dir[i]) = PARAM(input_load); |
||||
|
} |
||||
|
|
||||
|
if (dsize > size) |
||||
|
dsize = size; |
||||
|
strength = PARAM(strength); |
||||
|
dir_param = PARAM(direction); |
||||
|
t_rise = PARAM(t_rise); |
||||
|
t_fall = PARAM(t_fall); |
||||
|
d = (struct d_data *)cm_event_get_ptr(0,0); |
||||
|
|
||||
|
if (CALL_TYPE == ANALOG) { |
||||
|
double in_high, in_low; |
||||
|
double out_high, out_low, drive_high, drive_low, r_high, r_low; |
||||
|
double r_stl, r_sth; |
||||
|
int smooth; // Smoothing level 0-2 (default 0). |
||||
|
|
||||
|
a = (struct a_data *)cm_analog_get_ptr(0,0); |
||||
|
olda = (struct a_data *)cm_analog_get_ptr(0, 1); |
||||
|
in_high = PARAM(in_high); |
||||
|
in_low = PARAM(in_low); |
||||
|
out_high = PARAM(out_high); |
||||
|
out_low = PARAM(out_low); |
||||
|
drive_low = PARAM(drive_low); |
||||
|
r_stl = PARAM(r_stl); |
||||
|
drive_high = PARAM(drive_high); |
||||
|
r_sth = PARAM(r_sth); |
||||
|
r_low = PARAM(r_low); |
||||
|
r_high = PARAM(r_high); |
||||
|
smooth = PARAM(smooth); |
||||
|
|
||||
|
for (i = 0; i < size; ++i) { |
||||
|
double svoc, voc; // Notional open-circuit voltage scaled/actual. |
||||
|
double in, out; |
||||
|
|
||||
|
/* Determine direction. */ |
||||
|
|
||||
|
in = INPUT(a[i]); |
||||
|
atod = (Digital_State_t)dir_param; |
||||
|
if (atod == UNKNOWN) |
||||
|
atod = (i < dsize) ? INPUT_STATE(dir[i]) : UNKNOWN; |
||||
|
|
||||
|
/* Analog to digital. */ |
||||
|
|
||||
|
if (atod != ZERO) { |
||||
|
Digital_State_t new; |
||||
|
|
||||
|
/* Determine digital output state. */ |
||||
|
|
||||
|
if (in_high < in_low) { // Hysteresis |
||||
|
if (in > in_low) |
||||
|
new = ONE; |
||||
|
else if (in < in_high) |
||||
|
new = ZERO; |
||||
|
else |
||||
|
new = d[i].o.state; // Same as before |
||||
|
} else { |
||||
|
if (in < in_low) |
||||
|
new = ZERO; |
||||
|
else if (in > in_high) |
||||
|
new = ONE; |
||||
|
else |
||||
|
new = UNKNOWN; |
||||
|
} |
||||
|
if (new != d[i].n.state) { |
||||
|
/* Output change, schedule EVENT call. */ |
||||
|
|
||||
|
d[i].n.state = new; |
||||
|
cm_event_queue(TIME); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Digital to analog. */ |
||||
|
|
||||
|
if (atod == ONE) { |
||||
|
out = 0.0; /* AtoD, no analogue output. */ |
||||
|
svoc = 0.5; |
||||
|
} else { |
||||
|
double target, iota, interval[2], range, partial; |
||||
|
int step, step_count; |
||||
|
Digital_t drive, *dp; |
||||
|
|
||||
|
/* Find analogue output current. */ |
||||
|
|
||||
|
if (atod == UNKNOWN) { |
||||
|
/* What is the external drive on the digital node? */ |
||||
|
|
||||
|
drive.state = UNKNOWN; drive.strength = HI_IMPEDANCE; |
||||
|
if (!cm_probe_node(1, (unsigned int)i, &drive)) |
||||
|
cm_message_printf("Can not probe port d[%d].", i); |
||||
|
} else { |
||||
|
drive = *(Digital_t *)INPUT(d[i]); |
||||
|
} |
||||
|
a[i].i = drive; |
||||
|
|
||||
|
/* Has the input changed during this timestep? */ |
||||
|
|
||||
|
iota = (T(0) - T(1)) * 1e-6; // Ignorable |
||||
|
if (T(0) - d[i].i_changed < iota) { |
||||
|
/* Previous input value in force for whole step. */ |
||||
|
|
||||
|
step_count = 1; |
||||
|
step = 0; |
||||
|
interval[0] = T(0) - T(1); |
||||
|
} else if (d[i].i_changed - T(1) < iota) { |
||||
|
/* New input value in force for whole step. |
||||
|
* Includes common no-change case where new == old. |
||||
|
*/ |
||||
|
|
||||
|
step_count = 2; |
||||
|
step = 1; |
||||
|
interval[1] = T(0) - T(1); |
||||
|
} else { |
||||
|
/* Calculate both sides of change. */ |
||||
|
|
||||
|
step_count = 2; |
||||
|
step = 0; |
||||
|
interval[0] = d[i].i_changed - T(1); |
||||
|
interval[1] = T(0) - d[i].i_changed; |
||||
|
} |
||||
|
|
||||
|
out = olda[i].o; |
||||
|
svoc = olda[i].svoc; |
||||
|
for (; step < step_count; ++step) { |
||||
|
double change, tv; |
||||
|
double max_high, max_low; |
||||
|
|
||||
|
if (step == 0) { |
||||
|
dp = &olda[i].i; |
||||
|
} else { |
||||
|
dp = &drive; |
||||
|
} |
||||
|
|
||||
|
/* Calculate new value for open-circuit output voltage. */ |
||||
|
|
||||
|
change = T(0) - T(1); |
||||
|
switch (dp->state) { |
||||
|
case ZERO: |
||||
|
svoc -= change / t_fall; |
||||
|
if (svoc < 0.0) |
||||
|
svoc = 0.0; |
||||
|
break; |
||||
|
case ONE: |
||||
|
svoc += change / t_rise; |
||||
|
if (svoc > 1.0) |
||||
|
svoc = 1.0; |
||||
|
break; |
||||
|
default: |
||||
|
if (dp->strength == HI_IMPEDANCE) { |
||||
|
svoc = 0.5; // Keeps compiler happy |
||||
|
} else { |
||||
|
/* Assume both drivers are on. */ |
||||
|
|
||||
|
if (dp->strength == STRONG) { |
||||
|
if (drive_high > drive_low) |
||||
|
tv = 1.0; |
||||
|
else if (drive_high > drive_low) |
||||
|
tv = 0.0; |
||||
|
else |
||||
|
tv = 0.5; |
||||
|
} else { |
||||
|
tv = r_low / (r_low + r_high); |
||||
|
} |
||||
|
if (svoc < tv) { |
||||
|
svoc += change / t_rise; |
||||
|
if (svoc > tv) |
||||
|
svoc = tv; |
||||
|
} else { |
||||
|
svoc -= change / t_fall; |
||||
|
if (svoc < tv) |
||||
|
svoc = tv; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (smooth > 0) { |
||||
|
cm_smooth_discontinuity(svoc, 0.0, 0.0, 1.0, 1.0, |
||||
|
&voc, &tv); // tv is dummy. |
||||
|
} else { |
||||
|
voc = svoc; |
||||
|
} |
||||
|
|
||||
|
/* Available current depends on svoc (driver cut-off). */ |
||||
|
|
||||
|
max_high = drive_high; |
||||
|
max_high *= (voc - OFF_HIGH) / (1 - OFF_HIGH); |
||||
|
if (max_high < 0.0) |
||||
|
max_high = 0.0; |
||||
|
if (smooth > 1) { |
||||
|
cm_smooth_discontinuity(max_high, 0.0, 0.0, |
||||
|
drive_high, drive_high, |
||||
|
&max_high, &tv); |
||||
|
} |
||||
|
max_low = drive_low * (OFF_LOW - voc) / OFF_LOW; |
||||
|
if (max_low < 0.0) |
||||
|
max_low = 0.0; |
||||
|
if (smooth > 1) { |
||||
|
cm_smooth_discontinuity(max_low, 0.0, 0.0, |
||||
|
drive_low, drive_low, |
||||
|
&max_low, &tv); |
||||
|
} |
||||
|
|
||||
|
/* Convert to voltage. */ |
||||
|
|
||||
|
voc = out_low + (out_high - out_low) * voc; |
||||
|
target = 0.0; |
||||
|
partial = 0.0; |
||||
|
|
||||
|
/* Calculate new value for output current. */ |
||||
|
|
||||
|
switch (dp->strength) { |
||||
|
case STRONG: |
||||
|
range = drive_high + drive_low; |
||||
|
switch (dp->state) { |
||||
|
case ZERO: |
||||
|
target = (in - voc) / r_stl; |
||||
|
partial = 1.0 / r_stl; |
||||
|
break; |
||||
|
case ONE: |
||||
|
target = (in - voc) / r_sth; |
||||
|
partial = 1.0 / r_sth; |
||||
|
break; |
||||
|
case UNKNOWN: |
||||
|
/* Assume both drivers are on. */ |
||||
|
|
||||
|
target = (in - voc) * |
||||
|
((r_stl + r_sth) / (r_stl * r_sth)); |
||||
|
partial = (r_stl + r_sth) / (r_stl * r_sth); |
||||
|
break; |
||||
|
} |
||||
|
if (target > max_low) { |
||||
|
target = max_low; |
||||
|
partial = 0.0; |
||||
|
} else if (target < -max_high) { |
||||
|
target = -max_high; |
||||
|
partial = 0.0; |
||||
|
} |
||||
|
if (smooth > 2) { |
||||
|
cm_smooth_discontinuity(target, |
||||
|
-max_high, -max_high, |
||||
|
max_low, max_low, |
||||
|
&target, &tv); |
||||
|
} |
||||
|
break; |
||||
|
case RESISTIVE: |
||||
|
case UNDETERMINED: // Who knows? |
||||
|
range = out_high / r_high + out_low / r_low; |
||||
|
switch (dp->state) { |
||||
|
case ZERO: |
||||
|
if (in < voc) { |
||||
|
target = 0.0; |
||||
|
} else { |
||||
|
target = (in - voc) / r_low; |
||||
|
partial = 1.0 / r_low; |
||||
|
} |
||||
|
break; |
||||
|
case ONE: |
||||
|
if (in > voc) { |
||||
|
target = 0.0; |
||||
|
} else { |
||||
|
target = (in - voc) / r_high; |
||||
|
partial = 1.0 / r_high; |
||||
|
} |
||||
|
break; |
||||
|
case UNKNOWN: |
||||
|
if (in < out_low) { |
||||
|
target = (in - out_high) / r_high; |
||||
|
partial = 1.0 / r_high; |
||||
|
} else if (in >= out_high) { |
||||
|
target = (in - out_low) / r_low; |
||||
|
partial = 1.0 / r_low; |
||||
|
} else { |
||||
|
/* Both drivers on. */ |
||||
|
|
||||
|
partial = 1.0 / r_low + 1.0 / r_high; |
||||
|
target = (in - voc ) * partial; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
break; |
||||
|
case HI_IMPEDANCE: |
||||
|
default: |
||||
|
range = fmax(drive_high, drive_low); |
||||
|
target = 0.0; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* Can the transition complete in available time? */ |
||||
|
|
||||
|
delta = target - out; // Current |
||||
|
delta *= |
||||
|
((delta > 0) ? t_rise : t_fall) / range; // Time |
||||
|
if (delta < 0) |
||||
|
delta = -delta; |
||||
|
if (delta > interval[step]) { |
||||
|
out += (target - out) * interval[step] / delta; |
||||
|
} else { |
||||
|
/* Transition complete. */ |
||||
|
|
||||
|
out = target; |
||||
|
} |
||||
|
} |
||||
|
if (partial != 0.0) |
||||
|
PARTIAL(a[i], a[i]) = partial; |
||||
|
} |
||||
|
OUTPUT(a[i]) = a[i].o = out; |
||||
|
a[i].svoc = svoc; |
||||
|
} |
||||
|
} else { |
||||
|
/* Digital. */ |
||||
|
|
||||
|
rise_delay = PARAM(rise_delay); |
||||
|
fall_delay = PARAM(fall_delay); |
||||
|
|
||||
|
for (i = 0; i < size; ++i) { |
||||
|
/* Determine direction. */ |
||||
|
|
||||
|
atod = (Digital_State_t)dir_param; |
||||
|
if (atod == UNKNOWN) |
||||
|
atod = (i < dsize) ? INPUT_STATE(dir[i]) : UNKNOWN; |
||||
|
|
||||
|
if (atod != ONE && (INPUT_STATE(d[i]) != d[i].i.state || |
||||
|
INPUT_STRENGTH(d[i]) != d[i].i.strength)) { |
||||
|
double transition; |
||||
|
|
||||
|
/* Digital input changed, request break. */ |
||||
|
|
||||
|
d[i].i = *(Digital_t *)INPUT(d[i]); |
||||
|
cm_analog_set_temp_bkpt(TIME); |
||||
|
d[i].i_changed = TIME; |
||||
|
|
||||
|
/* Do not let big timesteps smear the transition (it could be |
||||
|
* much faster with current output into high impedance. |
||||
|
*/ |
||||
|
|
||||
|
transition = (d[i].i.state == ZERO) ? t_fall : |
||||
|
(d[i].i.state == ONE) ? t_rise : fmin(t_rise, t_fall); |
||||
|
cm_analog_set_perm_bkpt(TIME + transition * 1.0001); |
||||
|
} |
||||
|
|
||||
|
/* Check for output change from analogue. */ |
||||
|
|
||||
|
if (atod == ZERO) { |
||||
|
if (d[i].o.strength != HI_IMPEDANCE) { |
||||
|
OUTPUT_STATE(d[i]) = d[i].o.state = UNKNOWN; |
||||
|
OUTPUT_STRENGTH(d[i]) = d[i].o.strength = HI_IMPEDANCE; |
||||
|
OUTPUT_DELAY(d[i]) = fmax(rise_delay, fall_delay); |
||||
|
} else { |
||||
|
OUTPUT_CHANGED(d[i]) = FALSE; |
||||
|
} |
||||
|
} else { |
||||
|
if (d[i].o.state != d[i].n.state) { |
||||
|
double delay; |
||||
|
|
||||
|
OUTPUT_STATE(d[i]) = d[i].o.state = d[i].n.state; |
||||
|
OUTPUT_STRENGTH(d[i]) = d[i].o.strength = strength; |
||||
|
switch (d[i].o.state) { |
||||
|
case ZERO: |
||||
|
delay = fall_delay; |
||||
|
break; |
||||
|
case ONE: |
||||
|
delay = rise_delay; |
||||
|
break; |
||||
|
default: |
||||
|
case UNKNOWN: |
||||
|
delay = fmin(rise_delay, fall_delay); |
||||
|
break; |
||||
|
} |
||||
|
OUTPUT_DELAY(d[i]) = delay; |
||||
|
} else { |
||||
|
OUTPUT_CHANGED(d[i]) = FALSE; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,196 @@ |
|||||
|
/* |
||||
|
AUTHORS |
||||
|
|
||||
|
24 Apr 2022 Giles Atkinson |
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This file contains the interface specification file for the |
||||
|
hybrid bidi_bridge code model, a (potentially) bidirectional |
||||
|
analogue/digital bridge. The device has direction inputs |
||||
|
but if they are not driven it tries to behave like a piece of wire. |
||||
|
A parameter may override any direction inputs. |
||||
|
The analogue ports are type "g" as that is bidirectional. |
||||
|
*/ |
||||
|
|
||||
|
NAME_TABLE: |
||||
|
|
||||
|
|
||||
|
C_Function_Name: cm_bidi_bridge |
||||
|
Spice_Model_Name: bidi_bridge |
||||
|
Description: "bidirectional digital/analog node bridge" |
||||
|
|
||||
|
|
||||
|
PORT_TABLE: |
||||
|
|
||||
|
Port_Name: a d |
||||
|
Description: "analog" "digital in/out" |
||||
|
Direction: inout inout |
||||
|
Default_Type: g d |
||||
|
Allowed_Types: [g, gd] [d] |
||||
|
Vector: yes yes |
||||
|
Vector_Bounds: [1 -] [1 -] |
||||
|
Null_Allowed: no no |
||||
|
|
||||
|
/* The direction of the bridge ports may be controlled by digital inputs. |
||||
|
* If null, or the value is UNKNOWN the bridge will be truly bi-directional. |
||||
|
*/ |
||||
|
|
||||
|
PORT_TABLE: |
||||
|
|
||||
|
Port_Name: dir |
||||
|
Description: "direction" |
||||
|
Direction: in |
||||
|
Default_Type: d |
||||
|
Allowed_Types: [d] |
||||
|
Vector: yes |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
/* Alternatively, this parameter sets direction: 0-2 for DAC, ADC, ignore. |
||||
|
* Values 0/1 override the direction port. |
||||
|
*/ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: direction input_load |
||||
|
Description: "force direction" "capacitive input load (F)" |
||||
|
Data_Type: int real |
||||
|
Default_Value: 2 1.0e-12 |
||||
|
Limits: [0 2] - |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
/* Output strength is 0 (strong, default) or 1 (resistive). |
||||
|
* Smooth controls use of smoothing functions, default is 0 (no smoothing). |
||||
|
*/ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: strength smooth |
||||
|
Description: "output strength" "smoothing level" |
||||
|
Data_Type: int int |
||||
|
Default_Value: 0 0 |
||||
|
Limits: [0 2] [0 2] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
/* Analog thresholds, in_low may be greater than in-high, enabling hysteresis. |
||||
|
*/ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: in_low |
||||
|
Description: "maximum 0-valued analog input" |
||||
|
Data_Type: real |
||||
|
Default_Value: 0.1 |
||||
|
Limits: - |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: in_high |
||||
|
Description: "minimum 1-valued analog input" |
||||
|
Data_Type: real |
||||
|
Default_Value: 0.9 |
||||
|
Limits: - |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
/* Analog maximum and minimum output voltages. */ |
||||
|
|
||||
|
Parameter_Name: out_low |
||||
|
Description: "minimum analog output voltage for 'ZERO' digital input" |
||||
|
Data_Type: real |
||||
|
Default_Value: 0.0 |
||||
|
Limits: - |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: out_high |
||||
|
Description: "maximum analog output voltage for 'ONE' digital input" |
||||
|
Data_Type: real |
||||
|
Default_Value: 3.3 |
||||
|
Limits: - |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
/* Analog maximum current. */ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: drive_low drive_high |
||||
|
Description: "max current to ground" "max current to ground" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 0.02 0.02 |
||||
|
Limits: - - |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
/* Strong analog output cuts off smoothly at the voltage limits. |
||||
|
* Let vth = out_high - r_sth * drive_high. |
||||
|
* Then for input voltage v, with drive_high > v > vth, |
||||
|
* the maximum output current is (drive_high - v) / r_sth |
||||
|
*/ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: r_stl r_sth |
||||
|
Description: "low taper resistance" "high taper resistance" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 20 20 |
||||
|
Limits: [1e-6 -] [1e-6 -] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
/* Resistive analog drive. */ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: r_low r_high |
||||
|
Description: "drive resistor to ground" "drive resistor to out_high" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 10000 10000 |
||||
|
Limits: [1e-6 -] [1e-6 -] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
/* Analog rise and fall times. */ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: t_rise t_fall |
||||
|
Description: "rise time 0 -> 1" "fall time 1 -> 0" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 1.0e-9 1.0e-9 |
||||
|
Limits: [1e-12 -] [1e-12 -] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
/* Digital rise and fall delays. */ |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: rise_delay fall_delay |
||||
|
Description: "rise delay 0 -> 1" "fall delay 1 -> 0" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 1.0e-9 1.0e-9 |
||||
|
Limits: [1e-12 -] [1e-12 -] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue