Interim version of inertial delay for tristate buffer.

This does not handle three-way or mixed transitions.
This commit is contained in:
Giles Atkinson 2023-03-12 13:13:58 +00:00 committed by Holger Vogt
parent e3b4df6a51
commit 4623a04615
2 changed files with 118 additions and 69 deletions

View File

@ -8,37 +8,30 @@ Public Domain
Georgia Tech Research Corporation Georgia Tech Research Corporation
Atlanta, Georgia 30332 Atlanta, Georgia 30332
PROJECT A-8503-405 PROJECT A-8503-405
AUTHORS AUTHORS
18 Nov 1991 Jeffrey P. Murray 18 Nov 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
26 Nov 1991 Jeffrey P. Murray 26 Nov 1991 Jeffrey P. Murray
SUMMARY SUMMARY
This file contains the functional description of the d_tristate This file contains the functional description of the d_tristate
code model. code model.
INTERFACES
INTERFACES FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc() CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr() void *cm_event_get_ptr()
REFERENCED FILES REFERENCED FILES
Inputs from and outputs to ARGS structure. Inputs from and outputs to ARGS structure.
NON-STANDARD FEATURES NON-STANDARD FEATURES
@ -48,39 +41,30 @@ NON-STANDARD FEATURES
/*=== INCLUDE FILES ====================*/ /*=== INCLUDE FILES ====================*/
#include "ngspice/inertial.h"
/*=== CONSTANTS ========================*/ /*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/ /*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*============================================================================== /*==============================================================================
FUNCTION cm_d_tristate() FUNCTION cm_d_tristate()
AUTHORS AUTHORS
18 Nov 1991 Jeffrey P. Murray 18 Nov 1991 Jeffrey P. Murray
MODIFICATIONS MODIFICATIONS
26 Nov 1991 Jeffrey P. Murray 26 Nov 1991 Jeffrey P. Murray
@ -88,9 +72,9 @@ SUMMARY
This function implements the d_tristate code model. This function implements the d_tristate code model.
INTERFACES INTERFACES
FILE ROUTINE CALLED FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc() CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr() void *cm_event_get_ptr()
@ -100,7 +84,7 @@ RETURNED VALUE
Returns inputs and outputs via ARGS structure. Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES GLOBAL VARIABLES
NONE NONE
NON-STANDARD FEATURES NON-STANDARD FEATURES
@ -123,43 +107,101 @@ NON-STANDARD FEATURES
* Last Modified 11/26/91 * * Last Modified 11/26/91 *
************************************************/ ************************************************/
void cm_d_tristate(ARGS) void cm_d_tristate(ARGS)
{ {
int enable; /* holding variable for enable input */ Digital_t *out;
Digital_State_t val, enable;
Digital_Strength_t str;
struct idata *idp;
if (INIT) { /* initial pass */
/* define input loading... */
LOAD(in) = PARAM(input_load);
LOAD(enable) = PARAM(enable_load);
OUTPUT_DELAY(out) = PARAM(delay);
/* allocate storage for the previous output. */
cm_event_alloc(0, sizeof (Digital_t));
out = (Digital_t *)cm_event_get_ptr(0, 0);
out->state = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
/* Inertial delay? */
STATIC_VAR(is_inertial) =
cm_is_inertial(PARAM_NULL(inertial_delay) ? Not_set :
PARAM(inertial_delay));
if (STATIC_VAR(is_inertial)) {
/* Allocate storage for event time. */
cm_event_alloc(1, 2 * sizeof (struct idata));
idp = (struct idata *)cm_event_get_ptr(1, 0);
idp[1].when = idp[0].when = -1.0;
}
/* Prepare initial output. */
out = (Digital_t *)cm_event_get_ptr(0, 0);
out->state = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
} else {
out = (Digital_t *)cm_event_get_ptr(0, 0);
}
/* Retrieve input values and static variables */ /* Retrieve input values and static variables */
val = INPUT_STATE(in);
enable = INPUT_STATE(enable); enable = INPUT_STATE(enable);
OUTPUT_STATE(out) = INPUT_STATE(in);
OUTPUT_DELAY(out) = PARAM(delay);
/* define input loading... */
LOAD(in) = PARAM(input_load);
LOAD(enable) = PARAM(enable_load);
if (ZERO == enable) { if (ZERO == enable) {
str = HI_IMPEDANCE;
OUTPUT_STRENGTH(out) = HI_IMPEDANCE; } else if (UNKNOWN == enable) {
str = UNDETERMINED;
} else {
str = STRONG;
} }
else
if (UNKNOWN == enable) {
OUTPUT_STRENGTH(out) = UNDETERMINED; if (val == out->state && str == out->strength) {
OUTPUT_CHANGED(out) = FALSE;
} else {
if (STATIC_VAR(is_inertial) && ANALYSIS == TRANSIENT) {
int d_cancel, s_cancel;
} idp = (struct idata *)cm_event_get_ptr(1, 0);
else { d_cancel = (idp[0].when > TIME && val == idp[0].prev);
s_cancel = (idp[1].when > TIME &&
OUTPUT_STRENGTH(out) = STRONG; str == (Digital_Strength_t)idp[1].prev);
if ((d_cancel && s_cancel) ||
(d_cancel && str == out->strength && TIME >= idp[1].when) ||
(s_cancel && val == out->state && TIME >= idp[0].when)) {
double when;
/* Changing back: override pending change. */
when = d_cancel ? idp[0].when : idp[1].when;
if (s_cancel && when > idp[1].when)
when = idp[1].when;
OUTPUT_DELAY(out) = (when - TIME) / 2.0; // Override
idp[1].when = idp[0].when = -1.0;
} else {
/* Normal transition, or third value during delay,
* or needs cancel followed by restore of
* the other component (fudge).
*/
OUTPUT_DELAY(out) = PARAM(delay);
if (val != out->state) {
idp[0].prev = out->state;
idp[0].when = TIME + OUTPUT_DELAY(out);
}
if (str != out->strength) {
idp[1].prev = (Digital_State_t)out->strength;
idp[1].when = TIME + OUTPUT_DELAY(out);
}
}
}
out->state = val;
out->strength = str;
*(Digital_t *)OUTPUT(out) = *out;
} }
} }

View File

@ -52,26 +52,33 @@ Null_Allowed: yes
PARAMETER_TABLE: PARAMETER_TABLE:
Parameter_Name: input_load Parameter_Name: input_load enable_load
Description: "input load value (F)" Description: "input load value (F)" "enable load value (F)"
Data_Type: real Data_Type: real real
Default_Value: 1.0e-12 Default_Value: 1.0e-12 1.0e-12
Limits: - Limits: - -
Vector: no Vector: no no
Vector_Bounds: - Vector_Bounds: - -
Null_Allowed: yes Null_Allowed: yes yes
PARAMETER_TABLE: PARAMETER_TABLE:
Parameter_Name: enable_load
Description: "enable load value (F)" Parameter_Name: inertial_delay family
Data_Type: real Description: "swallow short pulses" "Logic family for bridging"
Default_Value: 1.0e-12 Data_Type: boolean string
Limits: - Default_Value: false -
Vector: no Limits: - -
Vector_Bounds: - Vector: no no
Null_Allowed: yes Vector_Bounds: - -
Null_Allowed: yes yes
STATIC_VAR_TABLE:
Static_Var_Name: is_inertial
Data_Type: boolean
Description: "using inertial delay"