Added changes from tclspice 0.2.13
This commit is contained in:
parent
531d3a1fc6
commit
dd49ea7eaa
|
|
@ -5,7 +5,7 @@ dnl Create a configuration header
|
|||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Initialize automake stuff
|
||||
AM_INIT_AUTOMAKE(ng-spice-rework,14)
|
||||
AM_INIT_AUTOMAKE(ng-spice-rework,15pre1)
|
||||
|
||||
dnl --enable-ftedebug : enable frontend debug macros
|
||||
AC_ARG_ENABLE(ftedebug,
|
||||
|
|
@ -65,7 +65,6 @@ AM_MAINTAINER_MODE
|
|||
dnl Work on compiler options according to system:
|
||||
dnl Set default CFLAG - only use -Wall if we have gcc
|
||||
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
|
|
@ -420,8 +419,7 @@ src/maths/sparse/Makefile \
|
|||
src/misc/Makefile \
|
||||
src/xspice/Makefile \
|
||||
src/xspice/cm/Makefile \
|
||||
src/xspice/icm/Makefile \
|
||||
src/xspice/icm/icm_spice2poly/Makefile \
|
||||
src/xspice/icm/makedefs \
|
||||
src/xspice/mif/Makefile \
|
||||
src/xspice/evt/Makefile \
|
||||
src/xspice/enh/Makefile \
|
||||
|
|
|
|||
|
|
@ -15,49 +15,50 @@ initdatadir = $(pkgdatadir)/scripts
|
|||
initdata_DATA = spinit setplot spectrum
|
||||
|
||||
|
||||
DYNAMIC_DEVICELIBS = \
|
||||
spicelib/devices/asrc/libasrc.la \
|
||||
spicelib/devices/bjt/libbjt.la \
|
||||
spicelib/devices/bsim1/libbsim1.la \
|
||||
spicelib/devices/bsim2/libbsim2.la \
|
||||
spicelib/devices/bsim3/libbsim3.la \
|
||||
spicelib/devices/bsim3v1/libbsim3v1.la \
|
||||
spicelib/devices/bsim3v2/libbsim3v2.la \
|
||||
spicelib/devices/bsim4/libbsim4.la \
|
||||
spicelib/devices/cap/libcap.la \
|
||||
spicelib/devices/bsim3soi_pd/libbsim3soipd.la \
|
||||
spicelib/devices/bsim3soi_fd/libbsim3soifd.la \
|
||||
spicelib/devices/bsim3soi_dd/libbsim3soidd.la \
|
||||
spicelib/devices/cccs/libcccs.la \
|
||||
spicelib/devices/ccvs/libccvs.la \
|
||||
spicelib/devices/ccvs/libccvs.la \
|
||||
spicelib/devices/cpl/libcpl.a \
|
||||
spicelib/devices/csw/libcsw.la \
|
||||
spicelib/devices/dio/libdio.la \
|
||||
@EKVLIB@ \
|
||||
spicelib/devices/ind/libind.la \
|
||||
spicelib/devices/isrc/libisrc.la \
|
||||
spicelib/devices/hfet1/libhfet.la \
|
||||
spicelib/devices/hfet2/libhfet2.la \
|
||||
spicelib/devices/jfet/libjfet.la \
|
||||
spicelib/devices/jfet2/libjfet2.la \
|
||||
spicelib/devices/ltra/libltra.la \
|
||||
spicelib/devices/mes/libmes.la \
|
||||
spicelib/devices/mesa/libmesa.la \
|
||||
spicelib/devices/mos1/libmos1.la \
|
||||
spicelib/devices/mos2/libmos2.la \
|
||||
spicelib/devices/mos3/libmos3.la \
|
||||
spicelib/devices/mos6/libmos6.la \
|
||||
spicelib/devices/mos9/libmos9.la \
|
||||
spicelib/devices/res/libres.la \
|
||||
spicelib/devices/soi3/libsoi3.la \
|
||||
spicelib/devices/sw/libsw.la \
|
||||
spicelib/devices/txl/libtxl.a \
|
||||
spicelib/devices/tra/libtra.la \
|
||||
spicelib/devices/urc/liburc.la \
|
||||
spicelib/devices/vccs/libvccs.la \
|
||||
spicelib/devices/vcvs/libvcvs.la \
|
||||
spicelib/devices/vsrc/libvsrc.la
|
||||
DYNAMIC_DEVICELIBS = \
|
||||
spicelib/devices/asrc/libasrc.a \
|
||||
spicelib/devices/bjt/libbjt.a \
|
||||
spicelib/devices/bsim1/libbsim1.a \
|
||||
spicelib/devices/bsim2/libbsim2.a \
|
||||
spicelib/devices/bsim3/libbsim3.a \
|
||||
spicelib/devices/bsim3v1/libbsim3v1.a \
|
||||
spicelib/devices/bsim3v2/libbsim3v2.a \
|
||||
spicelib/devices/bsim4/libbsim4.a \
|
||||
spicelib/devices/cap/libcap.a \
|
||||
spicelib/devices/bsim3soi_pd/libbsim3soipd.a \
|
||||
spicelib/devices/bsim3soi_fd/libbsim3soifd.a \
|
||||
spicelib/devices/bsim3soi_dd/libbsim3soidd.a \
|
||||
spicelib/devices/cccs/libcccs.a \
|
||||
spicelib/devices/ccvs/libccvs.a \
|
||||
spicelib/devices/ccvs/libccvs.a \
|
||||
spicelib/devices/cpl/libcpl.a \
|
||||
spicelib/devices/csw/libcsw.a \
|
||||
spicelib/devices/dio/libdio.a \
|
||||
@EKVLIB@ \
|
||||
spicelib/devices/ind/libind.a \
|
||||
spicelib/devices/isrc/libisrc.a \
|
||||
spicelib/devices/hfet1/libhfet.a \
|
||||
spicelib/devices/hfet2/libhfet2.a \
|
||||
spicelib/devices/jfet/libjfet.a \
|
||||
spicelib/devices/jfet2/libjfet2.a \
|
||||
spicelib/devices/ltra/libltra.a \
|
||||
spicelib/devices/mes/libmes.a \
|
||||
spicelib/devices/mesa/libmesa.a \
|
||||
spicelib/devices/mos1/libmos1.a \
|
||||
spicelib/devices/mos2/libmos2.a \
|
||||
spicelib/devices/mos3/libmos3.a \
|
||||
spicelib/devices/mos6/libmos6.a \
|
||||
spicelib/devices/mos9/libmos9.a \
|
||||
spicelib/devices/res/libres.a \
|
||||
spicelib/devices/soi3/libsoi3.a \
|
||||
spicelib/devices/sw/libsw.a \
|
||||
spicelib/devices/txl/libtxl.a \
|
||||
spicelib/devices/tra/libtra.a \
|
||||
spicelib/devices/urc/liburc.a \
|
||||
spicelib/devices/vccs/libvccs.a \
|
||||
spicelib/devices/vcvs/libvcvs.a \
|
||||
spicelib/devices/vsrc/libvsrc.a
|
||||
|
||||
|
||||
|
||||
## ----- Note that I moved this stuff to here because it was causing automake
|
||||
|
|
@ -67,7 +68,6 @@ DYNAMIC_DEVICELIBS = \
|
|||
## poly added to dynamic libs by SDB on 6.1.2003
|
||||
## xspice/icm/poly/libpoly.a
|
||||
|
||||
|
||||
## Build ngspice first:
|
||||
|
||||
ngspice_SOURCES = \
|
||||
|
|
@ -123,8 +123,6 @@ ngnutmeg_LDADD = \
|
|||
maths/poly/libpoly.a \
|
||||
misc/libmisc.a
|
||||
|
||||
|
||||
|
||||
## help:
|
||||
|
||||
nghelp_SOURCES = nghelp.c
|
||||
|
|
@ -135,7 +133,6 @@ nghelp_LDADD = \
|
|||
frontend/libfte.a \
|
||||
misc/libmisc.a
|
||||
|
||||
|
||||
## sconvert:
|
||||
|
||||
ngsconvert_SOURCES = ngsconvert.c
|
||||
|
|
@ -147,7 +144,6 @@ ngsconvert_LDADD = \
|
|||
frontend/parser/libparser.a \
|
||||
misc/libmisc.a
|
||||
|
||||
|
||||
## proc2mod:
|
||||
|
||||
ngproc2mod_SOURCES = ngproc2mod.c
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "conf.h"
|
||||
|
||||
char Spice_Version[ ] = VERSION;
|
||||
char Spice_Notice[ ] = "Please submit bug-reports to: ng-spice-bugs@ieee.ing.uniroma1.it";
|
||||
char Spice_Notice[ ] = "Please submit bug-reports to: ngspice-devel@lists.sourceforge.net";
|
||||
char Spice_Build_Date[ ] = NGSPICEBUILDDATE;
|
||||
/*
|
||||
char *Spice_Exec_Dir = "/spice_win/bin";
|
||||
|
|
@ -23,7 +23,7 @@ int AsciiRawFile = 0;
|
|||
#endif
|
||||
|
||||
|
||||
char *Bug_Addr = "ng-spice-bugs@ieee.ing.uniroma1.it";
|
||||
char *Bug_Addr = "ngspice-devel@lists.sourceforge.net";
|
||||
char *Spice_Host = "";
|
||||
char *Spiced_Log = "";
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ com_bug(wordlist *wl)
|
|||
void
|
||||
com_bug(wordlist *wl)
|
||||
{
|
||||
fprintf(cp_out, "Send mail to the address ng-spice@ieee.ing.uniroma1.it\n");
|
||||
fprintf(cp_out, "Send mail to the address ngspice-devel@lists.sourceforge.net\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,10 @@ alias acct rusage all
|
|||
set x11lineararcs
|
||||
* For SPICE2 POLYs, edit the below line to point to the location
|
||||
* of your codemode.
|
||||
* codemodel /usr/local/src/ngspice/src/xspice/icm/spice2poly.cm
|
||||
* codemodel /usr/lib/spice/spice2poly.cm
|
||||
|
||||
* The other codemodels
|
||||
* codemodel /usr/lib/spice/analog.cm
|
||||
* codemodel /usr/lib/spice/digital.cm
|
||||
* codemodel /usr/lib/spice/xtradev.cm
|
||||
* codemodel /usr/lib/spice/xtraevt.cm
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 have changed in this diff Show More
Loading…
Reference in New Issue