First group of digital code models with improved implementation
of inertial delay: buffer, inverter, and, nor. Also adds utility function cm_is_inertial(().
This commit is contained in:
parent
a9270aa312
commit
22f3690fa4
|
|
@ -14,31 +14,25 @@ AUTHORS
|
||||||
|
|
||||||
14 June 1991 Jeffrey P. Murray
|
14 June 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
|
||||||
MODIFICATIONS
|
MODIFICATIONS
|
||||||
|
|
||||||
27 Sept 1991 Jeffrey P. Murray
|
27 Sept 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
|
||||||
SUMMARY
|
SUMMARY
|
||||||
|
|
||||||
This file contains the functional description of the d_and
|
This file contains the functional description of the d_and
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -53,29 +47,16 @@ NON-STANDARD FEATURES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ngspice/inertial.h"
|
||||||
|
|
||||||
/*=== CONSTANTS ========================*/
|
/*=== CONSTANTS ========================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=== MACROS ===========================*/
|
/*=== MACROS ===========================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
|
|
||||||
FUNCTION cm_d_and()
|
FUNCTION cm_d_and()
|
||||||
|
|
@ -94,13 +75,13 @@ SUMMARY
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
RETURNED VALUE
|
RETURNED VALUE
|
||||||
|
|
||||||
Returns inputs and outputs via ARGS structure.
|
Returns inputs and outputs via ARGS structure.
|
||||||
|
|
||||||
GLOBAL VARIABLES
|
GLOBAL VARIABLES
|
||||||
|
|
@ -123,124 +104,123 @@ NON-STANDARD FEATURES
|
||||||
* Created 6/14/91 J.P.Murray *
|
* Created 6/14/91 J.P.Murray *
|
||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
|
|
||||||
void cm_d_and(ARGS)
|
void cm_d_and(ARGS)
|
||||||
|
|
||||||
{
|
{
|
||||||
int i, /* generic loop counter index */
|
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 */
|
Digital_State_t val, /* Output value. */
|
||||||
*out_old, /* previous output for buffers */
|
*out, /* temporary output for buffers */
|
||||||
input; /* temp storage for input bits */
|
input; /* temp storage for input bits */
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve size value... **/
|
/** Retrieve size value... **/
|
||||||
size = PORT_SIZE(in);
|
size = PORT_SIZE(in);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*** Setup required state variables ***/
|
/*** Setup required state variables ***/
|
||||||
|
|
||||||
if(INIT) { /* initial pass */
|
if(INIT) { /* initial pass */
|
||||||
|
|
||||||
/* allocate storage for the outputs */
|
/* allocate storage for the outputs */
|
||||||
|
|
||||||
cm_event_alloc(0,sizeof(Digital_State_t));
|
cm_event_alloc(0,sizeof(Digital_State_t));
|
||||||
|
|
||||||
/* set loading for inputs */
|
/* 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);
|
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 */
|
/* retrieve storage for the outputs */
|
||||||
out = (Digital_State_t *) cm_event_get_ptr(0,0);
|
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 ***/
|
/*** Calculate new output value based on inputs ***/
|
||||||
|
|
||||||
*out = ONE;
|
val = ONE;
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
|
/* if a 0, set val low */
|
||||||
|
|
||||||
/* make sure this input isn't floating... */
|
if ( ZERO == (input = INPUT_STATE(in[i])) ) {
|
||||||
if ( FALSE == PORT_NULL(in) ) {
|
val = ZERO;
|
||||||
|
|
||||||
/* if a 0, set *out low */
|
|
||||||
if ( ZERO == (input = INPUT_STATE(in[i])) ) {
|
|
||||||
*out = ZERO;
|
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
/* if an unknown input, set val 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 { /* output value not changing */
|
||||||
|
switch (val) {
|
||||||
|
|
||||||
if ( *out != *out_old ) { /* output value is changing */
|
|
||||||
|
|
||||||
switch ( *out ) {
|
|
||||||
|
|
||||||
/* fall to zero value */
|
/* fall to zero value */
|
||||||
case 0: OUTPUT_STATE(out) = ZERO;
|
case 0:
|
||||||
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* rise to one value */
|
/* rise to one value */
|
||||||
case 1: OUTPUT_STATE(out) = ONE;
|
case 1:
|
||||||
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* unknown output */
|
/* unknown output */
|
||||||
default:
|
default:
|
||||||
OUTPUT_STATE(out) = *out = UNKNOWN;
|
OUTPUT_STATE(out) = UNKNOWN;
|
||||||
|
|
||||||
/* based on old value, add rise or fall delay */
|
/* 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);
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
}
|
} else { /* add falling delay */
|
||||||
else { /* add falling delay */
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
}
|
||||||
}
|
break;
|
||||||
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);
|
||||||
|
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 */
|
*out = val;
|
||||||
OUTPUT_CHANGED(out) = FALSE;
|
OUTPUT_STATE(out) = val;
|
||||||
}
|
OUTPUT_STRENGTH(out) = STRONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT_STRENGTH(out) = STRONG;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ Description: "input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: d d
|
Default_Type: d d
|
||||||
Allowed_Types: [d] [d]
|
Allowed_Types: [d] [d]
|
||||||
Vector: yes no
|
Vector: yes no
|
||||||
Vector_Bounds: [2 -] -
|
Vector_Bounds: [2 -] -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,12 +52,28 @@ Null_Allowed: yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
Parameter_Name: input_load
|
Parameter_Name: input_load family
|
||||||
Description: "input load value (F)"
|
Description: "input load value (F)" "Logic family for bridging"
|
||||||
Data_Type: real
|
Data_Type: real string
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12 -
|
||||||
Limits: -
|
Limits: - -
|
||||||
Vector: no
|
Vector: no no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes
|
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"
|
||||||
|
|
|
||||||
|
|
@ -9,36 +9,29 @@ Georgia Tech Research Corporation
|
||||||
Atlanta, Georgia 30332
|
Atlanta, Georgia 30332
|
||||||
PROJECT A-8503-405
|
PROJECT A-8503-405
|
||||||
|
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
|
|
||||||
14 June 1991 Jeffrey P. Murray
|
14 June 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
MODIFICATIONS
|
||||||
MODIFICATIONS
|
|
||||||
|
|
||||||
27 Sept 1991 Jeffrey P. Murray
|
27 Sept 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
|
||||||
SUMMARY
|
SUMMARY
|
||||||
|
|
||||||
This file contains the functional description of the d_buffer
|
This file contains the functional description of the d_buffer
|
||||||
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,25 @@ 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_buffer()
|
FUNCTION cm_d_buffer()
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
|
|
||||||
14 Jun 1991 Jeffrey P. Murray
|
14 Jun 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
MODIFICATIONS
|
MODIFICATIONS
|
||||||
|
|
||||||
27 Sep 1991 Jeffrey P. Murray
|
27 Sep 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
|
@ -88,7 +67,7 @@ SUMMARY
|
||||||
|
|
||||||
This function implements the d_buffer code model.
|
This function implements the d_buffer code model.
|
||||||
|
|
||||||
INTERFACES
|
INTERFACES
|
||||||
|
|
||||||
FILE ROUTINE CALLED
|
FILE ROUTINE CALLED
|
||||||
|
|
||||||
|
|
@ -96,7 +75,7 @@ INTERFACES
|
||||||
void *cm_event_get_ptr()
|
void *cm_event_get_ptr()
|
||||||
|
|
||||||
RETURNED VALUE
|
RETURNED VALUE
|
||||||
|
|
||||||
Returns inputs and outputs via ARGS structure.
|
Returns inputs and outputs via ARGS structure.
|
||||||
|
|
||||||
GLOBAL VARIABLES
|
GLOBAL VARIABLES
|
||||||
|
|
@ -119,78 +98,94 @@ NON-STANDARD FEATURES
|
||||||
* Created 6/14/91 J.P,Murray *
|
* Created 6/14/91 J.P,Murray *
|
||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
|
void cm_d_buffer(ARGS)
|
||||||
void cm_d_buffer(ARGS)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/*int i;*/ /* generic loop counter index */
|
Digital_State_t val, /* Output value. */
|
||||||
|
*out; /* Previous value */
|
||||||
|
|
||||||
|
|
||||||
Digital_State_t *out, /* temporary output for buffers */
|
|
||||||
*out_old; /* previous output for buffers */
|
|
||||||
|
|
||||||
|
|
||||||
/** Setup required state variables **/
|
/** Setup required state variables **/
|
||||||
|
|
||||||
if(INIT) { /* initial pass */
|
if(INIT) { /* initial pass */
|
||||||
|
|
||||||
/* allocate storage for the outputs */
|
/* 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.
|
||||||
|
|
||||||
/* define input loading... */
|
/* define input loading... */
|
||||||
LOAD(in) = PARAM(input_load);
|
LOAD(in) = PARAM(input_load);
|
||||||
|
} else { /* Retrieve previous values */
|
||||||
/* retrieve storage for the outputs */
|
/* 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 = (Digital_State_t *) cm_event_get_ptr(0,0);
|
||||||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = INPUT_STATE(in);
|
||||||
/** Check on analysis type **/
|
if (val == *out) {
|
||||||
|
/* output value not changing */
|
||||||
|
|
||||||
if (ANALYSIS == DC) { /* DC analysis...output w/o delays */
|
OUTPUT_CHANGED(out) = FALSE;
|
||||||
|
} else {
|
||||||
OUTPUT_STATE(out) = *out = INPUT_STATE(in);
|
switch (val) {
|
||||||
|
|
||||||
}
|
|
||||||
else { /* Transient Analysis */
|
|
||||||
|
|
||||||
switch ( INPUT_STATE(in) ) {
|
|
||||||
|
|
||||||
/* fall to zero value */
|
/* fall to zero value */
|
||||||
case 0: OUTPUT_STATE(out) = *out = ZERO;
|
case 0: OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* rise to one value */
|
/* rise to one value */
|
||||||
case 1: OUTPUT_STATE(out) = *out = ONE;
|
case 1: OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* unknown output */
|
/* unknown output */
|
||||||
default:
|
default:
|
||||||
OUTPUT_STATE(out) = *out = UNKNOWN;
|
|
||||||
|
|
||||||
/* based on old value, add rise or fall delay */
|
/* 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);
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
}
|
else /* add falling delay */
|
||||||
else { /* add falling delay */
|
|
||||||
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
}
|
|
||||||
break;
|
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);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
OUTPUT_STRENGTH(out) = STRONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,15 +48,30 @@ Vector: no no
|
||||||
Vector_Bounds: - -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
|
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_TABLE:
|
||||||
|
|
||||||
Parameter_Name: input_load
|
Parameter_Name: inertial_delay
|
||||||
Description: "input load value (F)"
|
Description: "swallow short pulses"
|
||||||
Data_Type: real
|
Data_Type: boolean
|
||||||
Default_Value: 1.0e-12
|
Default_Value: false
|
||||||
Limits: -
|
Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
STATIC_VAR_TABLE:
|
||||||
|
|
||||||
|
Static_Var_Name: is_inertial
|
||||||
|
Data_Type: boolean
|
||||||
|
Description: "using inertial delay"
|
||||||
|
|
|
||||||
|
|
@ -8,36 +8,31 @@ 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
|
||||||
|
|
||||||
14 Jun 1991 Jeffrey P. Murray
|
14 Jun 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
|
||||||
MODIFICATIONS
|
MODIFICATIONS
|
||||||
|
|
||||||
30 Sep 1991 Jeffrey P. Murray
|
30 Sep 1991 Jeffrey P. Murray
|
||||||
|
a
|
||||||
|
|
||||||
SUMMARY
|
SUMMARY
|
||||||
|
|
||||||
This file contains the functional description of the <model_name>
|
This file contains the functional description of the <model_name>
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -52,38 +47,25 @@ NON-STANDARD FEATURES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ngspice/inertial.h"
|
||||||
|
|
||||||
/*=== CONSTANTS ========================*/
|
/*=== CONSTANTS ========================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=== MACROS ===========================*/
|
/*=== MACROS ===========================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
|
|
||||||
FUNCTION cm_d_inverter()
|
FUNCTION cm_d_inverter()
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
|
|
||||||
14 Jun 1991 Jeffrey P. Murray
|
14 Jun 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
MODIFICATIONS
|
MODIFICATIONS
|
||||||
|
|
||||||
30 Sep 1991 Jeffrey P. Murray
|
30 Sep 1991 Jeffrey P. Murray
|
||||||
|
|
||||||
|
|
@ -91,13 +73,12 @@ SUMMARY
|
||||||
|
|
||||||
This function implements the d_inverter code model.
|
This function implements the d_inverter 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()
|
||||||
|
|
||||||
RETURNED VALUE
|
RETURNED VALUE
|
||||||
|
|
||||||
Returns inputs and outputs via ARGS structure.
|
Returns inputs and outputs via ARGS structure.
|
||||||
|
|
@ -122,92 +103,99 @@ NON-STANDARD FEATURES
|
||||||
* Created 6/14/91 J.P.Murray *
|
* Created 6/14/91 J.P.Murray *
|
||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
|
|
||||||
void cm_d_inverter(ARGS)
|
void cm_d_inverter(ARGS)
|
||||||
|
|
||||||
{
|
{
|
||||||
/*int i;*/ /* generic loop counter index */
|
Digital_State_t val, /* Output value. */
|
||||||
|
*out; /* Previous output. */
|
||||||
|
|
||||||
|
|
||||||
Digital_State_t *out, /* temporary output for inverter */
|
|
||||||
*out_old; /* previous output for inverter */
|
|
||||||
|
|
||||||
|
|
||||||
/** Setup required state variables **/
|
/** Setup required state variables **/
|
||||||
|
|
||||||
if(INIT) { /* initial pass */
|
if(INIT) { /* initial pass */
|
||||||
|
/* allocate storage for the output */
|
||||||
|
|
||||||
/* 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.
|
||||||
|
|
||||||
/* define load value on inputs */
|
/* define load value on inputs */
|
||||||
LOAD(in) = PARAM(input_load);
|
LOAD(in) = 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 */
|
/* retrieve storage for the outputs */
|
||||||
out = (Digital_State_t *) cm_event_get_ptr(0,0);
|
out = (Digital_State_t *) cm_event_get_ptr(0,0);
|
||||||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = INPUT_STATE(in);
|
||||||
/** Check on analysis type **/
|
if (val != UNKNOWN)
|
||||||
|
val = !val;
|
||||||
|
|
||||||
if (ANALYSIS == DC) { /* DC analysis...output w/o delays */
|
/*** Check for change and output appropriate values ***/
|
||||||
|
|
||||||
switch ( INPUT_STATE(in) ) {
|
|
||||||
|
|
||||||
case ZERO:
|
if (val == *out) { /* output value is changing */
|
||||||
OUTPUT_STATE(out) = *out = *out_old = ONE;
|
OUTPUT_CHANGED(out) = FALSE;
|
||||||
|
} else { /* output value not changing */
|
||||||
|
switch (val) {
|
||||||
|
|
||||||
|
/* fall to zero value */
|
||||||
|
case 0:
|
||||||
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONE:
|
/* rise to one value */
|
||||||
OUTPUT_STATE(out) = *out = *out_old = ZERO;
|
case 1:
|
||||||
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* unknown output */
|
||||||
default:
|
default:
|
||||||
OUTPUT_STATE(out) = *out = *out_old = UNKNOWN;
|
/* based on old value, add rise or fall delay */
|
||||||
break;
|
if (0 == *out) { /* add rising delay */
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else { /* Transient Analysis */
|
|
||||||
|
|
||||||
switch ( INPUT_STATE(in) ) {
|
|
||||||
|
|
||||||
/* fall to zero value */
|
|
||||||
case 1: OUTPUT_STATE(out) = *out = ZERO;
|
|
||||||
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* rise to one value */
|
|
||||||
case 0: OUTPUT_STATE(out) = *out = ONE;
|
|
||||||
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
break;
|
} else { /* add falling delay */
|
||||||
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
/* unknown output */
|
}
|
||||||
default:
|
break;
|
||||||
OUTPUT_STATE(out) = *out = UNKNOWN;
|
|
||||||
|
|
||||||
/* 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(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);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
OUTPUT_STRENGTH(out) = STRONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,18 @@ Vector_Bounds: - -
|
||||||
Null_Allowed: yes yes
|
Null_Allowed: yes yes
|
||||||
|
|
||||||
|
|
||||||
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
Parameter_Name: input_load
|
Parameter_Name: input_load
|
||||||
|
|
@ -61,3 +73,10 @@ Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_VAR_TABLE:
|
||||||
|
|
||||||
|
Static_Var_Name: is_inertial
|
||||||
|
Data_Type: boolean
|
||||||
|
Description: "using inertial delay"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,29 +48,20 @@ 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_nor()
|
FUNCTION cm_d_nor()
|
||||||
|
|
@ -119,126 +110,120 @@ NON-STANDARD FEATURES
|
||||||
* Created 6/18/91 J.P.Murray *
|
* Created 6/18/91 J.P.Murray *
|
||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
|
|
||||||
void cm_d_nor(ARGS)
|
void cm_d_nor(ARGS)
|
||||||
|
|
||||||
{
|
{
|
||||||
int i, /* generic loop counter index */
|
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 */
|
Digital_State_t val, /* Output value. */
|
||||||
*out_old, /* previous output for buffers */
|
*out, /* temporary output for buffers */
|
||||||
input; /* temp storage for input bits */
|
input; /* temp storage for input bits */
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve size value... **/
|
/** Retrieve size value... **/
|
||||||
size = PORT_SIZE(in);
|
size = PORT_SIZE(in);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*** Setup required state variables ***/
|
/*** Setup required state variables ***/
|
||||||
|
|
||||||
if(INIT) { /* initial pass */
|
if (INIT) { /* initial pass */
|
||||||
|
|
||||||
/* allocate storage for the outputs */
|
/* 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);
|
for (i=0; i<size; i++) LOAD(in[i]) = PARAM(input_load);
|
||||||
|
} else {
|
||||||
/* 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 */
|
/* retrieve storage for the outputs */
|
||||||
out = (Digital_State_t *) cm_event_get_ptr(0,0);
|
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 ***/
|
/*** Calculate new output value based on inputs ***/
|
||||||
|
|
||||||
*out = ONE;
|
val = ONE;
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
|
/* If a 1, set val low, and done. */
|
||||||
|
|
||||||
/* make sure this input isn't floating... */
|
if ( ONE == (input = INPUT_STATE(in[i])) ) {
|
||||||
if ( FALSE == PORT_NULL(in) ) {
|
val = ZERO;
|
||||||
|
|
||||||
/* if a 1, set *out low */
|
|
||||||
if ( ONE == (input = INPUT_STATE(in[i])) ) {
|
|
||||||
*out = ZERO;
|
|
||||||
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;
|
|
||||||
break;
|
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 { /* output value not changing */
|
||||||
|
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 */
|
/* fall to zero value */
|
||||||
case 0: OUTPUT_STATE(out) = ZERO;
|
case 0:
|
||||||
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* rise to one value */
|
/* rise to one value */
|
||||||
case 1: OUTPUT_STATE(out) = ONE;
|
case 1:
|
||||||
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* unknown output */
|
/* unknown output */
|
||||||
default:
|
default:
|
||||||
OUTPUT_STATE(out) = *out = UNKNOWN;
|
/* based on old value, add rise or fall delay */
|
||||||
|
if (0 == *out) { /* add rising delay */
|
||||||
/* based on old value, add rise or fall delay */
|
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
||||||
if (0 == *out_old) { /* add rising delay */
|
} else { /* add falling delay */
|
||||||
OUTPUT_DELAY(out) = PARAM(rise_delay);
|
OUTPUT_DELAY(out) = PARAM(fall_delay);
|
||||||
}
|
}
|
||||||
else { /* add falling delay */
|
break;
|
||||||
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);
|
||||||
|
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 */
|
*out = val;
|
||||||
OUTPUT_CHANGED(out) = FALSE;
|
OUTPUT_STATE(out) = val;
|
||||||
}
|
OUTPUT_STRENGTH(out) = STRONG;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
OUTPUT_STRENGTH(out) = STRONG;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ Description: "input" "output"
|
||||||
Direction: in out
|
Direction: in out
|
||||||
Default_Type: d d
|
Default_Type: d d
|
||||||
Allowed_Types: [d] [d]
|
Allowed_Types: [d] [d]
|
||||||
Vector: yes no
|
Vector: yes no
|
||||||
Vector_Bounds: [2 -] -
|
Vector_Bounds: [2 -] -
|
||||||
Null_Allowed: no no
|
Null_Allowed: no no
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,12 +52,28 @@ Null_Allowed: yes yes
|
||||||
|
|
||||||
PARAMETER_TABLE:
|
PARAMETER_TABLE:
|
||||||
|
|
||||||
Parameter_Name: input_load
|
Parameter_Name: input_load family
|
||||||
Description: "input load value (pF)"
|
Description: "input load value (F)" "Logic family for bridging"
|
||||||
Data_Type: real
|
Data_Type: real string
|
||||||
Default_Value: 1.0e-12
|
Default_Value: 1.0e-12 -
|
||||||
Limits: -
|
Limits: - -
|
||||||
Vector: no
|
Vector: no no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: - -
|
||||||
Null_Allowed: yes
|
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"
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "ngspice/dllitf.h"
|
#include "ngspice/dllitf.h"
|
||||||
#include "ngspice/evtudn.h"
|
#include "ngspice/evtudn.h"
|
||||||
#include "ngspice/inpdefs.h"
|
#include "ngspice/inpdefs.h"
|
||||||
|
#include "ngspice/inertial.h"
|
||||||
#include "cmextrn.h"
|
#include "cmextrn.h"
|
||||||
#include "udnextrn.h"
|
#include "udnextrn.h"
|
||||||
|
|
||||||
|
|
@ -547,3 +548,24 @@ cm_message_printf(const char *fmt, ...)
|
||||||
txfree(p);
|
txfree(p);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Function used for inertial delay in digital logic models. */
|
||||||
|
|
||||||
|
Mif_Boolean_t cm_is_inertial(enum param_vals param)
|
||||||
|
{
|
||||||
|
int cvar;
|
||||||
|
|
||||||
|
/* Get the value of the control variable. */
|
||||||
|
|
||||||
|
if (cm_getvar("digital_delay_type", CP_NUM, &cvar, sizeof cvar)) {
|
||||||
|
if (cvar >= OVERRIDE_TRANSPORT) {
|
||||||
|
/* Parameter override. */
|
||||||
|
|
||||||
|
return cvar > OVERRIDE_TRANSPORT;
|
||||||
|
}
|
||||||
|
if (param == Not_set) // Not specified
|
||||||
|
return cvar != DEFAULT_TRANSPORT;
|
||||||
|
return param != Off;
|
||||||
|
}
|
||||||
|
return param == On;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue