Browse Source

Add inertial delay to missed d_xnor and tidy blank lines in d_xor.

pre-master-46
Giles Atkinson 3 years ago
committed by Holger Vogt
parent
commit
e25f8bd522
  1. 158
      src/xspice/icm/digital/d_xnor/cfunc.mod
  2. 28
      src/xspice/icm/digital/d_xnor/ifspec.ifs
  3. 7
      src/xspice/icm/digital/d_xor/cfunc.mod

158
src/xspice/icm/digital/d_xnor/cfunc.mod

@ -9,24 +9,20 @@ Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503-405
AUTHORS
18 Jun 1991 Jeffrey P. Murray
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
FILE ROUTINE CALLED
@ -36,13 +32,10 @@ INTERFACES
CMevt.c void *cm_event_alloc()
void *cm_event_get_ptr()
REFERENCED FILES
Inputs from and outputs to ARGS structure.
NON-STANDARD FEATURES
NONE
@ -51,70 +44,53 @@ NON-STANDARD FEATURES
/*=== INCLUDE FILES ====================*/
#include "ngspice/inertial.h"
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION cm_toggle_bit()
AUTHORS
27 Sept 1991 Jeffrey P. Murray
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
FILE ROUTINE CALLED
N/A N/A
RETURNED VALUE
No returned value. Passed pointer to variable is used
to redefine the variable value.
GLOBAL VARIABLES
NONE
NON-STANDARD FEATURES
NONE
@ -124,7 +100,6 @@ NON-STANDARD FEATURES
/*=== CM_TOGGLE_BIT ROUTINE ===*/
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
@ -138,7 +113,6 @@ static void cm_toggle_bit(Digital_State_t *bit)
*bit = ONE;
}
}
}
@ -146,23 +120,19 @@ static void cm_toggle_bit(Digital_State_t *bit)
FUNCTION cm_d_xnor()
AUTHORS
18 Jun 1991 Jeffrey P. Murray
MODIFICATIONS
7 Aug 1991 Jeffrey P. Murray
2 Oct 1991 Jeffrey P. Murray
SUMMARY
This function implements the d_xnor code model.
INTERFACES
FILE ROUTINE CALLED
@ -172,17 +142,14 @@ INTERFACES
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
@ -199,126 +166,129 @@ NON-STANDARD FEATURES
* Created 6/18/91 J.P.Murray *
************************************************/
void cm_d_xnor(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 */
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 */
/* allocate storage for the outputs */
cm_event_alloc(0, sizeof (Digital_State_t));
for (i=0; i<size; i++) LOAD(in[i]) = PARAM(input_load);
/* Inertial delay? */
/* retrieve storage for the outputs */
out = out_old = (Digital_State_t *) cm_event_get_ptr(0,0);
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;
}
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);
}
/* 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 = (Digital_State_t *) cm_event_get_ptr(0,0);
}
/*** 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 */
cm_toggle_bit(&val);
} else {
/* if an unknown input, set val to unknown & break */
if ( UNKNOWN == input ) {
*out = UNKNOWN;
break;
}
}
}
else {
/* at least one port is floating...output is unknown */
*out = UNKNOWN;
val = UNKNOWN;
break;
}
}
/*** 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 ( *out != *out_old ) { /* output value is changing */
switch ( *out ) {
if (val == *out) { /* output value is not changing */
OUTPUT_CHANGED(out) = FALSE;
} else {
switch (val) {
/* fall to zero value */
case 0: OUTPUT_STATE(out) = ZERO;
case 0:
OUTPUT_DELAY(out) = PARAM(fall_delay);
break;
/* rise to one value */
case 1: OUTPUT_STATE(out) = ONE;
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 */
if (0 == *out) { /* add rising delay */
OUTPUT_DELAY(out) = PARAM(rise_delay);
}
else { /* add falling delay */
} else { /* add falling delay */
OUTPUT_DELAY(out) = PARAM(fall_delay);
}
break;
}
}
else { /* output value not changing */
OUTPUT_CHANGED(out) = FALSE;
}
}
OUTPUT_STRENGTH(out) = STRONG;
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
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) = STRONG;
}
}

28
src/xspice/icm/digital/d_xnor/ifspec.ifs

@ -52,12 +52,30 @@ 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 -]
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"

7
src/xspice/icm/digital/d_xor/cfunc.mod

@ -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…
Cancel
Save