Add inertial delay to missed d_xnor and tidy blank lines in d_xor.
This commit is contained in:
parent
cecce5163e
commit
e25f8bd522
|
|
@ -8,40 +8,33 @@ 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_xnor 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
|
||||
|
||||
|
|
@ -51,142 +44,116 @@ NON-STANDARD FEATURES
|
|||
|
||||
/*=== INCLUDE FILES ====================*/
|
||||
|
||||
|
||||
|
||||
#include "ngspice/inertial.h"
|
||||
|
||||
/*=== CONSTANTS ========================*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*=== MACROS ===========================*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
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
|
||||
|
||||
|
||||
===============================================================================*/
|
||||
|
||||
/*=== 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_xnor()
|
||||
|
||||
|
||||
AUTHORS
|
||||
AUTHORS
|
||||
|
||||
18 Jun 1991 Jeffrey P. Murray
|
||||
|
||||
|
||||
MODIFICATIONS
|
||||
MODIFICATIONS
|
||||
|
||||
7 Aug 1991 Jeffrey P. Murray
|
||||
2 Oct 1991 Jeffrey P. Murray
|
||||
|
||||
|
||||
SUMMARY
|
||||
|
||||
This function implements the d_xnor 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
|
||||
|
||||
NONE
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
NONE
|
||||
|
||||
|
||||
===============================================================================*/
|
||||
|
||||
/*=== CM_D_XNOR ROUTINE ===*/
|
||||
|
|
@ -199,126 +166,129 @@ NON-STANDARD FEATURES
|
|||
* Created 6/18/91 J.P.Murray *
|
||||
************************************************/
|
||||
|
||||
|
||||
void cm_d_xnor(ARGS)
|
||||
|
||||
void cm_d_xnor(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 = ONE;
|
||||
val = ONE;
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_xnor code model.
|
||||
|
||||
===============================================================================*/
|
||||
|
||||
|
||||
NAME_TABLE:
|
||||
|
||||
|
||||
|
|
@ -33,31 +33,49 @@ Description: "input" "output"
|
|||
Direction: in out
|
||||
Default_Type: d d
|
||||
Allowed_Types: [d] [d]
|
||||
Vector: yes no
|
||||
Vector_Bounds: [2 -] -
|
||||
Vector: yes no
|
||||
Vector_Bounds: [2 -] -
|
||||
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 (pF)"
|
||||
Data_Type: real
|
||||
Default_Value: 1.0
|
||||
Limits: [0.0 -]
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -157,9 +157,7 @@ NON-STANDARD FEATURES
|
|||
* Created 6/18/91 J.P.Murray *
|
||||
************************************************/
|
||||
|
||||
|
||||
void cm_d_xor(ARGS)
|
||||
|
||||
{
|
||||
int i, /* generic loop counter index */
|
||||
size; /* number of input & output ports */
|
||||
|
|
@ -285,8 +283,3 @@ void cm_d_xor(ARGS)
|
|||
OUTPUT_STRENGTH(out) = STRONG;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue