From 4623a0461584bcffbc7052820e1da45b78b1b09e Mon Sep 17 00:00:00 2001 From: Giles Atkinson <“gatk555@gmail.com”> Date: Sun, 12 Mar 2023 13:13:58 +0000 Subject: [PATCH] Interim version of inertial delay for tristate buffer. This does not handle three-way or mixed transitions. --- src/xspice/icm/digital/d_tristate/cfunc.mod | 148 ++++++++++++------- src/xspice/icm/digital/d_tristate/ifspec.ifs | 39 +++-- 2 files changed, 118 insertions(+), 69 deletions(-) diff --git a/src/xspice/icm/digital/d_tristate/cfunc.mod b/src/xspice/icm/digital/d_tristate/cfunc.mod index 74be5e56f..ac9cb086b 100644 --- a/src/xspice/icm/digital/d_tristate/cfunc.mod +++ b/src/xspice/icm/digital/d_tristate/cfunc.mod @@ -8,37 +8,30 @@ Public Domain Georgia Tech Research Corporation Atlanta, Georgia 30332 PROJECT A-8503-405 - -AUTHORS +AUTHORS 18 Nov 1991 Jeffrey P. Murray - -MODIFICATIONS +MODIFICATIONS 26 Nov 1991 Jeffrey P. Murray - SUMMARY This file contains the functional description of the d_tristate code model. +INTERFACES -INTERFACES - - FILE ROUTINE CALLED + FILE ROUTINE CALLED CMevt.c void *cm_event_alloc() void *cm_event_get_ptr() - - REFERENCED FILES Inputs from and outputs to ARGS structure. - NON-STANDARD FEATURES @@ -48,39 +41,30 @@ NON-STANDARD FEATURES /*=== INCLUDE FILES ====================*/ - - +#include "ngspice/inertial.h" /*=== CONSTANTS ========================*/ - - /*=== MACROS ===========================*/ - - -/*=== LOCAL VARIABLES & TYPEDEFS =======*/ +/*=== LOCAL VARIABLES & TYPEDEFS =======*/ - - /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ - - /*============================================================================== FUNCTION cm_d_tristate() -AUTHORS +AUTHORS 18 Nov 1991 Jeffrey P. Murray -MODIFICATIONS +MODIFICATIONS 26 Nov 1991 Jeffrey P. Murray @@ -88,9 +72,9 @@ SUMMARY This function implements the d_tristate code model. -INTERFACES +INTERFACES - FILE ROUTINE CALLED + FILE ROUTINE CALLED CMevt.c void *cm_event_alloc() void *cm_event_get_ptr() @@ -100,7 +84,7 @@ RETURNED VALUE Returns inputs and outputs via ARGS structure. GLOBAL VARIABLES - + NONE NON-STANDARD FEATURES @@ -123,43 +107,101 @@ NON-STANDARD FEATURES * Last Modified 11/26/91 * ************************************************/ - 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 */ + + val = INPUT_STATE(in); + 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) { - - OUTPUT_STRENGTH(out) = HI_IMPEDANCE; - + str = 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; - } - else { - - OUTPUT_STRENGTH(out) = STRONG; + idp = (struct idata *)cm_event_get_ptr(1, 0); + d_cancel = (idp[0].when > TIME && val == idp[0].prev); + s_cancel = (idp[1].when > TIME && + 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; } } - - diff --git a/src/xspice/icm/digital/d_tristate/ifspec.ifs b/src/xspice/icm/digital/d_tristate/ifspec.ifs index fc68e337a..20fe5eef9 100644 --- a/src/xspice/icm/digital/d_tristate/ifspec.ifs +++ b/src/xspice/icm/digital/d_tristate/ifspec.ifs @@ -52,26 +52,33 @@ Null_Allowed: yes PARAMETER_TABLE: -Parameter_Name: input_load -Description: "input load value (F)" -Data_Type: real -Default_Value: 1.0e-12 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: yes +Parameter_Name: input_load enable_load +Description: "input load value (F)" "enable load value (F)" +Data_Type: real real +Default_Value: 1.0e-12 1.0e-12 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes PARAMETER_TABLE: -Parameter_Name: enable_load -Description: "enable load value (F)" -Data_Type: real -Default_Value: 1.0e-12 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: yes + +Parameter_Name: inertial_delay family +Description: "swallow short pulses" "Logic family for bridging" +Data_Type: boolean string +Default_Value: false - +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + +STATIC_VAR_TABLE: + +Static_Var_Name: is_inertial +Data_Type: boolean +Description: "using inertial delay"