add d_const and da_switch code models

This commit is contained in:
Florian Ballenegger 2020-10-06 23:53:10 +02:00
parent c674c83440
commit 043484a19d
4 changed files with 391 additions and 0 deletions

View File

@ -0,0 +1,86 @@
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
AUTHORS
18 Nov 2019 Florian Ballenegger, Anamosic Ballenegger Design
SUMMARY
This file contains the functional description of the d_const
code model.
"word" string format: optional prefix 'h'=hex or 'd'=decimal
Output vector is LSB first (little endian)
===============================================================================*/
#include <string.h>
#include <stdlib.h>
void cm_d_const(ARGS)
{
unsigned int i,n,x;
char *str;
Digital_Strength_t strength;
Digital_State_t* vec;
n = (unsigned int) PORT_SIZE(out);
strength = UNDETERMINED;
if(INIT) {
str = PARAM(strength);
if(strcmp(str,"s")==0)
strength = STRONG;
else if(strcmp(str,"r")==0)
strength = RESISTIVE;
else if(strcmp(str,"h")==0)
strength = HI_IMPEDANCE;
else if(strcmp(str,"u")==0)
strength = UNDETERMINED;
else {
cm_message_send("Unknown strength string");
cm_message_send(PARAM(strength));
}
STATIC_VAR(locstrength) = (int) strength;
str = PARAM(word);
if(str[0]!='h' && str[0]!='d')
if(strlen(str)!=n)
cm_message_send("Mismatch between word string value length and output vector bus width");
vec = (Digital_State_t*) calloc(n, sizeof(Digital_State_t));
STATIC_VAR(locvec) = vec;
if(str[0]=='d') {
x = (unsigned int) atoi(&str[1]);
for(i=0;i<n;i++)
vec[i] = (x & (1<<i)) ? ONE : ZERO;
} else if(str[0]=='h') {
x = (unsigned int) strtol(&str[1],NULL,16);
for(i=0;i<n;i++)
vec[i] = (x & (1<<i)) ? ONE : ZERO;
} else for(i=0;i<n;i++) {
switch(str[i]){
case '0':
vec[i] = ZERO;
break;
case '1':
vec[i] = ONE;
break;
default:
vec[i] = UNKNOWN;
}
}
}
if(1) {
strength = (Digital_Strength_t) STATIC_VAR(locstrength);
vec = (Digital_State_t*) STATIC_VAR(locvec);
for(i=0;i<n;i++) {
OUTPUT_STATE(out[i]) = vec[i];
OUTPUT_STRENGTH(out[i]) = strength;
}
}
}

View File

@ -0,0 +1,56 @@
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
Copyright 1991
Georgia Tech Research Corporation, Atlanta, Ga. 30332
All Rights Reserved
AUTHORS
19 Nov 1991 Jeffrey P. Murray
18 Nov 2019 Florian Ballenegger
SUMMARY
This file contains the interface specification file for the
digital d_const code model.
===============================================================================*/
NAME_TABLE:
Spice_Model_Name: d_const
C_Function_Name: cm_d_const
Description: "digital constant source"
PORT_TABLE:
Port_Name: out
Description: "output"
Direction: out
Default_Type: d
Allowed_Types: [d]
Vector: yes
Vector_Bounds: -
Null_Allowed: no
PARAMETER_TABLE:
Parameter_Name: word strength
Description: "binary output value" "output strength"
Data_Type: string string
Default_Value: "0s" "s"
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: no no
Parameter_Scope: both both
STATIC_VAR_TABLE:
Static_Var_Name: locstrength locvec
Description: "decoded strength" "pre-decoded state vector"
Data_Type: int pointer

View File

@ -0,0 +1,185 @@
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
FILE da_switch/cfunc.mod
(C) 2019 Anamosic Ballenegger Design
Based on aswitch code model by Georgia Tech.
Copyright 1991
Georgia Tech Research Corporation, Atlanta, Ga. 30332
All Rights Reserved
PROJECT A-8503-405
===============================================================================*/
/*=== INCLUDE FILES ====================*/
#include <math.h>
/*============================================================================*/
void cm_da_switch(ARGS)
{
double
r, rinv, ron, roff; /* ON and OFF resistances of the switch */
Mif_Complex_t ac_gain;
int i, /* generic loop counter index */
size; /* number of input & output ports */
Digital_State_t *in, /* base address of array holding all input
values */
*in_old; /* array holding previous input values */
/* determine "width" of the node bridge... */
size = PORT_SIZE(in);
if(PORT_SIZE(out) != size) {
cm_message_send("Error: output port size different than input port size\n");
}
/** Read in remaining parameters **/
ron = PARAM(r_on);
roff = PARAM(r_off);
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/
/* printf("Call cm_da_switch with size=%d, ron=%g, roff=%g\n", size, ron, roff); */
/* Allocate storage for inputs */
cm_event_alloc(0, size * (int) sizeof(Digital_State_t));
/* assign discrete addresses */
in = in_old = (Digital_State_t *) cm_event_get_ptr(0,0);
/* read current input values */
for (i=0; i<size; i++) {
in[i] = INPUT_STATE(in[i]);
}
/* Output initial analog levels based on input values */
for (i=0; i<size; i++) { /* assign addresses */
r = roff;
switch (in[i]) {
case ZERO:
r = roff;
break;
case UNKNOWN:
r = roff;
break;
case ONE:
r = ron;
break;
}
rinv = 1/r;
OUTPUT(out[i]) = INPUT(out[i])*rinv;
PARTIAL(out[i],out[i]) = rinv;
LOAD(in[i]) = PARAM(input_load);
}
}
else { /*** This is not an initialization pass...read in parameters,
retrieve storage addresses and calculate new outputs,
if required. ***/
/** Retrieve previous values... **/
/* assign discrete addresses */
in = (Digital_State_t *) cm_event_get_ptr(0,0);
in_old= (Digital_State_t *) cm_event_get_ptr(0,1);
/* read current input values */
for (i=0; i<size; i++) {
in[i] = INPUT_STATE(in[i]);
}
}
switch (CALL_TYPE) {
case EVENT: /** discrete call... **/
/* Test to see if any change has occurred in an input */
/* since the last digital call... */
for (i=0; i<size; i++) {
if (in[i] != in_old[i]) { /* if there has been a change... */
/* post current time as a breakpoint */
cm_analog_set_perm_bkpt(TIME);
}
}
break;
case ANALOG: /** analog call... **/
for (i=0; i<size; i++) {
r = roff;
switch (in[i]) {
case ONE:
r = ron;
break;
case ZERO:
r = roff;
break;
case UNKNOWN:
r = roff;
break;
}
rinv = 1/r;
/* to do: implement maximum current limiter (with tanh ?) */
if(ANALYSIS != MIF_AC) { /* Output DC & Transient Values */
OUTPUT(out[i]) = INPUT(out[i])*rinv;
PARTIAL(out[i],out[i]) = rinv;
} else { /* Output AC Gain Values */
ac_gain.real = -rinv;
ac_gain.imag= 0.0;
AC_GAIN(out[i],out[i]) = ac_gain;
}
}
break;
}
}

View File

@ -0,0 +1,64 @@
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
Copyright 2019
Anamosic Ballenegger Design
Hameau des Indevis 7, 1613 Maracon
All Rights Reserved
AUTHORS
5 March 2019 Florian Ballenegger
SUMMARY
This file contains the interface specification file for the
analog switch code model with digital node control .
===============================================================================*/
NAME_TABLE:
C_Function_Name: cm_da_switch
Spice_Model_Name: da_switch
Description: "analog switch with digital control"
PORT_TABLE:
Port_Name: in out
Description: "input" "conductance output"
Direction: in inout
Default_Type: d gd
Allowed_Types: [d] [gd]
Vector: yes yes
Vector_Bounds: - -
Null_Allowed: no no
PARAMETER_TABLE:
Parameter_Name: r_on r_off
Description: "on resistance" "off resistance"
Data_Type: real real
Default_Value: 1.0 1.0e12
Limits: - -
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
Parameter_Scope: both both
PARAMETER_TABLE:
Parameter_Name: input_load
Description: "capacitive input load (F)"
Data_Type: real
Default_Value: 1.0e-15
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
Parameter_Scope: both