Inertial delay for remaining simple gates and buffers:

nand or xor open_c open_e, but not tristate.
This commit is contained in:
Giles Atkinson 2023-03-14 21:41:10 +00:00 committed by Holger Vogt
parent db38d4ad54
commit cecce5163e
10 changed files with 726 additions and 658 deletions

View File

@ -8,37 +8,31 @@ Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
AUTHORS
18 June 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
30 Sept 1991 Jeffrey P. Murray
SUMMARY
This file contains the functional description of the d_nand
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,38 +42,29 @@ NON-STANDARD FEATURES
/*=== INCLUDE FILES ====================*/
#include "ngspice/inertial.h"
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION cm_d_nand()
AUTHORS
AUTHORS
18 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
30 Sep 1991 Jeffrey P. Murray
@ -87,19 +72,19 @@ SUMMARY
This function implements the d_nand code model.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
RETURNED VALUE
Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
@ -118,128 +103,125 @@ NON-STANDARD FEATURES
* Created 6/18/91 J.P.Murray *
************************************************/
void cm_d_nand(ARGS)
void cm_d_nand(ARGS)
{
int i, /* generic loop counter index */
size; /* number of input & output ports */
Digital_State_t *out, /* temporary output for buffers */
*out_old, /* previous output for buffers */
input; /* temp storage for input bits */
size; /* number of input & output ports */
Digital_State_t val, /* Output value. */
*out, /* temporary output for buffers */
input; /* temp storage for input bits */
/** Retrieve size value... **/
size = PORT_SIZE(in);
/*** Setup required state variables ***/
if(INIT) { /* initial pass */
if(INIT) { /* initial pass */
/* allocate storage for the outputs */
cm_event_alloc(0,sizeof(Digital_State_t));
cm_event_alloc(0, sizeof (Digital_State_t));
/* 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, sizeof (struct idata));
((struct idata *)cm_event_get_ptr(1, 0))->when = -1.0;
}
/* Prepare initial output. */
out = (Digital_State_t *)cm_event_get_ptr(0, 0);
*out = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
for (i=0; i<size; i++) LOAD(in[i]) = PARAM(input_load);
} else { /* Retrieve previous values */
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
}
else { /* Retrieve previous values */
/* retrieve storage for the outputs */
out = (Digital_State_t *) cm_event_get_ptr(0,0);
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
}
/*** Calculate new output value based on inputs ***/
*out = ZERO;
val = ZERO;
for (i=0; i<size; i++) {
/* make sure this input isn't floating... */
if ( FALSE == PORT_NULL(in) ) {
/* if a 0, set *out high */
if ( ZERO == (input = INPUT_STATE(in[i])) ) {
*out = ONE;
break;
}
else {
/* if an unknown input, set *out to unknown & break */
if ( UNKNOWN == input ) {
*out = UNKNOWN;
}
}
}
else {
/* at least one port is floating...output is unknown */
*out = UNKNOWN;
/* if a 0, set *out high */
if ( ZERO == (input = INPUT_STATE(in[i])) ) {
val = ONE;
break;
} else {
/* if an unknown input, set *out to unknown & break */
if ( UNKNOWN == input )
val = UNKNOWN;
}
}
/*** Determine analysis type and output appropriate values ***/
if (ANALYSIS == DC) { /** DC analysis...output w/o delays **/
OUTPUT_STATE(out) = *out;
}
else { /** Transient Analysis **/
/*** Check for change and output appropriate values ***/
if (val == *out) { /* output value is not changing */
OUTPUT_CHANGED(out) = FALSE;
} else {
switch (val) {
if ( *out != *out_old ) { /* output value is changing */
switch ( *out ) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = ZERO;
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
case 0:
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1: OUTPUT_STATE(out) = ONE;
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
case 1:
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
default:
OUTPUT_STATE(out) = *out = UNKNOWN;
/* based on old value, add rise or fall delay */
if (0 == *out_old) { /* add rising delay */
default:
/* based on old value, add rise or fall delay */
if (0 == *out) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
} else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
if (STATIC_VAR(is_inertial) && ANALYSIS == TRANSIENT) {
struct idata *idp;
idp = (struct idata *)cm_event_get_ptr(1, 0);
if (idp->when <= TIME) {
/* Normal transition. */
idp->prev = *out;
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else if (val != idp->prev) {
Digital_t ov = {idp->prev, STRONG};
/* Third value: cancel earlier change and output as usual. */
cm_schedule_output(1, 0, (idp->when - TIME) / 2.0, &ov);
if (val == UNKNOWN) {
/* Delay based in idp->prev, not *out. */
if (idp->prev == ZERO)
OUTPUT_DELAY(out) = PARAM(rise_delay);
}
else { /* add falling delay */
else
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else {
/* Changing back: override pending change. */
OUTPUT_DELAY(out) = (idp->when - TIME) / 2.0; // Override
idp->when = -1.0;
}
}
else { /* output value not changing */
OUTPUT_CHANGED(out) = FALSE;
}
*out = val;
OUTPUT_STATE(out) = val;
OUTPUT_STRENGTH(out) = STRONG;
}
OUTPUT_STRENGTH(out) = STRONG;
}
}

View File

@ -28,14 +28,14 @@ Description: "digital n-input nand gate"
PORT_TABLE:
Port_Name: in out
Description: "input" "output"
Direction: in out
Default_Type: d d
Allowed_Types: [d] [d]
Vector: yes no
Vector_Bounds: [2 -] -
Null_Allowed: no no
Port_Name: in out
Description: "input" "output"
Direction: in out
Default_Type: d d
Allowed_Types: [d] [d]
Vector: yes no
Vector_Bounds: [2 -] -
Null_Allowed: no no
PARAMETER_TABLE:
@ -45,19 +45,35 @@ Description: "rise delay" "fall delay"
Data_Type: real real
Default_Value: 1.0e-9 1.0e-9
Limits: [1e-12 -] [1e-12 -]
Vector: no no
Vector_Bounds: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes 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 family
Description: "input load value (F)" "Logic family for bridging"
Data_Type: real string
Default_Value: 1.0e-12 -
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: inertial_delay
Description: "swallow short pulses"
Data_Type: boolean
Default_Value: false
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: is_inertial
Data_Type: boolean
Description: "using inertial delay"

View File

@ -8,37 +8,31 @@ Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
AUTHORS
19 Nov 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
19 Nov 1991 Jeffrey P. Murray
SUMMARY
This file contains the functional description of the d_open_c
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 +42,28 @@ NON-STANDARD FEATURES
/*=== INCLUDE FILES ====================*/
#include "ngspice/inertial.h"
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION cm_d_open_c()
AUTHORS
AUTHORS
19 Nov 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
19 Nov 1991 Jeffrey P. Murray
@ -88,19 +71,19 @@ SUMMARY
This function implements the d_open_c code model.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
RETURNED VALUE
Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
@ -109,6 +92,23 @@ NON-STANDARD FEATURES
==============================================================================*/
/* Find strength for given output. */
static Digital_Strength_t strength(Digital_State_t s)
{
switch (s) {
case ZERO:
return STRONG;
break;
case ONE:
return HI_IMPEDANCE;
break;
default:
return UNDETERMINED;
break;
}
}
/*=== CM_D_OPEN_C ROUTINE ===*/
/************************************************
@ -119,96 +119,106 @@ NON-STANDARD FEATURES
* Created 11/19/91 J.P,Murray *
************************************************/
void cm_d_open_c(ARGS)
void cm_d_open_c(ARGS)
{
/*int i;*/ /* generic loop counter index */
Digital_State_t *out, /* temporary output for buffers */
*out_old; /* previous output for buffers */
Digital_State_t val,
*out; /* temporary output for buffers */
/** Setup required state variables **/
if(INIT) { /* initial pass */
if(INIT) { /* initial pass */
/* allocate storage for the outputs */
cm_event_alloc(0,sizeof(Digital_State_t));
/* define input loading... */
cm_event_alloc(0, sizeof (Digital_State_t));
/* 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, sizeof (struct idata));
((struct idata *)cm_event_get_ptr(1, 0))->when = -1.0;
}
/* Prepare initial output. */
out = (Digital_State_t *)cm_event_get_ptr(0, 0);
*out = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
LOAD(in) = PARAM(input_load);
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
}
else { /* Retrieve previous values */
} else {
/* retrieve storage for the outputs */
out = (Digital_State_t *) cm_event_get_ptr(0,0);
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
}
/** Check on analysis type **/
/*** Calculate new output value based on inputs ***/
if (ANALYSIS == DC) { /* DC analysis...output w/o delays */
OUTPUT_STATE(out) = *out = INPUT_STATE(in);
if ( ONE == *out ) {
OUTPUT_STRENGTH(out) = HI_IMPEDANCE;
}
else
if ( ZERO == *out ) {
OUTPUT_STRENGTH(out) = STRONG;
}
else {
OUTPUT_STRENGTH(out) = UNDETERMINED;
}
val = INPUT_STATE(in);
}
else { /* Transient Analysis */
/*** Check for change and output appropriate values ***/
switch ( INPUT_STATE(in) ) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = *out = ZERO;
OUTPUT_STRENGTH(out) = STRONG;
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
if (val == *out) { /* output value is not changing */
OUTPUT_CHANGED(out) = FALSE;
} else {
switch (val) {
/* rise to one value */
case 1: OUTPUT_STATE(out) = *out = ONE;
OUTPUT_STRENGTH(out) = HI_IMPEDANCE;
OUTPUT_DELAY(out) = PARAM(open_delay);
break;
/* unknown output */
/* fall to zero value */
case 0:
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1:
OUTPUT_DELAY(out) = PARAM(open_delay);
break;
/* unknown output */
default:
OUTPUT_STATE(out) = *out = UNKNOWN;
OUTPUT_STRENGTH(out) = UNDETERMINED;
/* based on old value, add rise or fall delay */
if (0 == *out_old) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(open_delay);
}
else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
/* based on old value, add rise or fall delay */
if (0 == *out) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(open_delay);
} else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
if (STATIC_VAR(is_inertial) && ANALYSIS == TRANSIENT) {
struct idata *idp;
idp = (struct idata *)cm_event_get_ptr(1, 0);
if (idp->when <= TIME) {
/* Normal transition. */
idp->prev = *out;
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else if (val != idp->prev) {
Digital_t ov = {idp->prev, strength(idp->prev)};
/* Third value: cancel earlier change and output as usual. */
cm_schedule_output(1, 0, (idp->when - TIME) / 2.0, &ov);
if (val == UNKNOWN) {
/* Delay based in idp->prev, not *out. */
if (idp->prev == ZERO)
OUTPUT_DELAY(out) = PARAM(open_delay);
else
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else {
/* Changing back: override pending change. */
OUTPUT_DELAY(out) = (idp->when - TIME) / 2.0; // Override
idp->when = -1.0;
}
}
*out = val;
OUTPUT_STATE(out) = val;
OUTPUT_STRENGTH(out) = strength(val);
}
}
}

View File

@ -6,14 +6,14 @@ Georgia Tech Research Corporation
Atlanta, Georgia 30332
AUTHORS
AUTHORS
19 Nov 1991 Jeffrey P. Murray
SUMMARY
This file contains the interface specification file for the
This file contains the interface specification file for the
digital d_open_c (open collector) code model.
===============================================================================*/
@ -32,31 +32,49 @@ Description: "input" "output"
Direction: in out
Default_Type: d d
Allowed_Types: [d] [d]
Vector: no no
Vector_Bounds: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: no no
PARAMETER_TABLE:
Parameter_Name: open_delay fall_delay
Parameter_Name: open_delay fall_delay
Description: "open delay" "fall delay"
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
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
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 family
Description: "input load value (F)" "Logic family for bridging"
Data_Type: real string
Default_Value: 1.0e-12 -
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: inertial_delay
Description: "swallow short pulses"
Data_Type: boolean
Default_Value: false
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: is_inertial
Data_Type: boolean
Description: "using inertial delay"

View File

@ -8,37 +8,30 @@ Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
AUTHORS
19 Nov 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
19 Nov 1991 Jeffrey P. Murray
SUMMARY
This file contains the functional description of the d_open_e
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,29 @@ NON-STANDARD FEATURES
/*=== INCLUDE FILES ====================*/
#include "ngspice/inertial.h"
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION cm_d_open_e()
AUTHORS
AUTHORS
19 Nov 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
19 Nov 1991 Jeffrey P. Murray
@ -88,19 +71,19 @@ SUMMARY
This function implements the d_open_e code model.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
RETURNED VALUE
Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
@ -109,6 +92,23 @@ NON-STANDARD FEATURES
==============================================================================*/
/* Find strength for given output. */
static Digital_Strength_t strength(Digital_State_t s)
{
switch (s) {
case ZERO:
return HI_IMPEDANCE;
break;
case ONE:
return STRONG;
break;
default:
return UNDETERMINED;
break;
}
}
/*=== CM_D_OPEN_E ROUTINE ===*/
/************************************************
@ -120,100 +120,106 @@ NON-STANDARD FEATURES
************************************************/
void cm_d_open_e(ARGS)
void cm_d_open_e(ARGS)
{
/*int i;*/ /* generic loop counter index */
Digital_State_t *out, /* temporary output for buffers */
*out_old; /* previous output for buffers */
Digital_State_t val,
*out; /* temporary output for buffers */
/** Setup required state variables **/
if(INIT) { /* initial pass */
if(INIT) { /* initial pass */
/* allocate storage for the outputs */
cm_event_alloc(0,sizeof(Digital_State_t));
/* define input loading... */
cm_event_alloc(0, sizeof (Digital_State_t));
/* 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, sizeof (struct idata));
((struct idata *)cm_event_get_ptr(1, 0))->when = -1.0;
}
/* Prepare initial output. */
out = (Digital_State_t *)cm_event_get_ptr(0, 0);
*out = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
LOAD(in) = PARAM(input_load);
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
}
else { /* Retrieve previous values */
} else {
/* retrieve storage for the outputs */
out = (Digital_State_t *) cm_event_get_ptr(0,0);
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
}
/** Check on analysis type **/
/*** Calculate new output value based on inputs ***/
if (ANALYSIS == DC) { /* DC analysis...output w/o delays */
OUTPUT_STATE(out) = *out = INPUT_STATE(in);
if ( ONE == *out ) {
OUTPUT_STRENGTH(out) = STRONG;
}
else
if ( ZERO == *out ) {
OUTPUT_STRENGTH(out) = HI_IMPEDANCE;
}
else {
OUTPUT_STRENGTH(out) = UNDETERMINED;
}
val = INPUT_STATE(in);
}
else { /* Transient Analysis */
/*** Check for change and output appropriate values ***/
switch ( INPUT_STATE(in) ) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = *out = ZERO;
OUTPUT_STRENGTH(out) = HI_IMPEDANCE;
OUTPUT_DELAY(out) = PARAM(open_delay);
break;
if (val == *out) { /* output value is not changing */
OUTPUT_CHANGED(out) = FALSE;
} else {
switch (val) {
/* fall to zero value */
case 0:
OUTPUT_DELAY(out) = PARAM(open_delay);
break;
/* rise to one value */
case 1: OUTPUT_STATE(out) = *out = ONE;
OUTPUT_STRENGTH(out) = STRONG;
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
/* rise to one value */
case 1:
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
default:
OUTPUT_STATE(out) = *out = UNKNOWN;
OUTPUT_STRENGTH(out) = UNDETERMINED;
/* based on old value, add rise or fall delay */
if (0 == *out_old) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
}
else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(open_delay);
}
break;
/* based on old value, add rise or fall delay */
if (0 == *out) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
} else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(open_delay);
}
break;
}
if (STATIC_VAR(is_inertial) && ANALYSIS == TRANSIENT) {
struct idata *idp;
idp = (struct idata *)cm_event_get_ptr(1, 0);
if (idp->when <= TIME) {
/* Normal transition. */
idp->prev = *out;
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else if (val != idp->prev) {
Digital_t ov = {idp->prev, strength(idp->prev)};
/* Third value: cancel earlier change and output as usual. */
cm_schedule_output(1, 0, (idp->when - TIME) / 2.0, &ov);
if (val == UNKNOWN) {
/* Delay based in idp->prev, not *out. */
if (idp->prev == ZERO)
OUTPUT_DELAY(out) = PARAM(rise_delay);
else
OUTPUT_DELAY(out) = PARAM(open_delay);
}
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else {
/* Changing back: override pending change. */
OUTPUT_DELAY(out) = (idp->when - TIME) / 2.0; // Override
idp->when = -1.0;
}
}
*out = val;
OUTPUT_STATE(out) = val;
OUTPUT_STRENGTH(out) = strength(val);
}
}
}

View File

@ -6,14 +6,14 @@ Georgia Tech Research Corporation
Atlanta, Georgia 30332
AUTHORS
AUTHORS
19 Nov 1991 Jeffrey P. Murray
SUMMARY
This file contains the interface specification file for the
This file contains the interface specification file for the
digital d_open_e code model.
===============================================================================*/
@ -32,31 +32,49 @@ Description: "input" "output"
Direction: in out
Default_Type: d d
Allowed_Types: [d] [d]
Vector: no no
Vector_Bounds: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: no no
PARAMETER_TABLE:
Parameter_Name: rise_delay open_delay
Parameter_Name: rise_delay open_delay
Description: "rise delay" "open delay"
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
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
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 family
Description: "input load value (F)" "Logic family for bridging"
Data_Type: real string
Default_Value: 1.0e-12 -
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: inertial_delay
Description: "swallow short pulses"
Data_Type: boolean
Default_Value: false
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: is_inertial
Data_Type: boolean
Description: "using inertial delay"

View File

@ -8,37 +8,30 @@ Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
AUTHORS
18 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
30 Sep 1991 Jeffrey P. Murray
SUMMARY
This file contains the functional description of the d_or
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,29 @@ NON-STANDARD FEATURES
/*=== INCLUDE FILES ====================*/
#include "ngspice/inertial.h"
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION cm_d_or()
AUTHORS
AUTHORS
18 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
30 Sep 1991 Jeffrey P. Murray
@ -88,19 +71,19 @@ SUMMARY
This function implements the d_or code model.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
RETURNED VALUE
Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
@ -119,126 +102,132 @@ NON-STANDARD FEATURES
* Created 6/18/91 J.P.Murray *
************************************************/
void cm_d_or(ARGS)
void cm_d_or(ARGS)
{
int i, /* generic loop counter index */
size; /* number of input & output ports */
size; /* number of input & output ports */
Digital_State_t *out, /* temporary output for buffers */
*out_old, /* previous output for buffers */
Digital_State_t val, /* Output value. */
*out, /* temporary output for buffers */
input; /* temp storage for input bits */
/** Retrieve size value... **/
size = PORT_SIZE(in);
/*** Setup required state variables ***/
if(INIT) { /* initial pass */
if (INIT) { /* initial pass */
/* allocate storage for the outputs */
cm_event_alloc(0,sizeof(Digital_State_t));
cm_event_alloc(0, sizeof (Digital_State_t));
/* 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, sizeof (struct idata));
((struct idata *)cm_event_get_ptr(1, 0))->when = -1.0;
}
/* Prepare initial output. */
out = (Digital_State_t *)cm_event_get_ptr(0, 0);
*out = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
for (i=0; i<size; i++) LOAD(in[i]) = PARAM(input_load);
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
}
else { /* Retrieve previous values */
} else {
/* retrieve storage for the outputs */
out = (Digital_State_t *) cm_event_get_ptr(0,0);
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
}
/*** Calculate new output value based on inputs ***/
*out = ZERO;
val = ZERO;
for (i=0; i<size; i++) {
/* If a 1, set val high, and done. */
/* make sure this input isn't floating... */
if ( FALSE == PORT_NULL(in) ) {
/* if a 1, set *out high */
if ( ONE == (input = INPUT_STATE(in[i])) ) {
*out = ONE;
break;
}
else {
/* if an unknown input, set *out to unknown & break */
if ( UNKNOWN == input ) {
*out = UNKNOWN;
}
}
}
else {
/* at least one port is floating...output is unknown */
*out = UNKNOWN;
if ( ONE == (input = INPUT_STATE(in[i])) ) {
val = ONE;
break;
} else {
/* If an unknown input, set val to unknown. */
if (UNKNOWN == input)
val = UNKNOWN;
}
}
/*** Check for change and output appropriate values ***/
if (val == *out) { /* output value is not changing */
OUTPUT_CHANGED(out) = FALSE;
} else {
switch (val) {
/*** Determine analysis type and output appropriate values ***/
if (ANALYSIS == DC) { /** DC analysis...output w/o delays **/
OUTPUT_STATE(out) = *out;
}
else { /** Transient Analysis **/
if ( *out != *out_old ) { /* output value is changing */
switch ( *out ) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = ZERO;
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
case 0:
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1: OUTPUT_STATE(out) = ONE;
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
case 1:
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
default:
OUTPUT_STATE(out) = *out = UNKNOWN;
/* based on old value, add rise or fall delay */
if (0 == *out_old) { /* add rising delay */
default:
/* based on old value, add rise or fall delay */
if (0 == *out) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
} else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
if (STATIC_VAR(is_inertial) && ANALYSIS == TRANSIENT) {
struct idata *idp;
idp = (struct idata *)cm_event_get_ptr(1, 0);
if (idp->when <= TIME) {
/* Normal transition. */
idp->prev = *out;
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else if (val != idp->prev) {
Digital_t ov = {idp->prev, STRONG};
/* Third value: cancel earlier change and output as usual. */
cm_schedule_output(1, 0, (idp->when - TIME) / 2.0, &ov);
if (val == UNKNOWN) {
/* Delay based in idp->prev, not *out. */
if (idp->prev == ZERO)
OUTPUT_DELAY(out) = PARAM(rise_delay);
}
else { /* add falling delay */
else
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else {
/* Changing back: override pending change. */
OUTPUT_DELAY(out) = (idp->when - TIME) / 2.0; // Override
idp->when = -1.0;
}
}
else { /* output value not changing */
OUTPUT_CHANGED(out) = FALSE;
}
*out = val;
OUTPUT_STATE(out) = val;
OUTPUT_STRENGTH(out) = STRONG;
}
OUTPUT_STRENGTH(out) = STRONG;
}
}

View File

@ -6,18 +6,18 @@ Georgia Tech Research Corporation
Atlanta, Georgia 30332
AUTHORS
AUTHORS
30 Sept 1991 Jeffrey P. Murray
SUMMARY
This file contains the interface specification file for the
This file contains the interface specification file for the
digital d_or code model.
===============================================================================*/
NAME_TABLE:
@ -40,24 +40,43 @@ Null_Allowed: no no
PARAMETER_TABLE:
Parameter_Name: rise_delay fall_delay
Parameter_Name: rise_delay fall_delay
Description: "rise delay" "fall delay"
Data_Type: real real
Default_Value: 1.0e-9 1.0e-9
Limits: [1e-12 -] [1e-12 -]
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
Null_Allowed: yes 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 family
Description: "input load value (F)" "Logic family for bridging"
Data_Type: real string
Default_Value: 1.0e-12 -
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: inertial_delay
Description: "swallow short pulses"
Data_Type: boolean
Default_Value: false
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: is_inertial
Data_Type: boolean
Description: "using inertial delay"

View File

@ -8,125 +8,109 @@ Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
AUTHORS
18 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
7 Aug 1991 Jeffrey P. Murray
2 Oct 1991 Jeffrey P. Murray
SUMMARY
This file contains the model-specific routines used to
functionally describe the d_xor code model.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMutil.c void cm_toggle_bit();
CMutil.c void cm_toggle_bit();
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
REFERENCED FILES
Inputs from and outputs to ARGS structure.
NON-STANDARD FEATURES
NONE
================================================================================
FUNCTION cm_toggle_bit()
AUTHORS
AUTHORS
27 Sept 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
NONE
SUMMARY
Alters the state of a passed digital variable to its
complement. Thus, a ONE changes to a ZERO. A ZERO changes
to a ONE, and an UNKNOWN remains unchanged.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
N/A N/A
RETURNED VALUE
No returned value. Passed pointer to variable is used
No returned value. Passed pointer to variable is used
to redefine the variable value.
GLOBAL VARIABLES
NONE
NONE
NON-STANDARD FEATURES
NONE
===============================================================================*/
#include "ngspice/inertial.h"
/*=== CM_TOGGLE_BIT ROUTINE ===*/
static void cm_toggle_bit(Digital_State_t *bit)
static void cm_toggle_bit(Digital_State_t *bit)
{
/* Toggle bit from ONE to ZERO or vice versa, unless the
bit value is UNKNOWN. In the latter case, return
bit value is UNKNOWN. In the latter case, return
without changing the bit value. */
if ( UNKNOWN != *bit ) {
if ( ONE == *bit ) {
*bit = ZERO;
}
else {
else {
*bit = ONE;
}
}
}
/*==============================================================================
FUNCTION cm_d_xor()
AUTHORS
AUTHORS
18 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
MODIFICATIONS
7 Aug 1991 Jeffrey P. Murray
2 Oct 1991 Jeffrey P. Murray
@ -137,30 +121,30 @@ SUMMARY
This function implements the d_xor code model.
INTERFACES
INTERFACES
FILE ROUTINE CALLED
FILE ROUTINE CALLED
CMutil.c void cm_toggle_bit();
CMutil.c void cm_toggle_bit();
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
RETURNED VALUE
Returns inputs and outputs via ARGS structure.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
NONE
===============================================================================*/
/*=== CM_D_XOR ROUTINE ===*/
@ -174,125 +158,135 @@ NON-STANDARD FEATURES
************************************************/
void cm_d_xor(ARGS)
void cm_d_xor(ARGS)
{
int i, /* generic loop counter index */
size; /* number of input & output ports */
size; /* number of input & output ports */
Digital_State_t *out, /* temporary output for buffers */
*out_old, /* previous output for buffers */
input; /* temp storage for input bits */
Digital_State_t val,
*out, /* temporary output for buffers */
input; /* temp storage for input bits */
/** Retrieve size value... **/
size = PORT_SIZE(in);
/*** Setup required state variables ***/
if(INIT) { /* initial pass */
if(INIT) { /* initial pass */
/* allocate storage for the outputs */
cm_event_alloc(0,sizeof(Digital_State_t));
cm_event_alloc(0, sizeof (Digital_State_t));
/* 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, sizeof (struct idata));
((struct idata *)cm_event_get_ptr(1, 0))->when = -1.0;
}
/* Prepare initial output. */
out = (Digital_State_t *)cm_event_get_ptr(0, 0);
*out = (Digital_State_t)(UNKNOWN + 1); // Force initial output.
for (i=0; i<size; i++) LOAD(in[i]) = PARAM(input_load);
} else { /* Retrieve previous values */
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
}
else { /* Retrieve previous values */
/* retrieve storage for the outputs */
out = (Digital_State_t *) cm_event_get_ptr(0,0);
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
}
/*** Calculate new output value based on inputs ***/
*out = ZERO;
val = ZERO;
for (i=0; i<size; i++) {
/* make sure this input isn't floating... */
if ( FALSE == PORT_NULL(in) ) {
/* if a 1, toggle bit value */
if ( ONE == (input = INPUT_STATE(in[i])) ) {
cm_toggle_bit(out);
}
else {
/* if an unknown input, set *out to unknown & break */
if ( UNKNOWN == input ) {
*out = UNKNOWN;
break;
}
/* if a 1, toggle bit value */
if ( ONE == (input = INPUT_STATE(in[i])) ) {
cm_toggle_bit(&val);
} else {
/* if an unknown input, set val to unknown & break */
if ( UNKNOWN == input ) {
val = UNKNOWN;
break;
}
}
else {
/* at least one port is floating...output is unknown */
*out = UNKNOWN;
}
/*** Check for change and output appropriate values ***/
if (val == *out) { /* output value is not changing */
OUTPUT_CHANGED(out) = FALSE;
} else {
switch (val) {
/* fall to zero value */
case 0:
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1:
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
default:
/* based on old value, add rise or fall delay */
if (0 == *out) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
} else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
}
if (STATIC_VAR(is_inertial) && ANALYSIS == TRANSIENT) {
struct idata *idp;
idp = (struct idata *)cm_event_get_ptr(1, 0);
if (idp->when <= TIME) {
/* Normal transition. */
/*** Determine analysis type and output appropriate values ***/
idp->prev = *out;
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else if (val != idp->prev) {
Digital_t ov = {idp->prev, STRONG};
if (ANALYSIS == DC) { /** DC analysis...output w/o delays **/
OUTPUT_STATE(out) = *out;
/* Third value: cancel earlier change and output as usual. */
}
cm_schedule_output(1, 0, (idp->when - TIME) / 2.0, &ov);
if (val == UNKNOWN) {
/* Delay based in idp->prev, not *out. */
else { /** Transient Analysis **/
if ( *out != *out_old ) { /* output value is changing */
switch ( *out ) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = ZERO;
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1: OUTPUT_STATE(out) = ONE;
OUTPUT_DELAY(out) = PARAM(rise_delay);
break;
/* unknown output */
default:
OUTPUT_STATE(out) = *out = UNKNOWN;
/* based on old value, add rise or fall delay */
if (0 == *out_old) { /* add rising delay */
if (idp->prev == ZERO)
OUTPUT_DELAY(out) = PARAM(rise_delay);
}
else { /* add falling delay */
else
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
idp->when = TIME + OUTPUT_DELAY(out); // Actual output time
} else {
/* Changing back: override pending change. */
OUTPUT_DELAY(out) = (idp->when - TIME) / 2.0; // Override
idp->when = -1.0;
}
}
else { /* output value not changing */
OUTPUT_CHANGED(out) = FALSE;
}
*out = val;
OUTPUT_STATE(out) = val;
OUTPUT_STRENGTH(out) = STRONG;
}
OUTPUT_STRENGTH(out) = STRONG;
}
}

View File

@ -6,18 +6,18 @@ Georgia Tech Research Corporation
Atlanta, Georgia 30332
AUTHORS
AUTHORS
2 Oct 1991 Jeffrey P. Murray
SUMMARY
This file contains the interface specification file for the
This file contains the interface specification file for the
digital d_xor code model.
===============================================================================*/
NAME_TABLE:
@ -40,24 +40,40 @@ Null_Allowed: no no
PARAMETER_TABLE:
Parameter_Name: rise_delay fall_delay
Parameter_Name: rise_delay fall_delay
Description: "rise delay" "fall delay"
Data_Type: real real
Default_Value: 1.0e-9 1.0e-9
Limits: [1e-12 -] [1e-12 -]
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
Null_Allowed: yes 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 family
Description: "input load value (F)" "Logic family for bridging"
Data_Type: real string
Default_Value: 1.0e-12 -
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: inertial_delay
Description: "swallow short pulses"
Data_Type: boolean
Default_Value: false
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: is_inertial
Data_Type: boolean
Description: "using inertial delay"