146 changed files with 27695 additions and 56 deletions
-
6configure.in
-
92src/Makefile.am
-
4src/conf.c
-
2src/frontend/misccoms.c
-
8src/spinit
-
120src/xspice/icm/Makefile
-
266src/xspice/icm/analog/climit/cfunc.mod
-
77src/xspice/icm/analog/climit/ifspec.ifs
-
249src/xspice/icm/analog/d_dt/cfunc.mod
-
79src/xspice/icm/analog/d_dt/ifspec.ifs
-
204src/xspice/icm/analog/divide/cfunc.mod
-
108src/xspice/icm/analog/divide/ifspec.ifs
-
130src/xspice/icm/analog/gain/cfunc.mod
-
54src/xspice/icm/analog/gain/ifspec.ifs
-
360src/xspice/icm/analog/hyst/cfunc.mod
-
75src/xspice/icm/analog/hyst/cm_hyst.h
-
87src/xspice/icm/analog/hyst/ifspec.ifs
-
442src/xspice/icm/analog/ilimit/cfunc.mod
-
110src/xspice/icm/analog/ilimit/ifspec.ifs
-
242src/xspice/icm/analog/int/cfunc.mod
-
79src/xspice/icm/analog/int/ifspec.ifs
-
75src/xspice/icm/analog/int/int.h
-
203src/xspice/icm/analog/limit/cfunc.mod
-
80src/xspice/icm/analog/limit/ifspec.ifs
-
18src/xspice/icm/analog/modpath.lst
-
179src/xspice/icm/analog/mult/cfunc.mod
-
67src/xspice/icm/analog/mult/ifspec.ifs
-
568src/xspice/icm/analog/oneshot/cfunc.mod
-
117src/xspice/icm/analog/oneshot/ifspec.ifs
-
43src/xspice/icm/analog/oneshot/oneshot.h
-
520src/xspice/icm/analog/pwl/cfunc.mod
-
78src/xspice/icm/analog/pwl/ifspec.ifs
-
606src/xspice/icm/analog/s_xfer/cfunc.mod
-
93src/xspice/icm/analog/s_xfer/ifspec.ifs
-
24src/xspice/icm/analog/s_xfer/s_xfer.h
-
257src/xspice/icm/analog/sine/cfunc.mod
-
61src/xspice/icm/analog/sine/ifspec.ifs
-
80src/xspice/icm/analog/sine/sin.h
-
301src/xspice/icm/analog/slew/cfunc.mod
-
54src/xspice/icm/analog/slew/ifspec.ifs
-
77src/xspice/icm/analog/slew/slew.h
-
412src/xspice/icm/analog/square/cfunc.mod
-
83src/xspice/icm/analog/square/ifspec.ifs
-
84src/xspice/icm/analog/square/square.h
-
150src/xspice/icm/analog/summer/cfunc.mod
-
66src/xspice/icm/analog/summer/ifspec.ifs
-
364src/xspice/icm/analog/triangle/cfunc.mod
-
72src/xspice/icm/analog/triangle/ifspec.ifs
-
81src/xspice/icm/analog/triangle/triangle.h
-
2src/xspice/icm/analog/udnpath.lst
-
355src/xspice/icm/digital/adc_bridge/cfunc.mod
-
73src/xspice/icm/digital/adc_bridge/ifspec.ifs
-
247src/xspice/icm/digital/d_and/cfunc.mod
-
62src/xspice/icm/digital/d_and/ifspec.ifs
-
193src/xspice/icm/digital/d_buffer/cfunc.mod
-
61src/xspice/icm/digital/d_buffer/ifspec.ifs
-
677src/xspice/icm/digital/d_dff/cfunc.mod
-
123src/xspice/icm/digital/d_dff/ifspec.ifs
-
742src/xspice/icm/digital/d_dlatch/cfunc.mod
-
135src/xspice/icm/digital/d_dlatch/ifspec.ifs
-
241src/xspice/icm/digital/d_fdiv/cfunc.mod
-
86src/xspice/icm/digital/d_fdiv/ifspec.ifs
-
211src/xspice/icm/digital/d_inverter/cfunc.mod
-
62src/xspice/icm/digital/d_inverter/ifspec.ifs
-
765src/xspice/icm/digital/d_jkff/cfunc.mod
-
135src/xspice/icm/digital/d_jkff/ifspec.ifs
-
242src/xspice/icm/digital/d_nand/cfunc.mod
-
62src/xspice/icm/digital/d_nand/ifspec.ifs
-
242src/xspice/icm/digital/d_nor/cfunc.mod
-
62src/xspice/icm/digital/d_nor/ifspec.ifs
-
212src/xspice/icm/digital/d_open_c/cfunc.mod
-
61src/xspice/icm/digital/d_open_c/ifspec.ifs
-
217src/xspice/icm/digital/d_open_e/cfunc.mod
-
61src/xspice/icm/digital/d_open_e/ifspec.ifs
-
242src/xspice/icm/digital/d_or/cfunc.mod
-
62src/xspice/icm/digital/d_or/ifspec.ifs
-
476src/xspice/icm/digital/d_osc/cfunc.mod
-
91src/xspice/icm/digital/d_osc/d_osc.h
-
74src/xspice/icm/digital/d_osc/ifspec.ifs
-
134src/xspice/icm/digital/d_pulldown/cfunc.mod
-
51src/xspice/icm/digital/d_pulldown/ifspec.ifs
-
130src/xspice/icm/digital/d_pullup/cfunc.mod
-
51src/xspice/icm/digital/d_pullup/ifspec.ifs
-
1179src/xspice/icm/digital/d_ram/cfunc.mod
-
123src/xspice/icm/digital/d_ram/ifspec.ifs
-
1302src/xspice/icm/digital/d_source/cfunc.mod
-
83src/xspice/icm/digital/d_source/d_source.h
-
65src/xspice/icm/digital/d_source/ifspec.ifs
-
767src/xspice/icm/digital/d_srff/cfunc.mod
-
135src/xspice/icm/digital/d_srff/ifspec.ifs
-
827src/xspice/icm/digital/d_srlatch/cfunc.mod
-
147src/xspice/icm/digital/d_srlatch/ifspec.ifs
-
2217src/xspice/icm/digital/d_state/cfunc.mod
-
77src/xspice/icm/digital/d_state/d_state.h
-
130src/xspice/icm/digital/d_state/ifspec.ifs
-
698src/xspice/icm/digital/d_tff/cfunc.mod
-
123src/xspice/icm/digital/d_tff/ifspec.ifs
-
166src/xspice/icm/digital/d_tristate/cfunc.mod
-
76src/xspice/icm/digital/d_tristate/ifspec.ifs
-
322src/xspice/icm/digital/d_xnor/cfunc.mod
@ -0,0 +1,120 @@ |
|||
# The master makefile to make spiceopuse (TM) like codemodels
|
|||
# Under the GPLV2 or later license
|
|||
# 2003 - Stefan Jones <stefan.jones@multigig.com>
|
|||
|
|||
include $(TOPDIR)makedefs |
|||
|
|||
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) |
|||
|
|||
-include .deps/ifspec.P |
|||
-include .deps/cfunc.P |
|||
-include .deps/udnfunc.P |
|||
-include .deps/cm.P |
|||
-include .deps/dlmain.P |
|||
|
|||
UPMAKE = make -f $(TOPDIR)../Makefile TOPDIR=$(TOPDIR)../ |
|||
|
|||
MAKE = make -f $(TOPDIR)Makefile TOPDIR=$(TOPDIR) |
|||
|
|||
COMPILE = $(CC) $(INCLUDES) $(CFLAGS) |
|||
|
|||
INSTALL_DATA = ${INSTALL} -m 644 |
|||
|
|||
all: |
|||
@amf=$$2; for x in $(CMDIRS) ; do \
|
|||
( cd $$x && $(UPMAKE) $$x-mods ) \
|
|||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
|||
done && test -z "$$fail" |
|||
|
|||
install: all |
|||
$(mkinstalldirs) $(DESTDIR)$(libdir)/spice |
|||
@for x in $(CMDIRS) ; do \
|
|||
echo "$(INSTALL_DATA) $$x/$$x.cm $(DESTDIR)$(libdir)/spice"; \
|
|||
$(INSTALL_DATA) $$x/$$x.cm $(DESTDIR)$(libdir)/spice \
|
|||
|| exit 1; \
|
|||
done |
|||
|
|||
clean: |
|||
@amf=$$2; for x in $(CMDIRS) ; do \
|
|||
( cd $$x && $(UPMAKE) $$x-mods-clean ) \
|
|||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
|||
done && test -z "$$fail" |
|||
-rm -rf .deps |
|||
|
|||
ifspec.c: ifspec.ifs |
|||
-rm -f $@ |
|||
$(CMPP) -ifs |
|||
|
|||
cfunc.c: cfunc.mod |
|||
-rm -f $@ |
|||
$(CMPP) -mod |
|||
|
|||
dlmain.c: $(TOPDIR)/dlmain.c |
|||
-cp $(TOPDIR)/dlmain.c . |
|||
|
|||
objects.inc cmextrn.h cminfo.h udnextrn.h udninfo.h: modpath.lst udnpath.lst |
|||
-rm -f cmextrn.h cminfo.h objects.inc udnextrn.h udninfo.h |
|||
$(CMPP) -lst |
|||
|
|||
dlmain.o: cmextrn.h cminfo.h udnextrn.h udninfo.h |
|||
|
|||
%.cm: dlmain.o objects.inc |
|||
@echo $@: objects.inc dlmain.o \\ > .deps/cm.P |
|||
@for x in `cat modpath.lst` ; do \
|
|||
echo $$x/cfunc.o $$x/ifspec.o \\ >> .deps/cm.P ; done |
|||
@for x in `cat udnpath.lst` ; do \
|
|||
echo $$x/udnfunc.o \\ >> .deps/cm.P ; done |
|||
@echo "" >> .deps/cm.P |
|||
$(COMPILE) $(LDFLAGS) -o $@ `awk '{ print $$1 }' objects.inc` dlmain.o |
|||
|
|||
%-mods: modpath.lst udnpath.lst |
|||
@amf=$$2; for x in `cat modpath.lst` ; do \
|
|||
( cd $$x && $(UPMAKE) objs ) \
|
|||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
|||
done && test -z "$$fail" |
|||
@amf=$$2; for x in `cat udnpath.lst` ; do \
|
|||
( cd $$x && $(UPMAKE) uobjs ) \
|
|||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
|||
done && test -z "$$fail" |
|||
@target=`echo $@ | sed s/-mods//`; $(MAKE) $$target.cm |
|||
|
|||
%-mods-clean: |
|||
@target=`echo $@ | sed s/-mods-clean//` && rm -f $$target.cm |
|||
@amf=$$2; for x in `cat modpath.lst` ; do \
|
|||
( cd $$x && $(UPMAKE) objs-clean ) \
|
|||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
|||
done && test -z "$$fail" |
|||
@amf=$$2; for x in `cat udnpath.lst` ; do \
|
|||
( cd $$x && $(UPMAKE) uobjs-clean ) \
|
|||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
|||
done && test -z "$$fail" |
|||
-rm -f cmextrn.h cminfo.h objects.inc udnextrn.h udninfo.h \
|
|||
dlmain.c dlmain.o |
|||
-rm -rf .deps |
|||
|
|||
|
|||
objs: ifspec.o cfunc.o |
|||
|
|||
objs-clean: |
|||
-rm -f cfunc.c ifspec.c cfunc.o ifspec.o |
|||
-rm -rf .deps |
|||
|
|||
uobjs: udnfunc.o |
|||
|
|||
uobjs-clean: |
|||
-rm -f udnfunc.o |
|||
-rm -rf .deps |
|||
|
|||
%.o: %.c |
|||
@echo '$(COMPILE) -c $<'; \
|
|||
$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< |
|||
@-cp .deps/$(*F).pp .deps/$(*F).P; \
|
|||
tr ' ' '\012' < .deps/$(*F).pp \
|
|||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
|||
>> .deps/$(*F).P; \
|
|||
rm .deps/$(*F).pp |
|||
|
|||
makedefs: $(srcdir)/makedefs.in $(top_builddir)/config.status |
|||
cd $(top_builddir) \
|
|||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status |
|||
|
|||
@ -0,0 +1,266 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE climit/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
26 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the adc_bridge |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
void cm_smooth_discontinuity(); |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_climit() |
|||
|
|||
AUTHORS |
|||
|
|||
6 June 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
26 Sept 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the climit code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
void cm_smooth_discontinuity(); |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_CLIMIT ROUTINE ===*/ |
|||
|
|||
void cm_climit(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
/* Define error message string constants */ |
|||
|
|||
char *climit_range_error = "\n**** ERROR ****\n* CLIMIT function linear range less than zero. *\n"; |
|||
|
|||
|
|||
double lower_delta, /* lower delta value parameter */ |
|||
upper_delta, /* upper delta value parameter */ |
|||
limit_range, /* range of output below |
|||
(out_upper_limit - upper_delta) |
|||
or above (out_lower_limit + lower_delta) |
|||
within which smoothing will be applied */ |
|||
gain, /* gain parameter */ |
|||
threshold_upper, /* = out_upper_limit - upper_delta */ |
|||
threshold_lower, /* = out_lower_limit + lower_delta */ |
|||
linear_range, /* = threshold_upper - threshold_lower */ |
|||
out_lower_limit, /* output lower limit parameter */ |
|||
out_upper_limit, /* output upper limit parameter */ |
|||
out, /* originally-calculated output value */ |
|||
limited_out, /* output value after limiting */ |
|||
pout_pin, /* partial derivative of output w.r.t.input */ |
|||
pout_pcntl_upper, /* partial derivative of output w.r.t. |
|||
cntl_upper input */ |
|||
pout_pcntl_lower, /* partial derivative of output w.r.t. |
|||
cntl_lower input */ |
|||
junk; /* dummy variable */ |
|||
|
|||
Mif_Complex_t ac_gain; /* AC gain */ |
|||
|
|||
|
|||
|
|||
/* Retrieve frequently used parameters... */ |
|||
|
|||
lower_delta = PARAM(lower_delta); |
|||
upper_delta = PARAM(upper_delta); |
|||
limit_range = PARAM(limit_range); |
|||
gain = PARAM(gain); |
|||
|
|||
|
|||
/* Find Upper & Lower Limits */ |
|||
|
|||
out_lower_limit = INPUT(cntl_lower) + lower_delta; |
|||
out_upper_limit = INPUT(cntl_upper) - upper_delta; |
|||
|
|||
|
|||
if (PARAM(fraction) == MIF_TRUE) /* Set range to absolute value */ |
|||
limit_range = limit_range * |
|||
(out_upper_limit - out_lower_limit); |
|||
|
|||
|
|||
|
|||
threshold_upper = out_upper_limit - /* Set Upper Threshold */ |
|||
limit_range; |
|||
threshold_lower = out_lower_limit + /* Set Lower Threshold */ |
|||
limit_range; |
|||
linear_range = threshold_upper - threshold_lower; |
|||
|
|||
|
|||
/* Test the linear region & make sure there IS one... */ |
|||
if (linear_range < 0.0) { |
|||
/* This INIT test keeps the models from outputting |
|||
an error message the first time through when all |
|||
the inputs are initialized to zero */ |
|||
if( (INIT != 1) && (0.0 != TIME) ){ |
|||
cm_message_send(climit_range_error); |
|||
} |
|||
limited_out = 0.0; |
|||
pout_pin = 0.0; |
|||
pout_pcntl_lower = 0.0; |
|||
pout_pcntl_upper = 0.0; |
|||
return; |
|||
} |
|||
|
|||
/* Compute Un-Limited Output */ |
|||
out = gain * (PARAM(in_offset) + INPUT(in)); |
|||
|
|||
|
|||
if (out < threshold_lower) { /* Limit Out @ Lower Bound */ |
|||
|
|||
pout_pcntl_upper= 0.0; |
|||
|
|||
if (out > (out_lower_limit - limit_range)) { /* Parabolic */ |
|||
cm_smooth_corner(out,out_lower_limit,out_lower_limit, |
|||
limit_range,0.0,1.0,&limited_out, |
|||
&pout_pin); |
|||
pout_pin = gain * pout_pin; |
|||
cm_smooth_discontinuity(out,out_lower_limit,1.0,threshold_lower, |
|||
0.0,&pout_pcntl_lower,&junk); |
|||
} |
|||
else { /* Hard-Limited Region */ |
|||
limited_out = out_lower_limit; |
|||
pout_pin = 0.0; |
|||
pout_pcntl_lower = 1.0; |
|||
} |
|||
} |
|||
else { |
|||
if (out > threshold_upper) { /* Limit Out @ Upper Bound */ |
|||
|
|||
pout_pcntl_lower= 0.0; |
|||
|
|||
if (out < (out_upper_limit+limit_range)) { /* Parabolic */ |
|||
cm_smooth_corner(out,out_upper_limit,out_upper_limit, |
|||
limit_range,1.0,0.0,&limited_out, |
|||
&pout_pin); |
|||
pout_pin = gain * pout_pin; |
|||
cm_smooth_discontinuity(out,threshold_upper,0.0,out_upper_limit, |
|||
1.0,&pout_pcntl_upper,&junk); |
|||
} |
|||
else { /* Hard-Limited Region */ |
|||
limited_out = out_upper_limit; |
|||
pout_pin = 0.0; |
|||
pout_pcntl_upper = 1.0; |
|||
} |
|||
} |
|||
else { /* No Limiting Needed */ |
|||
limited_out = out; |
|||
pout_pin = gain; |
|||
pout_pcntl_lower = 0.0; |
|||
pout_pcntl_upper = 0.0; |
|||
} |
|||
} |
|||
|
|||
if (ANALYSIS != MIF_AC) { /* DC & Transient Analyses */ |
|||
|
|||
OUTPUT(out) = limited_out; |
|||
PARTIAL(out,in) = pout_pin; |
|||
PARTIAL(out,cntl_lower) = pout_pcntl_lower; |
|||
PARTIAL(out,cntl_upper) = pout_pcntl_upper; |
|||
|
|||
} |
|||
else { /* AC Analysis */ |
|||
ac_gain.real = pout_pin; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
|
|||
ac_gain.real = pout_pcntl_lower; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,cntl_lower) = ac_gain; |
|||
|
|||
ac_gain.real = pout_pcntl_upper; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,cntl_upper) = ac_gain; |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
|
|||
/* INTERFACE TABLE FOR CODE MODEL CLIMIT */ |
|||
|
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_climit |
|||
Spice_Model_Name: climit |
|||
Description: "controlled limiter block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in cntl_upper |
|||
Description: "input" "upper lim. control input" |
|||
Direction: in in |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id,vnam] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: cntl_lower out |
|||
Description: "lower limit control input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: in_offset gain |
|||
Description: "input offset" "gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: upper_delta lower_delta |
|||
Description: "output upper delta" "output lower delta" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 0.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: limit_range fraction |
|||
Description: "upper & lower sm. range" "smoothing %/abs switch" |
|||
Data_Type: real boolean |
|||
Default_Value: 1.0e-6 FALSE |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
@ -0,0 +1,249 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_dt/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_dt |
|||
(differentiator) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_integrate() |
|||
|
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_dt() |
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_dt code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_integrate() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_DT ROUTINE ===*/ |
|||
|
|||
|
|||
void cm_d_dt(ARGS) |
|||
|
|||
{ |
|||
|
|||
double *in, /* current input value */ |
|||
*in_old, /* previous input value */ |
|||
out, /* output */ |
|||
dum, /* fake input value...used for truncation |
|||
error checking */ |
|||
gain, /* gain parameter */ |
|||
out_offset, /* output offset parameter */ |
|||
out_lower_limit, /* output mower limit */ |
|||
out_upper_limit, /* output upper limit */ |
|||
limit_range, /* range of output below out_upper_limit |
|||
or above out_lower_limit to which |
|||
smoothing will be applied */ |
|||
pout_pin, /* partial derivative of output |
|||
w.r.t. input */ |
|||
dumpout_pin, /* fake partial derivative of output |
|||
w.r.t. input (for use with integration */ |
|||
delta, /* delta time value = TIME - T(1) */ |
|||
pout_gain; /* temporary storage for partial |
|||
returned by smoothing function |
|||
(subsequently multiplied w/pout_pin) */ |
|||
|
|||
Mif_Complex_t ac_gain; /* AC gain */ |
|||
|
|||
|
|||
|
|||
/** Retrieve frequently used parameters (used by all analyses)... **/ |
|||
|
|||
gain = PARAM(gain); |
|||
|
|||
|
|||
|
|||
if (ANALYSIS != MIF_AC) { /**** DC & Transient Analyses ****/ |
|||
|
|||
/** Retrieve frequently used parameters... **/ |
|||
|
|||
out_offset = PARAM(out_offset); |
|||
out_lower_limit = PARAM(out_lower_limit); |
|||
out_upper_limit = PARAM(out_upper_limit); |
|||
limit_range = PARAM(limit_range); |
|||
|
|||
|
|||
/** Test for INIT; if so, allocate storage, otherwise, retrieve |
|||
previous timepoint input value... **/ |
|||
|
|||
if (INIT==1) { /* First pass...allocate storage for previous state. */ |
|||
/* Also, calculate roughly where the current output */ |
|||
/* will be and use this value to define current state. */ |
|||
|
|||
in = cm_analog_alloc(TRUE,sizeof(double)); |
|||
in_old = cm_analog_get_ptr(TRUE,1); |
|||
|
|||
} |
|||
else { /* Allocation not necessary...retrieve previous values */ |
|||
|
|||
in = cm_analog_get_ptr(TRUE,0); /* Set out pointer to current |
|||
time storage */ |
|||
in_old = cm_analog_get_ptr(TRUE,1); /* Set old-output-state pointer |
|||
to previous time storage */ |
|||
} |
|||
|
|||
|
|||
if ( 0.0 == TIME ) { /*** Test to see if this is the first ***/ |
|||
/*** timepoint calculation...if ***/ |
|||
*in_old = *in = INPUT(in); /*** so, return a zero d/dt value. ***/ |
|||
out = 0.0; /*** so, return a zero d/dt value. ***/ |
|||
pout_pin = 0.0; |
|||
} |
|||
else { /*** Calculate value of d_dt.... ***/ |
|||
delta = TIME - T(1); |
|||
*in = INPUT(in); |
|||
out = gain * (*in - *in_old) / delta + out_offset; |
|||
pout_pin = gain / delta; |
|||
} |
|||
|
|||
|
|||
/*** Smooth output if it is within limit_range of |
|||
out_lower_limit or out_upper_limit. ***/ |
|||
|
|||
if (out < (out_lower_limit - limit_range)) { /* At lower limit. */ |
|||
out = out_lower_limit; |
|||
pout_pin = 0.0; |
|||
} |
|||
else { |
|||
if (out < (out_lower_limit + limit_range)) { /* Lower smoothing range */ |
|||
cm_smooth_corner(out,out_lower_limit,out_lower_limit,limit_range, |
|||
0.0,1.0,&out,&pout_gain); |
|||
pout_pin = pout_pin * pout_gain; |
|||
} |
|||
else { |
|||
if (out > (out_upper_limit + limit_range)) { /* At upper limit */ |
|||
out = out_upper_limit; |
|||
pout_pin = 0.0; |
|||
} |
|||
else { |
|||
if (out > (out_upper_limit - limit_range)) { /* Upper smoothing region */ |
|||
cm_smooth_corner(out,out_upper_limit,out_upper_limit,limit_range, |
|||
1.0,0.0,&out,&pout_gain); |
|||
pout_pin = pout_pin * pout_gain; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** Output values for DC & Transient **/ |
|||
|
|||
OUTPUT(out) = out; |
|||
PARTIAL(out,in) = pout_pin; |
|||
/* this cm_analog_integrate call is required in order to force |
|||
truncation error to be evaluated */ |
|||
cm_analog_integrate(out,&dum,&dumpout_pin); |
|||
|
|||
} |
|||
|
|||
else { /**** AC Analysis...output (0.0,s*gain) ****/ |
|||
ac_gain.real = 0.0; |
|||
ac_gain.imag= gain * RAD_FREQ; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,79 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog d_dt (differentiator) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_dt |
|||
Spice_Model_Name: d_dt |
|||
Description: "differentiator block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_offset gain |
|||
Description: "output offset" "gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_lower_limit out_upper_limit |
|||
Description: "output lower limit" "output upper limit" |
|||
Data_Type: real real |
|||
Default_Value: - - |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: limit_range |
|||
Description: "upper & lower sm. range" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-6 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
@ -0,0 +1,204 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE divide/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the divide code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <math.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_divide() |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the divide code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
|
|||
/*=== CM_DIVIDE ROUTINE ===*/ |
|||
|
|||
|
|||
void cm_divide(ARGS) |
|||
|
|||
{ |
|||
double den_lower_limit; /* denominator lower limit */ |
|||
double den_domain; /* smoothing range for the lower limit */ |
|||
double threshold_upper; /* value above which smoothing occurs */ |
|||
double threshold_lower; /* value below which smoothing occurs */ |
|||
double numerator; /* numerator input */ |
|||
double denominator; /* denominator input */ |
|||
double limited_den; /* denominator value if limiting is needed */ |
|||
double den_partial; /* partial of the output wrt denominator */ |
|||
double out_gain; /* output gain */ |
|||
double num_gain; /* numerator gain */ |
|||
double den_gain; /* denominator gain */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
|
|||
/* Retrieve frequently used parameters... */ |
|||
|
|||
den_lower_limit = PARAM(den_lower_limit); |
|||
den_domain = PARAM(den_domain); |
|||
out_gain = PARAM(out_gain); |
|||
num_gain = PARAM(num_gain); |
|||
den_gain = PARAM(den_gain); |
|||
|
|||
|
|||
if (PARAM(fraction) == MIF_TRUE) /* Set domain to absolute value */ |
|||
den_domain = den_domain * den_lower_limit; |
|||
|
|||
threshold_upper = den_lower_limit + /* Set Upper Threshold */ |
|||
den_domain; |
|||
|
|||
threshold_lower = den_lower_limit - /* Set Lower Threshold */ |
|||
den_domain; |
|||
|
|||
numerator = (INPUT(num) + PARAM(num_offset)) * num_gain; |
|||
denominator = (INPUT(den) + PARAM(den_offset)) * den_gain; |
|||
|
|||
if ((denominator < threshold_upper) && (denominator >= 0)) { /* Need to limit den...*/ |
|||
|
|||
if (denominator > threshold_lower) /* Parabolic Region */ |
|||
cm_smooth_corner(denominator,den_lower_limit, |
|||
den_lower_limit,den_domain,0.0,1.0, |
|||
&limited_den,&den_partial); |
|||
|
|||
else { /* Hard-Limited Region */ |
|||
limited_den = den_lower_limit; |
|||
den_partial = 0.0; |
|||
} |
|||
} |
|||
else |
|||
if ((denominator > -threshold_upper) && (denominator < 0)) { /* Need to limit den...*/ |
|||
if (denominator < -threshold_lower) /* Parabolic Region */ |
|||
cm_smooth_corner(denominator,-den_lower_limit, |
|||
-den_lower_limit,den_domain,0.0,1.0, |
|||
&limited_den,&den_partial); |
|||
|
|||
else { /* Hard-Limited Region */ |
|||
limited_den = -den_lower_limit; |
|||
den_partial = 0.0; |
|||
} |
|||
} |
|||
else { /* No limiting needed */ |
|||
limited_den = denominator; |
|||
den_partial = 1.0; |
|||
} |
|||
|
|||
if (ANALYSIS != MIF_AC) { |
|||
|
|||
OUTPUT(out) = PARAM(out_offset) + out_gain * |
|||
( numerator/limited_den ); |
|||
PARTIAL(out,num) = out_gain * num_gain / limited_den; |
|||
PARTIAL(out,den) = -out_gain * numerator * den_gain * |
|||
den_partial / (limited_den * limited_den); |
|||
|
|||
} |
|||
else { |
|||
ac_gain.real = out_gain * num_gain / limited_den; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,num) = ac_gain; |
|||
|
|||
ac_gain.real = -out_gain * numerator * den_gain * |
|||
den_partial / (limited_den * limited_den); |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,den) = ac_gain; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog divide code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_divide |
|||
Spice_Model_Name: divide |
|||
Description: "divider block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: num den out |
|||
Description: "numerator" "denominator" "output" |
|||
Direction: in in out |
|||
Default_Type: v v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no no |
|||
Vector_Bounds: - - - |
|||
Null_Allowed: no no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: num_offset num_gain |
|||
Description: "numerator offset" "numerator gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: den_offset den_gain |
|||
Description: "denominator offset" "denominator gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: den_lower_limit den_domain |
|||
Description: "denominator lower limit" "denominator smoothing domain" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-10 1.0e-16 |
|||
Limits: [1.0e-10 -] - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: fraction |
|||
Description: "smoothing fraction/absolute value switch" |
|||
Data_Type: boolean |
|||
Default_Value: false |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_gain out_offset |
|||
Description: "output gain" "output offset" |
|||
Data_Type: real real |
|||
Default_Value: 1.0 0.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
@ -0,0 +1,130 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE gain/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the gain code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_gain() |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the gain code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
|
|||
/*=== CM_GAIN ROUTINE ===*/ |
|||
|
|||
|
|||
void cm_gain(ARGS) /* structure holding parms, inputs, outputs, etc. */ |
|||
{ |
|||
Mif_Complex_t ac_gain; |
|||
|
|||
if(ANALYSIS != MIF_AC) { |
|||
OUTPUT(out) = PARAM(out_offset) + PARAM(gain) * |
|||
( INPUT(in) + PARAM(in_offset)); |
|||
PARTIAL(out,in) = PARAM(gain); |
|||
} |
|||
else { |
|||
ac_gain.real = PARAM(gain); |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog gain code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_gain |
|||
Spice_Model_Name: gain |
|||
Description: "A simple gain block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: in_offset gain out_offset |
|||
Description: "input offset" "gain" "output offset" |
|||
Data_Type: real real real |
|||
Default_Value: 0.0 1.0 0.0 |
|||
Limits: - - - |
|||
Vector: no no no |
|||
Vector_Bounds: - - - |
|||
Null_Allowed: yes yes yes |
|||
|
|||
|
|||
@ -0,0 +1,360 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE hyst/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the hyst code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "cm_hyst.h" |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void hyst() |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the hyst code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
|
|||
/*=== CM_HYST ROUTINE ===*/ |
|||
|
|||
|
|||
/************************************************************************* |
|||
* BEHAVIOR OF HYSTERESIS: * |
|||
* out hyst hyst * |
|||
* ^ ____/\_____ ____/\_____ * |
|||
* | / \/ \ * |
|||
* | x_fall_linear x_rise_zero * |
|||
* out_upper_limit- - *----<-------------<------*-------> * |
|||
* | /| /| /| * |
|||
* | / /in_high / * |
|||
* | / | / | / | * |
|||
* | / / __/ * |
|||
* | |/_ | / | /| | * |
|||
* | / / / * |
|||
* | / | / | / | * |
|||
* <------O----/------------/------------/-----------------------> in * |
|||
* | | / | / | / * |
|||
* | / / / * |
|||
* <--------*------->----|---->-------* - - - - out_lower_limit * |
|||
* x_fall_zero in_low x_rise_linear * |
|||
* V * |
|||
* * |
|||
* input_domain defines "in" increment below & above the "*" points * |
|||
* shown, within which smoothing of the d(out)/d(in) values * |
|||
* occurs...this prevents abrupt changes in d(out)/d(in) which * |
|||
* could prevent the simulator from reaching convergence during * |
|||
* a transient or DC analysis. * |
|||
* * |
|||
**************************************************************************/ |
|||
|
|||
/**************************************************************************/ |
|||
/* Usage of cm_smooth_corner: */ |
|||
/* */ |
|||
/* void cm_smooth_corner(double x_input, double x_center, double y_center, */ |
|||
/* double domain, double lower_slope, */ |
|||
/* double upper_slope,double *y_output, double *dy_dx) */ |
|||
/* */ |
|||
/**************************************************************************/ |
|||
|
|||
|
|||
|
|||
void cm_hyst(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
double in, /* input to hysteresis block */ |
|||
out, /* output from hysteresis block */ |
|||
in_low, /* lower input value for hyst=0 at which |
|||
the transfer curve changes from constant |
|||
to linear */ |
|||
in_high, /* upper input value for hyst=0 at which |
|||
the transfer curve changes from constant |
|||
to linear */ |
|||
hyst, /* the hysteresis value (see above diagram) */ |
|||
out_lower_limit, /* the minimum output value from the block */ |
|||
out_upper_limit, /* the maximum output value from the block */ |
|||
input_domain, /* the delta value of the input above and |
|||
below in_low and in_high within which |
|||
smoothing will be applied to the output |
|||
in order to maintain continuous first partial |
|||
derivatives. */ |
|||
slope, /* calculated rise and fall slope for the block */ |
|||
pout_pin, /* partial derivative of output w.r.t. input */ |
|||
x_rise_linear, /* = in_low + hyst */ |
|||
x_rise_zero, /* = in_high + hyst */ |
|||
x_fall_linear, /* = in_high - hyst */ |
|||
x_fall_zero; /* = in_low - hyst */ |
|||
|
|||
Boolean_t *hyst_state, /* TRUE => input is on lower leg of |
|||
hysteresis curve, between -infinity |
|||
and in_high + hyst. |
|||
FALSE => input is on upper leg |
|||
of hysteresis curve, between |
|||
in_low - hyst and +infinity */ |
|||
*old_hyst_state; /* previous value of *hyst_state */ |
|||
|
|||
Mif_Complex_t ac_gain; /* AC gain */ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/** Retrieve frequently used parameters... **/ |
|||
|
|||
in_low = PARAM(in_low); |
|||
in_high = PARAM(in_high); |
|||
hyst = PARAM(hyst); |
|||
out_lower_limit = PARAM(out_lower_limit); |
|||
out_upper_limit = PARAM(out_upper_limit); |
|||
input_domain = PARAM(input_domain); |
|||
|
|||
|
|||
|
|||
|
|||
/** Calculate Hysteresis Linear Region Slopes & Derived Values **/ |
|||
|
|||
|
|||
/* Define slope of rise and fall lines when not being smoothed */ |
|||
|
|||
slope = (out_upper_limit - out_lower_limit)/(in_high - in_low); |
|||
|
|||
x_rise_linear = in_low + hyst; /* Breakpoint - x rising to |
|||
linear region */ |
|||
x_rise_zero = in_high + hyst; /* Breakpoint - x rising to |
|||
zero-slope (out_upper_limit) */ |
|||
x_fall_linear = in_high - hyst; /* Breakpoint - x falling to |
|||
linear region */ |
|||
x_fall_zero = in_low - hyst; /* Breakpoint - x falling to |
|||
zero-slope (out_lower_limit) */ |
|||
|
|||
if (PARAM(fraction) == MIF_TRUE) /* Set range to absolute value */ |
|||
input_domain = input_domain * (in_high - in_low); |
|||
|
|||
|
|||
|
|||
|
|||
/** Retrieve frequently used inputs... **/ |
|||
|
|||
in = INPUT(in); |
|||
|
|||
|
|||
|
|||
/** Test for INIT; if so, allocate storage, otherwise, retrieve |
|||
previous timepoint value for output... **/ |
|||
|
|||
if (INIT==1) { /* First pass...allocate storage for previous state. */ |
|||
/* Also, calculate roughly where the current output */ |
|||
/* will be and use this value to define current state. */ |
|||
|
|||
hyst_state = cm_analog_alloc(TRUE,sizeof(Boolean_t)); |
|||
old_hyst_state = cm_analog_get_ptr(TRUE,1); |
|||
|
|||
if (in < x_rise_zero + input_domain) { /* Set state to X_RISING */ |
|||
*old_hyst_state = X_RISING; |
|||
} |
|||
else { |
|||
*old_hyst_state = X_FALLING; |
|||
} |
|||
} |
|||
else { /* Allocation not necessary...retrieve previous values */ |
|||
|
|||
hyst_state = cm_analog_get_ptr(TRUE,0); /* Set out pointer to current |
|||
time storage */ |
|||
old_hyst_state = cm_analog_get_ptr(TRUE,1); /* Set old-output-state pointer |
|||
to previous time storage */ |
|||
} |
|||
|
|||
|
|||
|
|||
/** Set *hyst_out = *old_hyst_out, unless changed below... |
|||
we don't need the last iteration value of *hyst_state. **/ |
|||
|
|||
*hyst_state = *old_hyst_state; |
|||
|
|||
|
|||
|
|||
|
|||
/*** Calculate value of hyst_state, pout_pin.... ***/ |
|||
|
|||
if (*old_hyst_state == X_RISING) { /* Assume calculations on lower */ |
|||
/* hysteresis section (x rising) */ |
|||
|
|||
if ( in <= x_rise_linear - input_domain ) { /* Output @ lower limit */ |
|||
|
|||
out = out_lower_limit; |
|||
pout_pin = 0.0; |
|||
} |
|||
else { |
|||
if ( in <= x_rise_linear + input_domain ) { /* lower smoothing region */ |
|||
cm_smooth_corner(in,x_rise_linear,out_lower_limit,input_domain, |
|||
0.0,slope,&out,&pout_pin); |
|||
} |
|||
else { |
|||
if (in <= x_rise_zero - input_domain) { /* Rising linear region */ |
|||
out = (in - x_rise_linear)*slope + out_lower_limit; |
|||
pout_pin = slope; |
|||
} |
|||
else { |
|||
if (in <= x_rise_zero + input_domain) { /* Upper smoothing region */ |
|||
cm_smooth_corner(in,x_rise_zero,out_upper_limit,input_domain, |
|||
slope,0.0,&out,&pout_pin); |
|||
} |
|||
else { /* input has transitioned to X_FALLING region... */ |
|||
out = out_upper_limit; |
|||
pout_pin = 0.0; |
|||
*hyst_state = X_FALLING; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
else { /* Assume calculations on upper hysteresis section (x falling) */ |
|||
|
|||
if ( in >= x_fall_linear + input_domain ) { /* Output @ upper limit */ |
|||
|
|||
out = out_upper_limit; |
|||
pout_pin = 0.0; |
|||
} |
|||
else { |
|||
if ( in >= x_fall_linear - input_domain ) { /* Upper smoothing region */ |
|||
cm_smooth_corner(in,x_fall_linear,out_upper_limit,input_domain, |
|||
slope,0.0,&out,&pout_pin); |
|||
} |
|||
else { |
|||
if (in >= x_fall_zero + input_domain) { /* Falling linear region */ |
|||
out = (in - x_fall_zero)*slope + out_lower_limit; |
|||
pout_pin = slope; |
|||
} |
|||
else { |
|||
if (in >= x_fall_zero - input_domain) { /* Lower smoothing region */ |
|||
cm_smooth_corner(in,x_fall_zero,out_lower_limit,input_domain, |
|||
0.0,slope,&out,&pout_pin); |
|||
} |
|||
else { /* input has transitioned to X_RISING region... */ |
|||
out = out_lower_limit; |
|||
pout_pin = 0.0; |
|||
*hyst_state = X_RISING; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
if (ANALYSIS != MIF_AC) { /* DC & Transient Analyses */ |
|||
|
|||
OUTPUT(out) = out; |
|||
PARTIAL(out,in) = pout_pin; |
|||
|
|||
} |
|||
else { /* AC Analysis */ |
|||
ac_gain.real = pout_pin; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,75 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE hyst/cm_hyst.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
23 Oct 1990 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains additional header information for |
|||
the hyst code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
N/A |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define HYST 1 |
|||
#define X_RISING TRUE |
|||
#define X_FALLING FALSE |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,87 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog hyst code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_hyst |
|||
Spice_Model_Name: hyst |
|||
Description: "hysteresis block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: in_low in_high |
|||
Description: "input low value" "input high value" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: hyst out_lower_limit |
|||
Description: "hysteresis" "output lower limit" |
|||
Data_Type: real real |
|||
Default_Value: 0.1 0.0 |
|||
Limits: [0 -] - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: out_upper_limit input_domain |
|||
Description: "output upper limit" "input smoothing domain" |
|||
Data_Type: real real |
|||
Default_Value: 1.0 0.01 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: fraction |
|||
Description: "smoothing percent/abs switch" |
|||
Data_Type: boolean |
|||
Default_Value: TRUE |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
@ -0,0 +1,442 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE ilimit/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the ilimit code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
void cm_smooth_discontinuity(); |
|||
void cm_climit_fcn() |
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_ilimit() |
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the ilimit code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
void cm_smooth_discontinuity(); |
|||
void cm_climit_fcn() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_ILIMIT ROUTINE ===*/ |
|||
|
|||
void cm_ilimit(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
double in_offset,gain,r_out_source,r_out_sink,i_limit_source, |
|||
i_limit_sink,v_pwr_range,i_source_range,i_sink_range, |
|||
r_out_domain,out_lower_limit,out_upper_limit,veq,pveq_pvin, |
|||
pveq_pvpos,pveq_pvneg,r_out,pr_out_px,i_out,i_threshold_lower, |
|||
i_threshold_upper,i_pos_pwr,pi_out_pvin,pi_pos_pvneg, |
|||
pi_pos_pvpos,pi_pos_pvout,i_neg_pwr,pi_neg_pvin,pi_neg_pvneg, |
|||
pi_neg_pvpos,pi_neg_pvout,vout,pi_out_plimit,pi_out_pvout, |
|||
pi_out_ppos_pwr,pi_out_pneg_pwr,pi_pos_pvin,pi_neg_plimit, |
|||
pi_pos_plimit,pos_pwr_in,neg_pwr_in; |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
|
|||
|
|||
/* Retrieve frequently used parameters... */ |
|||
|
|||
in_offset = PARAM(in_offset); |
|||
gain = PARAM(gain); |
|||
r_out_source = PARAM(r_out_source); |
|||
r_out_sink = PARAM(r_out_sink); |
|||
i_limit_source = PARAM(i_limit_source); |
|||
i_limit_sink = PARAM(i_limit_sink); |
|||
v_pwr_range = PARAM(v_pwr_range); |
|||
i_source_range = PARAM(i_source_range); |
|||
i_sink_range = PARAM(i_sink_range); |
|||
r_out_domain = PARAM(r_out_domain); |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/* Retrieve frequently used inputs... */ |
|||
|
|||
vout = INPUT(out); |
|||
|
|||
|
|||
|
|||
/* Test to see if pos_pwr or neg_pwr are connected... */ |
|||
/* if not, assign large voltage values to the variables */ |
|||
/* pos_pwr andneg_pwr... */ |
|||
|
|||
if ( PORT_NULL(pos_pwr) ) { |
|||
pos_pwr_in = 1.0e6; |
|||
} |
|||
else { |
|||
pos_pwr_in = INPUT(pos_pwr); |
|||
} |
|||
|
|||
if ( PORT_NULL(neg_pwr) ) { |
|||
neg_pwr_in = -1.0e6; |
|||
} |
|||
else { |
|||
neg_pwr_in = INPUT(neg_pwr); |
|||
} |
|||
|
|||
|
|||
/* Compute Veq plus derivatives using climit_fcn */ |
|||
|
|||
if(INIT != 1){ |
|||
/* If reasonable power and voltage values exist (i.e., not INIT)... */ |
|||
/* then calculate expected equivalent voltage values and derivs. */ |
|||
|
|||
cm_climit_fcn(INPUT(in), in_offset, pos_pwr_in, neg_pwr_in, |
|||
0.0, 0.0, v_pwr_range, gain, MIF_FALSE, &veq, |
|||
&pveq_pvin, &pveq_pvneg, &pveq_pvpos); |
|||
} |
|||
else { |
|||
/* Initialization pass...set nominal values */ |
|||
|
|||
veq = (pos_pwr_in - neg_pwr_in) / 2.0; |
|||
pveq_pvin = 0.0; |
|||
pveq_pvpos = 0.0; |
|||
pveq_pvneg = 0.0; |
|||
} |
|||
|
|||
|
|||
/* Calculate Rout */ |
|||
|
|||
if (r_out_source == r_out_sink) { |
|||
/* r_out constant => no calculation necessary */ |
|||
|
|||
r_out = r_out_source; |
|||
pr_out_px = 0.0; |
|||
|
|||
} |
|||
else { /* Interpolate smoothly between sourcing & sinking values */ |
|||
cm_smooth_discontinuity(veq - vout, -r_out_domain, r_out_sink, r_out_domain, |
|||
r_out_source, &r_out, &pr_out_px); |
|||
} |
|||
|
|||
|
|||
|
|||
/* Calculate i_out & derivatives */ |
|||
|
|||
i_threshold_lower = -i_limit_sink + i_sink_range; |
|||
i_threshold_upper = i_limit_source - i_source_range; |
|||
|
|||
i_out = (veq - vout) / r_out; |
|||
pi_out_pvin = (pveq_pvin/r_out - veq*pr_out_px*pveq_pvin/ |
|||
(r_out*r_out)); |
|||
pi_out_pvout = (-1.0/r_out - vout*pr_out_px/(r_out*r_out)); |
|||
|
|||
pi_out_ppos_pwr = (pveq_pvpos/r_out - veq*pr_out_px*pveq_pvpos/ |
|||
(r_out*r_out)); |
|||
pi_out_pneg_pwr = (pveq_pvneg/r_out - veq*pr_out_px*pveq_pvneg/ |
|||
(r_out*r_out)); |
|||
|
|||
|
|||
/* Preset i_pos_pwr & i_neg_pwr & partials to 0.0 */ |
|||
|
|||
i_pos_pwr = 0.0; |
|||
pi_pos_pvin = 0.0; |
|||
pi_pos_pvneg = 0.0; |
|||
pi_pos_pvpos = 0.0; |
|||
pi_pos_pvout = 0.0; |
|||
|
|||
|
|||
i_neg_pwr = 0.0; |
|||
pi_neg_pvin = 0.0; |
|||
pi_neg_pvneg = 0.0; |
|||
pi_neg_pvpos = 0.0; |
|||
pi_neg_pvout = 0.0; |
|||
|
|||
|
|||
|
|||
|
|||
/* Determine operating point of i_out for limiting */ |
|||
|
|||
if (i_out < 0.0) { /* i_out sinking */ |
|||
if (i_out < i_threshold_lower) { |
|||
if (i_out < (-i_limit_sink-i_sink_range)) { /* i_out lower-limited */ |
|||
i_out = -i_limit_sink; |
|||
i_neg_pwr = -i_out; |
|||
pi_out_pvin = 0.0; |
|||
pi_out_pvout = 0.0; |
|||
pi_out_ppos_pwr = 0.0; |
|||
pi_out_pneg_pwr = 0.0; |
|||
} |
|||
else { /* i_out in lower smoothing region */ |
|||
cm_smooth_corner(i_out,-i_limit_sink,-i_limit_sink,i_sink_range, |
|||
0.0,1.0,&i_out,&pi_out_plimit); |
|||
pi_out_pvin = pi_out_pvin * pi_out_plimit; |
|||
pi_out_pvout = pi_out_pvout * pi_out_plimit; |
|||
pi_out_ppos_pwr = pi_out_ppos_pwr * pi_out_plimit; |
|||
pi_out_pneg_pwr = pi_out_pneg_pwr * pi_out_plimit; |
|||
|
|||
i_neg_pwr = -i_out; |
|||
pi_neg_pvin = -pi_out_pvin; |
|||
pi_neg_pvneg = -pi_out_pneg_pwr; |
|||
pi_neg_pvpos = -pi_out_ppos_pwr; |
|||
pi_neg_pvout = -pi_out_pvout; |
|||
} |
|||
} |
|||
else { /* i_out in lower linear region...calculate i_neg_pwr */ |
|||
if (i_out > -2.0*i_sink_range) { /* i_out near 0.0...smooth i_neg_pwr */ |
|||
cm_smooth_corner(i_out,-i_sink_range,0.0,i_sink_range,1.0,0.0, |
|||
&i_neg_pwr,&pi_neg_plimit); |
|||
i_neg_pwr = -i_neg_pwr; |
|||
pi_neg_pvin = -pi_out_pvin * pi_neg_plimit; |
|||
pi_neg_pvneg = -pi_out_pneg_pwr * pi_neg_plimit; |
|||
pi_neg_pvpos = -pi_out_ppos_pwr * pi_neg_plimit; |
|||
pi_neg_pvout = -pi_out_pvout * pi_neg_plimit; |
|||
} |
|||
else { |
|||
i_neg_pwr = -i_out; /* Not near i_out=0.0 => i_neg_pwr=-i_out */ |
|||
pi_neg_pvin = -pi_out_pvin; |
|||
pi_neg_pvneg = -pi_out_pneg_pwr; |
|||
pi_neg_pvpos = -pi_out_ppos_pwr; |
|||
pi_neg_pvout = -pi_out_pvout; |
|||
} |
|||
} |
|||
} |
|||
else { /* i_out sourcing */ |
|||
if (i_out > i_threshold_upper) { |
|||
if (i_out > (i_limit_source + i_source_range)) { /* i_out upper-limited */ |
|||
i_out = i_limit_source; |
|||
i_pos_pwr = -i_out; |
|||
pi_out_pvin = 0.0; |
|||
pi_out_pvout = 0.0; |
|||
pi_out_ppos_pwr = 0.0; |
|||
pi_out_pneg_pwr = 0.0; |
|||
} |
|||
else { /* i_out in upper smoothing region */ |
|||
cm_smooth_corner(i_out,i_limit_source,i_limit_source,i_sink_range, |
|||
1.0,0.0,&i_out,&pi_out_plimit); |
|||
pi_out_pvin = pi_out_pvin * pi_out_plimit; |
|||
pi_out_pvout = pi_out_pvout * pi_out_plimit; |
|||
pi_out_ppos_pwr = pi_out_ppos_pwr * pi_out_plimit; |
|||
pi_out_pneg_pwr = pi_out_pneg_pwr * pi_out_plimit; |
|||
|
|||
i_pos_pwr = -i_out; |
|||
pi_pos_pvin = -pi_out_pvin; |
|||
pi_pos_pvneg = -pi_out_pneg_pwr; |
|||
pi_pos_pvpos = -pi_out_ppos_pwr; |
|||
pi_pos_pvout = -pi_out_pvout; |
|||
} |
|||
} |
|||
else { /* i_out in upper linear region...calculate i_pos_pwr */ |
|||
if (i_out < 2.0*i_source_range) { /* i_out near 0.0...smooth i_pos_pwr */ |
|||
cm_smooth_corner(i_out,i_source_range,0.0,i_source_range,0.0,1.0, |
|||
&i_pos_pwr,&pi_pos_plimit); |
|||
i_pos_pwr = -i_pos_pwr; |
|||
pi_pos_pvin = -pi_out_pvin * pi_pos_plimit; |
|||
pi_pos_pvneg = -pi_out_pneg_pwr * pi_pos_plimit; |
|||
pi_pos_pvpos = -pi_out_ppos_pwr * pi_pos_plimit; |
|||
pi_pos_pvout = -pi_out_pvout * pi_pos_plimit; |
|||
} |
|||
else { /* Not near i_out=0.0 => i_pos_pwr=-i_out */ |
|||
i_pos_pwr = -i_out; |
|||
pi_pos_pvin = -pi_out_pvin; |
|||
pi_pos_pvneg = -pi_out_pneg_pwr; |
|||
pi_pos_pvpos = -pi_out_ppos_pwr; |
|||
pi_pos_pvout = -pi_out_pvout; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
if (ANALYSIS != MIF_AC) { /* DC & Transient Analyses */ |
|||
|
|||
|
|||
/* Debug line...REMOVE FOR FINAL VERSION!!! */ |
|||
/*OUTPUT(t1) = veq; |
|||
OUTPUT(t2) = r_out; |
|||
OUTPUT(t3) = pveq_pvin; |
|||
OUTPUT(t4) = pveq_pvpos; |
|||
OUTPUT(t5) = pveq_pvneg;*/ |
|||
|
|||
|
|||
OUTPUT(out) = -i_out; /* Remember...current polarity must be */ |
|||
PARTIAL(out,in) = -pi_out_pvin; /* reversed for SPICE...all previous code */ |
|||
PARTIAL(out,out) = -pi_out_pvout; /* assumes i_out positive when EXITING */ |
|||
/* the model and negative when entering. */ |
|||
/* SPICE assumes the opposite, so a */ |
|||
/* minus sign is added to all currents */ |
|||
/* and current partials to compensate for */ |
|||
/* this fact.... JPM */ |
|||
|
|||
if ( !PORT_NULL(neg_pwr) ) { |
|||
OUTPUT(neg_pwr) = -i_neg_pwr; |
|||
PARTIAL(neg_pwr,in) = -pi_neg_pvin; |
|||
PARTIAL(neg_pwr,out) = -pi_neg_pvout; |
|||
if(!PORT_NULL(pos_pwr)){ |
|||
PARTIAL(neg_pwr,pos_pwr) = -pi_neg_pvpos; |
|||
} |
|||
PARTIAL(neg_pwr,neg_pwr) = -pi_neg_pvneg; |
|||
PARTIAL(out,neg_pwr) = -pi_out_pneg_pwr; |
|||
} |
|||
|
|||
if ( !PORT_NULL(pos_pwr) ) { |
|||
OUTPUT(pos_pwr) = -i_pos_pwr; |
|||
PARTIAL(pos_pwr,in) = -pi_pos_pvin; |
|||
PARTIAL(pos_pwr,out) = -pi_pos_pvout; |
|||
PARTIAL(pos_pwr,pos_pwr) = -pi_pos_pvpos; |
|||
if ( !PORT_NULL(neg_pwr) ) { |
|||
PARTIAL(pos_pwr,neg_pwr) = -pi_pos_pvneg; |
|||
} |
|||
PARTIAL(out,pos_pwr) = -pi_out_ppos_pwr; |
|||
} |
|||
|
|||
} |
|||
else { /* AC Analysis */ |
|||
ac_gain.real = -pi_out_pvin; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_out_pvout; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,out) = ac_gain; |
|||
|
|||
if ( !PORT_NULL(neg_pwr) ) { |
|||
ac_gain.real = -pi_neg_pvin; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(neg_pwr,in) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_out_pneg_pwr; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,neg_pwr) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_neg_pvout; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(neg_pwr,out) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_neg_pvpos; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(neg_pwr,pos_pwr) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_neg_pvneg; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(neg_pwr,neg_pwr) = ac_gain; |
|||
} |
|||
|
|||
|
|||
if ( !PORT_NULL(pos_pwr) ) { |
|||
ac_gain.real = -pi_pos_pvin; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(pos_pwr,in) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_out_ppos_pwr; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,pos_pwr) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_pos_pvout; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(pos_pwr,out) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_pos_pvpos; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(pos_pwr,pos_pwr) = ac_gain; |
|||
|
|||
ac_gain.real = -pi_pos_pvneg; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(pos_pwr,neg_pwr) = ac_gain; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,110 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog ilimit code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_ilimit |
|||
Spice_Model_Name: ilimit |
|||
Description: "current limiter block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in pos_pwr |
|||
Description: "input" "positive power supply" |
|||
Direction: in inout |
|||
Default_Type: v g |
|||
Allowed_Types: [v,vd,i,id,vnam] [g,gd] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no yes |
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: neg_pwr out |
|||
Description: "negative power supply" "output" |
|||
Direction: inout inout |
|||
Default_Type: g g |
|||
Allowed_Types: [g,gd] [g,gd] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: in_offset gain |
|||
Description: "input offset" "gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: r_out_source r_out_sink |
|||
Description: "sourcing resistance" "sinking resistance" |
|||
Data_Type: real real |
|||
Default_Value: 1.0 1.0 |
|||
Limits: [1e-9 1e9] [1e-9 1e9] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: i_limit_source i_limit_sink |
|||
Description: "current sourcing limit" "current sinking limit" |
|||
Data_Type: real real |
|||
Default_Value: 10.0e-3 10.0e-3 |
|||
Limits: [1e-12 -] [1e-12 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: v_pwr_range i_source_range |
|||
Description: "pwr. smoothing range" "sourcing cur sm. rng" |
|||
Data_Type: real real |
|||
Default_Value: 1e-6 1e-9 |
|||
Limits: [1e-15 -] [1e-15 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: i_sink_range r_out_domain |
|||
Description: "sinking cur sm. rng" "output resistance sm. domain" |
|||
Data_Type: real real |
|||
Default_Value: 1e-9 1e-9 |
|||
Limits: [1e-15 -] [1e-15 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
@ -0,0 +1,242 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE int/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the int code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_integrate() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "int.h" |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_int() |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the int code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_integrate() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_INT ROUTINE ===*/ |
|||
|
|||
void cm_int(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
double *out, /* current output */ |
|||
*in, /* input */ |
|||
in_offset, /* input offset */ |
|||
gain, /* gain parameter */ |
|||
out_lower_limit, /* output lower limit */ |
|||
out_upper_limit, /* output upper limit */ |
|||
limit_range, /* range of output below out_upper_limit |
|||
and above out_lower_limit within which |
|||
smoothing will take place */ |
|||
out_ic, /* output initial condition - initial output value */ |
|||
pout_pin, /* partial derivative of output w.r.t. input */ |
|||
pout_gain; /* temporary storage variable for partial |
|||
value returned by smoothing function |
|||
(subsequently multiplied by pout_pin) */ |
|||
|
|||
Mif_Complex_t ac_gain; /* AC gain */ |
|||
|
|||
|
|||
|
|||
/** Retrieve frequently used parameters (used by all analyses)... **/ |
|||
|
|||
gain = PARAM(gain); |
|||
|
|||
|
|||
|
|||
if (ANALYSIS != MIF_AC) { /**** DC & Transient Analyses ****/ |
|||
|
|||
/** Retrieve frequently used parameters... **/ |
|||
|
|||
in_offset = PARAM(in_offset); |
|||
out_lower_limit = PARAM(out_lower_limit); |
|||
out_upper_limit = PARAM(out_upper_limit); |
|||
limit_range = PARAM(limit_range); |
|||
out_ic = PARAM(out_ic); |
|||
|
|||
|
|||
|
|||
/** Test for INIT; if so, allocate storage, otherwise, retrieve |
|||
previous timepoint input value... **/ |
|||
|
|||
if (INIT==1) { /* First pass...allocate storage for previous value. */ |
|||
|
|||
in = cm_analog_alloc(INT1,sizeof(double)); |
|||
out = cm_analog_alloc(INT2,sizeof(double)); |
|||
} |
|||
else { /* Allocation not necessary...retrieve previous value */ |
|||
|
|||
in = cm_analog_get_ptr(INT1,0); /* Set out pointer to input storage location */ |
|||
out = cm_analog_get_ptr(INT2,0); /* Set out pointer to output storage location */ |
|||
} |
|||
|
|||
|
|||
/*** Read input value for current time, and calculate pseudo-input ***/ |
|||
/*** which includes input offset and gain.... ***/ |
|||
|
|||
*in = gain*(INPUT(in)+in_offset); |
|||
|
|||
/*** Test to see if this is the first timepoint calculation... ***/ |
|||
/*** this would imply that TIME equals zero. ***/ |
|||
|
|||
if ( 0.0 == TIME ) { /*** Test to see if this is the first ***/ |
|||
/*** timepoint calculation...if ***/ |
|||
*out = out_ic; /*** so, return out_ic. ***/ |
|||
pout_pin = 0.0; |
|||
} |
|||
else { /*** Calculate value of integral.... ***/ |
|||
cm_analog_integrate(*in,out,&pout_pin); |
|||
} |
|||
|
|||
|
|||
/*** Smooth output if it is within limit_range of |
|||
out_lower_limit or out_upper_limit. ***/ |
|||
|
|||
if (*out < (out_lower_limit - limit_range)) { /* At lower limit. */ |
|||
*out = out_lower_limit; |
|||
pout_pin = 0.0; |
|||
} |
|||
else { |
|||
if (*out < (out_lower_limit + limit_range)) { /* Lower smoothing range */ |
|||
cm_smooth_corner(*out,out_lower_limit,out_lower_limit,limit_range, |
|||
0.0,1.0,out,&pout_gain); |
|||
pout_pin = pout_pin * pout_gain; |
|||
} |
|||
else { |
|||
if (*out > (out_upper_limit + limit_range)) { /* At upper limit */ |
|||
*out = out_upper_limit; |
|||
pout_pin = 0.0; |
|||
} |
|||
else { |
|||
if (*out > (out_upper_limit - limit_range)) { /* Upper smoothing region */ |
|||
cm_smooth_corner(*out,out_upper_limit,out_upper_limit,limit_range, |
|||
1.0,0.0,out,&pout_gain); |
|||
pout_pin = pout_pin * pout_gain; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/** Output values for DC & Transient **/ |
|||
|
|||
OUTPUT(out) = *out; |
|||
PARTIAL(out,in) = pout_pin; |
|||
|
|||
} |
|||
|
|||
else { /**** AC Analysis...output (0.0,gain/s) ****/ |
|||
ac_gain.real = 0.0; |
|||
ac_gain.imag = -gain / RAD_FREQ; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,79 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
6 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog int code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_int |
|||
Spice_Model_Name: int |
|||
Description: "integrator block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: in_offset gain |
|||
Description: "input offset" "gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_lower_limit out_upper_limit |
|||
Description: "output lower limit" "output upper limit" |
|||
Data_Type: real real |
|||
Default_Value: - - |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: limit_range out_ic |
|||
Description: "upper & lower sm. range" "output initial condition" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-6 0.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
@ -0,0 +1,75 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE int/int.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Nov 1990 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains additional header information for |
|||
the int code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
REFERENCED FILES |
|||
|
|||
NONE |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define INT1 1 |
|||
#define INT2 2 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,203 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE limit/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the limit code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_limit() |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the limit code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_LIMIT ROUTINE ===*/ |
|||
|
|||
void cm_limit(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
double out_lower_limit; /* output lower limit */ |
|||
double out_upper_limit; /* output upper limit */ |
|||
double limit_range; /* upper and lower limit smoothing range */ |
|||
double gain; /* gain */ |
|||
double threshold_upper; /* value above which smoothing takes place */ |
|||
double threshold_lower; /* value below which smoothing takes place */ |
|||
double out; /* output */ |
|||
double limited_out; /* limited output value */ |
|||
double out_partial; /* partial of the output wrt input */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
|
|||
/* Retrieve frequently used parameters... */ |
|||
|
|||
out_lower_limit = PARAM(out_lower_limit); |
|||
out_upper_limit = PARAM(out_upper_limit); |
|||
limit_range = PARAM(limit_range); |
|||
gain = PARAM(gain); |
|||
|
|||
|
|||
if (PARAM(fraction) == MIF_TRUE) /* Set range to absolute value */ |
|||
limit_range = limit_range * |
|||
(out_upper_limit - out_lower_limit); |
|||
|
|||
|
|||
|
|||
threshold_upper = out_upper_limit - /* Set Upper Threshold */ |
|||
limit_range; |
|||
|
|||
threshold_lower = out_lower_limit + /* Set Lower Threshold */ |
|||
limit_range; |
|||
|
|||
|
|||
|
|||
/* Compute Un-Limited Output */ |
|||
|
|||
out = gain * (PARAM(in_offset) + INPUT(in)); |
|||
|
|||
|
|||
|
|||
if (out < threshold_lower) { /* Limit Out @ Lower Bound */ |
|||
|
|||
if (out > (out_lower_limit - limit_range)) { /* Parabolic */ |
|||
cm_smooth_corner(out,out_lower_limit,out_lower_limit, |
|||
limit_range,0.0,1.0,&limited_out, |
|||
&out_partial); |
|||
out_partial = gain * out_partial; |
|||
} |
|||
else { /* Hard-Limited Region */ |
|||
limited_out = out_lower_limit; |
|||
out_partial = 0.0; |
|||
} |
|||
} |
|||
else { |
|||
if (out > threshold_upper) { /* Limit Out @ Upper Bound */ |
|||
|
|||
if (out < (out_upper_limit + limit_range)) { /* Parabolic */ |
|||
cm_smooth_corner(out,out_upper_limit,out_upper_limit, |
|||
limit_range,1.0,0.0,&limited_out, |
|||
&out_partial); |
|||
out_partial = gain * out_partial; |
|||
} |
|||
else { /* Hard-Limited Region */ |
|||
limited_out = out_upper_limit; |
|||
out_partial = 0.0; |
|||
} |
|||
} |
|||
else { /* No Limiting Needed */ |
|||
limited_out = out; |
|||
out_partial = gain; |
|||
} |
|||
} |
|||
|
|||
if (ANALYSIS != MIF_AC) { /* DC & Transient Analyses */ |
|||
|
|||
OUTPUT(out) = limited_out; |
|||
PARTIAL(out,in) = out_partial; |
|||
|
|||
} |
|||
else { /* AC Analysis */ |
|||
ac_gain.real = out_partial; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog limit code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_limit |
|||
Spice_Model_Name: limit |
|||
Description: "limit block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: in_offset gain |
|||
Description: "input offset" "gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_lower_limit out_upper_limit |
|||
Description: "output lower limit" "output upper limit" |
|||
Data_Type: real real |
|||
Default_Value: - - |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: limit_range fraction |
|||
Description: "upper & lower sm. range" "smoothing percent/abs switch" |
|||
Data_Type: real boolean |
|||
Default_Value: 1.0e-6 FALSE |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,18 @@ |
|||
climit |
|||
divide |
|||
d_dt |
|||
gain |
|||
hyst |
|||
ilimit |
|||
int |
|||
limit |
|||
mult |
|||
oneshot |
|||
pwl |
|||
sine |
|||
slew |
|||
square |
|||
summer |
|||
s_xfer |
|||
triangle |
|||
|
|||
@ -0,0 +1,179 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE mult/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the mult code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_mult() |
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the mult code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_MULT ROUTINE ===*/ |
|||
|
|||
|
|||
void cm_mult(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int size; /* number of input ports */ |
|||
|
|||
double accumulate_gain; /* product of all the gains */ |
|||
double accumulate_in; /* product of all (inputs + offsets) */ |
|||
double final_gain; /* output gain */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
size = PORT_SIZE(in); /* Note that port size */ |
|||
final_gain = PARAM(out_gain); /* and out_gain are read only */ |
|||
/* once...saves access time. */ |
|||
|
|||
|
|||
/* Calculate multiplication of inputs and gains for */ |
|||
/* all types of analyes.... */ |
|||
|
|||
accumulate_gain = 1.0; |
|||
accumulate_in = 1.0; |
|||
|
|||
for (i=0; i<size; i++) { |
|||
accumulate_gain = accumulate_gain * /* Multiply all input gains */ |
|||
PARAM(in_gain[i]); |
|||
accumulate_in = accumulate_in * /* Multiply offset input values */ |
|||
(INPUT(in[i]) + PARAM(in_offset[i])); |
|||
} |
|||
|
|||
|
|||
if(ANALYSIS != MIF_AC) { /* DC & Transient */ |
|||
|
|||
for (i=0; i<size; i++) { /* Partials are product of all gains and */ |
|||
/* inputs divided by each individual */ |
|||
/* input value. */ |
|||
|
|||
if (0.0 != accumulate_in) { /* make sure that no division by zero |
|||
will occur.... */ |
|||
PARTIAL(out,in[i]) = (accumulate_in/(INPUT(in[i]) + |
|||
PARAM(in_offset[i]))) * accumulate_gain * final_gain; |
|||
} |
|||
else { /* otherwise, set partial to zero. */ |
|||
PARTIAL(out,in[i]) = 0.0; |
|||
} |
|||
|
|||
} |
|||
|
|||
OUTPUT(out) = accumulate_in * accumulate_gain * final_gain + |
|||
PARAM(out_offset); |
|||
} |
|||
|
|||
else { /* AC Analysis */ |
|||
|
|||
for (i=0; i<size; i++) { /* Partials are product of all gains and */ |
|||
/* inputs divided by each individual */ |
|||
/* input value. */ |
|||
ac_gain.real = (accumulate_in/(INPUT(in[i]) + |
|||
PARAM(in_offset[i]))) * accumulate_gain * final_gain; |
|||
ac_gain.imag = 0.0; |
|||
AC_GAIN(out,in[i]) = ac_gain; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog mult code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_mult |
|||
Spice_Model_Name: mult |
|||
Description: "multiplier block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input array" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: yes no |
|||
Vector_Bounds: [2 -] - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: in_offset in_gain |
|||
Description: "input offset array" "input gain array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: yes yes |
|||
Vector_Bounds: in in |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_gain out_offset |
|||
Description: "output gain" "output offset" |
|||
Data_Type: real real |
|||
Default_Value: 1.0 0.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,568 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE oneshot/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
17 Sep 1991 Jeffrey P. Murray |
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the oneshot code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_set_temp_bkpt() |
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "oneshot.h" |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_oneshot() |
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
17 Sep 1991 Jeffrey P. Murray |
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the oneshot code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_set_temp_bkpt() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_ONESHOT ROUTINE ===*/ |
|||
|
|||
/*************************************************************************************** |
|||
* |
|||
* This model describes a totally analog oneshot. |
|||
* After a rising edge is detected, the model will |
|||
* output a pulse width specified by the controling |
|||
* voltage. |
|||
* HWL 20Mar91 |
|||
* |
|||
* |
|||
* |
|||
* ___________________________________ |
|||
* /<---pulse width ---> :\ |
|||
* / : : : \ |
|||
* <---rise_delay--> / : :<-fall_delay->: \ |
|||
* ___|________________/ : : : \____________ |
|||
* ^ <-->: : :<--> |
|||
* Trigger Risetime Falltime |
|||
* |
|||
* |
|||
****************************************************************************************/ |
|||
|
|||
void cm_oneshot(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int *locked; /* pointer used to store the locked1 variable */ |
|||
int locked1; /* flag which allows the time points to be |
|||
reset. value determined by retrig parameter */ |
|||
int cntl_size; /* size of the control array */ |
|||
int pw_size; /* size of the pulse-width array */ |
|||
int *state; /* pointer used to store state1 variable */ |
|||
int state1; /* if state1 = 1, then oneshot has |
|||
been triggered. if state1 = 0, no change */ |
|||
int *set; /* pointer used to store the state of set1 */ |
|||
int set1; /* flag used to set/reset the oneshot */ |
|||
int trig_pos_edge; /* flag used to define positive or negative |
|||
edge triggering. 1=positive, 0=negative */ |
|||
|
|||
double *x; /* pointer used to store the control array */ |
|||
double *y; /* pointer used to store the pulse-width array */ |
|||
double cntl_input; /* the actual value of the control input */ |
|||
double out; /* value of the output */ |
|||
double dout_din; /* slope of the pw wrt the control voltage */ |
|||
double output_low; /* output low value */ |
|||
double output_hi; /* output high value */ |
|||
double pw; /* actual value of the pulse-width */ |
|||
/* double del_out; value of the delay time between triggering |
|||
and a change in the output */ |
|||
double del_rise; /* value of the delay time between triggering |
|||
and a change in the output */ |
|||
double del_fall; /* value of the delay time between the end of the |
|||
pw and a change in the output */ |
|||
double *t1; /* pointer used to store time1 */ |
|||
double *t2; /* pointer used to store time2 */ |
|||
double *t3; /* pointer used to store time3 */ |
|||
double *t4; /* pointer used to store time4 */ |
|||
double time1; /* time at which the output first begins to |
|||
change (trigger + delay) */ |
|||
double time2; /* time2 = time1 + risetime */ |
|||
double time3; /* time3 = time2 + pw */ |
|||
double time4; /* time4 = time3 + falltime */ |
|||
double t_rise; /* risetime */ |
|||
double t_fall; /* falltime */ |
|||
double *output_old;/* pointer which stores the previous output */ |
|||
double *clock; /* pointer which stores the clock */ |
|||
double *old_clock; /* pointer which stores the previous clock */ |
|||
double trig_clk; /* value at which the clock triggers the oneshot */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
/**** Retrieve frequently used parameters... ****/ |
|||
|
|||
cntl_size = PARAM_SIZE(cntl_array); |
|||
pw_size = PARAM_SIZE(pw_array); |
|||
trig_clk = PARAM(clk_trig); |
|||
trig_pos_edge = PARAM(pos_edge_trig); |
|||
output_low = PARAM(out_low); |
|||
output_hi = PARAM(out_high); |
|||
/*del_out = PARAM(delay);*/ |
|||
del_rise = PARAM(rise_delay); |
|||
del_fall = PARAM(fall_delay); |
|||
t_rise = PARAM(rise_time); |
|||
t_fall = PARAM(fall_time); |
|||
|
|||
/* set minimum rise and fall_times */ |
|||
|
|||
if(t_rise < 1e-12){ |
|||
t_rise = 1e-12; |
|||
} |
|||
|
|||
if(t_fall < 1e-12){ |
|||
t_fall = 1e-12; |
|||
} |
|||
|
|||
/* the control array must be the same size as the pulse-width array */ |
|||
|
|||
if(cntl_size != pw_size){ |
|||
cm_message_send(oneshot_array_error); |
|||
return; |
|||
} |
|||
|
|||
if(INIT == 1){ /* first time through, allocate memory */ |
|||
|
|||
t1 = cm_analog_alloc(T1,sizeof(double)); |
|||
t2 = cm_analog_alloc(T2,sizeof(double)); |
|||
t3 = cm_analog_alloc(T3,sizeof(double)); |
|||
t4 = cm_analog_alloc(T4,sizeof(double)); |
|||
set = cm_analog_alloc(SET,sizeof(int)); |
|||
state = cm_analog_alloc(STATE,sizeof(int)); |
|||
clock = cm_analog_alloc(CLOCK,sizeof(double)); |
|||
locked = cm_analog_alloc(LOCKED,sizeof(int)); |
|||
output_old = cm_analog_alloc(OUTPUT_OLD,sizeof(double)); |
|||
|
|||
} |
|||
|
|||
if(ANALYSIS == MIF_DC){ |
|||
|
|||
/* for DC, initialize values and set the output = output_low */ |
|||
|
|||
t1 = cm_analog_get_ptr(T1,0); |
|||
t2 = cm_analog_get_ptr(T2,0); |
|||
t3 = cm_analog_get_ptr(T3,0); |
|||
t4 = cm_analog_get_ptr(T4,0); |
|||
set = cm_analog_get_ptr(SET,0); |
|||
state = cm_analog_get_ptr(STATE,0); |
|||
locked = cm_analog_get_ptr(LOCKED,0); |
|||
output_old = cm_analog_get_ptr(OUTPUT_OLD,0); |
|||
|
|||
/* initialize time and state values */ |
|||
*t1 = -1; |
|||
*t2 = -1; |
|||
*t3 = -1; |
|||
*t4 = -1; |
|||
*set = 0; |
|||
*locked = 0; |
|||
*state = 0; |
|||
*output_old = output_low; |
|||
|
|||
OUTPUT(out) = output_low; |
|||
if(PORT_NULL(cntl_in) != 1){ |
|||
PARTIAL(out,cntl_in) = 0; |
|||
} |
|||
if(PORT_NULL(clear) != 1){ |
|||
PARTIAL(out,clear) = 0; |
|||
} |
|||
PARTIAL(out,clk) = 0; |
|||
|
|||
}else |
|||
|
|||
if(ANALYSIS == MIF_TRAN){ |
|||
|
|||
/* retrieve previous values, set them equal to the variables |
|||
Note that these pointer values are immediately dumped into |
|||
other variables because the previous values can't change- |
|||
can't rewrite the old values */ |
|||
|
|||
t1 = cm_analog_get_ptr(T1,1); |
|||
t2 = cm_analog_get_ptr(T2,1); |
|||
t3 = cm_analog_get_ptr(T3,1); |
|||
t4 = cm_analog_get_ptr(T4,1); |
|||
set = cm_analog_get_ptr(SET,1); |
|||
state = cm_analog_get_ptr(STATE,1); |
|||
locked = cm_analog_get_ptr(LOCKED,1); |
|||
clock = cm_analog_get_ptr(CLOCK,0); |
|||
old_clock = cm_analog_get_ptr(CLOCK,1); |
|||
output_old = cm_analog_get_ptr(OUTPUT_OLD,1); |
|||
|
|||
time1 = *t1; |
|||
time2 = *t2; |
|||
time3 = *t3; |
|||
time4 = *t4; |
|||
set1 = *set; |
|||
state1 = *state; |
|||
locked1 = *locked; |
|||
|
|||
if((PORT_NULL(clear) != 1) && (INPUT(clear) > trig_clk)){ |
|||
|
|||
time1 = -1; |
|||
time2 = -1; |
|||
time3 = -1; |
|||
time4 = -1; |
|||
set1 = 0; |
|||
locked1 = 0; |
|||
state1 = 0; |
|||
|
|||
OUTPUT(out) = output_low; |
|||
|
|||
|
|||
}else{ |
|||
|
|||
/* Allocate storage for breakpoint domain & freq. range values */ |
|||
|
|||
x = (double *) calloc(cntl_size, sizeof(double)); |
|||
if (x == '\0') { |
|||
cm_message_send(oneshot_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
y = (double *) calloc(pw_size, sizeof(double)); |
|||
if (y == '\0') { |
|||
cm_message_send(oneshot_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
|
|||
/* Retrieve control and pulse-width values. */ |
|||
for (i=0; i<cntl_size; i++) { |
|||
*(x+i) = PARAM(cntl_array[i]); |
|||
*(y+i) = PARAM(pw_array[i]); |
|||
} |
|||
|
|||
|
|||
/* Retrieve cntl_input and clock value. */ |
|||
|
|||
if(PORT_NULL(cntl_in) != 1){ |
|||
|
|||
cntl_input = INPUT(cntl_in); |
|||
|
|||
}else{ |
|||
|
|||
cntl_input = 0; |
|||
|
|||
} |
|||
|
|||
*clock = INPUT(clk); |
|||
|
|||
|
|||
|
|||
|
|||
/* Determine segment boundaries within which cntl_input resides */ |
|||
|
|||
if (cntl_input <= *x) { /* cntl_input below lowest cntl_voltage */ |
|||
dout_din = (*(y+1) - *y)/(*(x+1) - *x); |
|||
pw = *y + (cntl_input - *x) * dout_din; |
|||
|
|||
if(pw < 0){ |
|||
cm_message_send(oneshot_pw_clamp); |
|||
pw = 0; |
|||
} |
|||
} |
|||
else |
|||
/*** cntl_input above highest cntl_voltage ***/ |
|||
|
|||
if (cntl_input >= *(x+cntl_size-1)){ |
|||
dout_din = (*(y+cntl_size-1) - *(y+cntl_size-2)) / |
|||
(*(x+cntl_size-1) - *(x+cntl_size-2)); |
|||
pw = *(y+cntl_size-1) + (cntl_input - *(x+cntl_size-1)) * dout_din; |
|||
|
|||
} else { /*** cntl_input within bounds of end midpoints... |
|||
must determine position progressively & then |
|||
calculate required output. ***/ |
|||
|
|||
for (i=0; i<cntl_size-1; i++) { |
|||
|
|||
if ((cntl_input < *(x+i+1)) && (cntl_input >= *(x+i))){ |
|||
|
|||
/* Interpolate to get the correct pulse width value */ |
|||
|
|||
pw = ((cntl_input - *(x+i))/(*(x+i+1) - *(x+i)))* |
|||
(*(y+i+1)-*(y+i)) + *(y+i); |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
if(trig_pos_edge){ /* for a positive edge trigger */ |
|||
|
|||
if(!set1){ /* if set1=0, then look for |
|||
1. a rising edge trigger |
|||
2. the clock to be higher than the trigger value */ |
|||
|
|||
if((*clock > *old_clock) && (*clock > trig_clk)){ |
|||
|
|||
state1 = 1; |
|||
set1 = 1; |
|||
|
|||
} |
|||
|
|||
}else |
|||
|
|||
/* look for a neg edge before resetting the trigger */ |
|||
|
|||
if((*clock < *old_clock) && (*clock < trig_clk)){ |
|||
|
|||
set1 = 0; |
|||
|
|||
} |
|||
|
|||
}else{ |
|||
/* This stuff belongs to the case where a negative edge |
|||
is needed */ |
|||
|
|||
if(!set1){ |
|||
|
|||
if((*clock < *old_clock) && (*clock < trig_clk)){ |
|||
|
|||
state1 = 1; |
|||
set1 = 1; |
|||
|
|||
} |
|||
|
|||
}else |
|||
/* look for a pos edge before resetting the trigger */ |
|||
|
|||
if((*clock > *old_clock) && (*clock > trig_clk)){ |
|||
|
|||
set1 = 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
/* I can only set the breakpoints if the state1 is high and |
|||
the output is low, and locked = 0 */ |
|||
if((state1) && (*output_old - output_low < 1e-20) && (!locked1)){ |
|||
|
|||
/* if state1 is 1, and the output is low, then set the time points |
|||
and the temporary breakpoints */ |
|||
|
|||
time1 = TIME + del_rise; |
|||
time2 = time1 + t_rise; |
|||
time3 = time2 + pw + del_fall; |
|||
time4 = time3 + t_fall; |
|||
|
|||
if(PARAM(retrig) == MIF_FALSE){ |
|||
|
|||
locked1 = 1; |
|||
|
|||
} |
|||
|
|||
if((TIME < time1) || (T(1) == 0)){ |
|||
cm_analog_set_temp_bkpt(time1); |
|||
} |
|||
|
|||
cm_analog_set_temp_bkpt(time2); |
|||
cm_analog_set_temp_bkpt(time3); |
|||
cm_analog_set_temp_bkpt(time4); |
|||
|
|||
/* reset the state value */ |
|||
state1 = 0; |
|||
OUTPUT(out) = output_low; |
|||
|
|||
}else |
|||
|
|||
/* state1 = 1, and the output is high, then just set time3 and time4 |
|||
and their temporary breakpoints This implies that the oneshot was |
|||
retriggered */ |
|||
|
|||
if((state1) && (*output_old - output_hi < 1e-20) && (!locked1)){ |
|||
|
|||
time3 = TIME + pw + del_rise + del_fall + t_rise; |
|||
time4 = time3 + t_fall; |
|||
|
|||
cm_analog_set_temp_bkpt(time3); |
|||
cm_analog_set_temp_bkpt(time4); |
|||
|
|||
OUTPUT(out) = output_hi; |
|||
|
|||
state1 = 0; |
|||
|
|||
} |
|||
|
|||
/* reset the state if it's 1 and the locked flag is 1. This |
|||
means that the clock tried to retrigger the oneshot, but |
|||
the retrig flag prevented it from doing so */ |
|||
|
|||
if((state1) && (locked1)){ |
|||
|
|||
state1 = 0; |
|||
|
|||
} |
|||
/* set the value for the output depending on the current time, and |
|||
the values of time1, time2, time3, and time4 */ |
|||
if(TIME < time1){ |
|||
|
|||
OUTPUT(out) = output_low; |
|||
|
|||
}else |
|||
if((time1 <= TIME) && (TIME < time2)){ |
|||
|
|||
OUTPUT(out) = output_low + ((TIME - time1)/(time2 - time1))* |
|||
(output_hi - output_low); |
|||
|
|||
}else |
|||
if((time2 <= TIME) && (TIME < time3)){ |
|||
|
|||
OUTPUT(out) = output_hi; |
|||
|
|||
}else |
|||
if((time3 <= TIME) && (TIME < time4)){ |
|||
|
|||
OUTPUT(out) = output_hi + ((TIME - time3)/(time4 - time3))* |
|||
(output_low - output_hi); |
|||
|
|||
}else{ |
|||
|
|||
|
|||
OUTPUT(out) = output_low; |
|||
|
|||
/* oneshot can now be retriggered, set locked to 0 */ |
|||
if(PARAM(retrig) == MIF_FALSE){ |
|||
|
|||
locked1 = 0; |
|||
|
|||
} |
|||
} |
|||
|
|||
/* set the variables which need to be stored for the next iteration */ |
|||
} |
|||
t1 = cm_analog_get_ptr(T1,0); |
|||
t2 = cm_analog_get_ptr(T2,0); |
|||
t3 = cm_analog_get_ptr(T3,0); |
|||
t4 = cm_analog_get_ptr(T4,0); |
|||
set = cm_analog_get_ptr(SET,0); |
|||
locked = cm_analog_get_ptr(LOCKED,0); |
|||
state = cm_analog_get_ptr(STATE,0); |
|||
output_old = cm_analog_get_ptr(OUTPUT_OLD,0); |
|||
|
|||
*t1 = time1; |
|||
*t2 = time2; |
|||
*t3 = time3; |
|||
*t4 = time4; |
|||
*set = set1; |
|||
*state = state1; |
|||
*output_old = OUTPUT(out); |
|||
*locked = locked1; |
|||
|
|||
if(PORT_NULL(cntl_in) != 1){ |
|||
PARTIAL(out,cntl_in) = 0; |
|||
} |
|||
if(PORT_NULL(clear) != 1){ |
|||
PARTIAL(out,clear) = 0; |
|||
} |
|||
PARTIAL(out,clk) = 0 ; |
|||
|
|||
} else { /* Output AC Gain */ |
|||
|
|||
/* This model has no AC capability */ |
|||
|
|||
ac_gain.real = 0.0; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,clk) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,117 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog oneshot code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_oneshot |
|||
Spice_Model_Name: oneshot |
|||
Description: "one-shot" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: clk cntl_in |
|||
Description: "clock input" "input" |
|||
Direction: in in |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,vnam,i,id] [v,vnam,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no yes |
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: clear out |
|||
Description: "clear signal" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,vnam,i,id] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes no |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: cntl_array pw_array |
|||
Description: "control in array" "pulse width array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0e-6 |
|||
Limits: - [0 -] |
|||
Vector: yes yes |
|||
Vector_Bounds: [2 -] [2 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: clk_trig pos_edge_trig |
|||
Description: "clock trigger value" "pos/neg edge trigger switch" |
|||
Data_Type: real boolean |
|||
Default_Value: 0.5 TRUE |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: out_low out_high |
|||
Description: "output low value" "output high value" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: rise_time |
|||
Description: "output rise time" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-9 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: rise_delay fall_delay |
|||
Description: "output delay from trigger" "output delay from pw" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-9 1.0e-9 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: fall_time retrig |
|||
Description: "output rise time" "retrigger switch" |
|||
Data_Type: real boolean |
|||
Default_Value: 1.0e-9 FALSE |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
@ -0,0 +1,43 @@ |
|||
/************************************************/ |
|||
/****** Structures, etc. for pwl model. ******/ |
|||
/****** 10/10/90 JPM ******/ |
|||
/************************************************/ |
|||
|
|||
|
|||
|
|||
/**** Error Messages ****/ |
|||
|
|||
char *oneshot_allocation_error = "\n**** Error ****\nONESHOT: Error allocating oneshot block storage \n"; |
|||
char *oneshot_array_error = "\n**** Error ****\nONESHOT: Size of control array different than pulse-width array \n"; |
|||
char *oneshot_pw_clamp = "\n**** Warning ****\nONESHOT: Extrapolated Pulse-Width Limited to zero \n"; |
|||
|
|||
|
|||
#define T1 1 |
|||
#define T2 2 |
|||
#define T3 3 |
|||
#define T4 4 |
|||
#define SET 5 |
|||
#define STATE 6 |
|||
#define CLOCK 7 |
|||
#define OUTPUT_OLD 8 |
|||
#define LOCKED 9 |
|||
|
|||
/***** Define Error Messages **************************************/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/***** Structure Definitions *************************************/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/***** Function Definitions ***************************************/ |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,520 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE pwl/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
19 Apr 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
25 Sep 1991 Jeffrey P. Murray |
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the pwl (piece-wise linear) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void cm_analog_not_converged() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <math.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define FRACTION 0.30 |
|||
#define EPSILON 1.0e-9 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION double limit_x_value() |
|||
|
|||
AUTHORS |
|||
|
|||
25 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
Limits a passed input value to some fraction |
|||
of the segment length defined by |
|||
(x_upper - x_lower). The fractional value in |
|||
question is passed as a value to the routine |
|||
(fraction). |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CM.c void cm_analog_not_converged() |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns a double. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== Static LIMIT_X_VALUE ROUTINE ================*/ |
|||
|
|||
/** limit_x_value ******************************************/ |
|||
/** **/ |
|||
/** Limits a passed input value to some fraction **/ |
|||
/** of the segment length defined by **/ |
|||
/** (x_upper - x_lower). The fractional value in **/ |
|||
/** question is passed as a value to the routine **/ |
|||
/** (fraction). **/ |
|||
/** **/ |
|||
/** 9/25/91 JPM **/ |
|||
/***********************************************************/ |
|||
|
|||
static double limit_x_value(double x_lower,double x_upper, |
|||
double x_input,double fraction, |
|||
double *last_x_value) |
|||
{ |
|||
double max_x_delta, /* maximum delta value permissible for |
|||
this segment domain. */ |
|||
hold; /* Holding variable for previous x_input value */ |
|||
|
|||
|
|||
/** Limit effective change of input to fraction of value of lowest **/ |
|||
/** x-segment length... **/ |
|||
|
|||
/* calculate maximum delta value for this region */ |
|||
max_x_delta = fraction * (x_upper - x_lower); |
|||
|
|||
/* Test new input */ |
|||
if ( max_x_delta < fabs(x_input - *last_x_value) ) { |
|||
|
|||
hold = x_input; |
|||
|
|||
/* Assign new x_input based of direction of movement */ |
|||
/* since last iteration call */ |
|||
if ( 0.0 <= (x_input - *last_x_value) ) { |
|||
x_input = *last_x_value = *last_x_value + max_x_delta; |
|||
} |
|||
else { |
|||
x_input = *last_x_value = *last_x_value - max_x_delta; |
|||
} |
|||
|
|||
/* Alert the simulator to non-convergence */ |
|||
cm_analog_not_converged(); |
|||
|
|||
/*** Debugging printf statement ***/ |
|||
/* printf("Assigning new x_input...\nPrevious value=%e, New value=%e\n\n", |
|||
hold,x_input); |
|||
*/ |
|||
|
|||
} |
|||
else { /* No limiting of x_input required */ |
|||
*last_x_value = x_input; |
|||
} |
|||
|
|||
return x_input; |
|||
|
|||
} |
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_pwl(> |
|||
|
|||
AUTHORS |
|||
|
|||
19 Apr 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
25 Sep 1991 Jeffrey P. Murray |
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the pwl code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_smooth_corner(); |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void cm_analog_not_converged() |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_PWL ROUTINE ================*/ |
|||
|
|||
void cm_pwl(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int size; /* size of the x_array */ |
|||
|
|||
double input_domain; /* smoothing range */ |
|||
double *x; /* pointer to the x-coordinate array */ |
|||
double *y; /* pointer to the y-coordinate array */ |
|||
double lower_seg; /* x segment below which input resides */ |
|||
double upper_seg; /* x segment above which the input resides */ |
|||
double lower_slope; /* slope of the lower segment */ |
|||
double upper_slope; /* slope of the upper segment */ |
|||
double x_input; /* input */ |
|||
double out; /* output */ |
|||
double dout_din; /* partial derivative of the output wrt input */ |
|||
double threshold_lower; /* value below which the output begins smoothing */ |
|||
double threshold_upper; /* value above which the output begins smoothing */ |
|||
double test1; /* debug testing value */ |
|||
double test2; /* debug testing value */ |
|||
double *last_x_value; /* static variable for limiting */ |
|||
double test; /* temp storage variable for limit testing */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
char *allocation_error="\n***ERROR***\nPWL: Allocation calloc failed!\n"; |
|||
char *limit_error="\n***ERROR***\nPWL: Violation of 50% rule in breakpoints!\n"; |
|||
|
|||
/* Retrieve frequently used parameters... */ |
|||
|
|||
input_domain = PARAM(input_domain); |
|||
|
|||
size = PARAM_SIZE(x_array); |
|||
|
|||
|
|||
|
|||
if (INIT==1) { /* First pass...allocate storage for previous value... */ |
|||
|
|||
/* Allocate storage for last_x_value */ |
|||
STATIC_VAR(last_x_value) = (double *) malloc(sizeof(double)); |
|||
last_x_value = STATIC_VAR(last_x_value); |
|||
|
|||
/* Allocate storage for breakpoint domain & range values */ |
|||
STATIC_VAR(x) = (double *) calloc(size, sizeof(double)); |
|||
x = STATIC_VAR(x); |
|||
if (x == '\0') { |
|||
cm_message_send(allocation_error); |
|||
} |
|||
|
|||
STATIC_VAR(y) = (double *) calloc(size, sizeof(double)); |
|||
y = STATIC_VAR(y); |
|||
if (y == '\0') { |
|||
cm_message_send(allocation_error); |
|||
} |
|||
|
|||
/* Retrieve x and y values. */ |
|||
for (i=0; i<size; i++) { |
|||
x[i] = PARAM(x_array[i]); |
|||
y[i] = PARAM(y_array[i]); |
|||
} |
|||
|
|||
} |
|||
else { |
|||
|
|||
last_x_value = STATIC_VAR(last_x_value); |
|||
|
|||
x = STATIC_VAR(x); |
|||
|
|||
y = STATIC_VAR(y); |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/* See if input_domain is absolute...if so, test against */ |
|||
/* breakpoint segments for violation of 50% rule... */ |
|||
if (PARAM(fraction) == MIF_FALSE) { |
|||
if ( 3 < size ) { |
|||
for (i=1; i<(size-2); i++) { |
|||
/* Test for overlap...0.999999999 factor is to */ |
|||
/* prevent floating point problems with comparison. */ |
|||
if ( (test1 = x[i+1] - x[i]) < |
|||
(test2 = 0.999999999 * (2.0 * input_domain)) ) { |
|||
cm_message_send(limit_error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/* Retrieve x_input value. */ |
|||
x_input = INPUT(in); |
|||
|
|||
|
|||
/* If this is the first call, set *last_x_value to x_input */ |
|||
if (INIT == 1) |
|||
*last_x_value=x_input; |
|||
|
|||
|
|||
/*** Add debugging printf statement ***/ |
|||
/* printf("Last x_input=%e, Current x_input=%e,\n", |
|||
*last_x_value,x_input); |
|||
*/ |
|||
|
|||
|
|||
/**** Add internal limiting to input value ****/ |
|||
|
|||
/* Determine region of input, and limit accordingly */ |
|||
if ( *last_x_value < x[0] ) { /** Non-limited input less than x[0] **/ |
|||
|
|||
/* Obtain the test value of the input, if it has changed excessively */ |
|||
if ( (x[0] - x_input) > (x[1] - x[0]) ) { |
|||
test = limit_x_value(x_input,x[0],x_input,FRACTION,last_x_value); |
|||
} |
|||
else { |
|||
test = limit_x_value(x[0],x[1],x_input,FRACTION,last_x_value); |
|||
} |
|||
|
|||
/* If the test value is greater than x[0], force to x[0] */ |
|||
if ( test >= x[0] ) { |
|||
x_input = *last_x_value = x[0]; |
|||
|
|||
/* Alert the simulator to non-convergence */ |
|||
cm_analog_not_converged(); |
|||
} |
|||
else { |
|||
x_input = *last_x_value = test; |
|||
} |
|||
} |
|||
else |
|||
if ( *last_x_value >= x[size-1] ) { /** Non-Limited input greater than x[size-1] **/ |
|||
|
|||
/* Obtain the test value of the input, if it has changed excessively */ |
|||
if ( (x_input - x[size-1]) > (x[size-1] - x[size-2]) ) { |
|||
test = limit_x_value(x[size-1],x_input,x_input,FRACTION,last_x_value); |
|||
} |
|||
else { |
|||
test = limit_x_value(x[size-2],x[size-1],x_input,FRACTION,last_x_value); |
|||
} |
|||
|
|||
/* If the test value is less than x[size-1], force to x[size-1] */ |
|||
/* minus some epsilon value. */ |
|||
if ( test < x[size-1] ) { |
|||
x_input = *last_x_value = x[size-1] - EPSILON; |
|||
|
|||
/* Alert the simulator to non-convergence */ |
|||
cm_analog_not_converged(); |
|||
} |
|||
else { |
|||
x_input = *last_x_value = test; |
|||
} |
|||
} |
|||
else { |
|||
for (i=1; i<size; i++) { |
|||
if ( *last_x_value < x[i] ) { |
|||
|
|||
/* Obtain the test value of the input */ |
|||
test = limit_x_value(x[i-1],x[i],x_input,FRACTION,last_x_value); |
|||
|
|||
/* If the test value is greater than x[i], force to x[i] */ |
|||
if ( test > x[i] ) { |
|||
x_input = *last_x_value = x[i]; |
|||
|
|||
/* Alert the simulator to non-convergence */ |
|||
cm_analog_not_converged(); |
|||
|
|||
break; |
|||
} |
|||
else |
|||
/* If the test value is less than x[i-1], force to x[i-1] */ |
|||
/* minus some epsilon value... */ |
|||
if ( test < x[i-1] ) { |
|||
x_input = *last_x_value = x[i-1] - EPSILON; |
|||
|
|||
/* Alert the simulator to non-convergence */ |
|||
cm_analog_not_converged(); |
|||
|
|||
break; |
|||
} |
|||
else { /* Use returned value for next input */ |
|||
x_input = *last_x_value = test; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* Assign new limited value back to the input for */ |
|||
/* use in the matrix calculations.... */ |
|||
INPUT(in) = x_input; |
|||
|
|||
|
|||
/*** Add debugging printf statement ***/ |
|||
/* printf("Limited x_input=%e\n\n", |
|||
x_input); |
|||
*/ |
|||
|
|||
|
|||
/**** End internal limiting ****/ |
|||
|
|||
|
|||
|
|||
/* Determine segment boundaries within which x_input resides */ |
|||
|
|||
if (x_input <= (x[0] + x[1])/2.0) {/*** x_input below lowest midpoint ***/ |
|||
dout_din = (y[1] - y[0])/(x[1] - x[0]); |
|||
|
|||
|
|||
/* Compute new output */ |
|||
out = y[0] + (x_input - x[0]) * dout_din; |
|||
|
|||
} |
|||
else { |
|||
if (x_input >= (x[size-2] + x[size-1])/2.0) { |
|||
/*** x_input above highest midpoint ***/ |
|||
dout_din = (y[size-1] - y[size-2]) / |
|||
(x[size-1] - x[size-2]); |
|||
|
|||
out = y[size-1] + (x_input - x[size-1]) * dout_din; |
|||
} |
|||
else { /*** x_input within bounds of end midpoints... ***/ |
|||
/*** must determine position progressively & then ***/ |
|||
/*** calculate required output. ***/ |
|||
|
|||
for (i=1; i<size; i++) { |
|||
|
|||
if (x_input < (x[i] + x[i+1])/2.0) { |
|||
/* approximate position known... */ |
|||
|
|||
lower_seg = (x[i] - x[i-1]); |
|||
upper_seg = (x[i+1] - x[i]); |
|||
|
|||
|
|||
/* Calculate input_domain about this region's breakpoint.*/ |
|||
|
|||
if (PARAM(fraction) == MIF_TRUE) { /* Translate input_domain */ |
|||
/* into an absolute.... */ |
|||
if ( lower_seg <= upper_seg ) /* Use lower */ |
|||
/* segment */ |
|||
/* for % calc.*/ |
|||
input_domain = input_domain * lower_seg; |
|||
else /* Use upper */ |
|||
/* segment */ |
|||
/* for % calc.*/ |
|||
input_domain = input_domain * upper_seg; |
|||
} |
|||
|
|||
/* Set up threshold values about breakpoint... */ |
|||
threshold_lower = x[i] - input_domain; |
|||
threshold_upper = x[i] + input_domain; |
|||
|
|||
/* Determine where x_input is within region & determine */ |
|||
/* output and partial values.... */ |
|||
if (x_input < threshold_lower) { /* Lower linear region */ |
|||
dout_din = (y[i] - y[i-1])/lower_seg; |
|||
|
|||
out = y[i] + (x_input - x[i]) * dout_din; |
|||
} |
|||
else { |
|||
if (x_input < threshold_upper) { /* Parabolic region */ |
|||
lower_slope = (y[i] - y[i-1])/lower_seg; |
|||
upper_slope = (y[i+1] - y[i])/upper_seg; |
|||
|
|||
cm_smooth_corner(x_input,x[i],y[i],input_domain, |
|||
lower_slope,upper_slope,&out,&dout_din); |
|||
} |
|||
else { /* Upper linear region */ |
|||
dout_din = (y[i+1] - y[i])/upper_seg; |
|||
out = y[i] + (x_input - x[i]) * dout_din; |
|||
} |
|||
} |
|||
break; /* Break search loop...x_input has been found, */ |
|||
/* and out and dout_din have been assigned. */ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
if(ANALYSIS != MIF_AC) { /* Output DC & Transient Values */ |
|||
OUTPUT(out) = out; |
|||
PARTIAL(out,in) = dout_din; |
|||
} |
|||
else { /* Output AC Gain */ |
|||
ac_gain.real = dout_din; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,78 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
19 Apr 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog pwl code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_pwl |
|||
Spice_Model_Name: pwl |
|||
Description: "piecwise linear controlled source" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: x_array y_array |
|||
Description: "x-element array" "y-element array" |
|||
Data_Type: real real |
|||
Default_Value: - - |
|||
Limits: - - |
|||
Vector: yes yes |
|||
Vector_Bounds: [2 -] [2 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: input_domain fraction |
|||
Description: "input sm. domain" "smoothing %/abs switch" |
|||
Data_Type: real boolean |
|||
Default_Value: 0.01 TRUE |
|||
Limits: [1e-12 0.5] - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
STATIC_VAR_TABLE: |
|||
|
|||
Static_Var_Name: last_x_value |
|||
Data_Type: pointer |
|||
Vector: no |
|||
Description: "iteration holding variable for limiting" |
|||
|
|||
|
|||
STATIC_VAR_TABLE: |
|||
|
|||
Static_Var_Name: x y |
|||
Data_Type: pointer pointer |
|||
Description: "x-coefficient array" "y-coefficient array" |
|||
|
|||
|
|||
@ -0,0 +1,606 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE s_xfer/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
17 Mar 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
18 Apr 1991 Harry Li |
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the s-domain |
|||
transfer function (s_xfer) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_integrate() |
|||
|
|||
|
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <math.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================= |
|||
|
|||
FUNCTION cm_complex_div |
|||
|
|||
AUTHORS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
Performs a complex division. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
A Mif_Complex_t value representing the result of the complex division. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== Static CM_COMPLEX_DIV ROUTINE ===*/ |
|||
|
|||
/**** Cm_complex_div Function - FAKE ***********/ |
|||
/* */ |
|||
/* Function will not be used in finished */ |
|||
/* system...provides a stub for performing */ |
|||
/* a simple complex division. */ |
|||
/* 12/3/90 JPM */ |
|||
/* */ |
|||
/***********************************************/ |
|||
|
|||
static Mif_Complex_t cm_complex_div(Mif_Complex_t x, Mif_Complex_t y) |
|||
{ |
|||
double mag_x, phase_x, mag_y, phase_y; |
|||
|
|||
Mif_Complex_t out; |
|||
|
|||
mag_x = sqrt( (x.real * x.real) + (x.imag * x.imag) ); |
|||
phase_x = atan2(x.imag, x.real); |
|||
|
|||
mag_y = sqrt( (y.real * y.real) + (y.imag * y.imag) ); |
|||
phase_y = atan2(y.imag, y.real); |
|||
|
|||
mag_x = mag_x/mag_y; |
|||
phase_x = phase_x - phase_y; |
|||
|
|||
out.real = mag_x * cos(phase_x); |
|||
out.imag = mag_x * sin(phase_x); |
|||
|
|||
return out; |
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_s_xfer() |
|||
|
|||
AUTHORS |
|||
|
|||
17 Mar 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
18 Apr 1991 Harry Li |
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the s_xfer code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_integrate() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_S_XFER ROUTINE ===*/ |
|||
|
|||
/**************************************** |
|||
* S-Domain Transfer Function - * |
|||
* Code Body * |
|||
* * |
|||
* Last Modified - 9/27/91 JPM * |
|||
****************************************/ |
|||
|
|||
void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */ |
|||
{ |
|||
double *out; /* pointer to the output */ |
|||
double *in; /* pointer to the input */ |
|||
double in_offset; /* input offset */ |
|||
double *gain; /* pointer to the gain */ |
|||
double **den_coefficient; /* dynamic array that holds the denominator |
|||
coefficients */ |
|||
double **old_den_coefficient;/* dynamic array that holds the old |
|||
denonminator coefficients */ |
|||
double **num_coefficient; /* dynamic array that holds the numerator |
|||
coefficients */ |
|||
double **old_num_coefficient;/* dynamic array that holds the old numerator |
|||
coefficients */ |
|||
double factor; /* gain factor in case the highest |
|||
denominator coefficient is not 1 */ |
|||
double **integrator; /* outputs of the integrators */ |
|||
double **old_integrator; /* previous integrator outputs */ |
|||
double null; /* dummy pointer for use with the |
|||
integrate function */ |
|||
double pout_pin; /* partial out wrt in */ |
|||
double total_gain; /* not used, currently-used with ITP stuff */ |
|||
double temp; /* temporary variable used with the |
|||
correct type of AC value */ |
|||
double frac; /* holds fractional part of a divide */ |
|||
double divide_integer; /* integer part of a modf used in AC */ |
|||
double denormalized_freq; /* denormalization constant...the nominal |
|||
corner or center frequencies specified |
|||
by the model coefficients will be |
|||
denormalized by this amount. Thus, if |
|||
coefficients were obtained which specified |
|||
a 1 rad/sec cornere frequency, specifying |
|||
a value of 1000.0 for denormalized_freq |
|||
will cause the model to shift the corner |
|||
freq. to 2.0 * pi * 1000.0 */ |
|||
double *old_gain; /* pointer to the gain if the highest order |
|||
denominator coefficient is not factored out */ |
|||
|
|||
Mif_Complex_t ac_gain, acc_num, acc_den; |
|||
|
|||
int i; /* generic loop counter index */ |
|||
int den_size; /* size of the denominator coefficient array */ |
|||
int num_size; /* size of the numerator coefficient array */ |
|||
|
|||
char *num_size_error="\n***ERROR***\nS_XFER: Numerator coefficient array size greater than\ndenominator coefficiant array size.\n"; |
|||
|
|||
|
|||
|
|||
/** Retrieve frequently used parameters (used by all analyses)... **/ |
|||
|
|||
in_offset = PARAM(in_offset); |
|||
num_size = PARAM_SIZE(num_coeff); |
|||
den_size = PARAM_SIZE(den_coeff); |
|||
if ( PARAM_NULL(denormalized_freq) ) { |
|||
denormalized_freq = 1.0; |
|||
} |
|||
else { |
|||
denormalized_freq = PARAM(denormalized_freq); |
|||
} |
|||
|
|||
if ( num_size > den_size ) { |
|||
cm_message_send(num_size_error); |
|||
return; |
|||
} |
|||
|
|||
/** Test for INIT; if so, allocate storage, otherwise, retrieve previous **/ |
|||
/** timepoint input values as necessary in subsequent analysis sections... **/ |
|||
|
|||
if (INIT==1) { /* First pass...allocate storage for previous values... */ |
|||
|
|||
/* Allocate rotational storage for integrator outputs, in & out */ |
|||
|
|||
|
|||
/***** The following two lines may be unnecessary in the final version *****/ |
|||
|
|||
/* We have to allocate memory and use cm_analog_alloc, because the ITP variables |
|||
are not functional */ |
|||
|
|||
integrator = (double **) calloc(den_size,sizeof(double *)); |
|||
old_integrator = (double **) calloc(den_size,sizeof(double *)); |
|||
|
|||
for (i=0; i<den_size; i++) { |
|||
integrator[i] = cm_analog_alloc(i,sizeof(double)); |
|||
old_integrator[i] = cm_analog_get_ptr(i,0); |
|||
} |
|||
|
|||
|
|||
/* Allocate storage for coefficient values */ |
|||
|
|||
den_coefficient = (double **) calloc(den_size,sizeof(double)); |
|||
|
|||
for(i=den_size;i<(2*den_size);i++){ |
|||
den_coefficient[i-den_size] = cm_analog_alloc(i,sizeof(double)); |
|||
} |
|||
|
|||
num_coefficient = (double **) calloc(num_size,sizeof(double)); |
|||
|
|||
for(i=2*den_size;i<(2*den_size + num_size);i++){ |
|||
num_coefficient[i-2*den_size] = cm_analog_alloc(i,sizeof(double)); |
|||
} |
|||
|
|||
/* I don't really need to allocate old_den_coefficient. It's just that |
|||
I free it at the end of the model every time through */ |
|||
|
|||
old_den_coefficient = (double **) calloc(den_size,sizeof(double)); |
|||
|
|||
out = cm_analog_alloc(2*den_size+num_size,sizeof(double)); |
|||
in = cm_analog_alloc(2*den_size+num_size+1,sizeof(double)); |
|||
|
|||
/* ITP_VAR_SIZE(den) = den_size; */ |
|||
|
|||
gain = cm_analog_alloc(2*den_size+num_size+2,sizeof(double)); |
|||
|
|||
/* gain = (double *) calloc(1,sizeof(double)); |
|||
ITP_VAR(total_gain) = gain; |
|||
ITP_VAR_SIZE(total_gain) = 1.0; */ |
|||
|
|||
}else { /* Allocation was not necessary...retrieve previous values */ |
|||
|
|||
/* Set pointers to storage locations for in, out, and integrators...*/ |
|||
|
|||
integrator = (double **) calloc(den_size,sizeof(double *)); |
|||
old_integrator = (double **) calloc(den_size,sizeof(double *)); |
|||
|
|||
for (i=0; i<den_size; i++) { |
|||
integrator[i] = cm_analog_get_ptr(i,0); |
|||
old_integrator[i] = cm_analog_get_ptr(i,1); |
|||
|
|||
} |
|||
out = cm_analog_get_ptr(2*den_size+num_size,0); |
|||
in = cm_analog_get_ptr(2*den_size+num_size+1,0); |
|||
|
|||
|
|||
/* Set den_coefficient & gain pointers to ITP values */ |
|||
/* for denominator coefficients & gain... */ |
|||
|
|||
old_den_coefficient = (double **) calloc(den_size,sizeof(double)); |
|||
den_coefficient = (double **) calloc(den_size,sizeof(double)); |
|||
|
|||
for(i=den_size;i<2*den_size;i++){ |
|||
old_den_coefficient[i-den_size] = cm_analog_get_ptr(i,1); |
|||
den_coefficient[i-den_size] = cm_analog_get_ptr(i,0); |
|||
*(den_coefficient[i-den_size]) = *(old_den_coefficient[i-den_size]); |
|||
} |
|||
|
|||
num_coefficient = (double **) calloc(num_size,sizeof(double)); |
|||
|
|||
for(i=2*den_size;i<2*den_size+num_size;i++){ |
|||
num_coefficient[i-2*den_size] = cm_analog_get_ptr(i,0); |
|||
} |
|||
|
|||
/* gain has to be stored each time since it could possibly change |
|||
if the highest order denominator coefficient isn't zero. This |
|||
is a hack until the ITP variables work */ |
|||
|
|||
old_gain = cm_analog_get_ptr(2*den_size+num_size+2,1); |
|||
gain = cm_analog_get_ptr(2*den_size+num_size+2,0); |
|||
|
|||
*gain = *old_gain; |
|||
|
|||
/* gain = ITP_VAR(total_gain); */ |
|||
|
|||
} |
|||
|
|||
|
|||
/** Test for TIME=0.0; if so, initialize... **/ |
|||
|
|||
if (TIME == 0.0) { /* First pass...set initial conditions... */ |
|||
|
|||
/* Initialize integrators to int_ic condition values... */ |
|||
for (i=0; i<den_size-1; i++) { /* Note...do NOT set the highest */ |
|||
/* order value...this represents */ |
|||
/* the "calculated" input to the */ |
|||
/* actual highest integrator...it */ |
|||
/* is NOT a true state variable. */ |
|||
if ( PARAM_NULL(int_ic) ) { |
|||
*(integrator[i]) = *(old_integrator[i]) = PARAM(int_ic[0]); |
|||
} |
|||
else { |
|||
*(integrator[i]) = *(old_integrator[i]) = |
|||
PARAM(int_ic[den_size - 2 - i]); |
|||
} |
|||
} |
|||
|
|||
|
|||
/*** Read in coefficients and denormalize, if required ***/ |
|||
|
|||
for (i=0; i<num_size; i++) { |
|||
*(num_coefficient[i]) = PARAM(num_coeff[num_size - 1 - i]); |
|||
if ( denormalized_freq != 1.0 ) { |
|||
*(num_coefficient[i]) = *(num_coefficient[i]) / |
|||
pow(denormalized_freq,(double) i); |
|||
} |
|||
} |
|||
|
|||
for (i=0; i<den_size; i++) { |
|||
*(den_coefficient[i]) = PARAM(den_coeff[den_size - 1 - i]); |
|||
if ( denormalized_freq != 1.0 ) { |
|||
*(den_coefficient[i]) = *(den_coefficient[i]) / |
|||
pow(denormalized_freq,(double) i); |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/* Test denominator highest order coefficient...if that value */ |
|||
/* is other than 1.0, then divide all denominator coefficients */ |
|||
/* and the gain by that value... */ |
|||
if ( factor = PARAM(den_coeff[den_size-1]) != 1.0 ) { |
|||
for (i=0; i<den_size; i++) { |
|||
*(den_coefficient[i]) = *(den_coefficient[i]) / factor; |
|||
} |
|||
*gain = PARAM(gain) / factor; |
|||
} |
|||
else { /* No division by coefficient necessary... */ |
|||
/* only need to adjust gain value. */ |
|||
*gain = PARAM(gain); |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/**** DC & Transient Analyses **************************/ |
|||
if (ANALYSIS != MIF_AC) { |
|||
|
|||
/**** DC Analysis - Not needed JPM 10/29/91 *****************/ |
|||
/* if (ANALYSIS == MIF_DC) { |
|||
|
|||
/* Test to see if a term exists for the zero-th order |
|||
denom coeff... |
|||
|
|||
/* division by zero if output |
|||
/* num_coefficient[0]/den_coefficient[0], |
|||
/* so output init. conds. instead... |
|||
if ( 0.0 == *(den_coefficient[0])) { |
|||
|
|||
|
|||
*out = 0.0; |
|||
for (i=0; i<num_size; i++) { |
|||
*out = *out + ( *(old_integrator[i]) * |
|||
*(num_coefficient[i]) ); |
|||
} |
|||
*out = *gain * *out; |
|||
pout_pin = *(old_integrator[1]); |
|||
|
|||
} |
|||
|
|||
/* Zero-th order den term != 0.0, so output |
|||
/* num_coeff[0]/den_coeff[0]... |
|||
else { |
|||
|
|||
*out = *gain * ( INPUT(in) + |
|||
in_offset) * ( *(num_coefficient[0]) / |
|||
*(den_coefficient[0]) ); |
|||
pout_pin = 0.0; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
else { |
|||
*/ |
|||
|
|||
|
|||
/**** Transient & DC Analyses ****************************/ |
|||
|
|||
/*** Read input value for current time, and |
|||
calculate pseudo-input which includes input |
|||
offset and gain.... ***/ |
|||
|
|||
*in = *gain * (INPUT(in)+in_offset); |
|||
|
|||
|
|||
|
|||
/*** Obtain the "new" input to the Controller |
|||
Canonical topology, then propagate through |
|||
the integrators.... ***/ |
|||
|
|||
/* calculate the "new" input to the first integrator, based on */ |
|||
/* the old values of each integrator multiplied by their */ |
|||
/* respective denominator coefficients and then subtracted */ |
|||
/* from *in.... */ |
|||
/* Note that this value, which is similar to a state variable, */ |
|||
/* is stored in *(integrator[den_size-1]). */ |
|||
|
|||
*(integrator[den_size-1]) = *in; |
|||
for (i=0; i<den_size-1; i++) { |
|||
*(integrator[den_size-1]) = |
|||
*(integrator[den_size-1]) - |
|||
*(old_integrator[i]) * *(den_coefficient[i]); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/* Propagate the new input through each integrator in succession. */ |
|||
|
|||
for (i=den_size-1; i>0; i--) { |
|||
cm_analog_integrate(*(integrator[i]),(integrator[i-1]),&null); |
|||
} |
|||
|
|||
|
|||
|
|||
/* Calculate the output based on the new integrator values... */ |
|||
|
|||
*out = 0.0; |
|||
for (i=0; i<num_size; i++) { |
|||
*out = *out + ( *(integrator[i]) * |
|||
*(num_coefficient[i]) ); |
|||
} |
|||
pout_pin = *(integrator[1]); |
|||
|
|||
|
|||
/** Output values for DC & Transient **/ |
|||
|
|||
OUTPUT(out) = *out; |
|||
PARTIAL(out,in) = pout_pin; |
|||
|
|||
} |
|||
|
|||
/**** AC Analysis ************************************/ |
|||
else { |
|||
|
|||
/*** Calculate Real & Imaginary portions of AC gain ***/ |
|||
/*** at the current RAD_FREQ point... ***/ |
|||
|
|||
|
|||
/*** Calculate Numerator Real & Imaginary Components... ***/ |
|||
|
|||
acc_num.real = 0.0; |
|||
acc_num.imag = 0.0; |
|||
|
|||
for (i=0; i<num_size; i++) { |
|||
frac = modf(i/2.0, ÷_integer); /* Determine the integer portion */ |
|||
/* of a divide-by-2.0 on the index. */ |
|||
|
|||
if (modf(divide_integer/2.0,&temp) > 0.0 ) { /* Negative coefficient */ |
|||
/* values for this iteration. */ |
|||
if (frac > 0.0 ) { /** Odd Powers of "s" **/ |
|||
acc_num.imag = acc_num.imag - *(num_coefficient[i]) * pow(RAD_FREQ,i) * (*gain); |
|||
} |
|||
else { /** Even Powers of "s" **/ |
|||
acc_num.real = acc_num.real - *(num_coefficient[i]) * pow(RAD_FREQ,i) * (*gain); |
|||
} |
|||
} |
|||
else { /* Positive coefficient values for this iteration */ |
|||
if (frac> 0.0 ) { /** Odd Powers of "s" **/ |
|||
acc_num.imag = acc_num.imag + *(num_coefficient[i]) * pow(RAD_FREQ,i) * (*gain); |
|||
} |
|||
else { /** Even Powers of "s" **/ |
|||
acc_num.real = acc_num.real + *(num_coefficient[i]) * pow(RAD_FREQ,i) * (*gain); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** Calculate Denominator Real & Imaginary Components... ***/ |
|||
|
|||
acc_den.real = 0.0; |
|||
acc_den.imag = 0.0; |
|||
|
|||
for (i=0; i<den_size; i++) { |
|||
frac = modf(i/2.0, ÷_integer); /* Determine the integer portion */ |
|||
/* of a divide-by-2.0 on the index. */ |
|||
if (modf(divide_integer/2.0,&temp) > 0.0 ) { /* Negative coefficient */ |
|||
/* values for this iteration. */ |
|||
if (frac > 0.0 ) { /** Odd Powers of "s" **/ |
|||
acc_den.imag = acc_den.imag - *(den_coefficient[i]) * pow(RAD_FREQ,i); |
|||
} |
|||
else { /** Even Powers of "s" **/ |
|||
acc_den.real = acc_den.real - *(den_coefficient[i]) * pow(RAD_FREQ,i); |
|||
} |
|||
} |
|||
else { /* Positive coefficient values for this iteration */ |
|||
if (frac > 0.0 ) { /** Odd Powers of "s" **/ |
|||
acc_den.imag = acc_den.imag + *(den_coefficient[i]) * pow(RAD_FREQ,i); |
|||
} |
|||
else { /** Even Powers of "s" **/ |
|||
acc_den.real = acc_den.real + *(den_coefficient[i]) * pow(RAD_FREQ,i); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* divide numerator values by denominator values */ |
|||
|
|||
ac_gain = cm_complex_div(acc_num, acc_den); |
|||
|
|||
AC_GAIN(out,in) = ac_gain; |
|||
} |
|||
|
|||
/* free all allocated memory */ |
|||
free(integrator); |
|||
free(old_integrator); |
|||
free(den_coefficient); |
|||
free(old_den_coefficient); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,93 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog s-domain transfer function (s_xfer) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: s_xfer |
|||
C_Function_Name: cm_s_xfer |
|||
Description: "s-domain transfer function block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: in_offset gain |
|||
Description: "input offset" "gain" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: num_coeff den_coeff |
|||
Description: "numerator poly coef" "denominator poly coef" |
|||
Data_Type: real real |
|||
Default_Value: - - |
|||
Limits: - - |
|||
Vector: yes yes |
|||
Vector_Bounds: [1 -] [1 -] |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: int_ic |
|||
Description: "int stage init. cond" |
|||
Data_Type: real |
|||
Default_Value: 0.0 |
|||
Limits: - |
|||
Vector: yes |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: denormalized_freq |
|||
Description: "frequency (radians/second) at which to denormalize coefficients" |
|||
Data_Type: real |
|||
Default_Value: 1.0 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
@ -0,0 +1,24 @@ |
|||
|
|||
|
|||
/***************************************************/ |
|||
/****** Structures, etc. for int model. ******/ |
|||
/****** 11/6/90 JPM ******/ |
|||
/***************************************************/ |
|||
|
|||
/***** Value Definitions ******************************************/ |
|||
|
|||
#define INT1 1 |
|||
#define INT2 2 |
|||
|
|||
|
|||
|
|||
/***** Define Macros **************************************/ |
|||
|
|||
|
|||
|
|||
/***** Structure Definitions *************************************/ |
|||
|
|||
|
|||
|
|||
/***** Function Prototype Definitions ***************************************/ |
|||
|
|||
@ -0,0 +1,257 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE sine/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the sine (controlled sine-wave |
|||
oscillator) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "sin.h" |
|||
#include <math.h> |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_sine() |
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the sine (controlled sinewave |
|||
oscillator) code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_SINE ROUTINE ===*/ |
|||
|
|||
void cm_sine(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int cntl_size; /* control array size */ |
|||
int freq_size; /* frequency array size */ |
|||
|
|||
double *x; /* pointer to the control array values */ |
|||
double *y; /* pointer to the frequency array values */ |
|||
double cntl_input; /* control input */ |
|||
double out; /* output value */ |
|||
double dout_din; /* partial derivative of output wrt control in */ |
|||
double output_low; /* output low value */ |
|||
double output_hi; /* output high value */ |
|||
double *phase; /* pointer to the instantaneous phase value */ |
|||
double *phase1; /* pointer to the previous value for the phase */ |
|||
double freq; /* frequency of the sine wave */ |
|||
double center; /* dc offset for the sine wave */ |
|||
double peak; /* peak voltage value for the wave */ |
|||
double radian; /* phase value in radians */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
/**** Retrieve frequently used parameters... ****/ |
|||
|
|||
|
|||
cntl_size = PARAM_SIZE(cntl_array); |
|||
freq_size = PARAM_SIZE(freq_array); |
|||
output_low = PARAM(out_low); |
|||
output_hi = PARAM(out_high); |
|||
|
|||
if(cntl_size != freq_size){ |
|||
cm_message_send(array_error); |
|||
return; |
|||
} |
|||
|
|||
if(INIT == 1){ |
|||
|
|||
phase = cm_analog_alloc(INT1,sizeof(double)); |
|||
|
|||
} |
|||
if(ANALYSIS == MIF_DC){ |
|||
|
|||
OUTPUT(out) = (output_hi + output_low)/2; |
|||
PARTIAL(out,cntl_in) = 0; |
|||
phase = cm_analog_get_ptr(INT1,0); |
|||
*phase = 0; |
|||
|
|||
}else |
|||
|
|||
if(ANALYSIS == MIF_TRAN){ |
|||
|
|||
phase = cm_analog_get_ptr(INT1,0); |
|||
phase1 = cm_analog_get_ptr(INT1,1); |
|||
|
|||
/* Allocate storage for breakpoint domain & freq. range values */ |
|||
x = (double *) calloc(cntl_size, sizeof(double)); |
|||
if (x == '\0') { |
|||
cm_message_send(allocation_error); |
|||
return; |
|||
} |
|||
y = (double *) calloc(freq_size, sizeof(double)); |
|||
if (y == '\0') { |
|||
cm_message_send(allocation_error); |
|||
return; |
|||
} |
|||
|
|||
|
|||
/* Retrieve x and y values. */ |
|||
for (i=0; i<cntl_size; i++) { |
|||
*(x+i) = PARAM(cntl_array[i]); |
|||
*(y+i) = PARAM(freq_array[i]); |
|||
} |
|||
|
|||
|
|||
|
|||
/* Retrieve cntl_input value. */ |
|||
cntl_input = INPUT(cntl_in); |
|||
|
|||
|
|||
/* Determine segment boundaries within which cntl_input resides */ |
|||
/*** cntl_input below lowest cntl_voltage ***/ |
|||
if (cntl_input <= *x) { |
|||
dout_din = (*(y+1) - *y)/(*(x+1) - *x); |
|||
freq = *y + (cntl_input - *x) * dout_din; |
|||
|
|||
if(freq <= 0){ |
|||
cm_message_send(sine_freq_clamp); |
|||
freq = 1e-16; |
|||
} |
|||
/* freq = *y; */ |
|||
} |
|||
else |
|||
/*** cntl_input above highest cntl_voltage ***/ |
|||
|
|||
if (cntl_input >= *(x+cntl_size-1)){ |
|||
dout_din = (*(y+cntl_size-1) - *(y+cntl_size-2)) / |
|||
(*(x+cntl_size-1) - *(x+cntl_size-2)); |
|||
freq = *(y+cntl_size-1) + (cntl_input - *(x+cntl_size-1)) * dout_din; |
|||
|
|||
} else { /*** cntl_input within bounds of end midpoints... |
|||
must determine position progressively & then |
|||
calculate required output. ***/ |
|||
|
|||
for (i=0; i<cntl_size; i++) { |
|||
|
|||
if ((cntl_input < *(x+i+1)) && (cntl_input >= *(x+i))) { |
|||
|
|||
/* Interpolate to the correct frequency value */ |
|||
|
|||
freq = ((cntl_input - *(x+i))/(*(x+i+1) - *(x+i)))* |
|||
(*(y+i+1)-*(y+i)) + *(y+i); |
|||
} |
|||
|
|||
} |
|||
} |
|||
/* calculate the peak value of the wave, the center of the wave, the |
|||
instantaneous phase and the radian value of the phase */ |
|||
peak = (output_hi - output_low)/2; |
|||
center = (output_hi + output_low)/2; |
|||
*phase = *phase1 + freq*(TIME - T(1)); |
|||
radian = *phase * 2.0 * PI; |
|||
|
|||
OUTPUT(out) = peak*sin(radian) + center; |
|||
PARTIAL(out,cntl_in) = 0; |
|||
|
|||
} else { /* Output AC Gain */ |
|||
|
|||
ac_gain.real = 0.0; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,cntl_in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,61 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog sine (controlled sinewave oscillator) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_sine |
|||
Spice_Model_Name: sine |
|||
Description: "controlled sine wave oscillator" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: cntl_in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: cntl_array freq_array |
|||
Description: "control in array" "frequency array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0e3 |
|||
Limits: - [0 -] |
|||
Vector: yes yes |
|||
Vector_Bounds: [2 -] [2 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: out_low out_high |
|||
Description: "output low value" "output high value" |
|||
Data_Type: real real |
|||
Default_Value: -1.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
@ -0,0 +1,80 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE sine/sin.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
20 Mar 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains additional header information for the |
|||
sine code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
NONE |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define PI 3.141592654; |
|||
|
|||
#define INT1 1 |
|||
|
|||
char *allocation_error = "\n**** Error ****\nSINE: Error allocating sine block storage \n"; |
|||
char *limit_error = "\n**** Error ****\nSINE: Smoothing domain value too large \n"; |
|||
char *sine_freq_clamp = "\n**** Warning ****\nSINE: Extrapolated frequency limited to 1e-16 Hz \n"; |
|||
char *array_error = "\n**** Error ****\nSINE: Size of control array different than frequency array \n"; |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,301 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE slew/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
15 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the slew (slew rate) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "slew.h" |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_slew() |
|||
|
|||
AUTHORS |
|||
|
|||
15 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the slew code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_SLEW ROUTINE ===*/ |
|||
|
|||
/**************************************************************** |
|||
* * |
|||
* This model describes a single input, single output slew * |
|||
* rate limited block. The user may specify the positive * |
|||
* and negative slew rates. * |
|||
* * |
|||
* Note that the model makes no provision for output high and * |
|||
* low values. That is assumed to be handled by another model. * |
|||
* * |
|||
****************************************************************/ |
|||
|
|||
void cm_slew(ARGS) |
|||
|
|||
{ |
|||
double *ins; /* input value */ |
|||
double *in_old; /* previous input value */ |
|||
double *outs; /* output value */ |
|||
double *out_old; /* previous output value */ |
|||
double pout_pin; /* partial derivative--output wrt input */ |
|||
double delta; /* change in time from previous iteration */ |
|||
double slope_rise; /* positive going slew rate */ |
|||
double slope_fall; /* negative going slew rate */ |
|||
double out_slew; /* "slewed" output value */ |
|||
double slope; /* slope of the input wrt time */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
/** Retrieve frequently used parameters (used by all analyses)... **/ |
|||
|
|||
if (INIT == 1) { |
|||
|
|||
/* First pass...allocate storage for previous state. */ |
|||
|
|||
ins = cm_analog_alloc(INT1,sizeof(double)); |
|||
outs = cm_analog_alloc(INT4,sizeof(double)); |
|||
out_old = cm_analog_alloc(INT2,sizeof(double)); |
|||
in_old = cm_analog_alloc(INT3,sizeof(double)); |
|||
|
|||
} |
|||
|
|||
if (ANALYSIS == MIF_DC) { |
|||
|
|||
/* DC analysis, get old values */ |
|||
|
|||
ins= cm_analog_get_ptr(INT1,0); |
|||
outs= cm_analog_get_ptr(INT4,0); |
|||
in_old = cm_analog_get_ptr(INT1,0); |
|||
out_old = cm_analog_get_ptr(INT4,0); |
|||
|
|||
*ins = *in_old = INPUT(in); |
|||
*outs = *out_old = *ins; |
|||
|
|||
/*** so, return a zero d/dt value. ***/ |
|||
pout_pin = 1.0; |
|||
|
|||
OUTPUT(out) = INPUT(in); |
|||
PARTIAL(out,in) = 1; |
|||
|
|||
}else |
|||
|
|||
if (ANALYSIS == MIF_TRAN) { /**** DC & Transient Analyses ****/ |
|||
|
|||
/** Retrieve frequently used parameters... **/ |
|||
|
|||
slope_rise = PARAM(rise_slope); |
|||
slope_fall = PARAM(fall_slope); |
|||
|
|||
/* Allocation not necessary...retrieve previous values */ |
|||
|
|||
ins = cm_analog_get_ptr(INT1,0); /* Set out pointer to current |
|||
time storage */ |
|||
in_old = cm_analog_get_ptr(INT1,1); /* Set old-output-state pointer */ |
|||
outs = cm_analog_get_ptr(INT4,0); |
|||
out_old = cm_analog_get_ptr(INT4,1); /* Set old-output-state pointer |
|||
previous time storage */ |
|||
|
|||
|
|||
if ( TIME == 0.0 ) { /*** Test to see if this is the first ***/ |
|||
/*** timepoint calculation...if ***/ |
|||
|
|||
*ins = *in_old = INPUT(in); |
|||
*outs = *out_old = *ins; /* input = output, d/dt = 1 */ |
|||
pout_pin = 1.0; |
|||
|
|||
}else{ |
|||
|
|||
/* determine the slope of the input */ |
|||
delta = TIME - T(1); |
|||
*ins = INPUT(in); |
|||
slope = (*ins - *in_old)/delta; |
|||
|
|||
if(slope >= 0){ |
|||
|
|||
out_slew = *out_old + slope_rise*delta; |
|||
|
|||
if(*ins < (*out_old - slope_fall*delta)){ |
|||
|
|||
/* If the input had a negative slope (and the output |
|||
was slewing) and then changed direction to a positive |
|||
slope and the "slewed" response hasn't caught up |
|||
to the input yet (input < slewed output), then |
|||
continue negative slewing until the slewed output |
|||
meets the positive sloping input */ |
|||
|
|||
*outs = *out_old - slope_fall*delta; |
|||
pout_pin = 0; |
|||
|
|||
}else |
|||
|
|||
/* Two conditions for slewing, if the slope is greater |
|||
than the positive slew rate, or if the input slope |
|||
is less than the positive slew rate and the slewed output |
|||
is less than the input. This second condition occurs |
|||
if the input levels off and the slewed output hasn't |
|||
caught up to the input yet */ |
|||
|
|||
if((slope > slope_rise) || ((slope < slope_rise) && (out_slew <= *ins))){ |
|||
/* SLEWING ! */ |
|||
*outs = out_slew; |
|||
pout_pin = 0; |
|||
|
|||
}else{ |
|||
/* No slewing, output=input */ |
|||
*outs = *ins; |
|||
pout_pin = 1; |
|||
|
|||
} |
|||
|
|||
}else{ /* this ends the positive slope stuff */ |
|||
|
|||
out_slew = *out_old - slope_fall*delta; |
|||
|
|||
if(*ins > (*out_old + slope_rise*delta)){ |
|||
|
|||
/* If the input had a positive slope (and the output |
|||
was slewing) and then changed direction to a negative |
|||
slope and the "slewed" response hasn't caught up |
|||
to the input yet (input > slewed output), then |
|||
continue positive slewing until the slewed output |
|||
meets the negative sloping input */ |
|||
|
|||
*outs = *out_old + slope_rise*delta; |
|||
pout_pin = 0; |
|||
|
|||
}else |
|||
|
|||
/* Two conditions for slewing, if the negative slope is |
|||
greater than the neg. slew rate, or if the neg. input |
|||
slope is less than the negative slew rate and the |
|||
slewed output is greater than the input. This second |
|||
condition occurs if the input levels off and the |
|||
slewed output hasn't caught up to the input yet */ |
|||
|
|||
if((-slope > slope_fall) || ((-slope < slope_fall) && (out_slew > *ins))){ /* SLEWING ! */ |
|||
*outs = out_slew; |
|||
pout_pin = 0; |
|||
|
|||
}else{ |
|||
|
|||
*outs = *ins; |
|||
pout_pin = 1; |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
} |
|||
/** Output values for DC & Transient **/ |
|||
|
|||
OUTPUT(out) = *outs; |
|||
PARTIAL(out,in) = pout_pin; |
|||
|
|||
|
|||
}else{ /**** AC Analysis...output (0.0,s*gain) ****/ |
|||
ac_gain.real = 1.0; |
|||
ac_gain.imag= 0; |
|||
AC_GAIN(out,in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,54 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
15 Apr 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog slew (slew rate) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_slew |
|||
Spice_Model_Name: slew |
|||
Description: "a simple slew rate follower block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: rise_slope fall_slope |
|||
Description: "rising slew limit" "falling slew limit" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-9 1.0e-9 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
@ -0,0 +1,77 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE slew/slew.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
15 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains additional header information for the |
|||
slew code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
NONE |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define INT1 1 |
|||
#define INT2 2 |
|||
#define INT3 3 |
|||
#define INT4 4 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,412 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE square/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the square (controlled squarewave |
|||
oscillator) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_set_temp_bkpt() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "square.h" |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_square() |
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the square (controlled squarewave |
|||
oscillator) code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_set_temp_bkpt() |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_SQUARE ROUTINE ===*/ |
|||
|
|||
|
|||
/*********************************************************** |
|||
* * |
|||
* I <-dutycycle-> * |
|||
* I * |
|||
* I out_high * |
|||
* I t2 | t3 * |
|||
* I \____v_____/ * |
|||
* I / \ * |
|||
* I * |
|||
* I / \ * |
|||
* I * |
|||
* I / \ * |
|||
* I * |
|||
* I-----------------I I--------------- * |
|||
* ^ t1 t4 * |
|||
* | * |
|||
* out_low * |
|||
* t2 = t1 + t_rise * |
|||
* t4 = t3 + t_fall * |
|||
* * |
|||
***********************************************************/ |
|||
|
|||
void cm_square(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int cntl_size; /* control array size */ |
|||
int freq_size; /* frequency array size */ |
|||
int int_cycle; /* integer number of cycles */ |
|||
|
|||
double *x; /* pointer to the control array values */ |
|||
double *y; /* pointer to the frequecy array values */ |
|||
double cntl_input; /* control input */ |
|||
double out; /* output */ |
|||
double dout_din; /* slope of the frequency array wrt the control |
|||
array. Used to extrapolate a frequency above |
|||
and below the control input high and low level */ |
|||
double output_low; /* output low */ |
|||
double output_hi; /* output high */ |
|||
double dphase; /* fractional part into cycle */ |
|||
double *phase; /* pointer to the phase value */ |
|||
double *phase1; /* pointer to the old phase value */ |
|||
double freq; /* frequency of the wave */ |
|||
double d_cycle; /* duty cycle */ |
|||
double *t1; /* pointer containing the value of time1 */ |
|||
double *t2; /* pointer containing the value of time2 */ |
|||
double *t3; /* pointer containing the value of time3 */ |
|||
double *t4; /* pointer containing the value of time4 */ |
|||
double time1; /* time1 = duty_cycle * period of the wave */ |
|||
double time2; /* time2 = time1 + risetime */ |
|||
double time3; /* time3 = current time+time to end of period*/ |
|||
double time4; /* time4 = time3 + falltime */ |
|||
double t_rise; /* risetime */ |
|||
double t_fall; /* falltime */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
/**** Retrieve frequently used parameters... ****/ |
|||
|
|||
cntl_size = PARAM_SIZE(cntl_array); |
|||
freq_size = PARAM_SIZE(freq_array); |
|||
output_low = PARAM(out_low); |
|||
output_hi = PARAM(out_high); |
|||
d_cycle = PARAM(duty_cycle); |
|||
t_rise = PARAM(rise_time); |
|||
t_fall = PARAM(fall_time); |
|||
|
|||
/* check and make sure that the control array is the |
|||
same size as the frequency array */ |
|||
|
|||
if(cntl_size != freq_size){ |
|||
cm_message_send(square_array_error); |
|||
return; |
|||
} |
|||
|
|||
/* First time throught allocate memory */ |
|||
if(INIT==1){ |
|||
phase = cm_analog_alloc(INT1,sizeof(double)); |
|||
t1 = cm_analog_alloc(T1,sizeof(double)); |
|||
t2 = cm_analog_alloc(T2,sizeof(double)); |
|||
t3 = cm_analog_alloc(T3,sizeof(double)); |
|||
t4 = cm_analog_alloc(T4,sizeof(double)); |
|||
|
|||
} |
|||
|
|||
if(ANALYSIS == MIF_DC){ |
|||
|
|||
/* initialize time values */ |
|||
t1 = cm_analog_get_ptr(T1,0); |
|||
t2 = cm_analog_get_ptr(T2,0); |
|||
t3 = cm_analog_get_ptr(T3,0); |
|||
t4 = cm_analog_get_ptr(T4,0); |
|||
|
|||
*t1 = -1; |
|||
*t2 = -1; |
|||
*t3 = -1; |
|||
*t4 = -1; |
|||
|
|||
OUTPUT(out) = output_low; |
|||
PARTIAL(out,cntl_in) = 0; |
|||
|
|||
}else |
|||
|
|||
/* Retrieve previous values */ |
|||
|
|||
if(ANALYSIS == MIF_TRAN){ |
|||
|
|||
phase = cm_analog_get_ptr(INT1,0); |
|||
phase1 = cm_analog_get_ptr(INT1,1); |
|||
t1 = cm_analog_get_ptr(T1,1); |
|||
t2 = cm_analog_get_ptr(T2,1); |
|||
t3 = cm_analog_get_ptr(T3,1); |
|||
t4 = cm_analog_get_ptr(T4,1); |
|||
|
|||
time1 = *t1; |
|||
time2 = *t2; |
|||
time3 = *t3; |
|||
time4 = *t4; |
|||
|
|||
/* Allocate storage for breakpoint domain & freq. range values */ |
|||
|
|||
x = (double *) calloc(cntl_size, sizeof(double)); |
|||
if (x == '\0') { |
|||
cm_message_send(square_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
y = (double *) calloc(freq_size, sizeof(double)); |
|||
if (y == '\0') { |
|||
cm_message_send(square_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
/* Retrieve x and y values. */ |
|||
for (i=0; i<cntl_size; i++) { |
|||
*(x+i) = PARAM(cntl_array[i]); |
|||
*(y+i) = PARAM(freq_array[i]); |
|||
} |
|||
|
|||
/* Retrieve cntl_input value. */ |
|||
cntl_input = INPUT(cntl_in); |
|||
|
|||
/* Determine segment boundaries within which cntl_input resides */ |
|||
/*** cntl_input below lowest cntl_voltage ***/ |
|||
if (cntl_input <= *x) { |
|||
dout_din = (*(y+1) - *y)/(*(x+1) - *x); |
|||
freq = *y + (cntl_input - *x) * dout_din; |
|||
|
|||
if(freq <= 0){ |
|||
cm_message_send(square_freq_clamp); |
|||
freq = 1e-16; |
|||
} |
|||
/* freq = *y; */ |
|||
} |
|||
else |
|||
/*** cntl_input above highest cntl_voltage ***/ |
|||
|
|||
if (cntl_input >= *(x+cntl_size-1)){ |
|||
dout_din = (*(y+cntl_size-1) - *(y+cntl_size-2)) / |
|||
(*(x+cntl_size-1) - *(x+cntl_size-2)); |
|||
freq = *(y+cntl_size-1) + (cntl_input - *(x+cntl_size-1)) * dout_din; |
|||
/* freq = *(y+cntl_size-1); */ |
|||
|
|||
} else { /*** cntl_input within bounds of end midpoints... |
|||
must determine position progressively & then |
|||
calculate required output. ***/ |
|||
|
|||
for (i=0; i<cntl_size-1; i++) { |
|||
|
|||
if ((cntl_input < *(x+i+1)) && (cntl_input >= *(x+i))){ |
|||
|
|||
/* Interpolate to the correct frequency value */ |
|||
|
|||
freq = ((cntl_input - *(x+i))/(*(x+i+1) - *(x+i)))* |
|||
(*(y+i+1)-*(y+i)) + *(y+i); |
|||
} |
|||
|
|||
} |
|||
} |
|||
/* calculate the instantaneous phase */ |
|||
*phase = *phase1 + freq*(TIME - T(1)); |
|||
|
|||
/* convert the phase to an integer */ |
|||
int_cycle = *phase1; |
|||
|
|||
/* dphase is the percent into the cycle for |
|||
the period */ |
|||
dphase = *phase1 - int_cycle; |
|||
|
|||
/* Calculate the time variables and the output value |
|||
for this iteration */ |
|||
|
|||
if((time1 <= TIME) && (TIME <= time2)){ |
|||
time3 = T(1) + (1 - dphase)/freq; |
|||
time4 = time3 + t_fall; |
|||
|
|||
if(TIME < time2){ |
|||
cm_analog_set_temp_bkpt(time2); |
|||
} |
|||
|
|||
cm_analog_set_temp_bkpt(time3); |
|||
cm_analog_set_temp_bkpt(time4); |
|||
|
|||
OUTPUT(out) = output_low + ((TIME - time1)/(time2 - time1))* |
|||
(output_hi - output_low); |
|||
|
|||
}else |
|||
|
|||
if((time2 <= TIME) && (TIME <= time3)){ |
|||
|
|||
time3 = T(1) + (1.0 - dphase)/freq; |
|||
time4 = time3 + t_fall; |
|||
if(TIME < time3){ |
|||
cm_analog_set_temp_bkpt(time3); |
|||
} |
|||
cm_analog_set_temp_bkpt(time4); |
|||
OUTPUT(out) = output_hi; |
|||
|
|||
}else |
|||
|
|||
if((time3 <= TIME) && (TIME <= time4)){ |
|||
|
|||
if(dphase > 1-d_cycle){ |
|||
dphase = dphase - 1.0; |
|||
} |
|||
|
|||
/* subtract d_cycle from 1 because my initial definition |
|||
of duty cyle was that part of the cycle which the output |
|||
is low. The more standard definition is the part of the |
|||
cycle where the output is high. */ |
|||
time1 = T(1) + ((1-d_cycle) - dphase)/freq; |
|||
time2 = time1 + t_rise; |
|||
|
|||
if(TIME < time4){ |
|||
cm_analog_set_temp_bkpt(time4); |
|||
} |
|||
|
|||
cm_analog_set_temp_bkpt(time1); |
|||
cm_analog_set_temp_bkpt(time2); |
|||
|
|||
OUTPUT(out) = output_hi + ((TIME - time3)/(time4 - time3))* |
|||
(output_low - output_hi); |
|||
|
|||
}else{ |
|||
|
|||
if(dphase > 1-d_cycle){ |
|||
dphase = dphase - 1.0; |
|||
} |
|||
|
|||
/* subtract d_cycle from 1 because my initial definition |
|||
of duty cyle was that part of the cycle which the output |
|||
is low. The more standard definition is the part of the |
|||
cycle where the output is high. */ |
|||
time1 = T(1) + ((1-d_cycle) - dphase)/freq; |
|||
time2 = time1 + t_rise; |
|||
|
|||
if((TIME < time1) || (T(1) == 0)){ |
|||
cm_analog_set_temp_bkpt(time1); |
|||
} |
|||
|
|||
cm_analog_set_temp_bkpt(time2); |
|||
OUTPUT(out) = output_low; |
|||
} |
|||
|
|||
PARTIAL(out,cntl_in) = 0.0; |
|||
|
|||
/* set the time values for storage */ |
|||
|
|||
t1 = cm_analog_get_ptr(T1,0); |
|||
t2 = cm_analog_get_ptr(T2,0); |
|||
t3 = cm_analog_get_ptr(T3,0); |
|||
t4 = cm_analog_get_ptr(T4,0); |
|||
|
|||
*t1 = time1; |
|||
*t2 = time2; |
|||
*t3 = time3; |
|||
*t4 = time4; |
|||
|
|||
} else { /* Output AC Gain */ |
|||
|
|||
/* This model has no AC capabilities */ |
|||
|
|||
ac_gain.real = 0.0; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,cntl_in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,83 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog square (controlled squarewave oscillator) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_square |
|||
Spice_Model_Name: square |
|||
Description: "controlled square wave oscillator" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: cntl_in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: cntl_array freq_array |
|||
Description: "control in array" "frequency array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0e3 |
|||
Limits: - [0 -] |
|||
Vector: yes yes |
|||
Vector_Bounds: [2 -] [2 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: out_low out_high |
|||
Description: "output low value" "output high value" |
|||
Data_Type: real real |
|||
Default_Value: -1.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: duty_cycle rise_time |
|||
Description: "duty cycle" "rise time" |
|||
Data_Type: real real |
|||
Default_Value: 0.5 1.0e-9 |
|||
Limits: [1e-6 .999999] - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: fall_time |
|||
Description: "fall time" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-9 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
@ -0,0 +1,84 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE square/square.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains additional header information for the |
|||
square (controlled squarewave oscillator) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
NONE |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
char *square_allocation_error = "\n**** Error ****\nSQUARE: Error allocating square block storage \n"; |
|||
char *square_limit_error = "\n**** Error ****\nSQUARE: Smoothing domain value too large \n"; |
|||
char *square_freq_clamp = "\n**** WARNING ****\nSQUARE: Frequency extrapolation limited to 1e-16 \n"; |
|||
char *square_array_error = "\n**** Error ****\nSQUARE: Size of control array different than frequency array \n"; |
|||
|
|||
|
|||
#define INT1 1 |
|||
#define T1 2 |
|||
#define T2 3 |
|||
#define T3 4 |
|||
#define T4 5 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,150 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE summer/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
9 Apr 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the summer code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_summer() |
|||
|
|||
AUTHORS |
|||
|
|||
9 Apr 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the summer code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_SUMMER ROUTINE ===*/ |
|||
|
|||
|
|||
void cm_summer(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int size; /* number of inputs */ |
|||
|
|||
double accumulate; /* sum of all the (inputs times their |
|||
respective gains plus their offset). */ |
|||
double final_gain; /* output gain stage */ |
|||
double in_gain_temp; /* temporary variable used to calculate |
|||
accumulate */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
size = PORT_SIZE(in); /* Note that port size */ |
|||
final_gain = PARAM(out_gain); /* and out_gain are read only */ |
|||
/* once...saves access time. */ |
|||
if(ANALYSIS != MIF_AC) { /* DC & Transient */ |
|||
accumulate = 0.0; |
|||
for (i=0; i<size; i++) { |
|||
in_gain_temp = PARAM(in_gain[i]); /* Ditto for in_gain[i] */ |
|||
accumulate = accumulate + in_gain_temp * |
|||
(INPUT(in[i]) + PARAM(in_offset[i])); |
|||
PARTIAL(out,in[i]) = in_gain_temp * final_gain; |
|||
} |
|||
OUTPUT(out) = accumulate * final_gain + PARAM(out_offset); |
|||
} |
|||
|
|||
else { /* AC Analysis */ |
|||
for (i=0; i<size; i++) { |
|||
ac_gain.real = PARAM(in_gain[i]) * final_gain; |
|||
ac_gain.imag = 0.0; |
|||
AC_GAIN(out,in[i]) = ac_gain; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
9 Apr 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog summer code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_summer |
|||
Spice_Model_Name: summer |
|||
Description: "summer block" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in out |
|||
Description: "input array" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: yes no |
|||
Vector_Bounds: [2 -] - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
Parameter_Name: in_offset in_gain |
|||
Description: "input offset array" "input gain array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0 |
|||
Limits: - - |
|||
Vector: yes yes |
|||
Vector_Bounds: in in |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: out_gain out_offset |
|||
Description: "output gain" "output offset" |
|||
Data_Type: real real |
|||
Default_Value: 1.0 0.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,364 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE triangle/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the triangle (controlled trianglewave |
|||
oscillator) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_set_temp_bkpt() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "triangle.h" |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION void cm_triangle() |
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the triangle (controlled trianglewave |
|||
oscillator) code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
int cm_analog_set_temp_bkpt() |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_TRIANGLE ROUTINE ===*/ |
|||
|
|||
/***************************************************** |
|||
* * |
|||
* I /\ <- output_high * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I / \ * |
|||
* I/------------------------------------------ * |
|||
* \ / * |
|||
* \ / * |
|||
* \ / * |
|||
* \ / * |
|||
* \ / * |
|||
* \ / * |
|||
* \ / * |
|||
* \/ <- output_low * |
|||
* * |
|||
*****************************************************/ |
|||
|
|||
void cm_triangle(ARGS) /* structure holding parms, |
|||
inputs, outputs, etc. */ |
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
int cntl_size; /* size of the control array */ |
|||
int freq_size; /* size of the frequency array */ |
|||
int int_cycle; /* the number of cycles rounded to the nearest int */ |
|||
|
|||
double *x; /* pointer holds the values of the control array */ |
|||
double *y; /* pointer holds the values of the freq array */ |
|||
double cntl_input; /* control input */ |
|||
double out; /* output */ |
|||
double dout_din; /* partial out wrt to control input */ |
|||
double output_low; /* lowest point of the wave */ |
|||
double output_hi; /* highest point of the wave */ |
|||
double dphase; /* percent into the current phase of the cycle */ |
|||
double *phase; /* instantaneous phase value */ |
|||
double *phase1; /* pointer to the previous phase value */ |
|||
double freq; /* actual frequency of the wave */ |
|||
double d_cycle; /* duty cycle */ |
|||
double *t1; /* pointer which stores time1 */ |
|||
double *t2; /* pointer which stores time2 */ |
|||
double *t_end; /* pointer which stores t_start */ |
|||
double time1; /* time of high peak */ |
|||
double time2; /* time of low peak */ |
|||
double t_start; /* time of the beginning of each cycle */ |
|||
|
|||
Mif_Complex_t ac_gain; |
|||
|
|||
|
|||
/**** Retrieve frequently used parameters... ****/ |
|||
|
|||
|
|||
cntl_size = PARAM_SIZE(cntl_array); |
|||
freq_size = PARAM_SIZE(freq_array); |
|||
output_low = PARAM(out_low); |
|||
output_hi = PARAM(out_high); |
|||
d_cycle = PARAM(duty_cycle); |
|||
|
|||
if(cntl_size != freq_size){ |
|||
cm_message_send(triangle_array_error); |
|||
return; |
|||
} |
|||
|
|||
/* Allocate memory */ |
|||
|
|||
if(INIT==1){ |
|||
phase = cm_analog_alloc(INT1,sizeof(double)); |
|||
t1 = cm_analog_alloc(T1,sizeof(double)); |
|||
t2 = cm_analog_alloc(T2,sizeof(double)); |
|||
t_end = cm_analog_alloc(T3,sizeof(double)); |
|||
|
|||
} |
|||
|
|||
if(ANALYSIS == MIF_DC){ |
|||
|
|||
/* initialize time values */ |
|||
|
|||
t1 = cm_analog_get_ptr(T1,0); |
|||
t2 = cm_analog_get_ptr(T2,0); |
|||
t_end = cm_analog_get_ptr(T3,0); |
|||
|
|||
*t1 = -1; |
|||
*t2 = -1; |
|||
*t_end = 0; |
|||
|
|||
OUTPUT(out) = output_low; |
|||
PARTIAL(out,cntl_in) = 0; |
|||
|
|||
}else |
|||
|
|||
if(ANALYSIS == MIF_TRAN){ |
|||
|
|||
/* Retrieve previous values and set equal to corresponding variables */ |
|||
|
|||
phase = cm_analog_get_ptr(INT1,0); |
|||
phase1 = cm_analog_get_ptr(INT1,1); |
|||
t1 = cm_analog_get_ptr(T1,1); |
|||
t2 = cm_analog_get_ptr(T2,1); |
|||
t_end = cm_analog_get_ptr(T3,1); |
|||
|
|||
time1 = *t1; |
|||
time2 = *t2; |
|||
t_start = *t_end; |
|||
|
|||
/* Allocate storage for breakpoint domain & freq. range values */ |
|||
|
|||
x = (double *) calloc(cntl_size, sizeof(double)); |
|||
if (x == '\0') { |
|||
cm_message_send(triangle_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
y = (double *) calloc(freq_size, sizeof(double)); |
|||
if (y == '\0') { |
|||
cm_message_send(triangle_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
|
|||
/* Retrieve x and y values. */ |
|||
for (i=0; i<cntl_size; i++) { |
|||
*(x+i) = PARAM(cntl_array[i]); |
|||
*(y+i) = PARAM(freq_array[i]); |
|||
} |
|||
|
|||
/* Retrieve cntl_input value. */ |
|||
cntl_input = INPUT(cntl_in); |
|||
|
|||
/* Determine segment boundaries within which cntl_input resides */ |
|||
|
|||
/*** cntl_input below lowest cntl_voltage ***/ |
|||
if (cntl_input <= *x) { |
|||
|
|||
dout_din = (*(y+1) - *y)/(*(x+1) - *x); |
|||
freq = *y + (cntl_input - *x) * dout_din; |
|||
|
|||
if(freq <= 0){ |
|||
cm_message_send(triangle_freq_clamp); |
|||
freq = 1e-16; |
|||
} |
|||
/* freq = *y; */ |
|||
} |
|||
else |
|||
/*** cntl_input above highest cntl_voltage ***/ |
|||
|
|||
if (cntl_input >= *(x+cntl_size-1)){ |
|||
dout_din = (*(y+cntl_size-1) - *(y+cntl_size-2)) / |
|||
(*(x+cntl_size-1) - *(x+cntl_size-2)); |
|||
freq = *(y+cntl_size-1) + (cntl_input - *(x+cntl_size-1)) * dout_din; |
|||
/* freq = *(y+cntl_size-1); */ |
|||
|
|||
} else { /*** cntl_input within bounds of end midpoints... |
|||
must determine position progressively & then |
|||
calculate required output. ***/ |
|||
|
|||
for (i=0; i<cntl_size-1; i++) { |
|||
|
|||
if ((cntl_input < *(x+i+1)) && (cntl_input >= *(x+i))){ |
|||
|
|||
/* Interpolate to the correct frequency value */ |
|||
|
|||
freq = ((cntl_input - *(x+i))/(*(x+i+1) - *(x+i)))* |
|||
(*(y+i+1)-*(y+i)) + *(y+i); |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
/* Instantaneous phase is the old phase + frequency/(delta time) |
|||
int_cycle is the integer value for the number cycles. */ |
|||
|
|||
*phase = *phase1 + freq*(TIME - T(1)); |
|||
int_cycle = *phase1; |
|||
dphase = *phase1 - int_cycle; |
|||
/* if the current time is greater than time1, but less than time2, |
|||
calculate time2 and set the temporary breakpoint. */ |
|||
if((time1 <= TIME) && (TIME <= time2)){ |
|||
|
|||
time2 = T(1) + (1 - dphase)/freq; |
|||
|
|||
if(TIME < time2){ |
|||
cm_analog_set_temp_bkpt(time2); |
|||
} |
|||
|
|||
/* store the time that the next cycle is scheduled to begin */ |
|||
t_start = time2; |
|||
|
|||
/* set output value */ |
|||
OUTPUT(out) = output_hi - ((TIME - time1)/(time2 - time1))* |
|||
(output_hi - output_low); |
|||
|
|||
|
|||
}else{ |
|||
|
|||
/* otherwise, calculate time1 and time2 and set their respective |
|||
breakpoints */ |
|||
|
|||
if(dphase > d_cycle){ |
|||
dphase = dphase - 1.0; |
|||
} |
|||
|
|||
time1 = T(1) + (d_cycle - dphase)/freq; |
|||
time2 = T(1) + (1 - dphase)/freq; |
|||
|
|||
if((TIME < time1) || (T(1) == 0)){ |
|||
cm_analog_set_temp_bkpt(time1); |
|||
} |
|||
|
|||
cm_analog_set_temp_bkpt(time2); |
|||
|
|||
/* set output value */ |
|||
OUTPUT(out) = output_low + ((TIME - t_start)/(time1 - t_start))* |
|||
(output_hi - output_low); |
|||
} |
|||
|
|||
PARTIAL(out,cntl_in) = 0.0; |
|||
|
|||
/* set the time values for storage */ |
|||
|
|||
t1 = cm_analog_get_ptr(T1,0); |
|||
t2 = cm_analog_get_ptr(T2,0); |
|||
t_end = cm_analog_get_ptr(T3,0); |
|||
|
|||
*t1 = time1; |
|||
*t2 = time2; |
|||
*t_end = t_start; |
|||
|
|||
} else { /* Output AC Gain */ |
|||
|
|||
/* This model has no AC capabilities */ |
|||
|
|||
ac_gain.real = 0.0; |
|||
ac_gain.imag= 0.0; |
|||
AC_GAIN(out,cntl_in) = ac_gain; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,72 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
analog triangle (controlled trianglewave oscillator) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_triangle |
|||
Spice_Model_Name: triangle |
|||
Description: "controlled triangle wave oscillator" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: cntl_in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v v |
|||
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: cntl_array freq_array |
|||
Description: "control in array" "frequency array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0e3 |
|||
Limits: - [0 -] |
|||
Vector: yes yes |
|||
Vector_Bounds: [2 -] [2 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: out_low out_high |
|||
Description: "output low value" "output high value" |
|||
Data_Type: real real |
|||
Default_Value: -1.0 1.0 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: duty_cycle |
|||
Description: "rise time duty cycle" |
|||
Data_Type: real |
|||
Default_Value: 0.5 |
|||
Limits: [1e-6 .999999] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
@ -0,0 +1,81 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE triangle/triangle.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
12 Apr 1991 Harry Li |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains additional header information for the |
|||
triangle (controlled trianglewave oscillator) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
NONE |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
char *triangle_allocation_error = "\n**** Error ****\nTRIANGLE: Error allocating triangle block storage \n"; |
|||
char *triangle_freq_clamp = "\n**** Warning ****\nTRIANGLE: Extrapolated Minimum Frequency Set to 1e-16 Hz \n"; |
|||
char *triangle_array_error = "\n**** Error ****\nTRIANGLE: Size of control array different than frequency array \n"; |
|||
|
|||
|
|||
#define INT1 1 |
|||
#define T1 2 |
|||
#define T2 3 |
|||
#define T3 4 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,2 @@ |
|||
|
|||
|
|||
@ -0,0 +1,355 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE adc_bridge/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
6 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
26 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the adc_bridge |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
CMevt.c void *cm_event_alloc() |
|||
void *cm_event_get_ptr() |
|||
int cm_event_queue() |
|||
|
|||
|
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_adc_bridge() |
|||
|
|||
AUTHORS |
|||
|
|||
6 June 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
26 Sept 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the adc_bridge code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
CMevt.c void *cm_event_alloc() |
|||
void *cm_event_get_ptr() |
|||
int cm_event_queue() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_ADC_BRIDGE ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* analog-to-digital nodebridge for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/6/91 * |
|||
* Last Modified 7/26/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_adc_bridge(ARGS) |
|||
|
|||
{ |
|||
double in_low, /* analog output value corresponding to '0' |
|||
digital input */ |
|||
in_high, /* analog output value corresponding to '1' |
|||
digital input */ |
|||
current_time, /* the current time value */ |
|||
*in, /* base address of array holding all digital output |
|||
values plus their previous values */ |
|||
*in_old; /* base address of array holding previous |
|||
output values */ |
|||
|
|||
|
|||
int i, /* generic loop counter index */ |
|||
size; /* number of input & output ports */ |
|||
|
|||
|
|||
|
|||
Digital_State_t *out, /* base address of array holding all input |
|||
values plus their previous values */ |
|||
*out_old, /* base address of array holding previous |
|||
input values */ |
|||
test; /* temp holding variable for digital states */ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/* determine "width" of the node bridge... */ |
|||
|
|||
size = PORT_SIZE(in); |
|||
in_high = PARAM(in_high); |
|||
in_low = PARAM(in_low); |
|||
|
|||
|
|||
|
|||
|
|||
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/ |
|||
|
|||
|
|||
/* Allocate storage for inputs */ |
|||
|
|||
in = in_old = cm_analog_alloc(0,size * sizeof(double)); |
|||
|
|||
|
|||
/* Allocate storage for outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(1,size * sizeof(Digital_State_t)); |
|||
|
|||
} |
|||
|
|||
else { /*** This is not an initialization pass...retrieve storage |
|||
addresses and calculate new outputs, if required. ***/ |
|||
|
|||
|
|||
/** Retrieve previous values... **/ |
|||
|
|||
/* assign discrete addresses */ |
|||
in = cm_analog_get_ptr(0,0); |
|||
in_old = cm_analog_get_ptr(0,1); |
|||
|
|||
/* assign analog addresses */ |
|||
out = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
|
|||
} |
|||
|
|||
|
|||
/* read current input values */ |
|||
for (i=0; i<size; i++) { |
|||
in[i] = INPUT(in[i]); |
|||
} |
|||
|
|||
|
|||
/*** If TIME == 0.0, bypass calculations ***/ |
|||
if (0.0 != TIME) { |
|||
|
|||
switch (CALL_TYPE) { |
|||
|
|||
case ANALOG: /** analog call...check for breakpoint calls. **/ |
|||
|
|||
/* loop through all inputs... */ |
|||
for (i=0; i<size; i++) { |
|||
|
|||
if (in[i] <= in_low) { /* low output required */ |
|||
|
|||
test = ZERO; |
|||
|
|||
if ( test != out_old[i] ) { |
|||
/* call for event breakpoint... */ |
|||
current_time = TIME; |
|||
cm_event_queue(current_time); |
|||
} |
|||
else { |
|||
/* no change since last time */ |
|||
} |
|||
|
|||
} |
|||
else { |
|||
if (in[i] >= in_high) { /* high output required */ |
|||
|
|||
test = ONE; |
|||
|
|||
if ( test != out_old[i] ) { |
|||
/* call for event breakpoint... */ |
|||
current_time = TIME; |
|||
cm_event_queue(current_time); |
|||
} |
|||
else { |
|||
/* no change since last time */ |
|||
} |
|||
|
|||
} |
|||
else { /* unknown output required */ |
|||
|
|||
if ( UNKNOWN != out_old[i] ) { |
|||
|
|||
/* call for event breakpoint... */ |
|||
current_time = TIME; |
|||
cm_event_queue(current_time); |
|||
} |
|||
else { |
|||
/* no change since last time */ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
break; |
|||
|
|||
|
|||
|
|||
case EVENT: /** discrete call...lots to do **/ |
|||
|
|||
/* loop through all inputs... */ |
|||
for (i=0; i<size; i++) { |
|||
|
|||
if (in[i] <= in_low) { /* low output required */ |
|||
|
|||
out[i] = ZERO; |
|||
|
|||
if ( out[i] != out_old[i] ) { |
|||
/* post changed value */ |
|||
OUTPUT_STATE(out[i]) = ZERO; |
|||
OUTPUT_DELAY(out[i]) = PARAM(fall_delay); |
|||
} |
|||
else { |
|||
/* no change since last time */ |
|||
OUTPUT_CHANGED(out[i]) = FALSE; |
|||
} |
|||
|
|||
} |
|||
else { |
|||
if (in[i] >= in_high) { /* high output required */ |
|||
|
|||
out[i] = ONE; |
|||
|
|||
if ( out[i] != out_old[i] ) { |
|||
/* post changed value */ |
|||
OUTPUT_STATE(out[i]) = ONE; |
|||
OUTPUT_DELAY(out[i]) = PARAM(rise_delay); |
|||
} |
|||
else { |
|||
/* no change since last time */ |
|||
OUTPUT_CHANGED(out[i]) = FALSE; |
|||
} |
|||
|
|||
} |
|||
else { /* unknown output required */ |
|||
|
|||
out[i] = UNKNOWN; |
|||
|
|||
if ( UNKNOWN != out_old[i] ) { |
|||
|
|||
/* post changed value */ |
|||
OUTPUT_STATE(out[i]) = UNKNOWN; |
|||
|
|||
switch (out_old[i]) { |
|||
case ONE: |
|||
OUTPUT_DELAY(out[i]) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
case ZERO: |
|||
OUTPUT_DELAY(out[i]) = PARAM(rise_delay); |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
/* no change since last time */ |
|||
OUTPUT_CHANGED(out[i]) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
/* regardless, output the strength */ |
|||
OUTPUT_STRENGTH(out[i]) = STRONG; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { /*** TIME == 0.0 => set outputs to input value... ***/ |
|||
/* loop through all inputs... */ |
|||
for (i=0; i<size; i++) { |
|||
|
|||
if (in[i] <= in_low) { /* low output required */ |
|||
OUTPUT_STATE(out[i]) = out[i] = ZERO; |
|||
} |
|||
else |
|||
if (in[i] >= in_high) { /* high output required */ |
|||
OUTPUT_STATE(out[i]) = out[i] = ONE; |
|||
} |
|||
else { |
|||
OUTPUT_STATE(out[i]) = out[i] = UNKNOWN; |
|||
} |
|||
OUTPUT_STRENGTH(out[i]) = STRONG; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
@ -0,0 +1,73 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
26 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
hybrid adc_bridge code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: adc_bridge |
|||
C_Function_Name: cm_adc_bridge |
|||
Description: "analog-to-digital converter node bridge" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: v d |
|||
Allowed_Types: [v,vd,i,id,vnam] [d] |
|||
Vector: yes yes |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: in_low |
|||
Description: "maximum 0-valued analog input" |
|||
Data_Type: real |
|||
Default_Value: 0.1 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: in_high |
|||
Description: "minimum 1-valued analog input" |
|||
Data_Type: real |
|||
Default_Value: 0.9 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
@ -0,0 +1,247 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_and/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
14 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_and |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <stdio.h> |
|||
#include <ctype.h> |
|||
#include <math.h> |
|||
#include <string.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_and() |
|||
|
|||
AUTHORS |
|||
|
|||
14 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
27 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_and code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_AND ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital AND gate for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/14/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_and(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 */ |
|||
|
|||
|
|||
/** Retrieve size value... **/ |
|||
size = PORT_SIZE(in); |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
/* set loading for inputs */ |
|||
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); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/*** Calculate new output value based on inputs ***/ |
|||
|
|||
*out = 1; |
|||
for (i=0; i<size; i++) { |
|||
|
|||
/* make sure this input isn't floating... */ |
|||
if ( FALSE == PORT_NULL(in) ) { |
|||
|
|||
/* 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; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/*** 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) = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_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; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,62 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_and code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_and |
|||
Spice_Model_Name: d_and |
|||
Description: "digital n-input and 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 |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
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 |
|||
|
|||
@ -0,0 +1,193 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_buffer/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
14 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_buffer |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_buffer() |
|||
|
|||
AUTHORS |
|||
|
|||
14 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
27 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_buffer code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_BUFFER ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital buffer for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/14/91 J.P,Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_buffer(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
|
|||
Digital_State_t *out, /* temporary output for buffers */ |
|||
*out_old; /* previous output for buffers */ |
|||
|
|||
|
|||
/** Setup required state variables **/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
/* define input loading... */ |
|||
LOAD(in) = PARAM(input_load); |
|||
} |
|||
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); |
|||
} |
|||
|
|||
|
|||
/** Check on analysis type **/ |
|||
|
|||
if (ANALYSIS == DC) { /* DC analysis...output w/o delays */ |
|||
|
|||
OUTPUT_STATE(out) = *out = INPUT_STATE(in); |
|||
|
|||
} |
|||
else { /* Transient Analysis */ |
|||
|
|||
switch ( INPUT_STATE(in) ) { |
|||
|
|||
/* fall to zero value */ |
|||
case 0: OUTPUT_STATE(out) = *out = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = *out = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_delay); |
|||
} |
|||
else { /* add falling delay */ |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
|
|||
|
|||
|
|||
@ -0,0 +1,61 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_buffer code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_buffer |
|||
C_Function_Name: cm_d_buffer |
|||
Description: "digital one-bit-wide buffer" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
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 |
|||
|
|||
@ -0,0 +1,677 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_dff/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
19 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
8 Aug 1991 Jeffrey P. Murray |
|||
27 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_dff |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== 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 |
|||
|
|||
/*=============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_dff() |
|||
|
|||
AUTHORS |
|||
|
|||
19 June 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
8 Aug 1991 Jeffrey P. Murray |
|||
27 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_dff code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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_DFF ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital d-type flip flop for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/19/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_dff(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
Digital_State_t *clk, /* current clk value */ |
|||
*clk_old, /* previous clk value */ |
|||
*set, /* current set value for dff */ |
|||
*set_old, /* previous set value for dff */ |
|||
*reset, /* current reset value for dff */ |
|||
*reset_old, /* previous reset value for dff */ |
|||
*out, /* current output for dff */ |
|||
*out_old, /* previous output for dff */ |
|||
|
|||
temp; /* temp storage for state values */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
clk = clk_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
set = set_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
|
|||
reset = reset_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
|
|||
out = out_old = (Digital_State_t *) cm_event_alloc(3,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(data) = PARAM(data_load); |
|||
LOAD(clk) = PARAM(clk_load); |
|||
if ( !PORT_NULL(set) ) { |
|||
LOAD(set) = PARAM(set_load); |
|||
} |
|||
if ( !PORT_NULL(reset) ) { |
|||
LOAD(reset) = PARAM(reset_load); |
|||
} |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
clk = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
clk_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
|
|||
set = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
set_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
|
|||
reset = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
reset_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
|
|||
out = (Digital_State_t *) cm_event_get_ptr(3,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(3,1); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/******** load current input values if set or reset |
|||
are not connected, set to zero... ********/ |
|||
*clk = INPUT_STATE(clk); |
|||
if ( PORT_NULL(set) ) { |
|||
*set = *set_old = ZERO; |
|||
} |
|||
else { |
|||
*set = INPUT_STATE(set); |
|||
} |
|||
if ( PORT_NULL(reset) ) { |
|||
*reset = *reset_old = ZERO; |
|||
} |
|||
else { |
|||
*reset = INPUT_STATE(reset); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** Initial conditions...output w/o delays ******/ |
|||
|
|||
temp = PARAM(ic); |
|||
|
|||
/** Modify output if set or reset lines are active **/ |
|||
if ( (*set==ONE) && (*reset==ZERO) ) temp = ONE; |
|||
if ( (*set==ZERO) && (*reset==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ONE) ) temp = UNKNOWN; |
|||
|
|||
*out = *out_old = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
} |
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
|
|||
/***** Find input that has changed... *****/ |
|||
|
|||
/**** Test set value for change ****/ |
|||
if ( *set != *set_old ) { /* either set or set release */ |
|||
switch ( *set ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *reset) { |
|||
if (*out_old != ONE) { /* set will change output */ |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already set */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* set will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *reset) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ZERO) { /* set will change output */ |
|||
/* output returns to reset condition */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
|
|||
if ( ONE == *reset ) { |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test reset value for change ****/ |
|||
if ( *reset != *reset_old ) { /* either reset or reset release */ |
|||
switch ( *reset ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *set) { |
|||
if (*out_old != ZERO) { /* reset will change output */ |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* reset will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *set) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ONE) { /* reset will change output */ |
|||
/* output returns to set condition */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
if ( ONE == *set ) { |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test clk value for change ****/ |
|||
if ( (*clk != *clk_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { /* clock or clock release */ |
|||
switch ( *clk ) { |
|||
|
|||
case ONE: |
|||
/* active edge...save current data value */ |
|||
temp = INPUT_STATE(data); |
|||
|
|||
if (*out_old != temp) { /* clk will change output */ |
|||
|
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(clk_delay); |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(clk_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive edge...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
|
|||
} |
|||
} |
|||
|
|||
else { /* data value must have changed... |
|||
return previous output value. */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/***** Add additional rise or fall delays, if appropriate *****/ |
|||
|
|||
if ( *out != *out_old ) { /*** output value is changing ***/ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/** fall to zero value **/ |
|||
case 0: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
break; |
|||
|
|||
/** rise to one value **/ |
|||
case 1: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
break; |
|||
|
|||
/** unknown output **/ |
|||
default: |
|||
/* based on old value, add rise or fall delay */ |
|||
if (0 == *out_old) { /* add rising delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
} |
|||
else { /* add falling delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** output strength values ***/ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STRENGTH(Nout) = STRONG; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,123 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
27 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_ff code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_dff |
|||
Spice_Model_Name: d_dff |
|||
Description: "digital d-type flip flop" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: data clk |
|||
Description: "input data" "clock" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: set reset |
|||
Description: "asynch. set" "asynch. reset" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out Nout |
|||
Description: "data output" "inverted data output" |
|||
Direction: out out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: clk_delay set_delay |
|||
Description: "delay from clk" "delay from set" |
|||
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: reset_delay ic |
|||
Description: "delay from reset" "output initial state" |
|||
Data_Type: real int |
|||
Default_Value: 1.0e-9 0 |
|||
Limits: [1e-12 -] [0 2] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: data_load clk_load |
|||
Description: "data load value (F)" "clk load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: set_load reset_load |
|||
Description: "set load value (F)" "reset load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,742 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_dlatch/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
25 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
13 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_latch |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_toggle_bit() |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
30 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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_dlatch() |
|||
|
|||
AUTHORS |
|||
|
|||
25 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
13 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_dlatch code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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_DLATCH ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital d-type latch for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/25/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_dlatch(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
Digital_State_t *data, /* current data value */ |
|||
*data_old, /* previous data value */ |
|||
*enable, /* current enable value */ |
|||
*enable_old, /* previous enable value */ |
|||
*set, /* current set value for dlatch */ |
|||
*set_old, /* previous set value for dlatch */ |
|||
*reset, /* current reset value for dlatch */ |
|||
*reset_old, /* previous reset value for dlatch */ |
|||
*out, /* current output for dlatch */ |
|||
*out_old, /* previous output for dlatch */ |
|||
|
|||
temp; /* temp storage for state values */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
data = data_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
enable = enable_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
set = set_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
reset = reset_old = (Digital_State_t *) cm_event_alloc(3,sizeof(Digital_State_t)); |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(4,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(data) = PARAM(data_load); |
|||
LOAD(enable) = PARAM(enable_load); |
|||
if ( !PORT_NULL(set) ) { |
|||
LOAD(set) = PARAM(set_load); |
|||
} |
|||
if ( !PORT_NULL(reset) ) { |
|||
LOAD(reset) = PARAM(reset_load); |
|||
} |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
data = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
data_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
enable = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
enable_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
set = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
set_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
reset = (Digital_State_t *) cm_event_get_ptr(3,0); |
|||
reset_old = (Digital_State_t *) cm_event_get_ptr(3,1); |
|||
out = (Digital_State_t *) cm_event_get_ptr(4,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(4,1); |
|||
} |
|||
|
|||
|
|||
|
|||
/******* load current input values if set or reset |
|||
are not connected, set to zero... *******/ |
|||
*data = INPUT_STATE(data); |
|||
*enable = INPUT_STATE(enable); |
|||
if ( PORT_NULL(set) ) { |
|||
*set = *set_old = ZERO; |
|||
} |
|||
else { |
|||
*set = INPUT_STATE(set); |
|||
} |
|||
if ( PORT_NULL(reset) ) { |
|||
*reset = *reset_old = ZERO; |
|||
} |
|||
else { |
|||
*reset = INPUT_STATE(reset); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** DC analysis...output w/o delays ******/ |
|||
|
|||
temp = PARAM(ic); |
|||
|
|||
/** Modify output if set or reset lines are active **/ |
|||
if (*enable==ONE) temp = *data; |
|||
if ( (*set==ONE) && (*reset==ZERO) ) temp = ONE; |
|||
if ( (*set==ZERO) && (*reset==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ONE) ) temp = UNKNOWN; |
|||
|
|||
*out = *out_old = temp; |
|||
|
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
} |
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
|
|||
/***** Find input that has changed... *****/ |
|||
|
|||
/**** Test set value for change ****/ |
|||
if ( *set != *set_old ) { /* either set or set release */ |
|||
switch ( *set ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *reset) { |
|||
if (*out_old != ONE) { /* set will change output */ |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already set */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* set will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
if ( ONE != *reset) { |
|||
if ( ONE == *enable ) { |
|||
/* active level...save & output current data value */ |
|||
temp = *data; |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
|
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ZERO) { /* set will change output */ |
|||
/* output returns to reset condition */ |
|||
*out = ZERO; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test reset value for change ****/ |
|||
if ( *reset != *reset_old ) { /* either reset or reset release */ |
|||
switch ( *reset ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *set) { |
|||
if (*out_old != ZERO) { /* reset will change output */ |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* reset will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
if ( ONE != *set) { |
|||
if ( ONE == *enable ) { |
|||
/* active level...save & output current data value */ |
|||
temp = *data; |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
|
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ONE) { /* reset will change output */ |
|||
/* output returns to set condition */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test for enable change... ****/ |
|||
if ( (*enable != *enable_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { /* enable or enable release */ |
|||
switch ( *enable ) { |
|||
|
|||
case ONE: |
|||
/* active edge...save & output current data value */ |
|||
temp = *data; |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
|
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(enable_delay); |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(enable_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive edge...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
else { /* test data value for change... */ |
|||
|
|||
if ( (*data != *data_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { |
|||
/* data value has changed... |
|||
test enable, and if active, update |
|||
the output...else return w/o change. */ |
|||
switch ( *enable ) { |
|||
|
|||
case ONE: |
|||
/* active level...save & output current data value */ |
|||
temp = *data; |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(data_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(data_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive level...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { /* nothing has changed!!! This shouldn't happen! */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/***** Add additional rise or fall delays, if appropriate *****/ |
|||
|
|||
if ( *out != *out_old ) { /*** output value is changing ***/ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/** fall to zero value **/ |
|||
case 0: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
break; |
|||
|
|||
/** rise to one value **/ |
|||
case 1: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
break; |
|||
|
|||
/** unknown output **/ |
|||
default: |
|||
/* based on old value, add rise or fall delay */ |
|||
if (0 == *out_old) { /* add rising delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
} |
|||
else { /* add falling delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** output strength values ***/ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STRENGTH(Nout) = STRONG; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,135 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_latch code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_dlatch |
|||
Spice_Model_Name: d_dlatch |
|||
Description: "digital d-type latch" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: data enable |
|||
Description: "input data" "enable" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: set reset |
|||
Description: "asynch. set" "asynch. reset" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out Nout |
|||
Description: "data output" "inverted data output" |
|||
Direction: out out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: data_delay |
|||
Description: "delay from data" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-9 |
|||
Limits: [1e-12 -] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: enable_delay set_delay |
|||
Description: "delay from clk" "delay from set" |
|||
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: reset_delay ic |
|||
Description: "delay from reset" "output initial state" |
|||
Data_Type: real int |
|||
Default_Value: 1.0e-9 0 |
|||
Limits: [1e-12 -] [0 2] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: data_load enable_load |
|||
Description: "data load value (F)" "clk load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: set_load reset_load |
|||
Description: "set load value (F)" "reset load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,241 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_fdiv/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
10 Jul 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
22 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the f_div |
|||
(frequency divider) code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <stdio.h> |
|||
#include <ctype.h> |
|||
#include <math.h> |
|||
#include <string.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_fdiv() |
|||
|
|||
AUTHORS |
|||
|
|||
10 Jul 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
22 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_fdiv code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_FDIV ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital frequency divider for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 7/10/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_fdiv(ARGS) |
|||
|
|||
{ |
|||
int div_factor; /* division factor */ |
|||
|
|||
|
|||
Digital_State_t *freq_in, /* freq_in clock value */ |
|||
*freq_in_old, /* previous freq_in value */ |
|||
*freq_out, /* current output for fdiv */ |
|||
*freq_out_old, /* previous output for fdiv */ |
|||
|
|||
*count, /* counter value */ |
|||
*count_old; /* previous counter value */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
freq_in = freq_in_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
freq_out = freq_out_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
count = count_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(freq_in) = PARAM(freq_in_load); |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
freq_in = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
freq_in_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
freq_out = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
freq_out_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
count = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
count_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*** Output the strength of freq_out (always strong)... ***/ |
|||
OUTPUT_STRENGTH(freq_out) = STRONG; |
|||
|
|||
|
|||
/** Retrieve parameters */ |
|||
div_factor = PARAM(div_factor); |
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** DC analysis...output w/o delays ******/ |
|||
|
|||
|
|||
/* read initial count value, normalize, and if it is out of |
|||
bounds, set to "zero" equivalent */ |
|||
*count = PARAM(i_count); |
|||
if ( (div_factor <= *count) || (0 > *count) ) { |
|||
*count = 0; |
|||
OUTPUT_STATE(freq_out) = *freq_out = *freq_out_old = ZERO; |
|||
} |
|||
|
|||
if ( (0 < *count) && (*count <= PARAM(high_cycles)) ) { |
|||
OUTPUT_STATE(freq_out) = *freq_out = *freq_out_old = ONE; |
|||
} |
|||
|
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
/*** load current input value... ***/ |
|||
*freq_in = INPUT_STATE(freq_in); |
|||
|
|||
|
|||
/**** Test to see if the input has provided an edge... ****/ |
|||
if ( (*freq_in != *freq_in_old)&&(*freq_in == 1) ) { |
|||
|
|||
/** An edge has been provided...revise count value **/ |
|||
*count = *count_old + 1; |
|||
|
|||
/* If new count value is equal to the div_factor+1 value, |
|||
need to normalize count to "1", and raise output */ |
|||
if ( ((div_factor+1) == *count)||(1 == *count) ) { |
|||
*count = 1; |
|||
OUTPUT_STATE(freq_out) = *freq_out = ONE; |
|||
OUTPUT_DELAY(freq_out) = PARAM(rise_delay); |
|||
} |
|||
else { |
|||
/* If new count value is equal to the |
|||
high_cycles+1 value, drop the output to ZERO */ |
|||
if ( ( PARAM(high_cycles)+1) == *count ) { |
|||
OUTPUT_STATE(freq_out) = *freq_out = ZERO; |
|||
OUTPUT_DELAY(freq_out) = PARAM(fall_delay); |
|||
} |
|||
else { |
|||
OUTPUT_CHANGED(freq_out) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { /** Output does not change!! **/ |
|||
|
|||
OUTPUT_CHANGED(freq_out) = FALSE; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,86 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_fdiv (frequency divider) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_fdiv |
|||
Spice_Model_Name: d_fdiv |
|||
Description: "digital frequency divider" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: freq_in freq_out |
|||
Description: "frequency input" "frequency output" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: div_factor high_cycles |
|||
Description: "divide factor" "number of high clock cycles" |
|||
Data_Type: int int |
|||
Default_Value: 2 1 |
|||
Limits: [1 -] [1 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: i_count |
|||
Description: "output initial count value" |
|||
Data_Type: int |
|||
Default_Value: 0 |
|||
Limits: [0 -] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: freq_in_load |
|||
Description: "freq_in load value (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
@ -0,0 +1,211 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_inverter/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
14 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the <model_name> |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <stdio.h> |
|||
#include <ctype.h> |
|||
#include <math.h> |
|||
#include <string.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_inverter() |
|||
|
|||
AUTHORS |
|||
|
|||
14 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_inverter code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_INVERTER ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital inverter gate for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/14/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_inverter(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
|
|||
Digital_State_t *out, /* temporary output for inverter */ |
|||
*out_old; /* previous output for inverter */ |
|||
|
|||
|
|||
/** Setup required state variables **/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
/* define load value on inputs */ |
|||
LOAD(in) = PARAM(input_load); |
|||
|
|||
} |
|||
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); |
|||
} |
|||
|
|||
|
|||
/** Check on analysis type **/ |
|||
|
|||
if (ANALYSIS == DC) { /* DC analysis...output w/o delays */ |
|||
|
|||
switch ( INPUT_STATE(in) ) { |
|||
|
|||
case ZERO: |
|||
OUTPUT_STATE(out) = *out = *out_old = ONE; |
|||
break; |
|||
|
|||
case ONE: |
|||
OUTPUT_STATE(out) = *out = *out_old = ZERO; |
|||
break; |
|||
|
|||
default: |
|||
OUTPUT_STATE(out) = *out = *out_old = UNKNOWN; |
|||
break; |
|||
} |
|||
|
|||
} |
|||
else { /* Transient Analysis */ |
|||
|
|||
switch ( INPUT_STATE(in) ) { |
|||
|
|||
/* fall to zero value */ |
|||
case 1: OUTPUT_STATE(out) = *out = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 0: OUTPUT_STATE(out) = *out = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_delay); |
|||
} |
|||
else { /* add falling delay */ |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,62 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_inverter code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_inverter |
|||
Spice_Model_Name: d_inverter |
|||
Description: "digital one-bit-wide inverter" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
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 |
|||
|
|||
@ -0,0 +1,765 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_jkff/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
21 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
12 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_jkff |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== 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 |
|||
|
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_eval_jk_result |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
Evaluates the J and K input states, plus the last state of |
|||
the flip flop, and returns the expected output value. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_toggle_bit(); |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
A Digital_State_t. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_EVAL_JK_RESULT ROUTINE ===*/ |
|||
|
|||
static Digital_State_t cm_eval_jk_result(Digital_State_t j_input, |
|||
Digital_State_t k_input, |
|||
Digital_State_t old_output) |
|||
{ |
|||
Digital_State_t output; /* returned output value */ |
|||
|
|||
|
|||
switch (j_input) { |
|||
|
|||
case ZERO: |
|||
switch (k_input) { |
|||
case ZERO: |
|||
output = old_output; |
|||
break; |
|||
case ONE: |
|||
output = ZERO; |
|||
break; |
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
case ONE: |
|||
switch (k_input) { |
|||
case ZERO: |
|||
output = ONE; |
|||
break; |
|||
case ONE: |
|||
output = old_output; |
|||
cm_toggle_bit(&output); |
|||
break; |
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
|
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
|
|||
return output; |
|||
|
|||
} |
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_jkff() |
|||
|
|||
AUTHORS |
|||
|
|||
21 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
12 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_jkff code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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_JKFF ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital jk-type flip flop for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/21/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_jkff(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
Digital_State_t *clk, /* current clk value */ |
|||
*clk_old, /* previous clk value */ |
|||
*set, /* current set value for dff */ |
|||
*set_old, /* previous set value for dff */ |
|||
*reset, /* current reset value for dff */ |
|||
*reset_old, /* previous reset value for dff */ |
|||
*out, /* current output for dff */ |
|||
*out_old, /* previous output for dff */ |
|||
|
|||
j_input, /* current j input value */ |
|||
k_input, /* current k input value */ |
|||
|
|||
temp; /* temp storage for state values */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
clk = clk_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
set = set_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
reset = reset_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(3,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(j) = PARAM(jk_load); |
|||
LOAD(k) = PARAM(jk_load); |
|||
LOAD(clk) = PARAM(clk_load); |
|||
if ( !PORT_NULL(set) ) { |
|||
LOAD(set) = PARAM(set_load); |
|||
} |
|||
if ( !PORT_NULL(reset) ) { |
|||
LOAD(reset) = PARAM(reset_load); |
|||
} |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
clk = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
clk_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
set = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
set_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
reset = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
reset_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
out = (Digital_State_t *) cm_event_get_ptr(3,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(3,1); |
|||
} |
|||
|
|||
|
|||
|
|||
/******** load current input values if set or reset |
|||
are not connected, set to zero... ********/ |
|||
*clk = INPUT_STATE(clk); |
|||
if ( PORT_NULL(set) ) { |
|||
*set = *set_old = ZERO; |
|||
} |
|||
else { |
|||
*set = INPUT_STATE(set); |
|||
} |
|||
if ( PORT_NULL(reset) ) { |
|||
*reset = *reset_old = ZERO; |
|||
} |
|||
else { |
|||
*reset = INPUT_STATE(reset); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** DC analysis...output w/o delays ******/ |
|||
|
|||
temp = PARAM(ic); |
|||
|
|||
/** Modify output if set or reset lines are active **/ |
|||
if ( (*set==ONE) && (*reset==ZERO) ) temp = ONE; |
|||
if ( (*set==ZERO) && (*reset==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ONE) ) temp = UNKNOWN; |
|||
|
|||
*out = *out_old = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
} |
|||
|
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
|
|||
/***** Find input that has changed... *****/ |
|||
|
|||
/**** Test set value for change ****/ |
|||
if ( *set != *set_old ) { /* either set or set release */ |
|||
switch ( *set ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *reset) { |
|||
if (*out_old != ONE) { /* set will change output */ |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already set */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* set will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *reset) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ZERO) { /* set will change output */ |
|||
/* output returns to reset condition */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
|
|||
if ( ONE == *reset ) { |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test reset value for change ****/ |
|||
if ( *reset != *reset_old ) { /* either reset or reset release */ |
|||
switch ( *reset ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *set) { |
|||
if (*out_old != ZERO) { /* reset will change output */ |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* reset will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *set) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ONE) { /* reset will change output */ |
|||
/* output returns to set condition */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
if ( ONE == *set ) { |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test clk value for change ****/ |
|||
if ( (*clk != *clk_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { /* clock or clock release */ |
|||
switch ( *clk ) { |
|||
|
|||
case ONE: |
|||
/* active edge...calculate new data output */ |
|||
j_input = INPUT_STATE(j); |
|||
k_input = INPUT_STATE(k); |
|||
temp = cm_eval_jk_result(j_input,k_input,*out_old); |
|||
|
|||
|
|||
if (*out_old != temp) { /* clk will change output */ |
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(clk_delay); |
|||
} |
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(clk_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive edge...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
else { /* data value must have changed... |
|||
return previous output value. */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/***** Add additional rise or fall delays, if appropriate *****/ |
|||
|
|||
if ( *out != *out_old ) { /*** output value is changing ***/ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/** fall to zero value **/ |
|||
case 0: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
break; |
|||
|
|||
/** rise to one value **/ |
|||
case 1: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
break; |
|||
|
|||
/** unknown output **/ |
|||
default: |
|||
/* based on old value, add rise or fall delay */ |
|||
if (0 == *out_old) { /* add rising delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
} |
|||
else { /* add falling delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** output strength values ***/ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STRENGTH(Nout) = STRONG; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,135 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_jkff code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_jkff |
|||
Spice_Model_Name: d_jkff |
|||
Description: "digital jk-type flip flop" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: j k |
|||
Description: "j input" "k input" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: clk |
|||
Description: "clock" |
|||
Direction: in |
|||
Default_Type: d |
|||
Allowed_Types: [d] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: set reset |
|||
Description: "asynch. set" "asynch. reset" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out Nout |
|||
Description: "data output" "inverted data output" |
|||
Direction: out out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: clk_delay set_delay |
|||
Description: "delay from clk" "delay from set" |
|||
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: reset_delay ic |
|||
Description: "delay from reset" "output initial state" |
|||
Data_Type: real int |
|||
Default_Value: 1.0e-9 0 |
|||
Limits: [1e-12 -] [0 2] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: jk_load clk_load |
|||
Description: "j,k load values (F)" "clk load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: set_load reset_load |
|||
Description: "set load value (F)" "reset load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,242 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_nand/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
18 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_nand |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_nand() |
|||
|
|||
AUTHORS |
|||
|
|||
18 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_nand code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_NAND ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital NAND gate for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/18/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
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 */ |
|||
|
|||
|
|||
/** Retrieve size value... **/ |
|||
size = PORT_SIZE(in); |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
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); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/*** Calculate new output value based on inputs ***/ |
|||
|
|||
*out = 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; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/*** 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) = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_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; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,62 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_nand code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_nand |
|||
Spice_Model_Name: d_nand |
|||
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 |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
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 |
|||
|
|||
@ -0,0 +1,242 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_nor/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
18 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_nor |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_nor() |
|||
|
|||
AUTHORS |
|||
|
|||
18 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_nor code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
|
|||
/*=== CM_D_NOR ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital NOR gate for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/18/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_nor(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 */ |
|||
|
|||
|
|||
/** Retrieve size value... **/ |
|||
size = PORT_SIZE(in); |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
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); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/*** Calculate new output value based on inputs ***/ |
|||
|
|||
*out = ONE; |
|||
for (i=0; i<size; i++) { |
|||
|
|||
/* make sure this input isn't floating... */ |
|||
if ( FALSE == PORT_NULL(in) ) { |
|||
|
|||
/* 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; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/*** 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) = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_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; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,62 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_nor code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_nor |
|||
Spice_Model_Name: d_nor |
|||
Description: "digital n-input nor 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 |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: input_load |
|||
Description: "input load value (pF)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
@ -0,0 +1,212 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_open_c/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_open_c |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_open_c() |
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_open_c code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_OPEN_C ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital open collector buffer for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 11/19/91 J.P,Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
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 */ |
|||
|
|||
|
|||
/** Setup required state variables **/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) |
|||
cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
/* define input loading... */ |
|||
LOAD(in) = PARAM(input_load); |
|||
} |
|||
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); |
|||
} |
|||
|
|||
|
|||
/** Check on analysis type **/ |
|||
|
|||
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; |
|||
} |
|||
|
|||
|
|||
} |
|||
else { /* Transient Analysis */ |
|||
|
|||
switch ( INPUT_STATE(in) ) { |
|||
|
|||
/* fall to zero value */ |
|||
case 0: OUTPUT_STATE(out) = *out = 0; |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = *out = 1; |
|||
OUTPUT_STRENGTH(out) = HI_IMPEDANCE; |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,61 @@ |
|||
/* $Id$ */ |
|||
/*.......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 |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_open_c (open collector) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_open_c |
|||
C_Function_Name: cm_d_open_c |
|||
Description: "digital one-bit-wide open-collector buffer" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 |
|||
|
|||
|
|||
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 |
|||
|
|||
@ -0,0 +1,217 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_open_e/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_open_e |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_open_e() |
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_open_e code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_OPEN_E ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital open emitter buffer for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 11/19/91 J.P,Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
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 */ |
|||
|
|||
|
|||
/** Setup required state variables **/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) |
|||
cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
/* define input loading... */ |
|||
LOAD(in) = PARAM(input_load); |
|||
} |
|||
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); |
|||
} |
|||
|
|||
|
|||
/** Check on analysis type **/ |
|||
|
|||
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; |
|||
} |
|||
|
|||
|
|||
} |
|||
else { /* Transient Analysis */ |
|||
|
|||
switch ( INPUT_STATE(in) ) { |
|||
|
|||
/* fall to zero value */ |
|||
case 0: OUTPUT_STATE(out) = *out = 0; |
|||
OUTPUT_STRENGTH(out) = HI_IMPEDANCE; |
|||
OUTPUT_DELAY(out) = PARAM(open_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = *out = 1; |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,61 @@ |
|||
/* $Id$ */ |
|||
/*.......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 |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_open_e code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_open_e |
|||
C_Function_Name: cm_d_open_e |
|||
Description: "digital one-bit-wide open-emitter buffer" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in out |
|||
Description: "input" "output" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 |
|||
|
|||
|
|||
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 |
|||
|
|||
@ -0,0 +1,242 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_or/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
18 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_or |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_or() |
|||
|
|||
AUTHORS |
|||
|
|||
18 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_or code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_OR ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital OR gate for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/18/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_or(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 */ |
|||
|
|||
|
|||
/** Retrieve size value... **/ |
|||
size = PORT_SIZE(in); |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage for the outputs */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
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); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/*** Calculate new output value based on inputs ***/ |
|||
|
|||
*out = ZERO; |
|||
for (i=0; i<size; i++) { |
|||
|
|||
/* 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; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/*** 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) = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_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; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,62 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_or code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_or |
|||
Spice_Model_Name: d_or |
|||
Description: "digital n-input or 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 |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
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 |
|||
|
|||
@ -0,0 +1,476 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_osc/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
24 Jul 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
23 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the d_osc code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
CMevt.c void cm_event_queue() |
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
Inputs from and outputs to ARGS structure. |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include "d_osc.h" /* ...contains macros & type defns. |
|||
for this model. 7/24/91 - JPM */ |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_osc() |
|||
|
|||
AUTHORS |
|||
|
|||
24 Jul 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_osc code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMmacros.h cm_message_send(); |
|||
|
|||
CM.c void *cm_analog_alloc() |
|||
void *cm_analog_get_ptr() |
|||
|
|||
CMevt.c void cm_event_queue() |
|||
|
|||
RETURNED VALUE |
|||
|
|||
Returns inputs and outputs via ARGS structure. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_OSC ROUTINE ===*/ |
|||
|
|||
/************************************************************* |
|||
* The following is the model for the controlled digital * |
|||
* oscillator for the ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 7/24/91 J.P.Murray * |
|||
*************************************************************/ |
|||
|
|||
/************************************************************* |
|||
* * |
|||
* * |
|||
* <-----duty_cycle-----> * |
|||
* I * |
|||
* I t2 t3 * |
|||
* I \______________/_____ * |
|||
* I | | * |
|||
* I | | | | * |
|||
* I | | * |
|||
* I | | | | * |
|||
* I | | * |
|||
* I | | | | * |
|||
* I-----------------*-----* - - - - - - - - - -*--------- * |
|||
* t1 t4 * |
|||
* * |
|||
* * |
|||
* t2 = t1 + rise_delay * |
|||
* t4 = t3 + fall_delay * |
|||
* * |
|||
* Note that for the digital model, unlike for the * |
|||
* analog "square" model, t1 and t3 are stored and * |
|||
* adjusted values, but t2 & t4 are implied by the * |
|||
* rise and fall delays of the model, but are otherwise * |
|||
* not stored values. JPM * |
|||
* * |
|||
*************************************************************/ |
|||
|
|||
void cm_d_osc(ARGS) |
|||
{ |
|||
|
|||
double *x, /* analog input value control array */ |
|||
*y, /* frequency array */ |
|||
cntl_input, /* control input value */ |
|||
*phase, /* instantaneous phase of the model */ |
|||
*phase_old, /* previous phase of the model */ |
|||
*t1, /* pointer to t1 value */ |
|||
*t3, /* pointer to t3 value */ |
|||
time1, /* variable for calculating new time1 value */ |
|||
time3, /* variable for calculating new time3 value */ |
|||
freq, /* instantaneous frequency value */ |
|||
dphase, /* fractional part into cycle */ |
|||
duty_cycle, /* duty_cycle value */ |
|||
test_double, /* testing variable */ |
|||
slope; /* slope value...used to extrapolate |
|||
freq values past endpoints. */ |
|||
|
|||
|
|||
int i, /* generic loop counter index */ |
|||
cntl_size, /* control array size */ |
|||
freq_size, /* frequency array size */ |
|||
int_cycle; /* integer number of cycles */ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/**** Retrieve frequently used parameters... ****/ |
|||
|
|||
cntl_size = PARAM_SIZE(cntl_array); |
|||
freq_size = PARAM_SIZE(freq_array); |
|||
duty_cycle = PARAM(duty_cycle); |
|||
|
|||
|
|||
/* check and make sure that the control array is the |
|||
same size as the frequency array */ |
|||
|
|||
if(cntl_size != freq_size){ |
|||
cm_message_send(d_osc_array_error); |
|||
return; |
|||
} |
|||
|
|||
|
|||
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/ |
|||
|
|||
|
|||
/* Allocate storage for internal variables */ |
|||
phase = phase_old = cm_analog_alloc(0,sizeof(double)); |
|||
|
|||
t1 = cm_analog_alloc(1,sizeof(double)); |
|||
|
|||
t3 = cm_analog_alloc(2,sizeof(double)); |
|||
|
|||
|
|||
} |
|||
|
|||
else { /*** This is not an initialization pass...retrieve storage |
|||
addresses and calculate new outputs, if required. ***/ |
|||
|
|||
|
|||
/** Retrieve previous values... **/ |
|||
|
|||
|
|||
/* assign internal variables */ |
|||
phase = cm_analog_get_ptr(0,0); |
|||
phase_old = cm_analog_get_ptr(0,1); |
|||
|
|||
t1 = cm_analog_get_ptr(1,0); |
|||
|
|||
t3 = cm_analog_get_ptr(2,0); |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
switch (CALL_TYPE) { |
|||
|
|||
case ANALOG: /** analog call **/ |
|||
|
|||
test_double = TIME; |
|||
|
|||
if ( AC == ANALYSIS ) { /* this model does not function |
|||
in AC analysis mode. */ |
|||
|
|||
return; |
|||
|
|||
} |
|||
else { |
|||
|
|||
if ( 0.0 == TIME ) { /* DC analysis */ |
|||
|
|||
/* retrieve & normalize phase value */ |
|||
*phase = PARAM(init_phase); |
|||
if ( 0 > *phase ) { |
|||
*phase = *phase + 360.0; |
|||
} |
|||
*phase = *phase / 360.0; |
|||
|
|||
|
|||
/* set phase value to init_phase */ |
|||
*phase_old = *phase; |
|||
|
|||
/* preset time values to harmless values... */ |
|||
*t1 = -1; |
|||
*t3 = -1; |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
/* Allocate storage for breakpoint domain & freq. range values */ |
|||
|
|||
x = (double *) calloc(cntl_size, sizeof(double)); |
|||
if (x == '\0') { |
|||
cm_message_send(d_osc_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
y = (double *) calloc(freq_size, sizeof(double)); |
|||
if (y == '\0') { |
|||
cm_message_send(d_osc_allocation_error); |
|||
return; |
|||
} |
|||
|
|||
/* Retrieve x and y values. */ |
|||
for (i=0; i<cntl_size; i++) { |
|||
x[i] = PARAM(cntl_array[i]); |
|||
y[i] = PARAM(freq_array[i]); |
|||
} |
|||
|
|||
/* Retrieve cntl_input value. */ |
|||
cntl_input = INPUT(cntl_in); |
|||
|
|||
/* Determine segment boundaries within which cntl_input resides */ |
|||
/*** cntl_input below lowest cntl_voltage ***/ |
|||
if (cntl_input <= x[0]) { |
|||
|
|||
slope = (y[1] - y[0])/(x[1] - x[0]); |
|||
freq = y[0] + (cntl_input - x[0]) * slope; |
|||
|
|||
} |
|||
else |
|||
/*** cntl_input above highest cntl_voltage ***/ |
|||
|
|||
if (cntl_input >= x[cntl_size-1]) { |
|||
|
|||
slope = (y[cntl_size-1] - y[cntl_size-2]) / |
|||
(x[cntl_size-1] - x[cntl_size-2]); |
|||
freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * slope; |
|||
|
|||
} |
|||
else { /*** cntl_input within bounds of end midpoints... |
|||
must determine position progressively & then |
|||
calculate required output. ***/ |
|||
|
|||
for (i=0; i<cntl_size-1; i++) { |
|||
|
|||
if ( (cntl_input < x[i+1]) && (cntl_input >= x[i]) ) { |
|||
|
|||
/* Interpolate to the correct frequency value */ |
|||
|
|||
freq = ( (cntl_input - x[i]) / (x[i+1] - x[i]) ) * |
|||
( y[i+1]-y[i] ) + y[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** If freq < 0.0, clamp to 1e-16 & issue a warning ***/ |
|||
if ( 0.0 > freq ) { |
|||
freq = 1.0e-16; |
|||
cm_message_send(d_osc_negative_freq_error); |
|||
} |
|||
|
|||
|
|||
/* calculate the instantaneous phase */ |
|||
*phase = *phase_old + freq * (TIME - T(1)); |
|||
|
|||
/* convert the phase to an integer */ |
|||
int_cycle = *phase_old; |
|||
|
|||
/* dphase is the percent into the cycle for |
|||
the period */ |
|||
dphase = *phase_old - int_cycle; |
|||
|
|||
|
|||
/* Calculate the time variables and the output value |
|||
for this iteration */ |
|||
|
|||
if((*t1 <= TIME) && (TIME <= *t3)) { /* output high */ |
|||
|
|||
*t3 = T(1) + (1 - dphase)/freq; |
|||
|
|||
if(TIME < *t3) { |
|||
cm_event_queue(*t3); |
|||
} |
|||
|
|||
|
|||
} |
|||
else |
|||
|
|||
if((*t3 <= TIME) && (TIME <= *t1)) { /* output low */ |
|||
|
|||
if(dphase > (1.0 - duty_cycle) ) { |
|||
dphase = dphase - 1.0; |
|||
} |
|||
*t1 = T(1) + ( (1.0 - duty_cycle) - dphase)/freq; |
|||
|
|||
if(TIME < *t1) { |
|||
|
|||
cm_event_queue(*t1); |
|||
|
|||
} |
|||
} |
|||
else { |
|||
|
|||
if(dphase > (1.0 - duty_cycle) ) { |
|||
dphase = dphase - 1.0; |
|||
} |
|||
*t1 = T(1) + ( (1.0 - duty_cycle) - dphase )/freq; |
|||
|
|||
if((TIME < *t1) || (T(1) == 0)) { |
|||
cm_event_queue(*t1); |
|||
} |
|||
|
|||
*t3 = T(1) + (1 - dphase)/freq; |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
free(x); |
|||
free(y); |
|||
|
|||
|
|||
} |
|||
break; |
|||
|
|||
|
|||
case EVENT: /** discrete call...lots to do **/ |
|||
|
|||
|
|||
test_double = TIME; |
|||
|
|||
if ( 0.0 == TIME ) { /* DC analysis...preset values, |
|||
as appropriate.... */ |
|||
|
|||
/* retrieve & normalize phase value */ |
|||
*phase = PARAM(init_phase); |
|||
if ( 0 > *phase ) { |
|||
*phase = *phase + 360.0; |
|||
} |
|||
*phase = *phase / 360.0; |
|||
|
|||
|
|||
/* set phase value to init_phase */ |
|||
*phase_old = *phase; |
|||
|
|||
/* preset time values to harmless values... */ |
|||
*t1 = -1; |
|||
*t3 = -1; |
|||
} |
|||
|
|||
|
|||
|
|||
/* Calculate the time variables and the output value |
|||
for this iteration */ |
|||
|
|||
/* Output is always set to STRONG */ |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
|
|||
|
|||
|
|||
if( *t1 == TIME ) { /* rising edge */ |
|||
|
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(rise_delay); |
|||
|
|||
} |
|||
else { |
|||
|
|||
if ( *t3 == TIME ) { /* falling edge */ |
|||
|
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
} |
|||
|
|||
else { /* no change in output */ |
|||
|
|||
if ( TIME != 0.0 ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
|
|||
if ( (*t1 < TIME) && (TIME < *t3) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
} |
|||
else { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
} |
|||
} |
|||
} |
|||
|
|||
break; |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,91 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_osc/d_osc.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
25 Jul 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the header information for the d_osc |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
N/A |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
/* |
|||
Structures, etc. for d_osc oscillator model. |
|||
7/25/90 |
|||
Last Modified 7/25/91 J.P.Murray */ |
|||
|
|||
/*=======================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES =====================================================*/ |
|||
|
|||
#include <stdio.h> |
|||
#include <ctype.h> |
|||
#include <math.h> |
|||
#include <string.h> |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS =========================================================*/ |
|||
|
|||
|
|||
/**** Error Messages ****/ |
|||
char *d_osc_allocation_error = "\n**** Error ****\nD_OSC: Error allocating VCO block storage \n"; |
|||
char *d_osc_array_error = "\n**** Error ****\nD_OSC: Size of control array different than frequency array \n"; |
|||
char *d_osc_negative_freq_error = "\n**** Error ****\nD_OSC: The extrapolated value for frequency\nhas been found to be negative... \n Lower frequency level has been clamped to 0.0 Hz \n"; |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ============================================================*/ |
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS ========================================*/ |
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ====================================*/ |
|||
|
|||
|
|||
/*=======================================================================*/ |
|||
|
|||
|
|||
@ -0,0 +1,74 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
hybrid d_osc code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_osc |
|||
C_Function_Name: cm_d_osc |
|||
Description: "controlled digital oscillator" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: cntl_in out |
|||
Description: "control input" "output" |
|||
Direction: in out |
|||
Default_Type: v d |
|||
Allowed_Types: [v,vd,i,id] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: cntl_array freq_array |
|||
Description: "control array" "frequency array" |
|||
Data_Type: real real |
|||
Default_Value: 0.0 1.0e6 |
|||
Limits: - [0 -] |
|||
Vector: yes yes |
|||
Vector_Bounds: [2 -] [2 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: duty_cycle init_phase |
|||
Description: "output duty cycle" "initial phase of output" |
|||
Data_Type: real real |
|||
Default_Value: 0.5 0 |
|||
Limits: [1e-6 0.999999] [-180.0 +360.0] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: rise_delay fall_delay |
|||
Description: "rise delay" "fall delay" |
|||
Data_Type: real real |
|||
Default_Value: 1e-9 1e-9 |
|||
Limits: [0 -] [0 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
@ -0,0 +1,134 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_pulldown/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_pulldown |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_pulldown() |
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_pulldown code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_PULLDOWN ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital pulldown resistor for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 11/19/91 J.P,Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_pulldown(ARGS) |
|||
|
|||
{ |
|||
LOAD(out) = PARAM(load); |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_STRENGTH(out) = RESISTIVE; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,51 @@ |
|||
/* $Id$ */ |
|||
/*.......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 |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_pulldown code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_pulldown |
|||
C_Function_Name: cm_d_pulldown |
|||
Description: "digital pulldown resistor" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out |
|||
Description: "output" |
|||
Direction: out |
|||
Default_Type: d |
|||
Allowed_Types: [d] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: load |
|||
Description: "load value (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
@ -0,0 +1,130 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_pullup/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_pullup |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_pullup() |
|||
|
|||
AUTHORS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
19 Nov 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_pullup code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_PULLUP ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital pullup resistor for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 11/19/91 J.P,Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_pullup(ARGS) |
|||
|
|||
{ |
|||
LOAD(out) = PARAM(load); |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_STRENGTH(out) = RESISTIVE; |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
/* $Id$ */ |
|||
/*.......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 |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_pullup code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_pullup |
|||
C_Function_Name: cm_d_pullup |
|||
Description: "digital pullup resistor" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out |
|||
Description: "output" |
|||
Direction: out |
|||
Default_Type: d |
|||
Allowed_Types: [d] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: load |
|||
Description: "load value (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
1179
src/xspice/icm/digital/d_ram/cfunc.mod
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,123 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_ram code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_ram |
|||
Spice_Model_Name: d_ram |
|||
Description: "digital random-access memory" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: data_in data_out |
|||
Description: "data input line(s)" "data output line(s)" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: yes yes |
|||
Vector_Bounds: [1 -] [1 -] |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: address write_en |
|||
Description: "address input line(s)" "write enable" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: yes no |
|||
Vector_Bounds: [1 -] - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: select |
|||
Description: "chip select line(s)" |
|||
Direction: in |
|||
Default_Type: d |
|||
Allowed_Types: [d] |
|||
Vector: yes |
|||
Vector_Bounds: [1 16] |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: select_value |
|||
Description: "decimal active value for select line comparison" |
|||
Data_Type: int |
|||
Default_Value: 1 |
|||
Limits: [0 32767] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: ic |
|||
Description: "initial bit state @ DC" |
|||
Data_Type: int |
|||
Default_Value: 2 |
|||
Limits: [0 2] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: read_delay |
|||
Description: "read delay from address/select/write_en active" |
|||
Data_Type: real |
|||
Default_Value: 100.0e-9 |
|||
Limits: [1e-12 -] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: data_load address_load |
|||
Description: "data_in load value (F)" "address line load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: select_load enable_load |
|||
Description: "select load value (F)" "enable line load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
1302
src/xspice/icm/digital/d_source/cfunc.mod
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,83 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_source/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
13 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
8 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the header information used by the |
|||
d_source code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
NONE |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
#include <stdio.h> |
|||
#include <ctype.h> |
|||
#include <math.h> |
|||
#include <string.h> |
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define OK 0 |
|||
#define FAIL 1 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */ |
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*=============================================================================*/ |
|||
@ -0,0 +1,65 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_source code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_source |
|||
Spice_Model_Name: d_source |
|||
Description: "digital signal 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: input_file |
|||
Description: "digital input vector filename" |
|||
Data_Type: string |
|||
Default_Value: "source.txt" |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: input_load |
|||
Description: "input loading capacitance (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
@ -0,0 +1,767 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_srff/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
24 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the d_srff code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== 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 |
|||
|
|||
/*=============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_eval_sr_result |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
Evaluates the S and R input states, plus the last state of |
|||
the flip flop, and returns the expected output value. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_toggle_bit(); |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
A Digital_State_t. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_EVAL_SR_RESULT ROUTINE ===*/ |
|||
|
|||
static Digital_State_t cm_eval_sr_result(Digital_State_t s_input, |
|||
Digital_State_t r_input, |
|||
Digital_State_t old_output) |
|||
{ |
|||
Digital_State_t output; |
|||
|
|||
|
|||
switch (s_input) { |
|||
|
|||
case ZERO: |
|||
switch (r_input) { |
|||
case ZERO: |
|||
output = old_output; |
|||
break; |
|||
case ONE: |
|||
output = ZERO; |
|||
break; |
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
case ONE: |
|||
switch (r_input) { |
|||
case ZERO: |
|||
output = ONE; |
|||
break; |
|||
case ONE: |
|||
output = UNKNOWN; |
|||
break; |
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
|
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
|
|||
return output; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_srff() |
|||
|
|||
AUTHORS |
|||
|
|||
24 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
24 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_srff code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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_SRFF ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital sr-type flip flop for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/24/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_srff(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
Digital_State_t *clk, /* current clk value */ |
|||
*clk_old, /* previous clk value */ |
|||
*set, /* current set value for dff */ |
|||
*set_old, /* previous set value for dff */ |
|||
*reset, /* current reset value for dff */ |
|||
*reset_old, /* previous reset value for dff */ |
|||
*out, /* current output for dff */ |
|||
*out_old, /* previous output for dff */ |
|||
|
|||
s_input, /* current j input value */ |
|||
r_input, /* current k input value */ |
|||
|
|||
temp; /* temp storage for state values */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
clk = clk_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
set = set_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
reset = reset_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(3,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(s) = PARAM(sr_load); |
|||
LOAD(r) = PARAM(sr_load); |
|||
LOAD(clk) = PARAM(clk_load); |
|||
if ( !PORT_NULL(set) ) { |
|||
LOAD(set) = PARAM(set_load); |
|||
} |
|||
if ( !PORT_NULL(reset) ) { |
|||
LOAD(reset) = PARAM(reset_load); |
|||
} |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
clk = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
clk_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
set = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
set_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
reset = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
reset_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
out = (Digital_State_t *) cm_event_get_ptr(3,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(3,1); |
|||
} |
|||
|
|||
|
|||
/******** load current input values if set or reset |
|||
are not connected, set to zero... ********/ |
|||
*clk = INPUT_STATE(clk); |
|||
if ( PORT_NULL(set) ) { |
|||
*set = *set_old = ZERO; |
|||
} |
|||
else { |
|||
*set = INPUT_STATE(set); |
|||
} |
|||
if ( PORT_NULL(reset) ) { |
|||
*reset = *reset_old = ZERO; |
|||
} |
|||
else { |
|||
*reset = INPUT_STATE(reset); |
|||
} |
|||
|
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** DC analysis...output w/o delays ******/ |
|||
|
|||
temp = PARAM(ic); |
|||
|
|||
/** Modify output if set or reset lines are active **/ |
|||
if ( (*set==ONE) && (*reset==ZERO) ) temp = ONE; |
|||
if ( (*set==ZERO) && (*reset==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ONE) ) temp = UNKNOWN; |
|||
|
|||
*out = *out_old = temp; |
|||
|
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
} |
|||
|
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
|
|||
|
|||
/***** Find input that has changed... *****/ |
|||
|
|||
/**** Test set value for change ****/ |
|||
if ( *set != *set_old ) { /* either set or set release */ |
|||
switch ( *set ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *reset) { |
|||
if (*out_old != ONE) { /* set will change output */ |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already set */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* set will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *reset) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ZERO) { /* set will change output */ |
|||
/* output returns to reset condition */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
|
|||
if ( ONE == *reset ) { |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test reset value for change ****/ |
|||
if ( *reset != *reset_old ) { /* either reset or reset release */ |
|||
switch ( *reset ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *set) { |
|||
if (*out_old != ZERO) { /* reset will change output */ |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* reset will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *set) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ONE) { /* reset will change output */ |
|||
/* output returns to set condition */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
|
|||
if ( ONE == *set ) { |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test clk value for change ****/ |
|||
if ( (*clk != *clk_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { /* clock or clock release */ |
|||
switch ( *clk ) { |
|||
|
|||
case ONE: |
|||
/* active edge...calculate new data output */ |
|||
s_input = INPUT_STATE(s); |
|||
r_input = INPUT_STATE(r); |
|||
temp = cm_eval_sr_result(s_input,r_input,*out_old); |
|||
|
|||
|
|||
if (*out_old != temp) { /* clk will change output */ |
|||
|
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(clk_delay); |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(clk_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive edge...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
|
|||
} |
|||
} |
|||
|
|||
else { /* data value must have changed... |
|||
return previous output value. */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/***** Add additional rise or fall delays, if appropriate *****/ |
|||
|
|||
if ( *out != *out_old ) { /*** output value is changing ***/ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/** fall to zero value **/ |
|||
case 0: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
break; |
|||
|
|||
/** rise to one value **/ |
|||
case 1: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
break; |
|||
|
|||
/** unknown output **/ |
|||
default: |
|||
/* based on old value, add rise or fall delay */ |
|||
if (0 == *out_old) { /* add rising delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
} |
|||
else { /* add falling delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** output strength values ***/ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STRENGTH(Nout) = STRONG; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,135 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_srff code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_srff |
|||
Spice_Model_Name: d_srff |
|||
Description: "digital set-reset flip flop" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: s r |
|||
Description: "s input" "r input" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: clk |
|||
Description: "clock" |
|||
Direction: in |
|||
Default_Type: d |
|||
Allowed_Types: [d] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: set reset |
|||
Description: "asynch. set" "asynch. reset" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out Nout |
|||
Description: "data output" "inverted data output" |
|||
Direction: out out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: clk_delay set_delay |
|||
Description: "delay from clk" "delay from set" |
|||
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: reset_delay ic |
|||
Description: "delay from reset" "output initial state" |
|||
Data_Type: real int |
|||
Default_Value: 1.0e-9 0 |
|||
Limits: [1e-12 -] [0 2] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: sr_load clk_load |
|||
Description: "s,r load values (F)" "clk load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: set_load reset_load |
|||
Description: "set load value (F)" "reset load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,827 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE <model_name>/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
25 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
13 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the <model_name> code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== 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 |
|||
|
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_eval_sr_result |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
NONE |
|||
|
|||
SUMMARY |
|||
|
|||
Evaluates the S and R input states, plus the last state of |
|||
the latch, and returns the expected output value. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
CMutil.c void cm_toggle_bit(); |
|||
|
|||
|
|||
RETURNED VALUE |
|||
|
|||
A Digital_State_t. |
|||
|
|||
GLOBAL VARIABLES |
|||
|
|||
NONE |
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_EVAL_SR_RESULT ROUTINE ===*/ |
|||
|
|||
static Digital_State_t cm_eval_sr_result(Digital_State_t s_input, |
|||
Digital_State_t r_input, |
|||
Digital_State_t old_output) |
|||
{ |
|||
Digital_State_t output; |
|||
|
|||
|
|||
switch (s_input) { |
|||
|
|||
case ZERO: |
|||
switch (r_input) { |
|||
case ZERO: |
|||
output = old_output; |
|||
break; |
|||
case ONE: |
|||
output = ZERO; |
|||
break; |
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
case ONE: |
|||
switch (r_input) { |
|||
case ZERO: |
|||
output = ONE; |
|||
break; |
|||
case ONE: |
|||
output = UNKNOWN; |
|||
break; |
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
break; |
|||
|
|||
|
|||
case UNKNOWN: |
|||
output = UNKNOWN; |
|||
break; |
|||
} |
|||
|
|||
return output; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_srlatch() |
|||
|
|||
AUTHORS |
|||
|
|||
25 Jun 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
13 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_srlatch code model. |
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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_SRLATCH ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital sr-type latch for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/25/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_srlatch(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
Digital_State_t *s, /* current s-input value */ |
|||
*s_old, /* previous s-input value */ |
|||
*r, /* current r-input value */ |
|||
*r_old, /* previous r-input value */ |
|||
*enable, /* current enable value */ |
|||
*enable_old, /* previous enable value */ |
|||
*set, /* current set value for srlatch */ |
|||
*set_old, /* previous set value for srlatch */ |
|||
*reset, /* current reset value for srlatch */ |
|||
*reset_old, /* previous reset value for srlatch */ |
|||
*out, /* current output for srlatch */ |
|||
*out_old, /* previous output for srlatch */ |
|||
|
|||
temp; /* temp storage for state values */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
s = s_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
r = r_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
enable = enable_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
set = set_old = (Digital_State_t *) cm_event_alloc(3,sizeof(Digital_State_t)); |
|||
reset = reset_old = (Digital_State_t *) cm_event_alloc(4,sizeof(Digital_State_t)); |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(5,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(s) = PARAM(sr_load); |
|||
LOAD(r) = PARAM(sr_load); |
|||
LOAD(enable) = PARAM(enable_load); |
|||
if ( !PORT_NULL(set) ) { |
|||
LOAD(set) = PARAM(set_load); |
|||
} |
|||
if ( !PORT_NULL(reset) ) { |
|||
LOAD(reset) = PARAM(reset_load); |
|||
} |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
s = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
s_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
r = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
r_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
enable = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
enable_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
set = (Digital_State_t *) cm_event_get_ptr(3,0); |
|||
set_old = (Digital_State_t *) cm_event_get_ptr(3,1); |
|||
reset = (Digital_State_t *) cm_event_get_ptr(4,0); |
|||
reset_old = (Digital_State_t *) cm_event_get_ptr(4,1); |
|||
out = (Digital_State_t *) cm_event_get_ptr(5,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(5,1); |
|||
} |
|||
|
|||
|
|||
|
|||
/******* load current input values if set or reset |
|||
are not connected, set to zero... *******/ |
|||
*s = INPUT_STATE(s); |
|||
*r = INPUT_STATE(r); |
|||
*enable = INPUT_STATE(enable); |
|||
if ( PORT_NULL(set) ) { |
|||
*set = *set_old = ZERO; |
|||
} |
|||
else { |
|||
*set = INPUT_STATE(set); |
|||
} |
|||
if ( PORT_NULL(reset) ) { |
|||
*reset = *reset_old = ZERO; |
|||
} |
|||
else { |
|||
*reset = INPUT_STATE(reset); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** DC analysis...output w/o delays ******/ |
|||
|
|||
temp = PARAM(ic); |
|||
|
|||
/** Modify output if set or reset lines are active **/ |
|||
if ( (*enable==ONE) && (*s==ONE) && (*r==ZERO) ) temp = ONE; |
|||
if ( (*enable==ONE) && (*s==ZERO) && (*r==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ZERO) ) temp = ONE; |
|||
if ( (*set==ZERO) && (*reset==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ONE) ) temp = UNKNOWN; |
|||
|
|||
*out = *out_old = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
} |
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
|
|||
/***** Find input that has changed... *****/ |
|||
|
|||
/**** Test set value for change ****/ |
|||
if ( *set != *set_old ) { /* either set or set release */ |
|||
switch ( *set ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *reset) { |
|||
if (*out_old != ONE) { /* set will change output */ |
|||
*out = ONE; |
|||
|
|||
/* output goes to ONE */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already set */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* set will change output */ |
|||
*out = UNKNOWN; |
|||
|
|||
/* output goes to UNKNOWN */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
if ( ONE != *reset) { |
|||
if ( ONE == *enable ) { |
|||
/* active level...save & output current value */ |
|||
temp = cm_eval_sr_result(*s,*r,*out_old); |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ZERO) { /* set will change output */ |
|||
/* output returns to reset condition */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test reset value for change ****/ |
|||
if ( *reset != *reset_old ) { /* either reset or reset release */ |
|||
switch ( *reset ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *set) { |
|||
if (*out_old != ZERO) { /* reset will change output */ |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* reset will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
if ( ONE != *set) { |
|||
if ( ONE == *enable ) { |
|||
/* active level...save & output current value */ |
|||
temp = cm_eval_sr_result(*s,*r,*out_old); |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ONE) { /* reset will change output */ |
|||
/* output returns to set condition */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test for enable change... ****/ |
|||
if ( (*enable != *enable_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { /* enable or enable release */ |
|||
switch ( *enable ) { |
|||
|
|||
case ONE: |
|||
/* active edge...save & output current data value */ |
|||
temp = cm_eval_sr_result(*s,*r,*out_old); |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(enable_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(enable_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive edge...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
else { /* test data value for change... */ |
|||
|
|||
if ( ((*s != *s_old) || (*r != *r_old)) && |
|||
(*reset != ONE) && (*set != ONE) ) { |
|||
/* input values have changed... |
|||
test enable, and if active, update |
|||
the output...else return w/o change. */ |
|||
switch ( *enable ) { |
|||
|
|||
case ONE: |
|||
/* active level...save & output current data value */ |
|||
temp = cm_eval_sr_result(*s,*r,*out_old); |
|||
|
|||
if (*out_old != temp) { /* enable will change output */ |
|||
*out = temp; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(sr_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
cm_toggle_bit(&temp); |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(sr_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive level...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { /* nothing has changed!!! This shouldn't happen! */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/***** Add additional rise or fall delays, if appropriate *****/ |
|||
|
|||
if ( *out != *out_old ) { /*** output value is changing ***/ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/** fall to zero value **/ |
|||
case 0: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
break; |
|||
|
|||
/** rise to one value **/ |
|||
case 1: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
break; |
|||
|
|||
/** unknown output **/ |
|||
default: |
|||
/* based on old value, add rise or fall delay */ |
|||
if (0 == *out_old) { /* add rising delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
} |
|||
else { /* add falling delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** output strength values ***/ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STRENGTH(Nout) = STRONG; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,147 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_srlatch code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_srlatch |
|||
Spice_Model_Name: d_srlatch |
|||
Description: "digital sr-type latch" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: s r |
|||
Description: "s input" "r input" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: enable |
|||
Description: "enable" |
|||
Direction: in |
|||
Default_Type: d |
|||
Allowed_Types: [d] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: set reset |
|||
Description: "asynch. set" "asynch. reset" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out Nout |
|||
Description: "data output" "inverted data output" |
|||
Direction: out out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: sr_delay |
|||
Description: "delay from s or r input change" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-9 |
|||
Limits: [1e-12 -] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: enable_delay set_delay |
|||
Description: "delay from clk" "delay from set" |
|||
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: reset_delay ic |
|||
Description: "delay from reset" "output initial state" |
|||
Data_Type: real int |
|||
Default_Value: 1.0e-9 0 |
|||
Limits: [1e-12 -] [0 2] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: sr_load enable_load |
|||
Description: "s & r load values (F)" "clk load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: set_load reset_load |
|||
Description: "set load value (F)" "reset load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
2217
src/xspice/icm/digital/d_state/cfunc.mod
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,77 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_state/d_state.h |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
13 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
20 Aug 1991 Jeffrey P. Murray |
|||
30 Sep 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the header information for the |
|||
d_state model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
N/A N/A |
|||
|
|||
|
|||
|
|||
REFERENCED FILES |
|||
|
|||
N/A |
|||
|
|||
|
|||
NON-STANDARD FEATURES |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
#define OK 0 |
|||
#define FAIL 1 |
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */ |
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,130 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
30 Sept 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_state (state machine) code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_state |
|||
Spice_Model_Name: d_state |
|||
Description: "digital state machine" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: in clk |
|||
Description: "input" "clock" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: yes no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
|
|||
Port_Name: reset out |
|||
Description: "reset" "output" |
|||
Direction: in out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no yes |
|||
Vector_Bounds: - [1 -] |
|||
Null_Allowed: yes no |
|||
|
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: clk_delay reset_delay |
|||
Description: "delay from CLK" "delay from reset" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-9 1.0e-9 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: state_file |
|||
Description: "state transition specification file name" |
|||
Data_Type: string |
|||
Default_Value: "state.txt" |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: reset_state |
|||
Description: "default state on RESET & at DC" |
|||
Data_Type: int |
|||
Default_Value: 0 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: input_load |
|||
Description: "input loading capacitance (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: clk_load |
|||
Description: "clock loading capacitance (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
PARAMETER_TABLE: |
|||
|
|||
|
|||
Parameter_Name: reset_load |
|||
Description: "reset loading capacitance (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: no |
|||
|
|||
@ -0,0 +1,698 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_tff/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
24 June 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
12 Aug 1991 Jeffrey P. Murray |
|||
2 Oct 1991 Jeffrey P. Murray |
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the model-specific routines used to |
|||
functionally describe the d_tff code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*=============================================================================*/ |
|||
|
|||
/*=== CM<model_name> ROUTINE ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
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 |
|||
|
|||
/*=============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_tff() |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
24 Jun 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
29 Jan 1992 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_tff code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
FILE ROUTINE CALLED |
|||
|
|||
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_TFF ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital t-type flip flop for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* Created 6/24/91 J.P.Murray * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_tff(ARGS) |
|||
|
|||
{ |
|||
int i; /* generic loop counter index */ |
|||
|
|||
|
|||
Digital_State_t *clk, /* current clk value */ |
|||
*clk_old, /* previous clk value */ |
|||
*set, /* current set value for dff */ |
|||
*set_old, /* previous set value for dff */ |
|||
*reset, /* current reset value for dff */ |
|||
*reset_old, /* previous reset value for dff */ |
|||
*out, /* current output for dff */ |
|||
*out_old, /* previous output for dff */ |
|||
|
|||
toggle_input, /* current toggle input value */ |
|||
|
|||
temp; /* temp storage for state values */ |
|||
|
|||
|
|||
|
|||
/*** Setup required state variables ***/ |
|||
|
|||
if(INIT) { /* initial pass */ |
|||
|
|||
/* allocate storage */ |
|||
clk = clk_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
set = set_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); |
|||
reset = reset_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(3,sizeof(Digital_State_t)); |
|||
|
|||
/* declare load values */ |
|||
LOAD(t) = PARAM(t_load); |
|||
LOAD(clk) = PARAM(clk_load); |
|||
if ( !PORT_NULL(set) ) { |
|||
LOAD(set) = PARAM(set_load); |
|||
} |
|||
if ( !PORT_NULL(reset) ) { |
|||
LOAD(reset) = PARAM(reset_load); |
|||
} |
|||
|
|||
} |
|||
else { /* Retrieve previous values */ |
|||
|
|||
/* retrieve storage for the outputs */ |
|||
clk = (Digital_State_t *) cm_event_get_ptr(0,0); |
|||
clk_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
set = (Digital_State_t *) cm_event_get_ptr(1,0); |
|||
set_old = (Digital_State_t *) cm_event_get_ptr(1,1); |
|||
reset = (Digital_State_t *) cm_event_get_ptr(2,0); |
|||
reset_old = (Digital_State_t *) cm_event_get_ptr(2,1); |
|||
out = (Digital_State_t *) cm_event_get_ptr(3,0); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(3,1); |
|||
} |
|||
|
|||
|
|||
|
|||
/******** load current input values if set or reset |
|||
are not connected, set to zero... ********/ |
|||
*clk = INPUT_STATE(clk); |
|||
if ( PORT_NULL(set) ) { |
|||
*set = *set_old = ZERO; |
|||
} |
|||
else { |
|||
*set = INPUT_STATE(set); |
|||
} |
|||
if ( PORT_NULL(reset) ) { |
|||
*reset = *reset_old = ZERO; |
|||
} |
|||
else { |
|||
*reset = INPUT_STATE(reset); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/******* Determine analysis type and output appropriate values *******/ |
|||
|
|||
if (0.0 == TIME) { /****** DC analysis...output w/o delays ******/ |
|||
|
|||
temp = PARAM(ic); |
|||
|
|||
/** Modify output if set or reset lines are active **/ |
|||
if ( (*set==ONE) && (*reset==ZERO) ) temp = ONE; |
|||
if ( (*set==ZERO) && (*reset==ONE) ) temp = ZERO; |
|||
if ( (*set==ONE) && (*reset==ONE) ) temp = UNKNOWN; |
|||
|
|||
*out = *out_old = temp; |
|||
|
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
} |
|||
} |
|||
|
|||
else { /****** Transient Analysis ******/ |
|||
|
|||
|
|||
/***** Find input that has changed... *****/ |
|||
|
|||
/**** Test set value for change ****/ |
|||
if ( *set != *set_old ) { /* either set or set release */ |
|||
switch ( *set ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *reset) { |
|||
if (*out_old != ONE) { /* set will change output */ |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already set */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* set will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *reset) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ZERO) { /* set will change output */ |
|||
/* output returns to reset condition */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
if ( ONE == *reset ) { |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(set_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(set_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test reset value for change ****/ |
|||
if ( *reset != *reset_old ) { /* either reset or reset release */ |
|||
switch ( *reset ) { |
|||
|
|||
case ONE: |
|||
if ( ONE != *set) { |
|||
if (*out_old != ZERO) { /* reset will change output */ |
|||
/* output goes to ZERO */ |
|||
*out = ZERO; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ZERO; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ONE; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != UNKNOWN) { /* reset will change output */ |
|||
/* output goes to UNKNOWN */ |
|||
*out = UNKNOWN; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = UNKNOWN; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = UNKNOWN; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
if ( ONE != *set) { |
|||
/* output remains at current value */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
else { |
|||
if (*out_old != ONE) { /* reset will change output */ |
|||
/* output returns to set condition */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already reset */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case UNKNOWN: |
|||
if ( ONE == *set ) { |
|||
/* output goes to ONE */ |
|||
*out = ONE; |
|||
|
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = ONE; |
|||
OUTPUT_DELAY(out) = PARAM(reset_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = ZERO; |
|||
OUTPUT_DELAY(Nout) = PARAM(reset_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output already unknown */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
else { |
|||
|
|||
/**** Test clk value for change ****/ |
|||
if ( (*clk != *clk_old) && (*reset != ONE) && |
|||
(*set != ONE) ) { /* clock or clock release */ |
|||
switch ( *clk ) { |
|||
|
|||
case ONE: |
|||
/* active edge...calculate new data output */ |
|||
toggle_input = INPUT_STATE(t); |
|||
|
|||
switch (toggle_input) { |
|||
case ONE: |
|||
temp = *out_old; |
|||
cm_toggle_bit(&temp); |
|||
break; |
|||
case ZERO: |
|||
temp = *out_old; |
|||
break; |
|||
case UNKNOWN: |
|||
temp = UNKNOWN; |
|||
break; |
|||
} |
|||
|
|||
if (*out_old != temp) { /* clk will change output */ |
|||
*out = temp; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STATE(out) = temp; |
|||
OUTPUT_DELAY(out) = PARAM(clk_delay); |
|||
} |
|||
|
|||
cm_toggle_bit(&temp); |
|||
|
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STATE(Nout) = temp; |
|||
OUTPUT_DELAY(Nout) = PARAM(clk_delay); |
|||
} |
|||
} |
|||
else { |
|||
*out = *out_old; /* output same as before */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case ZERO: |
|||
case UNKNOWN: |
|||
/* inactive edge...return previous values */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
break; |
|||
|
|||
} |
|||
} |
|||
|
|||
else { /* data value must have changed... |
|||
return previous output value. */ |
|||
*out = *out_old; |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_CHANGED(out) = FALSE; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_CHANGED(Nout) = FALSE; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/***** Add additional rise or fall delays, if appropriate *****/ |
|||
|
|||
if ( *out != *out_old ) { /*** output value is changing ***/ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/** fall to zero value **/ |
|||
case 0: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
break; |
|||
|
|||
/** rise to one value **/ |
|||
case 1: |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
break; |
|||
|
|||
/** unknown output **/ |
|||
default: |
|||
/* based on old value, add rise or fall delay */ |
|||
if (0 == *out_old) { /* add rising delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(rise_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(fall_delay); |
|||
} |
|||
} |
|||
else { /* add falling delay */ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_DELAY(out) += PARAM(fall_delay); |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_DELAY(Nout) += PARAM(rise_delay); |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*** output strength values ***/ |
|||
if ( !PORT_NULL(out) ) { |
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
} |
|||
if ( !PORT_NULL(Nout) ) { |
|||
OUTPUT_STRENGTH(Nout) = STRONG; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,123 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
2 Oct 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_tff code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
NAME_TABLE: |
|||
|
|||
|
|||
C_Function_Name: cm_d_tff |
|||
Spice_Model_Name: d_tff |
|||
Description: "digital toggle flip flop" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: t clk |
|||
Description: "toggle input" "clock" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: no no |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: set reset |
|||
Description: "asynch. set" "asynch. reset" |
|||
Direction: in in |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: out Nout |
|||
Description: "data output" "inverted data output" |
|||
Direction: out out |
|||
Default_Type: d d |
|||
Allowed_Types: [d] [d] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: clk_delay set_delay |
|||
Description: "delay from clk" "delay from set" |
|||
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: reset_delay ic |
|||
Description: "delay from reset" "output initial state" |
|||
Data_Type: real int |
|||
Default_Value: 1.0e-9 0 |
|||
Limits: [1e-12 -] [0 2] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
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 -] |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: t_load clk_load |
|||
Description: "toggle load value (F)" "clk load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: set_load reset_load |
|||
Description: "set load value (F)" "reset load value (F)" |
|||
Data_Type: real real |
|||
Default_Value: 1.0e-12 1.0e-12 |
|||
Limits: - - |
|||
Vector: no no |
|||
Vector_Bounds: - - |
|||
Null_Allowed: yes yes |
|||
|
|||
|
|||
@ -0,0 +1,166 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_tristate/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
PROJECT A-8503-405 |
|||
|
|||
|
|||
AUTHORS |
|||
|
|||
18 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
MODIFICATIONS |
|||
|
|||
26 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the functional description of the d_tristate |
|||
code model. |
|||
|
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== CONSTANTS ========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== MACROS ===========================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
FUNCTION cm_d_tristate() |
|||
|
|||
AUTHORS |
|||
|
|||
18 Nov 1991 Jeffrey P. Murray |
|||
|
|||
MODIFICATIONS |
|||
|
|||
26 Nov 1991 Jeffrey P. Murray |
|||
|
|||
SUMMARY |
|||
|
|||
This function implements the d_tristate code model. |
|||
|
|||
INTERFACES |
|||
|
|||
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 |
|||
|
|||
NONE |
|||
|
|||
==============================================================================*/ |
|||
|
|||
/*=== CM_D_TRISTATE ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is a model for a simple * |
|||
* digital tristate for the ATESSE Version * |
|||
* 2.0 system. Note that this version has * |
|||
* a single delay for both input and enable... * |
|||
* a more realistic model is anticipated in * |
|||
* the not-so-distant future. * |
|||
* * |
|||
* Created 11/18/91 J.P,Murray * |
|||
* Last Modified 11/26/91 * |
|||
************************************************/ |
|||
|
|||
|
|||
void cm_d_tristate(ARGS) |
|||
{ |
|||
int enable; /* holding variable for enable input */ |
|||
|
|||
|
|||
|
|||
/* Retrieve input values and static variables */ |
|||
enable = INPUT_STATE(enable); |
|||
|
|||
OUTPUT_STATE(out) = INPUT_STATE(in); |
|||
OUTPUT_DELAY(out) = PARAM(delay); |
|||
|
|||
|
|||
/* define input loading... */ |
|||
LOAD(in) = PARAM(input_load); |
|||
LOAD(enable) = PARAM(enable_load); |
|||
|
|||
|
|||
|
|||
|
|||
if (ZERO == enable) { |
|||
|
|||
OUTPUT_STRENGTH(out) = HI_IMPEDANCE; |
|||
|
|||
} |
|||
else |
|||
if (UNKNOWN == enable) { |
|||
|
|||
OUTPUT_STRENGTH(out) = UNDETERMINED; |
|||
|
|||
} |
|||
else { |
|||
|
|||
OUTPUT_STRENGTH(out) = STRONG; |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,76 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
AUTHORS |
|||
|
|||
18 Nov 1991 Jeffrey P. Murray |
|||
|
|||
|
|||
SUMMARY |
|||
|
|||
This file contains the interface specification file for the |
|||
digital d_tristate code model. |
|||
|
|||
===============================================================================*/ |
|||
|
|||
|
|||
NAME_TABLE: |
|||
|
|||
Spice_Model_Name: d_tristate |
|||
C_Function_Name: cm_d_tristate |
|||
Description: "digital one-bit-wide tristate buffer" |
|||
|
|||
|
|||
PORT_TABLE: |
|||
|
|||
Port_Name: in enable out |
|||
Description: "input" "enable" "output" |
|||
Direction: in in out |
|||
Default_Type: d d d |
|||
Allowed_Types: [d] [d] [d] |
|||
Vector: no no no |
|||
Vector_Bounds: - - - |
|||
Null_Allowed: no no no |
|||
|
|||
|
|||
PARAMETER_TABLE: |
|||
|
|||
Parameter_Name: delay |
|||
Description: "delay" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-9 |
|||
Limits: [1e-12 -] |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: 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_TABLE: |
|||
|
|||
Parameter_Name: enable_load |
|||
Description: "enable load value (F)" |
|||
Data_Type: real |
|||
Default_Value: 1.0e-12 |
|||
Limits: - |
|||
Vector: no |
|||
Vector_Bounds: - |
|||
Null_Allowed: yes |
|||
|
|||
|
|||
|
|||
@ -0,0 +1,322 @@ |
|||
/* $Id$ */ |
|||
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
|||
================================================================================ |
|||
|
|||
FILE d_xnor/cfunc.mod |
|||
|
|||
Copyright 1991 |
|||
Georgia Tech Research Corporation, Atlanta, Ga. 30332 |
|||
All Rights Reserved |
|||
|
|||
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 |
|||
|
|||
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 |
|||
|
|||
===============================================================================*/ |
|||
|
|||
/*=== INCLUDE FILES ====================*/ |
|||
|
|||
|
|||
|
|||
|
|||
/*=== 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 |
|||
|
|||
/*=============================================================================*/ |
|||
|
|||
/*=== 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 |
|||
without changing the bit value. */ |
|||
|
|||
if ( UNKNOWN != *bit ) { |
|||
if ( ONE == *bit ) { |
|||
*bit = ZERO; |
|||
} |
|||
else { |
|||
*bit = ONE; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/*============================================================================== |
|||
|
|||
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 |
|||
|
|||
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_XNOR ROUTINE ===*/ |
|||
|
|||
/************************************************ |
|||
* The following is the model for the * |
|||
* digital XNOR gate for the * |
|||
* ATESSE Version 2.0 system. * |
|||
* * |
|||
* 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 */ |
|||
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 */ |
|||
out = out_old = (Digital_State_t *) cm_event_alloc(0,sizeof(Digital_State_t)); |
|||
|
|||
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); |
|||
out_old = (Digital_State_t *) cm_event_get_ptr(0,1); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/*** Calculate new output value based on inputs ***/ |
|||
|
|||
*out = 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; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
/* at least one port is floating...output is unknown */ |
|||
*out = 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 **/ |
|||
|
|||
|
|||
if ( *out != *out_old ) { /* output value is changing */ |
|||
|
|||
switch ( *out ) { |
|||
|
|||
/* fall to zero value */ |
|||
case 0: OUTPUT_STATE(out) = 0; |
|||
OUTPUT_DELAY(out) = PARAM(fall_delay); |
|||
break; |
|||
|
|||
/* rise to one value */ |
|||
case 1: OUTPUT_STATE(out) = 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 */ |
|||
OUTPUT_DELAY(out) = PARAM(rise_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; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue